Title: [221016] trunk
- Revision
- 221016
- Author
- [email protected]
- Date
- 2017-08-22 09:13:22 -0700 (Tue, 22 Aug 2017)
Log Message
Autoplay Muted Videos Don't Play When Outside Viewport
https://bugs.webkit.org/show_bug.cgi?id=175748
<rdar://problem/33974383>
Reviewed by Eric Carlson.
Source/WebCore:
Test: media/video-restricted-invisible-autoplay-not-allowed-source.html
The media session is notified that its client (the media element) will begin autoplaying inside
prepareForLoad(), where the m_autoplaying flag is also set. But loading via <source> elements does not go
through prepareForLoad(); the HTML standard states that the <source> element loading path does not trigger the
"media element load algorithm" which is implemented in prepareForLoad(). Since the m_autoplaying flag is
initially set to true, notify the media session that the element will begin autoplaying inside the element's
constructor.
Drive-by fix: Doing the above causes other tests to crash, as purturbing play state during style change can cause
re-entrancy in the native controls code, or fail, since we will transition from autoplay -> play even if there's
not yet a src or source to the media element. Add a task queue for updating the autoplay state and check the ready
state before allowing autoplay to transition to play.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::~HTMLMediaElement):
(WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay const):
(WebCore::HTMLMediaElement::isVisibleInViewportChanged):
LayoutTests:
* media/video-restricted-invisible-autoplay-not-allowed-source-expected.txt: Added.
* media/video-restricted-invisible-autoplay-not-allowed-source.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (221015 => 221016)
--- trunk/LayoutTests/ChangeLog 2017-08-22 16:03:26 UTC (rev 221015)
+++ trunk/LayoutTests/ChangeLog 2017-08-22 16:13:22 UTC (rev 221016)
@@ -1,3 +1,14 @@
+2017-08-22 Jer Noble <[email protected]>
+
+ Autoplay Muted Videos Don't Play When Outside Viewport
+ https://bugs.webkit.org/show_bug.cgi?id=175748
+ <rdar://problem/33974383>
+
+ Reviewed by Eric Carlson.
+
+ * media/video-restricted-invisible-autoplay-not-allowed-source-expected.txt: Added.
+ * media/video-restricted-invisible-autoplay-not-allowed-source.html: Added.
+
2017-08-21 Matt Rajca <[email protected]>
Call updateIsPlayingMedia whenever m_userHasInteractedWithMediaElement changes
Added: trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source-expected.txt (0 => 221016)
--- trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source-expected.txt (rev 0)
+++ trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source-expected.txt 2017-08-22 16:13:22 UTC (rev 221016)
@@ -0,0 +1,21 @@
+
+Test that "invisible autoplay not allowed restriction" pauses media when scrolled out of view.
+
+** setting video source.src
+
+EVENT(play)
+RUN(video.style.display = "none")
+EVENT(pause)
+RUN(video.style.removeProperty("display"))
+EVENT(play)
+RUN(video.style.visibility = "hidden")
+EVENT(pause)
+RUN(video.style.removeProperty("visibility"))
+EVENT(play)
+RUN(document.documentElement.style.height = window.innerHeight + 20 + video.offsetHeight)
+RUN(window.scrollBy(0, 20 + video.offsetHeight))
+EVENT(pause)
+RUN(window.scrollTo(0, 0))
+EVENT(play)
+END OF TEST
+
Added: trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source.html (0 => 221016)
--- trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source.html (rev 0)
+++ trunk/LayoutTests/media/video-restricted-invisible-autoplay-not-allowed-source.html 2017-08-22 16:13:22 UTC (rev 221016)
@@ -0,0 +1,65 @@
+<html>
+ <head>
+ <script src=""
+ <script src=""
+ <script>
+ if (window.internals)
+ internals.settings.setInvisibleAutoplayNotPermitted(true);
+
+ function start()
+ {
+ findMediaElement();
+ consoleWrite('** setting video source.src');
+ var source = document.createElement('source');
+ source.src = "" 'content/test');
+ video.appendChild(source);
+ video.muted = true;
+
+ waitForEventOnce('play', play1);
+ consoleWrite('');
+ }
+
+ function play1()
+ {
+ run('video.style.display = "none"');
+ waitForEventOnce('pause', pause1);
+ }
+
+ function pause1()
+ {
+ run('video.style.removeProperty("display")')
+ waitForEventOnce('play', play2);
+ }
+
+ function play2()
+ {
+ run('video.style.visibility = "hidden"');
+ waitForEventOnce('pause', pause2);
+ }
+
+ function pause2()
+ {
+ run('video.style.removeProperty("visibility")');
+ waitForEventOnce('play', play3);
+ }
+
+ function play3()
+ {
+ run('document.documentElement.style.height = window.innerHeight + 20 + video.offsetHeight');
+ run('window.scrollBy(0, 20 + video.offsetHeight)');
+ waitForEventOnce('pause', pause3);
+ }
+
+ function pause3()
+ {
+ run('window.scrollTo(0, 0)');
+ waitForEventOnce('play', endTest);
+ }
+ </script>
+ </head>
+
+ <body _onload_="start()">
+ <video autoplay></video>
+ <p>Test that "invisible autoplay not allowed restriction" pauses media when scrolled out of view.</p>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (221015 => 221016)
--- trunk/Source/WebCore/ChangeLog 2017-08-22 16:03:26 UTC (rev 221015)
+++ trunk/Source/WebCore/ChangeLog 2017-08-22 16:13:22 UTC (rev 221016)
@@ -1,3 +1,31 @@
+2017-08-22 Jer Noble <[email protected]>
+
+ Autoplay Muted Videos Don't Play When Outside Viewport
+ https://bugs.webkit.org/show_bug.cgi?id=175748
+ <rdar://problem/33974383>
+
+ Reviewed by Eric Carlson.
+
+ Test: media/video-restricted-invisible-autoplay-not-allowed-source.html
+
+ The media session is notified that its client (the media element) will begin autoplaying inside
+ prepareForLoad(), where the m_autoplaying flag is also set. But loading via <source> elements does not go
+ through prepareForLoad(); the HTML standard states that the <source> element loading path does not trigger the
+ "media element load algorithm" which is implemented in prepareForLoad(). Since the m_autoplaying flag is
+ initially set to true, notify the media session that the element will begin autoplaying inside the element's
+ constructor.
+
+ Drive-by fix: Doing the above causes other tests to crash, as purturbing play state during style change can cause
+ re-entrancy in the native controls code, or fail, since we will transition from autoplay -> play even if there's
+ not yet a src or source to the media element. Add a task queue for updating the autoplay state and check the ready
+ state before allowing autoplay to transition to play.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+ (WebCore::HTMLMediaElement::~HTMLMediaElement):
+ (WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay const):
+ (WebCore::HTMLMediaElement::isVisibleInViewportChanged):
+
2017-08-21 Matt Rajca <[email protected]>
Call updateIsPlayingMedia whenever m_userHasInteractedWithMediaElement changes
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (221015 => 221016)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-08-22 16:03:26 UTC (rev 221015)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-08-22 16:13:22 UTC (rev 221016)
@@ -519,6 +519,8 @@
#if USE(AUDIO_SESSION) && PLATFORM(MAC)
AudioSession::sharedSession().addMutedStateObserver(this);
#endif
+
+ mediaSession().clientWillBeginAutoplaying();
}
HTMLMediaElement::~HTMLMediaElement()
@@ -595,6 +597,7 @@
m_updatePlaybackControlsManagerQueue.close();
m_playbackControlsManagerBehaviorRestrictionsQueue.close();
m_resourceSelectionTaskQueue.close();
+ m_visibilityChangeTaskQueue.close();
#if ENABLE(ENCRYPTED_MEDIA)
m_encryptedMediaQueue.close();
#endif
@@ -2332,11 +2335,12 @@
SuccessOr<MediaPlaybackDenialReason> HTMLMediaElement::canTransitionFromAutoplayToPlay() const
{
if (isAutoplaying()
- && mediaSession().autoplayPermitted()
- && paused()
- && autoplay()
- && !pausedForUserInteraction()
- && !document().isSandboxed(SandboxAutomaticFeatures))
+ && mediaSession().autoplayPermitted()
+ && paused()
+ && autoplay()
+ && !pausedForUserInteraction()
+ && !document().isSandboxed(SandboxAutomaticFeatures)
+ && m_readyState == HAVE_ENOUGH_DATA)
return mediaSession().playbackPermitted(*this);
RELEASE_LOG(Media, "HTMLMediaElement::canTransitionFromAutoplayToPlay - page consent required");
@@ -7621,8 +7625,10 @@
void HTMLMediaElement::isVisibleInViewportChanged()
{
- updateShouldAutoplay();
- scheduleUpdatePlaybackControlsManager();
+ m_visibilityChangeTaskQueue.enqueueTask([this] {
+ updateShouldAutoplay();
+ scheduleUpdatePlaybackControlsManager();
+ });
}
void HTMLMediaElement::updateShouldAutoplay()
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (221015 => 221016)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2017-08-22 16:03:26 UTC (rev 221015)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2017-08-22 16:13:22 UTC (rev 221016)
@@ -901,6 +901,7 @@
GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue;
GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
GenericTaskQueue<Timer> m_resourceSelectionTaskQueue;
+ GenericTaskQueue<Timer> m_visibilityChangeTaskQueue;
RefPtr<TimeRanges> m_playedTimeRanges;
GenericEventQueue m_asyncEventQueue;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes