Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Media continues loading after rendered invisible (removed from DOM; s…
…crolled off screen) https://bugs.webkit.org/show_bug.cgi?id=185487 Reviewed by Eric Carlson. Source/WebCore: Test: media/video-buffering-allowed.html When a media element is removed from the dom (e.g. through innerHTML=""), it doesn't necessarily stop loading media data; it will continue to do so until its destructor is called through garbage collection. Similarly, when a media element is rendered not-visible by being scrolled off-screen or being made display:none, media loading continues. There are legitimate use cases for out-of-DOM media loading, so only temporarily block loading when the element transitions out of the document. Similarly, only block loading for non-visible media elements when returning from the "page is hidden" state, and only until the media element is asked to play or is otherwise made visible. Note: this refactors a lot of code out of PlatformMediaSession and into MediaElementSession, since this code is specific to "media elements". * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): (WebCore::HTMLMediaElement::insertedIntoAncestor): (WebCore::HTMLMediaElement::removedFromAncestor): (WebCore::HTMLMediaElement::playInternal): (WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): (WebCore::HTMLMediaElement::resume): (WebCore::HTMLMediaElement::visibilityStateChanged): (WebCore::HTMLMediaElement::createMediaPlayer): (WebCore::HTMLMediaElement::setShouldBufferData): (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible): (WebCore::HTMLMediaElement::isVisibleInViewportChanged): (WebCore::HTMLMediaElement::fullscreenModeChanged): (WebCore::HTMLMediaElement::setInActiveDocument): * html/HTMLMediaElement.h: (WebCore::HTMLMediaElement::shouldBufferData const): (WebCore::HTMLMediaElement::elementIsHidden const): * html/MediaElementSession.cpp: (WebCore::MediaElementSession::MediaElementSession): (WebCore::MediaElementSession::clientWillBeginAutoplaying): (WebCore::MediaElementSession::clientWillBeginPlayback): (WebCore::MediaElementSession::clientWillPausePlayback): (WebCore::MediaElementSession::visibilityChanged): (WebCore::MediaElementSession::isVisibleInViewportChanged): (WebCore::MediaElementSession::inActiveDocumentChanged): (WebCore::MediaElementSession::scheduleClientDataBufferingCheck): (WebCore::MediaElementSession::clientDataBufferingTimerFired): (WebCore::MediaElementSession::updateClientDataBuffering): (WebCore::MediaElementSession::dataBufferingPermitted const): (WebCore::MediaElementSession::wantsToObserveViewportVisibilityForAutoplay const): * html/MediaElementSession.h: * platform/audio/PlatformMediaSession.cpp: (WebCore::PlatformMediaSession::PlatformMediaSession): (WebCore::PlatformMediaSession::clientWillBeginAutoplaying): (WebCore::PlatformMediaSession::clientWillBeginPlayback): (WebCore::PlatformMediaSession::clientWillPausePlayback): (): Deleted. (WebCore::PlatformMediaSession::visibilityChanged): Deleted. (WebCore::PlatformMediaSession::scheduleClientDataBufferingCheck): Deleted. (WebCore::PlatformMediaSession::clientDataBufferingTimerFired): Deleted. (WebCore::PlatformMediaSession::updateClientDataBuffering): Deleted. (WebCore::PlatformMediaSession::isHidden const): Deleted. * platform/audio/PlatformMediaSession.h: (WebCore::PlatformMediaSessionClient::setShouldBufferData): Deleted. (WebCore::PlatformMediaSessionClient::elementIsHidden const): Deleted. * platform/audio/PlatformMediaSessionManager.cpp: (WebCore::PlatformMediaSessionManager::sessionCanLoadMedia const): Deleted. * platform/audio/PlatformMediaSessionManager.h: * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionCanLoadMedia const): Deleted. * rendering/RenderVideo.cpp: (WebCore::RenderVideo::willBeDestroyed): * testing/Internals.cpp: (WebCore::Internals::elementShouldBufferData): * testing/Internals.h: * testing/Internals.idl: LayoutTests: * media/video-buffering-allowed-expected.txt: Added. * media/video-buffering-allowed.html: Added. * media/video-test.js: (compare): (testExpected): (sleepFor): (testArraysEqual): Deleted. Canonical link: https://commits.webkit.org/201128@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231817 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
Showing
20 changed files
with
436 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
RUN(video.src = findMediaFile("video", "content/test")) | ||
EVENT(canplaythrough) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
* Remove the video element from the document. | ||
RUN(video.parentNode.removeChild(video)) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'false') OK | ||
* Play the video. | ||
RUN(video.play()) | ||
EVENT(playing) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
* Pause the video. | ||
RUN(video.pause()) | ||
EVENT(pause) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
* Re-insert the video element into the document. | ||
RUN(document.body.insertBefore(video, document.body.firstChild)) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
* display:none the video element. | ||
RUN(video.style.display = "none") | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
* Simulate the view becoming invisible. | ||
RUN(internals.setPageVisibility(false)) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'false') OK | ||
* Simulate the view becoming visible. | ||
RUN(internals.setPageVisibility(true)) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'false') OK | ||
* Remove display:none from the video element. | ||
RUN(video.style.removeProperty("display")) | ||
EXPECTED (internals.elementShouldBufferData(video) == 'true') OK | ||
END OF TEST | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>video-buffering-allowed</title> | ||
<script src=media-file.js></script> | ||
<script src=video-test.js></script> | ||
<script> | ||
async function runTest() { | ||
findMediaElement(); | ||
failTestIn(1000); | ||
|
||
run('video.src = findMediaFile("video", "content/test")'); | ||
await waitFor(video, 'canplaythrough'); | ||
testExpected('internals.elementShouldBufferData(video)', true); | ||
|
||
consoleWrite('* Remove the video element from the document.'); | ||
run('video.parentNode.removeChild(video)'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', false); | ||
|
||
consoleWrite('* Play the video.'); | ||
run ('video.play()'); | ||
await waitFor(video, 'playing'); | ||
testExpected('internals.elementShouldBufferData(video)', true); | ||
|
||
consoleWrite('* Pause the video.'); | ||
run('video.pause()'); | ||
await waitFor(video, 'pause'); | ||
testExpected('internals.elementShouldBufferData(video)', true); | ||
|
||
consoleWrite('* Re-insert the video element into the document.'); | ||
run('document.body.insertBefore(video, document.body.firstChild)'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', true); | ||
|
||
consoleWrite('* display:none the video element.'); | ||
run('video.style.display = "none"'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', true); | ||
|
||
consoleWrite('* Simulate the view becoming invisible.'); | ||
run('internals.setPageVisibility(false)'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', false); | ||
|
||
consoleWrite('* Simulate the view becoming visible.'); | ||
run('internals.setPageVisibility(true)'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', false); | ||
|
||
consoleWrite('* Remove display:none from the video element.'); | ||
run('video.style.removeProperty("display")'); | ||
await testExpectedEventually('internals.elementShouldBufferData(video)', true); | ||
|
||
endTest(); | ||
} | ||
window.addEventListener('load', runTest); | ||
</script> | ||
</head> | ||
<body> | ||
<video controls></video> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.