Skip to content
Permalink
Browse files
A black screen appears in a muted video element outside the viewport
https://bugs.webkit.org/show_bug.cgi?id=241152
rdar://problem/94562636

Patch by Youenn Fablet <youennf@gmail.com> on 2022-06-16
Reviewed by Eric Carlson.

We sometimes remove the invisible autoplay restrictions.
If we remove it while we are suspended due this restriction, we will not unsuspend and will wait for a user interaction.
To prevent this, we do not return early in updateShouldAutoplay if we are interrupted due to the invisible autoplay restriction.

* LayoutTests/fast/mediastream/video-mediastream-restricted-invisible-autoplay-user-click-expected.txt: Added.
* LayoutTests/fast/mediastream/video-mediastream-restricted-invisible-autoplay-user-click.html: Added.
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::updateShouldAutoplay):

Canonical link: https://commits.webkit.org/251596@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295591 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
youennf authored and webkit-commit-queue committed Jun 16, 2022
1 parent f137908 commit 0146d529d1fb0cae5a57149d65ca99e66d02cf3a
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
@@ -0,0 +1,4 @@


PASS Removing behavior restrictions should not disallow invisible uninterruption

@@ -0,0 +1,54 @@
<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
if (window.internals)
internals.settings.setInvisibleAutoplayNotPermitted(true);
</script>
</head>
<body>
<video id="localVideo1" controls autoplay></video>
<video id="localVideo2" controls autoplay></video>

<script>
async function waitForPlay(video)
{
if (!video.paused)
return;
return new Promise(resolve => { video.onplay = resolve; });
}

async function waitForPause(video)
{
if (video.paused)
return;
return new Promise(resolve => { video.onpause = resolve; });
}

promise_test(async () => {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
localVideo1.srcObject = stream;
localVideo2.srcObject = stream;

await Promise.all([waitForPlay(localVideo1), waitForPlay(localVideo2)]);

localVideo1.style.display = "none";
localVideo2.style.display = "none";

await Promise.all([waitForPause(localVideo1), waitForPause(localVideo2)]);

if (!window.internals)
return;
internals.withUserGesture(() => {
localVideo2.srcObject = stream;
});

localVideo1.style.removeProperty("display");
localVideo2.style.removeProperty("display");

await Promise.all([waitForPlay(localVideo1), waitForPlay(localVideo2)]);
}, "Removing behavior restrictions should not disallow invisible uninterruption");
</script>
</body>
</html>
@@ -8384,7 +8384,7 @@ void HTMLMediaElement::updateShouldAutoplay()
if (!autoplay())
return;

if (!mediaSession().hasBehaviorRestriction(MediaElementSession::InvisibleAutoplayNotPermitted))
if (!mediaSession().hasBehaviorRestriction(MediaElementSession::InvisibleAutoplayNotPermitted) && !m_wasInterruptedForInvisibleAutoplay)
return;

bool canAutoplay = mediaSession().autoplayPermitted();

0 comments on commit 0146d52

Please sign in to comment.