Skip to content

Commit

Permalink
[MSE] If src attribute is defined, ignore source alternative
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=274195
rdar://128098363

Reviewed by Youenn Fablet and Eric Carlson.

Per spec, if a media element has a src attribute defined, `<source>` alternative are ignored.
As such we should ignore the presence of the source children if a src attribute is set to determine
if the ManagedMediaSource is in open state.

* LayoutTests/media/media-source/media-managedmse-airplay-expected.txt:
* LayoutTests/media/media-source/media-managedmse-airplay-withsrc-expected.txt: Added.
* LayoutTests/media/media-source/media-managedmse-airplay-withsrc.html: Copied from LayoutTests/media/media-source/media-managedmse-airplay.html.
* LayoutTests/media/media-source/media-managedmse-airplay.html:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/ios/TestExpectations:
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::hasWirelessPlaybackTargetAlternative const):

Canonical link: https://commits.webkit.org/278834@main
  • Loading branch information
jyavenard committed May 15, 2024
1 parent 316776c commit fb01f88
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ EVENT(sourceopen)
RUN(sourceOpenAllowed = false)
RUN(video.disableRemotePlayback = false)
RUN(source = new ManagedMediaSource())
RUN(video.src = URL.createObjectURL(source))
RUN(sourceElement = document.createElement("source"))
RUN(sourceElement.src = "http://foo.com/playlist.m3u8")
RUN(sourceElement.type = "application/vnd.apple.mpegurl")
RUN(video.appendChild(sourceElement))
RUN(video.removeAttribute("src"))
RUN(sourceElement1 = document.createElement("source"))
RUN(sourceElement1.src = URL.createObjectURL(source))
RUN(video.appendChild(sourceElement1))
RUN(sourceElement2 = document.createElement("source"))
RUN(sourceElement2.src = "http://foo.com/playlist.m3u8")
RUN(sourceElement2.type = "application/vnd.apple.mpegurl")
RUN(video.appendChild(sourceElement2))
RUN(sourceOpenAllowed = true)
EVENT(sourceopen)
END OF TEST
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

RUN(source = new ManagedMediaSource())
RUN(url = URL.createObjectURL(source))
RUN(video.src = url)
RUN(sourceElement1 = document.createElement("source"))
RUN(sourceElement1.src = url)
RUN(video.appendChild(sourceElement1))
RUN(sourceElement2 = document.createElement("source"))
RUN(sourceElement2.src = "http://foo.com/playlist.m3u8")
RUN(sourceElement2.type = "application/vnd.apple.mpegurl")
RUN(video.appendChild(sourceElement2))
RUN(video.load())
RUN(video.removeAttribute("src"))
RUN(video.load())
RUN(sourceOpenAllowed = true)
EVENT(sourceopen)
END OF TEST

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html> <!-- webkit-test-runner [ ManagedMediaSourceEnabled=true MediaSourceEnabled=true ] -->
<html>
<head>
<title>managedmediasource-airplay</title>
<script src="../../media/media-source/media-source-loader.js"></script>
<script src="../../media/video-test.js"></script>
<script src="../../media/utilities.js"></script>
<script>
var loader;
var source;
var sourceBuffer;
var sourceElement1;
var sourceElement2;
var sourceOpenAllowed = false;
var url;

function loaderPromise(loader) {
return new Promise((resolve, reject) => {
loader.onload = resolve;
loader.onerror = reject;
});
}

