Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 1 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /media-source/mediasource-remove.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<html>
<head>
<meta charset="utf-8">
<title>SourceBuffer.remove() test cases.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="mediasource-util.js"></script>
</head>
<body>
<div id="log"></div>
<script>
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(-1, 2);
}, "remove");
test.done();
}, "Test remove with an negative start.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
[ undefined, NaN, Infinity, -Infinity ].forEach(function(item)
{
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(item, 2);
}, "remove");
});
test.done();
}, "Test remove with non-finite start.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(11, 12);
}, "remove");
test.done();
}, "Test remove with a start beyond the duration.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(2, 1);
}, "remove");
test.done();
}, "Test remove with a start larger than the end.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(0, Number.NEGATIVE_INFINITY);
}, "remove");
test.done();
}, "Test remove with a NEGATIVE_INFINITY end.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(0, Number.NaN);
}, "remove");
test.done();
}, "Test remove with a NaN end.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
mediaSource.removeSourceBuffer(sourceBuffer);
assert_throws_dom("InvalidStateError", function()
{
sourceBuffer.remove(1, 2);
}, "remove");
test.done();
}, "Test remove after SourceBuffer removed from mediaSource.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
assert_false(sourceBuffer.updating, "updating is false");
assert_equals(mediaSource.duration, NaN, "duration isn't set");
assert_throws_js(TypeError, function()
{
sourceBuffer.remove(0, 0);
}, "remove");
test.done();
}, "Test remove with a NaN duration.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
sourceBuffer.remove(1, 2);
assert_true(sourceBuffer.updating, "updating");
assert_throws_dom("InvalidStateError", function()
{
sourceBuffer.remove(3, 4);
}, "remove");
test.waitForExpectedEvents(function()
{
test.done();
});
}, "Test remove while update pending.");
mediasource_test(function(test, mediaElement, mediaSource)
{
var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
mediaSource.duration = 10;
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
sourceBuffer.remove(1, 2);
assert_true(sourceBuffer.updating, "updating");
assert_throws_dom("InvalidStateError", function()
{
sourceBuffer.abort();
}, "abort");
assert_true(sourceBuffer.updating, "updating");
test.waitForExpectedEvents(function()
{
test.done();
});
}, "Test aborting a remove operation.");
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
sourceBuffer.appendBuffer(mediaData);
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
test.waitForExpectedEvents(function()
{
assert_less_than(mediaSource.duration, 10)
mediaSource.duration = 10;
sourceBuffer.remove(mediaSource.duration, mediaSource.duration + 2);
assert_true(sourceBuffer.updating, "updating");
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
});
test.waitForExpectedEvents(function()
{
test.done();
});
}, "Test remove with a start at the duration.");
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
sourceBuffer.appendBuffer(mediaData);
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
test.waitForExpectedEvents(function()
{
assert_less_than(mediaSource.duration, 10)
mediaSource.duration = 10;
sourceBuffer.remove(1, 1 + 0.9 / (1000 * 1000));
assert_true(sourceBuffer.updating, "updating");
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
});
test.waitForExpectedEvents(function()
{
test.done();
});
}, "Test remove with a nanosecond range.");
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
sourceBuffer.appendBuffer(mediaData);
test.waitForExpectedEvents(function()
{
mediaSource.endOfStream();
assert_equals(mediaSource.readyState, "ended");
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
test.expectEvent(mediaSource, "sourceopen");
sourceBuffer.remove(1, 2);
assert_true(sourceBuffer.updating, "updating");
assert_equals(mediaSource.readyState, "open");
});
test.waitForExpectedEvents(function()
{
assert_false(sourceBuffer.updating, "updating");
test.done();
});
}, "Test remove transitioning readyState from 'ended' to 'open'.");
function removeAppendedDataTests(callback, description)
{
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
{
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
sourceBuffer.appendBuffer(mediaData);
test.waitForExpectedEvents(function()
{
mediaSource.endOfStream();
assert_false(sourceBuffer.updating, "updating");
var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
var duration = mediaElement.duration.toFixed(3);
var subType = MediaSourceUtil.getSubType(segmentInfo.type);
assertBufferedEquals(sourceBuffer, "{ [" + start + ", " + duration + ") }", "Initial buffered range.");
callback(test, mediaSource, sourceBuffer, duration, subType, segmentInfo);
});
}, description);
};
function removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, start, end, expected)
{
test.expectEvent(sourceBuffer, "updatestart");
test.expectEvent(sourceBuffer, "update");
test.expectEvent(sourceBuffer, "updateend");
sourceBuffer.remove(start, end);
test.waitForExpectedEvents(function()
{
mediaSource.endOfStream();
assert_false(sourceBuffer.updating, "updating");
assertBufferedEquals(sourceBuffer, expected, "Buffered ranges after remove().");
test.done();
});
}
removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
{
removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, Number.POSITIVE_INFINITY, "{ }");
}, "Test removing all appended data.");
removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
{
var expectations = {
webm: ("{ [3.315, " + duration + ") }"),
mp4: ("{ [3.298, " + duration + ") }"),
};
// Note: Range doesn't start exactly at the end of the remove range because there isn't
// a keyframe there. The resulting range starts at the first keyframe >= the end time.
removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, 3, expectations[subType]);
}, "Test removing beginning of appended data.");
removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
{
var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
var expectations = {
webm: ("{ [" + start + ", 1.005) [3.315, " + duration + ") }"),
mp4: ("{ [" + start + ", 0.997) [3.298, " + duration + ") }"),
};
// Note: The first resulting range ends slightly after start because the removal algorithm only removes
// frames with a timestamp >= the start time. If a frame starts before and ends after the remove() start
// timestamp, then it stays in the buffer.
removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, 3, expectations[subType]);
}, "Test removing the middle of appended data.");
removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
{
var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
var expectations = {
webm: "{ [" + start + ", 1.013) }",
mp4: "{ [" + start + ", 1.022) }",
};
removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, Number.POSITIVE_INFINITY, expectations[subType]);
}, "Test removing the end of appended data.");
</script>
</body>
</html>