Skip to content
Permalink
Browse files
[MSE] Should not seek with no seekable range
https://bugs.webkit.org/show_bug.cgi?id=247602

Reviewed by Jer Noble.

According https://html.spec.whatwg.org/multipage/media.html#seeking,
"If there are no ranges given in the seekable attribute then set
 the seeking IDL attribute to false and return."
For live streaming videos, their duration is infinity, then there
is no seekable range. So 'seek' should be aborted in this case.

* LayoutTests/media/media-source/media-source-no-seek-with-infinite-duration-expected.txt: Added.
* LayoutTests/media/media-source/media-source-no-seek-with-infinite-duration.html: Test seeking
status and currentTime with an infinite duration.
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::seekTask): Added a condtion to check if there is no seekable range
for for notifying the mdedia engine of a seek.

Canonical link: https://commits.webkit.org/256759@main
  • Loading branch information
ykimot authored and donny-dont committed Nov 17, 2022
1 parent dd4f45d commit ab539817a72136ed0d4a41d1489404ee9a0259dc
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
@@ -0,0 +1,15 @@
This test checks if seeking status and currentTime when duration is infinity.

RUN(video.currentTime = 1.0)
RUN(source = new MediaSource())
EVENT(sourceopen)
EXPECTED (mediaElement.readyState == '0') OK
RUN(source.duration = Infinity)
RUN(sourceBuffer.appendBuffer(initSegment))
EVENT(updateend)
EXPECTED (mediaElement.seekable.length == '0') OK
EXPECTED (mediaElement.currentTime == '0') OK
EXPECTED (mediaElement.readyState == '1') OK
EXPECTED (mediaElement.seeking == 'false') OK
END OF TEST

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<title>media-source-no-seek-with-infinite-duration</title>
<script src="mock-media-source.js"></script>
<script src="../video-test.js"></script>
<script>
var source;
var sourceBuffer;
var initSegment;

if (window.internals)
internals.initializeMockMediaSource();

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

run('video.currentTime = 1.0');

run('source = new MediaSource()');

const mediaElement = document.createElement('source');
mediaElement.type = 'video/mock; codecs=mock';
mediaElement.src = URL.createObjectURL(source);
video.appendChild(mediaElement);
await waitFor(source, 'sourceopen');
testExpected('mediaElement.readyState', HTMLMediaElement.HAVE_NOTHING);

// Test seeking a mediaElement backed by a mediaSource with infinite duration and
// empty buffered ranges. These factors trigger special considerations for
// HTMLMediaElement.seekable.
run('source.duration = Infinity');

sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock");
initSegment = makeAInit(0, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
run('sourceBuffer.appendBuffer(initSegment)');
await waitFor(sourceBuffer, 'updateend');

testExpected('mediaElement.seekable.length', 0);
testExpected('mediaElement.currentTime', 0);
testExpected('mediaElement.readyState', HTMLMediaElement.HAVE_METADATA);

// Seek should not actually occur because seekable is empty.
// From https://html.spec.whatwg.org/multipage/media.html#seeking,
// "If there are no ranges given in the seekable attribute then set the seeking IDL
// attribute to false and abort these steps."
testExpected('mediaElement.seeking', false);

endTest();
});
</script>
</head>
<body>
<div>This test checks if seeking status and currentTime when duration is infinity.</div>
<video></video>
</body>
</html>
@@ -3505,9 +3505,9 @@ void HTMLMediaElement::seekTask()
noSeekRequired = true;

#if ENABLE(MEDIA_SOURCE)
// Always notify the media engine of a seek if the source is not closed. This ensures that the source is
// always in a flushed state when the 'seeking' event fires.
if (m_mediaSource && !m_mediaSource->isClosed())
// Always notify the media engine of a seek if the source is not closed and there is seekable ranges.
// This ensures that the source is always in a flushed state when the 'seeking' event fires.
if (m_mediaSource && !m_mediaSource->isClosed() && seekableRanges->length())
noSeekRequired = false;
#endif

0 comments on commit ab53981

Please sign in to comment.