window.addEventListener('load', async event => {
try {
findMediaElement();

let manifests = [ 'content/test-opus-manifest.json', 'content/test-vorbis-manifest.json', 'content/test-48khz-manifest.json', 'content/test-xhe-aac-manifest.json' ];
for (const manifest of manifests) {
loader = new MediaSourceLoader(manifest);
await loaderPromise(loader);
if (ManagedMediaSource.isTypeSupported(loader.type()))
break;
}

waitFor(video, 'error').then(failTest);

run('source = new ManagedMediaSource()');
waitFor(source, 'sourceopen').then(() => {
if (!sourceOpenAllowed)
failTest()
endTest();
});

run('url = URL.createObjectURL(source)');
run('video.src = url');
await sleepFor(100);

run('sourceElement1 = document.createElement("source")');
run('sourceElement1.src = url');
run('video.appendChild(sourceElement1)');

await sleepFor(100);

run('sourceElement2 = document.createElement("source")');
run('sourceElement2.src = "http://foo.com/playlist.m3u8"');
run('sourceElement2.type = "application/vnd.apple.mpegurl"');
run('video.appendChild(sourceElement2)');
run('video.load()');

await sleepFor(100);
run('video.removeAttribute("src")');
run('video.load()');

run('sourceOpenAllowed = true');
} catch (e) {
failTest(`Caught exception: "${e}"`);
}
});
</script>
</head>
<body>
<video controls></video>
</body>
</html>
18 changes: 12 additions & 6 deletions LayoutTests/media/media-source/media-managedmse-airplay.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
var loader;
var source;
var sourceBuffer;
var sourceElement;
var sourceElement1;
var sourceElement2;
var sourceOpenAllowed = false;

function loaderPromise(loader) {
Expand Down Expand Up @@ -57,13 +58,18 @@
endTest();
});

run('video.src = URL.createObjectURL(source)');
run('video.removeAttribute("src")');
await sleepFor(100);

run('sourceElement1 = document.createElement("source")');
run('sourceElement1.src = URL.createObjectURL(source)');
run('video.appendChild(sourceElement1)');
await sleepFor(100);

run('sourceElement = document.createElement("source")');
run('sourceElement.src = "http://foo.com/playlist.m3u8"');
run('sourceElement.type = "application/vnd.apple.mpegurl"');
run('video.appendChild(sourceElement)');
run('sourceElement2 = document.createElement("source")');
run('sourceElement2.src = "http://foo.com/playlist.m3u8"');
run('sourceElement2.type = "application/vnd.apple.mpegurl"');
run('video.appendChild(sourceElement2)');
run('sourceOpenAllowed = true');

} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions LayoutTests/platform/glib/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,7 @@ webkit.org/b/158923 media/modern-media-controls/placard-support/placard-support-
webkit.org/b/158923 media/modern-media-controls/placard-support/placard-support-airplay-fullscreen.html [ Skip ]
webkit.org/b/206528 imported/w3c/web-platform-tests/remote-playback [ Skip ]
media/media-source/media-managedmse-airplay.html [ Skip ]
media/media-source/media-managedmse-airplay-withsrc.html [ Skip ]

# LEGACY_ENCRYPTED_MEDIA is deprecated
fast/events/webkit-media-key-events-constructor.html [ Skip ]
Expand Down
1 change: 1 addition & 0 deletions LayoutTests/platform/ios/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ http/tests/media/modern-media-controls/overflow-support [ Pass ]
# media/modern-media-controls/tracks-support [ Pass ]

media/media-source/media-managedmse-airplay.html [ Pass ]
media/media-source/media-managedmse-airplay-withsrc.html [ Pass ]
media/media-source/media-managedmse-idl.html [ Pass ]
webkit.org/b/269897 media/media-source/media-managedmse-poster.html [ Skip ]

Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/html/HTMLMediaElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6873,6 +6873,8 @@ void HTMLMediaElement::remoteHasAvailabilityCallbacksChanged()

bool HTMLMediaElement::hasWirelessPlaybackTargetAlternative() const
{
if (m_loadState != LoadingFromSourceElement)
return false;
for (auto& source : childrenOfType<HTMLSourceElement>(*this)) {
auto mediaURL = source.getNonEmptyURLAttribute(srcAttr);
bool maybeSuitable = !mediaURL.isEmpty();
Expand Down

0 comments on commit fb01f88

Please sign in to comment.