--- a/dom/media/mediasource/test/.eslintrc.js
+++ b/dom/media/mediasource/test/.eslintrc.js
@@ -5,17 +5,22 @@ module.exports = {
"extends": "plugin:mozilla/mochitest-test",
// Globals from mediasource.js. We use false to indicate they should not
// be overwritten in scripts.
"globals": {
"addMSEPrefs": false,
"fetchAndLoad": false,
"fetchAndLoadAsync": false,
"fetchWithXHR": false,
+ "logEvents": false,
"loadSegment": false,
+ "must_not_reject": false,
+ "must_not_throw": false,
+ "must_reject": false,
+ "must_throw": false,
"once": false,
"range": false,
"runWithMSE": false,
"waitUntilTime": false
},
// Use const/let instead of var for tighter scoping, avoiding redeclaration
"rules": {
"array-bracket-spacing": ["error", "always"],
--- a/dom/media/mediasource/test/mediasource.js
+++ b/dom/media/mediasource/test/mediasource.js
@@ -56,16 +56,47 @@ async function fetchWithXHR(uri, onLoadF
function range(start, end) {
const rv = [];
for (let i = start; i < end; ++i) {
rv.push(i);
}
return rv;
}
+function must_throw(f, msg, error = true) {
+ try {
+ f();
+ ok(!error, msg);
+ } catch (e) {
+ ok(error, msg);
+ if (error === true) {
+ ok(false, `Please provide name of expected error! Got ${e.name}: ${e.message}.`);
+ } else if (e.name != error) {
+ throw e;
+ }
+ }
+}
+
+async function must_reject(f, msg, error = true) {
+ try {
+ await f();
+ ok(!error, msg);
+ } catch (e) {
+ ok(error, msg);
+ if (error === true) {
+ ok(false, `Please provide name of expected error! Got ${e.name}: ${e.message}.`);
+ } else if (e.name != error) {
+ throw e;
+ }
+ }
+}
+
+const must_not_throw = (f, msg) => must_throw(f, msg, false);
+const must_not_reject = (f, msg) => must_reject(f, msg, false);
+
async function once(target, name, cb) {
let result = await new Promise(r => target.addEventListener(name, r, {once: true}));
if (cb) {
result = await cb();
}
return result;
}
@@ -77,17 +108,17 @@ function timeRangeToString(r) {
return str;
}
async function loadSegment(sb, typedArrayOrArrayBuffer) {
const typedArray = (typedArrayOrArrayBuffer instanceof ArrayBuffer) ? new Uint8Array(typedArrayOrArrayBuffer)
: typedArrayOrArrayBuffer;
info(`Loading buffer: [${typedArray.byteOffset}, ${typedArray.byteOffset + typedArray.byteLength})`);
const beforeBuffered = timeRangeToString(sb.buffered);
- const p = once(sb, 'update');
+ const p = once(sb, "update");
sb.appendBuffer(typedArray);
await p;
const afterBuffered = timeRangeToString(sb.buffered);
info(`SourceBuffer buffered ranges grew from ${beforeBuffered} to ${afterBuffered}`);
}
async function fetchAndLoad(sb, prefix, chunks, suffix) {
@@ -147,8 +178,17 @@ async function waitUntilTime(target, tar
if (target.currentTime >= targetTime) {
target.removeEventListener("waiting", onwaiting);
resolve();
}
});
});
ok(true, "Reached target time of: " + targetTime);
}
+
+// Log events for debugging.
+
+function logEvents(el) {
+ [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
+ "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
+ "waiting", "pause", "durationchange", "seeking",
+ "seeked" ].forEach(type => el.addEventListener(type, e => info(`got ${e.type} event`)));
+}
--- a/dom/media/mediasource/test/test_AVC3_mp4.html
+++ b/dom/media/mediasource/test/test_AVC3_mp4.html
@@ -7,38 +7,33 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(videosb, "avc3/init", [ "" ], ".mp4")
- .then(function() {
- const promises = [];
- promises.push(fetchAndLoad(videosb, "avc3/segment", range(1, 2), ".m4s"));
- promises.push(once(el, "loadeddata"));
- return Promise.all(promises);
- }).then(function() {
- is(videosb.buffered.length, 1, "continuous buffered range");
- ok(true, "got loadeddata");
- ms.endOfStream();
- return once(ms, "sourceended");
- }).then(function() {
- ok(true, "endOfStream completed");
- // Now ensure that we can play to the end.
- el.play();
- once(el, "ended").then(SimpleTest.finish.bind(SimpleTest));
- });
- });
+ await fetchAndLoad(videosb, "avc3/init", [ "" ], ".mp4");
+ const p = once(el, "loadeddata");
+ await fetchAndLoad(videosb, "avc3/segment", range(1, 2), ".m4s");
+ await p;
+ is(videosb.buffered.length, 1, "continuous buffered range");
+ ok(true, "got loadeddata");
+ ms.endOfStream();
+ await once(ms, "sourceended");
+ ok(true, "endOfStream completed");
+ // Now ensure that we can play to the end.
+ el.play();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_AudioChange_mp4.html
+++ b/dom/media/mediasource/test/test_AudioChange_mp4.html
@@ -9,62 +9,41 @@
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test checks loading a stereo segment, followed by a 5.1 segment plays without error.
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- // Log events for debugging.
- const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
- "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
- "waiting", "pause", "durationchange", "seeking", "seeked" ];
- function logEvent(e) {
- info("got " + e.type + " event");
- }
- events.forEach(function(e) {
- el.addEventListener(e, logEvent);
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ logEvents(el);
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- el.addEventListener("error", function(e) {
- ok(false, "should not fire '" + e.type + "' event");
- SimpleTest.finish();
- });
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const loadedmetadataPromises = [];
- loadedmetadataPromises.push(fetchAndLoad(audiosb, "aac20-48000-64000-", [ "init" ], ".mp4"));
- loadedmetadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(loadedmetadataPromises)
- .then(function() {
- ok(true, "got loadedmetadata event");
- const canplayPromises = [];
- canplayPromises.push(once(el, "loadeddata"));
- canplayPromises.push(once(el, "canplay"));
- canplayPromises.push(fetchAndLoad(audiosb, "aac20-48000-64000-", [ "1" ], ".m4s"));
- return Promise.all(canplayPromises);
- })
- .then(function() {
- ok(true, "got canplay event");
- el.play();
- return fetchAndLoad(audiosb, "aac51-48000-128000-", [ "init" ], ".mp4");
- })
- .then(fetchAndLoad.bind(null, audiosb, "aac51-48000-128000-", [ "2" ], ".m4s"))
- .then(function() {
- ms.endOfStream();
- return once(el, "ended");
- })
- .then(function() {
- ok(el.currentTime >= 6, "played to the end");
- SimpleTest.finish();
- });
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ el.addEventListener("error", e => {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(audiosb, "aac20-48000-64000-", [ "init" ], ".mp4");
+ await p;
+ ok(true, "got loadedmetadata event");
+ p = Promise.all([ once(el, "loadeddata"), once(el, "canplay") ]);
+ await fetchAndLoad(audiosb, "aac20-48000-64000-", [ "1" ], ".m4s");
+ await p;
+ ok(true, "got canplay event");
+ el.play();
+ await fetchAndLoad(audiosb, "aac51-48000-128000-", [ "init" ], ".mp4");
+ await fetchAndLoad(audiosb, "aac51-48000-128000-", [ "2" ], ".m4s");
+ ms.endOfStream();
+ await once(el, "ended");
+ ok(el.currentTime >= 6, "played to the end");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_BufferingWait.html
+++ b/dom/media/mediasource/test/test_BufferingWait.html
@@ -6,52 +6,47 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let receivedSourceOpen = false;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
- receivedSourceOpen = true;
- const sb = ms.addSourceBuffer("video/webm");
- ok(sb, "Create a SourceBuffer");
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen"));
+ const sb = ms.addSourceBuffer("video/webm");
+ ok(sb, "Create a SourceBuffer");
- fetchWithXHR("seek.webm", function(arrayBuffer) {
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 0, 318))()
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 318, 25523 - 318)))
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 25523, 46712 - 25523)))
- /* Note - Missing |46712, 67833 - 46712| segment here corresponding to (0.8, 1.2] */
- /* Note - Missing |67833, 88966 - 67833| segment here corresponding to (1.2, 1.6] */
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 88966)))
- .then(function() {
- // 0.767 is the time of the last video sample +- 40ms.
- const promise = waitUntilTime(v, .767 - 0.04);
- info("Playing video. It should play for a bit, then fire 'waiting'");
- v.play();
- return promise;
- }).then(function() {
- window.firstStop = Date.now();
- loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712));
- return waitUntilTime(v, 1.167 - 0.04);
- }).then(function() {
- const waitDuration = (Date.now() - window.firstStop) / 1000;
- ok(waitDuration < 15, "Should not spend an inordinate amount of time buffering: " + waitDuration);
- SimpleTest.finish();
- /* If we allow the rest of the stream to be played, we get stuck at
- around 2s. See bug 1093133.
- once(v, 'ended', SimpleTest.finish.bind(SimpleTest));
- return loadSegment(sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833));
- */
- });
- });
+ const arrayBuffer = await fetchWithXHR("seek.webm");
+ sb.addEventListener("error", e => {
+ ok(false, "Got Error: " + e);
+ SimpleTest.finish();
});
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 0, 318));
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 318, 25523 - 318));
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 25523, 46712 - 25523));
+ /* Note - Missing |46712, 67833 - 46712| segment here corresponding to (0.8, 1.2] */
+ /* Note - Missing |67833, 88966 - 67833| segment here corresponding to (1.2, 1.6] */
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 88966));
+ // 0.767 is the time of the last video sample +- 40ms.
+ info("Playing video. It should play for a bit, then fire 'waiting'");
+ v.play();
+ await waitUntilTime(v, .767 - 0.04);
+ const firstStop = Date.now();
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712));
+ await waitUntilTime(v, 1.167 - 0.04);
+ const waitDuration = (Date.now() - firstStop) / 1000;
+ ok(waitDuration < 15, `Should not spend inordinate amount of time buffering: ${waitDuration}`);
+ SimpleTest.finish();
+ /* If we allow the rest of the stream to be played, we get stuck at
+ around 2s. See bug 1093133.
+ await once(v, "ended");
+ SimpleTest.finish();
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833));
+ */
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_BufferingWait_mp4.html
+++ b/dom/media/mediasource/test/test_BufferingWait_mp4.html
@@ -6,49 +6,44 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let receivedSourceOpen = false;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
- receivedSourceOpen = true;
- const sb = ms.addSourceBuffer("video/mp4");
- ok(sb, "Create a SourceBuffer");
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen"));
+ const sb = ms.addSourceBuffer("video/mp4");
+ ok(sb, "Create a SourceBuffer");
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop", [ "1" ], ".m4s"))
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop", [ "2" ], ".m4s"))
- /* Note - Missing |bipbop3| segment here corresponding to (1.62, 2.41] */
- /* Note - Missing |bipbop4| segment here corresponding to (2.41, 3.20] */
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop", [ "5" ], ".m4s"))
- .then(function() {
- // last audio sample has a start time of 1.578956s
- const promise = waitUntilTime(v, 1.57895);
- info("Playing video. It should play for a bit, then fire 'waiting'");
- v.play();
- return promise;
- }).then(function() {
- window.firstStop = Date.now();
- fetchAndLoad(sb, "bipbop/bipbop", [ "3" ], ".m4s");
- // last audio sample has a start time of 2.368435
- return waitUntilTime(v, 2.36843);
- }).then(function() {
- const waitDuration = (Date.now() - window.firstStop) / 1000;
- ok(waitDuration < 15, "Should not spend an inordinate amount of time buffering: " + waitDuration);
- once(v, "ended", SimpleTest.finish.bind(SimpleTest));
- return fetchAndLoad(sb, "bipbop/bipbop", [ "4" ], ".m4s");
- }).then(function() {
- ms.endOfStream();
- });
+ sb.addEventListener("error", e => {
+ ok(false, "Got Error: " + e);
+ SimpleTest.finish();
});
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "1" ], ".m4s");
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "2" ], ".m4s");
+ /* Note - Missing |bipbop3| segment here corresponding to (1.62, 2.41] */
+ /* Note - Missing |bipbop4| segment here corresponding to (2.41, 3.20] */
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "5" ], ".m4s");
+ // last audio sample has a start time of 1.578956s
+ info("Playing video. It should play for a bit, then fire 'waiting'");
+ v.play();
+ await waitUntilTime(v, 1.57895);
+ const firstStop = Date.now();
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "3" ], ".m4s");
+ // last audio sample has a start time of 2.368435
+ await waitUntilTime(v, 2.36843);
+ const waitDuration = (Date.now() - firstStop) / 1000;
+ ok(waitDuration < 15, `Should not spend inordinate amount of time buffering: ${waitDuration}`);
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "4" ], ".m4s");
+ ms.endOfStream();
+ await once(v, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_ChangeWhileWaitingOnMissingData_mp4.html
+++ b/dom/media/mediasource/test/test_ChangeWhileWaitingOnMissingData_mp4.html
@@ -6,40 +6,32 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const sb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s"))
- .then(function() {
- el.play();
- // let seek to the last audio frame.
- // The seek will complete and then playback will stall.
- el.currentTime = 1.532517;
- return Promise.all([ once(el, "seeked"), once(el, "waiting") ]);
- })
- .then(function() {
- info("seek completed");
- return fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4");
- })
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop", range(1, 4), ".m4s"))
- .then(function() {
- ms.endOfStream();
- return once(el, "ended");
- }).then(function() {
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const sb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s");
+ el.play();
+ // let seek to the last audio frame.
+ // The seek will complete and then playback will stall.
+ el.currentTime = 1.532517;
+ await Promise.all([ once(el, "seeked"), once(el, "waiting") ]);
+ info("seek completed");
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop", range(1, 4), ".m4s");
+ ms.endOfStream();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html
+++ b/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html
@@ -6,55 +6,44 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(function() {
- // Set appendWindowEnd to ensure we only have about 6 frames worth.
- // We must feed at least 6 frames to pass the MDSM pre-roll.
- videosb.appendWindowEnd = .4;
- return fetchAndLoad(videosb, "bipbop/bipbop_video", [ "1" ], ".m4s");
- })
- .then(function() {
- info("Invoking play()");
- const promises = [];
- promises.push(once(el, "playing"));
- el.play();
- return Promise.all(promises);
- })
- .then(function() {
- info("got playing");
- return once(el, "waiting");
- }).then(function() {
- info("got waiting");
- info("Loading more data");
- // Waiting will be fired on the last frame +- 40ms.
- isfuzzy(el.currentTime, videosb.buffered.end(0) - 1 / 30,
- 0.04, "Got a waiting event at " + el.currentTime);
- videosb.appendWindowEnd = 1;
- const p = once(el, "ended");
- const loads = fetchAndLoad(videosb, "bipbop/bipbop_video", [ 1 ], ".m4s");
- loads.then(() => ms.endOfStream());
- return p;
- }).then(function() {
- // These fuzz factors are bigger than they should be. We should investigate
- // and fix them in bug 1137574.
- is(el.duration, 0.801666, "Video has correct duration: " + el.duration);
- is(el.currentTime, el.duration, "Video has correct currentTime.");
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ // Set appendWindowEnd to ensure we only have about 6 frames worth.
+ // We must feed at least 6 frames to pass the MDSM pre-roll.
+ videosb.appendWindowEnd = .4;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "1" ], ".m4s");
+ info("Invoking play()");
+ const p = once(el, "playing");
+ await el.play();
+ await p;
+ info("got playing");
+ await once(el, "waiting");
+ info("got waiting");
+ info("Loading more data");
+ // Waiting will be fired on the last frame +- 40ms.
+ isfuzzy(el.currentTime, videosb.buffered.end(0) - 1 / 30,
+ 0.04, `Got a waiting event at ${el.currentTime}`);
+ videosb.appendWindowEnd = 1;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ 1 ], ".m4s");
+ ms.endOfStream();
+ await once(el, "ended");
+ // These fuzz factors are bigger than they should be. We should investigate
+ // and fix them in bug 1137574.
+ is(el.duration, 0.801666, "Video has correct duration: " + el.duration);
+ is(el.currentTime, el.duration, "Video has correct currentTime.");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_DurationChange.html
+++ b/dom/media/mediasource/test/test_DurationChange.html
@@ -7,108 +7,65 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
- fetchWithXHR("seek.webm", function(arrayBuffer) {
- sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
- const promises = [];
- promises.push(once(v, "loadedmetadata"));
- promises.push(once(sb, "updateend"));
- Promise.all(promises)
- .then(function() {
- is(v.duration, ms.duration, "video duration is mediasource one");
- try {
- ms.duration = 0;
- } catch (e) { ok(false, "must not throw as operation is valid"); }
- is(v.duration, 0, "reducing duration with no data buffered is valid");
- sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
- // Adding more data will fire durationchange.
- once(sb, "updateend")
- .then(function() {
- ok(true, "got updateend");
- // XXX: Duration should be exactly 4.0, see bug 1065207.
- ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
- let error = false;
- try {
- ms.duration = 0;
- } catch (e) {
- ok(true, "must use remove for range removal");
- is(e.name, "InvalidStateError", "Error is InvalidStateError");
- error = true;
- }
- ok(error, "got an error");
- ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
- try {
- ms.duration = 10;
- } catch (e) { ok(false, "must not throw as setting duration past data is valid"); }
- is(v.duration, 10, "extending duration is always valid");
- // The last sample has a start time of 3.967000s and a end time of 4.001 (see bug 1065207).
- try {
- ms.duration = 3.967000;
- } catch (e) { ok(false, "setting duration with >= highest frame presentation time is valid"); }
- is(v.duration, sb.buffered.end(0), "duration is the highest end time reported by the buffered attribute ");
- try {
- ms.duration = 3.97;
- } catch (e) { ok(false, "setting duration with >= highest frame presentation time is valid"); }
- is(v.duration, sb.buffered.end(0), "duration is the highest end time reported by the buffered attribute ");
- error = false;
- try {
- ms.duration = 3.96;
- } catch (e) {
- ok(true, "setting duration with < highest frame presentation time is not valid");
- is(e.name, "InvalidStateError", "Error is InvalidStateError");
- error = true;
- }
- ok(error, "got an error");
- is(v.duration, sb.buffered.end(0), "duration is the highest end time reported by the buffered attribute ");
- error = false;
- try {
- ms.duration = -1;
- } catch (e) {
- ok(true, "can't set a negative duration");
- is(e.name, "TypeError", "Error is TypeError");
- error = true;
- }
- ok(error, "got an error");
- sb.remove(sb.buffered.end(0), Infinity);
- is(sb.updating, true, "updating is true");
- error = false;
- try {
- ms.duration = Infinity;
- } catch (e) {
- ok(true, "setting the duration while updating is not allowed");
- is(e.name, "InvalidStateError", "Error is InvalidStateError");
- error = true;
- }
- ok(error, "got an error");
- error = false;
- try {
- sb.abort();
- } catch (e) {
- ok(true, "Can't use abort while range removal is in progress");
- is(e.name, "InvalidStateError", "Error is InvalidStateError");
- error = true;
- }
- ok(error, "got an error");
- is(v.duration, sb.buffered.end(0), "duration is the highest end time reported by the buffered attribute ");
- once(sb, "updateend", () => ms.endOfStream());
- });
- });
- });
- });
- ms.addEventListener("sourceended", function() {
- SimpleTest.finish();
- });
+ const arrayBuffer = await fetchWithXHR("seek.webm");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
+ await Promise.all([ once(v, "loadedmetadata"), once(sb, "updateend") ]);
+ is(v.duration, ms.duration, "video duration is mediasource one");
+ must_not_throw(() => ms.duration = 0, "duration = 0 is valid initially");
+ is(v.duration, 0, "reducing duration with no data buffered is valid");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
+ // Adding more data will fire durationchange.
+ await once(sb, "updateend");
+ ok(true, "got updateend");
+ // XXX: Duration should be exactly 4.0, see bug 1065207.
+ ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
+ must_throw(() => ms.duration = 0,
+ "Must use remove for range removal",
+ "InvalidStateError");
+ ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
+ must_not_throw(() => ms.duration = 10, "setting duration past data is valid");
+ is(v.duration, 10, "extending duration is always valid");
+ // The last sample has a start time of 3.967000s and a end time of 4.001 (see bug 1065207).
+ must_not_throw(() => ms.duration = 3.967000,
+ "setting duration with >= highest frame presentation time is valid");
+ is(v.duration, sb.buffered.end(0),
+ "duration is the highest end time reported by the buffered attribute ");
+ must_not_throw(() => ms.duration = 3.97,
+ "setting duration with >= highest frame presentation time is valid");
+ is(v.duration, sb.buffered.end(0),
+ "duration is the highest end time reported by the buffered attribute ");
+ must_throw(() => ms.duration = 3.96,
+ "setting duration with < highest frame presentation time is not valid",
+ "InvalidStateError");
+ is(v.duration, sb.buffered.end(0),
+ "duration is the highest end time reported by the buffered attribute ");
+ must_throw(() => ms.duration = -1, "can't set a negative duration", "TypeError");
+ sb.remove(sb.buffered.end(0), Infinity);
+ is(sb.updating, true, "updating is true");
+ must_throw(() => ms.duration = Infinity,
+ "setting the duration while updating is not allowed",
+ "InvalidStateError");
+ must_throw(() => sb.abort(),
+ "Can't use abort while range removal is in progress",
+ "InvalidStateError");
+ is(v.duration, sb.buffered.end(0),
+ "duration is the highest end time reported by the buffered attribute ");
+ await once(sb, "updateend");
+ ms.endOfStream();
+ await once(ms, "sourceended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_DurationUpdated.html
+++ b/dom/media/mediasource/test/test_DurationUpdated.html
@@ -7,54 +7,42 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let durationChangeCount = 0;
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
+ let durationChangeCount = 0;
+ v.addEventListener("durationchange", () => durationChangeCount++);
- v.addEventListener("durationchange", function() {
- durationChangeCount++;
- });
+ const arrayBuffer = await fetchWithXHR("seek.webm");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
- fetchWithXHR("seek.webm", function(arrayBuffer) {
- sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
- // Adding the first init segment will fire a durationchange.
- const promises = [];
- promises.push(once(sb, "updateend"));
- promises.push(once(v, "loadedmetadata"));
- Promise.all(promises)
- .then(function() {
- ok(true, "got loadedmetadata");
- // Set mediasource duration to 0, so future appendBuffer
- // will update the mediasource duration.
- // Changing the duration will fire a durationchange.
- ms.duration = 0;
- sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
- // Adding more data will fire durationchange.
- once(sb, "updateend")
- .then(function() {
- ok(true, "got updateend");
- // this will not fire durationchange as new duration == old duration
- ms.endOfStream();
- });
- });
- });
- });
- ms.addEventListener("sourceended", function() {
- is(durationChangeCount, 3, "durationchange not fired as many times as expected");
- // XXX: Duration should be exactly 4.0, see bug 1065207.
- ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
- SimpleTest.finish();
- });
+ // Adding the first init segment will fire a durationchange.
+ await Promise.all([ once(sb, "updateend"), once(v, "loadedmetadata") ]);
+ ok(true, "got loadedmetadata");
+ // Set mediasource duration to 0, so future appendBuffer
+ // will update the mediasource duration.
+ // Changing the duration will fire a durationchange.
+ ms.duration = 0;
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
+ // Adding more data will fire durationchange.
+ await once(sb, "updateend");
+ ok(true, "got updateend");
+ // this will not fire durationchange as new duration == old duration
+ ms.endOfStream();
+ await once(ms, "sourceended");
+ is(durationChangeCount, 3, "durationchange not fired as many times as expected");
+ // XXX: Duration should be exactly 4.0, see bug 1065207.
+ ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_DurationUpdated_mp4.html
+++ b/dom/media/mediasource/test/test_DurationUpdated_mp4.html
@@ -7,53 +7,41 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let durationChangeCount = 0;
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/mp4");
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/mp4");
+ let durationChangeCount = 0;
+ v.addEventListener("durationchange", () => durationChangeCount++);
- v.addEventListener("durationchange", function() {
- durationChangeCount++;
- });
+ const arrayBuffer = await fetchWithXHR("bipbop/bipbop2s.mp4");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 1395));
- fetchWithXHR("bipbop/bipbop2s.mp4", function(arrayBuffer) {
- sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 1395));
- // Adding the first init segment will fire a durationchange.
- const promises = [];
- promises.push(once(sb, "updateend"));
- promises.push(once(v, "loadedmetadata"));
- Promise.all(promises)
- .then(function() {
- ok(true, "got loadedmetadata");
- // Set mediasource duration to 0, so future appendBuffer
- // will update the mediasource duration.
- // Changing the duration will fire a durationchange.
- ms.duration = 0;
- sb.appendBuffer(new Uint8Array(arrayBuffer, 1395));
- // Adding more data will fire durationchange.
- once(sb, "updateend")
- .then(function() {
- ok(true, "got updateend");
- // this will not fire durationchange as new duration == old duration
- ms.endOfStream();
- });
- });
- });
- });
- ms.addEventListener("sourceended", function() {
- is(durationChangeCount, 3, "durationchange not fired as many times as expected");
- is(v.duration, 1.696666, "Video has correct duration");
- SimpleTest.finish();
- });
+ // Adding the first init segment will fire a durationchange.
+ await Promise.all([ once(sb, "updateend"), once(v, "loadedmetadata") ]);
+ ok(true, "got loadedmetadata");
+ // Set mediasource duration to 0, so future appendBuffer
+ // will update the mediasource duration.
+ // Changing the duration will fire a durationchange.
+ ms.duration = 0;
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 1395));
+ // Adding more data will fire durationchange.
+ await once(sb, "updateend");
+ ok(true, "got updateend");
+ // this will not fire durationchange as new duration == old duration
+ ms.endOfStream();
+ await once(ms, "sourceended");
+ is(durationChangeCount, 3, "durationchange not fired as many times as expected");
+ is(v.duration, 1.696666, "Video has correct duration");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_EndedEvent.html
+++ b/dom/media/mediasource/test/test_EndedEvent.html
@@ -7,27 +7,25 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
- once(ms, "sourceopen").then(function() {
- const sb = ms.addSourceBuffer("video/webm");
- fetchWithXHR("seek.webm", (buf) => sb.appendBuffer(new Uint8Array(buf)));
- sb.addEventListener("updateend", () => ms.endOfStream());
+runWithMSE(async (ms, el) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
+ sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm")));
+ sb.addEventListener("updateend", () => ms.endOfStream());
- // Test 'ended' is fired when seeking to the end of the media
- // once the duration is known.
- ms.onsourceended = () => {
- el.currentTime = el.duration;
- };
- el.addEventListener("ended", SimpleTest.finish.bind(null));
- });
+ // Test "ended" is fired when seeking to the end of the media
+ // once the duration is known.
+ ms.onsourceended = () => el.currentTime = el.duration;
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_Eviction_mp4.html
+++ b/dom/media/mediasource/test/test_Eviction_mp4.html
@@ -10,73 +10,54 @@
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// We fill up the source buffer with audio data until the buffer is full.
// We ensure that QuotaExceededError is thrown once the buffer is full.
// We then seek to half the content. By that time, another appendBuffer must succeed
// as the auto-eviction would succeed (removing all data prior currentTime)
-// Fill up the SourceBuffer by appending data repeatedly via doAppendDataFunc until
-// an exception is thrown.
-function fillUpSourceBuffer(sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback) {
- // We are appending data repeatedly in sequence mode, there should be no gaps.
- ok(sourceBuffer.buffered.length <= 1, "there should be no gap in buffered ranges.");
- try {
- doAppendDataFunc();
- } catch (ex) {
- onCaughtExceptionCallback(ex);
- return;
- }
- once(sourceBuffer, "updateend", () => {
- fillUpSourceBuffer(sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback);
- });
-}
-
addMSEPrefs(
[ "media.mediasource.eviction_threshold.audio", 524288 ],
[ "media.dormant-on-pause-timeout-ms", -1 ] // FIXME: bug 1319292
);
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- audiosb.mode = "sequence";
- fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4")
- .then(function() {
- fetchWithXHR("bipbop/bipbop_audio1.m4s", function(audioBuffer) {
- fillUpSourceBuffer(audiosb,
- function() { // doAppendDataFunc
- audiosb.appendBuffer(audioBuffer);
- },
- function(ex1) { // onCaughtExceptionCallback
- is(ex1.name, "QuotaExceededError", "QuotaExceededError thrown");
- is(audiosb.buffered.end(0), el.duration, "Duration is end of buffered range");
- const seekTime = audiosb.buffered.end(0) / 2;
- el.currentTime = seekTime;
- once(el, "seeked", () => {
- dump("dump: seeked to " + seekTime);
- is(el.currentTime, seekTime, "correctly seeked to " + seekTime);
- try {
- audiosb.appendBuffer(audioBuffer);
- } catch (ex2) {
- ok(false, "Shouldn't throw another time when data can be evicted");
- el.mozDumpDebugInfo();
- SimpleTest.finish();
- return;
- }
- once(audiosb, "update", () => {
- ok(true, "appendBuffer succeeded");
- SimpleTest.finish();
- });
- });
- });
- });
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ audiosb.mode = "sequence";
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ const audioBuffer = await fetchWithXHR("bipbop/bipbop_audio1.m4s");
+
+ await must_reject(async () => {
+ // We are appending data repeatedly in sequence mode, there should be no gaps.
+ while (true) {
+ ok(audiosb.buffered.length <= 1, "there should be no gap in buffered ranges.");
+ audiosb.appendBuffer(audioBuffer);
+ await once(audiosb, "updateend");
+ }
+ },
+ "Fill up SourceBuffer by appending data until an exception is thrown.",
+ "QuotaExceededError");
+
+ is(audiosb.buffered.end(0), el.duration, "Duration is end of buffered range");
+ const seekTime = audiosb.buffered.end(0) / 2;
+ el.currentTime = seekTime;
+ await once(el, "seeked");
+ dump("dump: seeked to " + seekTime);
+ is(el.currentTime, seekTime, "correctly seeked to " + seekTime);
+ try {
+ audiosb.appendBuffer(audioBuffer);
+ await once(audiosb, "update");
+ ok(true, "appendBuffer succeeded");
+ } catch (ex) {
+ ok(false, "Shouldn't throw another time when data can be evicted");
+ el.mozDumpDebugInfo();
+ }
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_FrameSelection.html
+++ b/dom/media/mediasource/test/test_FrameSelection.html
@@ -7,72 +7,58 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-const updateCount = 0;
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
-const targets = [ { currentTime: 3, videoWidth: 160, videoHeight: 120 },
- { currentTime: 2, videoWidth: 160, videoHeight: 120 },
- { currentTime: 0, videoWidth: 320, videoHeight: 240 } ];
-let target;
+ let arrayBuffer = await fetchWithXHR("seek.webm");
+ let p = once(v, "loadedmetadata");
+ // Append entire file covering range [0, 4].
+ sb.appendBuffer(new Uint8Array(arrayBuffer));
+ await p;
+ is(v.currentTime, 0, "currentTime has correct initial value");
+ is(v.videoWidth, 320, "videoWidth has correct initial value");
+ is(v.videoHeight, 240, "videoHeight has correct initial value");
-let lowResBuffer;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
+ arrayBuffer = await fetchWithXHR("seek_lowres.webm");
+ // Append initialization segment.
+ info("Appending low-res init segment");
+ p = once(sb, "updateend");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 438));
+ await p;
- fetchWithXHR("seek.webm")
- .then(function(arrayBuffer) {
- const p = once(v, "loadedmetadata");
- // Append entire file covering range [0, 4].
- sb.appendBuffer(new Uint8Array(arrayBuffer));
- return p;
- }).then(function() {
- is(v.currentTime, 0, "currentTime has correct initial value");
- is(v.videoWidth, 320, "videoWidth has correct initial value");
- is(v.videoHeight, 240, "videoHeight has correct initial value");
- return fetchWithXHR("seek_lowres.webm");
- }).then(function(arrayBuffer) {
- // Append initialization segment.
- const p = once(sb, "updateend");
- info("Appending low-res init segment");
- sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 438));
- lowResBuffer = arrayBuffer;
- return p;
- }).then(function() {
- const p = once(sb, "updateend");
- info("Appending low-res range [2,4]");
- // Append media segment covering range [2, 4].
- sb.appendBuffer(new Uint8Array(lowResBuffer, 51003));
- return p;
- }).then(function() {
- ms.endOfStream();
- const p = Promise.all([ once(v, "seeked"), once(v, "resize") ]);
- info("Seeking to t=3");
- v.currentTime = 3;
- return p;
- }).then(function() {
- is(v.currentTime, 3, "Video currentTime at target");
- is(v.videoWidth, 160, "videoWidth has correct low-res value");
- is(v.videoHeight, 120, "videoHeight has correct low-res value");
+ info("Appending low-res range [2,4]");
+ // Append media segment covering range [2, 4].
+ p = once(sb, "updateend");
+ sb.appendBuffer(new Uint8Array(arrayBuffer, 51003));
+ await p;
+
+ ms.endOfStream();
- const p = Promise.all([ once(v, "seeked"), once(v, "resize") ]);
- info("Seeking to t=1");
- v.currentTime = 1;
- return p;
- }).then(function() {
- is(v.currentTime, 1, "Video currentTime at target");
- is(v.videoWidth, 320, "videoWidth has correct high-res value");
- is(v.videoHeight, 240, "videoHeight has correct high-res value");
- SimpleTest.finish();
- });
- });
+ info("Seeking to t=3");
+ p = Promise.all([ once(v, "seeked"), once(v, "resize") ]);
+ v.currentTime = 3;
+ await p;
+ is(v.currentTime, 3, "Video currentTime at target");
+ is(v.videoWidth, 160, "videoWidth has correct low-res value");
+ is(v.videoHeight, 120, "videoHeight has correct low-res value");
+
+ info("Seeking to t=1");
+ p = Promise.all([ once(v, "seeked"), once(v, "resize") ]);
+ v.currentTime = 1;
+ await p;
+ is(v.currentTime, 1, "Video currentTime at target");
+ is(v.videoWidth, 320, "videoWidth has correct high-res value");
+ is(v.videoHeight, 240, "videoHeight has correct high-res value");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_FrameSelection_mp4.html
+++ b/dom/media/mediasource/test/test_FrameSelection_mp4.html
@@ -9,64 +9,41 @@
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test loads partial video, plays and waits until playback stalls.
// It then loads only 3 frames of a video at higher resolution.
-let receivedSourceOpen = false;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
- receivedSourceOpen = true;
- const sb = ms.addSourceBuffer("video/mp4");
- ok(sb, "Create a SourceBuffer");
-
- // Log events for debugging.
- const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
- "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
- "waiting", "pause", "durationchange", "seeking", "seeked" ];
- function logEvent(e) {
- info("got " + e.type + " event");
- }
- events.forEach(function(e) {
- v.addEventListener(e, logEvent);
- });
-
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4")
- .then(function() {
- const promises = [];
- promises.push(fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s"));
- promises.push(once(v, "loadeddata"));
- return Promise.all(promises);
- }).then(function() {
- is(sb.buffered.length, 1, "continuous range");
- v.play();
- // We have nothing to play, waiting will be fired.
- return waitUntilTime(v, 1.5);
- }).then(function() {
- return fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4");
- }).then(function() {
- sb.timestampOffset = 1.601666; // End of the video track buffered - time of first video sample (0.095).
- sb.appendWindowEnd = 1.796677; // Only allow room for three extra video frames (we need 3 as this video has b-frames).
- return fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "1" ], ".m4s");
- }).then(function() {
- ms.endOfStream();
- const promises = [];
- promises.push(once(ms, "sourceended"));
- promises.push(once(v, "playing"));
- promises.push(once(v, "ended"));
- return Promise.all(promises);
- }).then(function() {
- if (v.width, 640, "has proper width");
- if (v.height, 480, "has proper height");
- SimpleTest.finish();
- });
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen"));
+ const sb = ms.addSourceBuffer("video/mp4");
+ ok(sb, "Create a SourceBuffer");
+ logEvents(v);
+ sb.addEventListener("error", function(e) {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4");
+ const p = once(v, "loadeddata");
+ await fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s");
+ await p;
+ is(sb.buffered.length, 1, "continuous range");
+ v.play();
+ // We have nothing to play, waiting will be fired.
+ await waitUntilTime(v, 1.5);
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4");
+ sb.timestampOffset = 1.601666; // End of the video track buffered - time of first video sample (0.095).
+ sb.appendWindowEnd = 1.796677; // Only allow room for three extra video frames (we need 3 as this video has b-frames).
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "1" ], ".m4s");
+ ms.endOfStream();
+ await Promise.all([ once(ms, "sourceended"), once(v, "playing"), once(v, "ended") ]);
+ if (v.width, 640, "has proper width");
+ if (v.height, 480, "has proper height");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_LiveSeekable.html
+++ b/dom/media/mediasource/test/test_LiveSeekable.html
@@ -7,74 +7,70 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
- // Load data with a +2 offset so that we can distinguish buffered range start
- // and seekable range start.
- sb.timestampOffset = 2;
- const promises = [];
- promises.push(fetchAndLoad(sb, "seek", [ "" ], ".webm"));
- promises.push(once(v, "loadedmetadata"));
- Promise.all(promises)
- .then(function() {
- ms.duration = Infinity;
- sb.abort();
- is(sb.buffered.length, 1, "continuous buffered range");
- is(sb.buffered.start(0), 2, "buffered range start at timestamp offset");
- is(sb.buffered.end(0), 6.001, "buffered range end at original duration + timestamp offset");
- is(v.seekable.length, 1, "continuous seekable range");
- is(v.seekable.start(0), 0, "seekable range start at 0");
- is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
- // LiveSeekableRange.start < buffered.start
- ms.setLiveSeekableRange(1, 5);
- is(v.seekable.length, 1, "continuous seekable range");
- is(v.seekable.start(0), 1, "seekable range start at live range start");
- is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
+ // Load data with a +2 offset so that we can distinguish buffered range start
+ // and seekable range start.
+ sb.timestampOffset = 2;
+ const p = once(v, "loadedmetadata");
+ await fetchAndLoad(sb, "seek", [ "" ], ".webm");
+ await p;
+ ms.duration = Infinity;
+ sb.abort();
+ is(sb.buffered.length, 1, "continuous buffered range");
+ is(sb.buffered.start(0), 2, "buffered range start at timestamp offset");
+ is(sb.buffered.end(0), 6.001, "buffered range end at original duration + timestamp offset");
+ is(v.seekable.length, 1, "continuous seekable range");
+ is(v.seekable.start(0), 0, "seekable range start at 0");
+ is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
+
+ // LiveSeekableRange.start < buffered.start
+ ms.setLiveSeekableRange(1, 5);
+ is(v.seekable.length, 1, "continuous seekable range");
+ is(v.seekable.start(0), 1, "seekable range start at live range start");
+ is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
- ms.clearLiveSeekableRange();
- ok(v.seekable.length, 1, "continuous seekable range");
- is(v.seekable.start(0), 0, "seekable range start at 0");
- is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
+ ms.clearLiveSeekableRange();
+ ok(v.seekable.length, 1, "continuous seekable range");
+ is(v.seekable.start(0), 0, "seekable range start at 0");
+ is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
- // LiveSeekableRange.end > buffered.end
- ms.setLiveSeekableRange(1, 8);
- is(v.seekable.start(0), 1, "seekable range start at live range start");
- is(v.seekable.end(0), 8, "seekable range end at live range end");
+ // LiveSeekableRange.end > buffered.end
+ ms.setLiveSeekableRange(1, 8);
+ is(v.seekable.start(0), 1, "seekable range start at live range start");
+ is(v.seekable.end(0), 8, "seekable range end at live range end");
- // LiveSeekableRange.start > buffered.start
- // LiveSeekableRange.end < buffered.end
- ms.setLiveSeekableRange(3, 5);
- is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start");
- is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at live range end");
+ // LiveSeekableRange.start > buffered.start
+ // LiveSeekableRange.end < buffered.end
+ ms.setLiveSeekableRange(3, 5);
+ is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start");
+ is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at live range end");
- // LiveSeekableRange.start > buffered.end
- ms.setLiveSeekableRange(8, 10);
- is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start");
- is(v.seekable.end(0), 10, "seekable range end at live range end");
+ // LiveSeekableRange.start > buffered.end
+ ms.setLiveSeekableRange(8, 10);
+ is(v.seekable.start(0), sb.buffered.start(0), "seekable range start at buffered start");
+ is(v.seekable.end(0), 10, "seekable range end at live range end");
- // LiveSeekableRange.end < buffered.start
- ms.setLiveSeekableRange(0, 2);
- is(v.seekable.start(0), 0, "seekable range start at live range start");
- is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
+ // LiveSeekableRange.end < buffered.start
+ ms.setLiveSeekableRange(0, 2);
+ is(v.seekable.start(0), 0, "seekable range start at live range start");
+ is(v.seekable.end(0), sb.buffered.end(0), "seekable range end at buffered end");
- try {
- ms.setLiveSeekableRange(2, 0);
- ok(false, "start > end");
- } catch (e) { ok(true, "must thow if start > end"); }
+ must_throw(() => ms.setLiveSeekableRange(2, 0),
+ "must thow if start > end",
+ "TypeError");
- SimpleTest.finish();
- });
- });
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_LoadedDataFired_mp4.html
+++ b/dom/media/mediasource/test/test_LoadedDataFired_mp4.html
@@ -7,64 +7,51 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
el.addEventListener("loadeddata", function() {
ok(el.buffered.length > 0, "data is buffered");
is(el.buffered.start(0), 0, "must fire loadeddata when data has been loaded");
is(el.currentTime, 0, "must fire loadeddata at start");
});
el.addEventListener("playing", function() {
ok(el.buffered.length > 0, "data is buffered");
is(el.buffered.start(0), 0, "must fire playing when data has been loaded");
ok(el.currentTime >= 0, "must have started playback");
});
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const loadedmetadataPromises = [];
- loadedmetadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- loadedmetadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(loadedmetadataPromises)
- .then(function() {
- videosb.appendWindowStart = 2;
- videosb.appendWindowEnd = 4;
- is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
- // Load [2.4, 3.968344). 2.4 as it's the first keyframe after 2s and
- // 3.968344 as the last frame ends after 4s.
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s");
- })
- .then(function() {
- is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
- // test that appendWindowEnd did its job.
- ok(el.buffered.start(0) >= 2, "no data can be found prior appendWindowStart");
- ok(el.buffered.end(el.buffered.length - 1) <= 4, "no data can be found beyond appendWindowEnd");
- el.play();
- return once(el, "play");
- })
- .then(function() {
- videosb.appendWindowStart = 0;
- const playingPromises = [];
- // Load [0, 3.971666).
- playingPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s"));
- // playback can only start now.
- playingPromises.push(once(el, "playing"));
- return Promise.all(playingPromises);
- })
- .then(function() {
- ok(true, "playing");
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await p;
+ videosb.appendWindowStart = 2;
+ videosb.appendWindowEnd = 4;
+ is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ // Load [2.4, 3.968344). 2.4 as it's the first keyframe after 2s and
+ // 3.968344 as the last frame ends after 4s.
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s");
+ is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ // test that appendWindowEnd did its job.
+ ok(el.buffered.start(0) >= 2, "no data can be found prior appendWindowStart");
+ ok(el.buffered.end(el.buffered.length - 1) <= 4, "no data can be found beyond appendWindowEnd");
+ el.play();
+ await once(el, "play");
+ videosb.appendWindowStart = 0;
+ p = once(el, "playing");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 8), ".m4s");
+ await p;
+ ok(true, "playing");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_MediaSource_flac_mp4.html
+++ b/dom/media/mediasource/test/test_MediaSource_flac_mp4.html
@@ -6,32 +6,28 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
- const sb = ms.addSourceBuffer("audio/mp4; codecs=\"flac\"");
- ok(sb, "Create a SourceBuffer");
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
+ const sb = ms.addSourceBuffer("audio/mp4; codecs=\"flac\"");
+ ok(sb, "Create a SourceBuffer");
- fetchAndLoad(sb, "flac/IS", [ "" ], ".mp4")
- .then(fetchAndLoad.bind(null, sb, "flac/0000", range(1, 3), ".m4s"))
- .then(function() {
- el.play();
- ms.endOfStream();
- return once(el, "ended");
- }).then(function() {
- SimpleTest.finish();
- });
- });
+ await fetchAndLoad(sb, "flac/IS", [ "" ], ".mp4");
+ await fetchAndLoad(sb, "flac/0000", range(1, 3), ".m4s");
+ el.play();
+ ms.endOfStream();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_MediaSource_memory_reporting.html
+++ b/dom/media/mediasource/test/test_MediaSource_memory_reporting.html
@@ -7,48 +7,41 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
+runWithMSE(async (ms, v) => {
+ // Load a webm video and play it.
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
+ await fetchAndLoad(sb, "seek", [ "" ], ".webm");
+ const p = once(v, "ended");
+ ms.endOfStream();
+ v.play();
+ await p;
+
// Test that memory reporting works once we've played a video.
- once(v, "ended", () => {
- // Grab a memory report.
- const mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
+ // Grab a memory report.
+ const mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(SpecialPowers.Ci.nsIMemoryReporterManager);
- let amount = 0;
- let resourcePathSeen = false;
- const handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) {
- if (aPath == "explicit/media/resources") {
- resourcePathSeen = true;
- amount += aAmount;
- }
- };
+ let amount;
+ const handleReport = (aProcess, aPath, aKind, aUnits, aAmount) => {
+ if (aPath == "explicit/media/resources") {
+ amount = (amount || 0) + aAmount;
+ }
+ };
- const finished = function() {
- ok(true, "Yay didn't crash!");
- ok(resourcePathSeen, "Got media resources amount");
- ok(amount > 0, "Non-zero amount reported for media resources");
- SimpleTest.finish();
- };
-
- mgr.getReports(handleReport, null, finished, null, /* anonymized = */ false);
- });
-
- // Load a webm video and play it.
- ms.addEventListener("sourceopen", () => {
- const sb = ms.addSourceBuffer("video/webm");
- fetchAndLoad(sb, "seek", [ "" ], ".webm").then(function() {
- ms.endOfStream();
- v.play();
- });
- });
+ await new Promise(r => mgr.getReports(handleReport, null, r, null, /* anonymized = */ false));
+ ok(true, "Yay didn't crash!");
+ ok(amount !== undefined, "Got media resources amount");
+ ok(amount > 0, "Non-zero amount reported for media resources");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_MultipleInitSegments.html
+++ b/dom/media/mediasource/test/test_MultipleInitSegments.html
@@ -8,46 +8,42 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
- fetchWithXHR("seek_lowres.webm", function(seek_lowres) {
- fetchWithXHR("seek.webm", function(seek) {
- const data = [
- [ seek_lowres, 0, 438 ], // lowres init segment
- [ seek_lowres, 438, 25950 ], // lowres media segment 0-1
- [ seek, 0, 318 ], // init segment
- [ seek, 46712, 67833 ] // media segment 0.8-1.201
- ];
- const length = data.map(d => d[2] - d[1]).reduce((a, b) => a + b);
- const arrayBuffer = new Uint8Array(length);
- let pos = 0;
- data.forEach(function(d) {
- const buffer = new Uint8Array(d[0], d[1], d[2] - d[1]);
- arrayBuffer.set(buffer, pos);
- pos += buffer.byteLength;
- });
- loadSegment.bind(null, sb, arrayBuffer)().then(function() {
- // Since we are passing multiple segments in one buffer,
- // the first durationchange event from parsing the init
- // segment will be fired before updateend.
- v.addEventListener("durationchange", function() {
- ok(v.duration, 1.201);
- SimpleTest.finish();
- });
- ms.endOfStream();
- });
- });
- });
- });
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
+ const seek_lowres = await fetchWithXHR("seek_lowres.webm");
+ const seek = await fetchWithXHR("seek.webm");
+ const data = [
+ [ seek_lowres, 0, 438 ], // lowres init segment
+ [ seek_lowres, 438, 25950 ], // lowres media segment 0-1
+ [ seek, 0, 318 ], // init segment
+ [ seek, 46712, 67833 ] // media segment 0.8-1.201
+ ];
+ const length = data.map(d => d[2] - d[1]).reduce((a, b) => a + b, 0);
+ const arrayBuffer = new Uint8Array(length);
+ let pos = 0;
+ for (const d of data) {
+ const buffer = new Uint8Array(d[0], d[1], d[2] - d[1]);
+ arrayBuffer.set(buffer, pos);
+ pos += buffer.byteLength;
+ }
+ await loadSegment(sb, arrayBuffer);
+ // Since we are passing multiple segments in one buffer,
+ // the first durationchange event from parsing the init
+ // segment will be fired before updateend.
+ const p = once(v, "durationchange");
+ ms.endOfStream();
+ await p;
+ ok(v.duration, 1.201);
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_MultipleInitSegments_mp4.html
+++ b/dom/media/mediasource/test/test_MultipleInitSegments_mp4.html
@@ -8,45 +8,37 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/mp4");
- fetchWithXHR("bipbop/bipbop_videoinit.mp4", function(init) {
- init = new Uint8Array(init);
- fetchWithXHR("bipbop/bipbop_video1.m4s", function(segment1) {
- segment1 = new Uint8Array(segment1);
- fetchWithXHR("bipbop/bipbop_video2.m4s", function(segment2) {
- segment2 = new Uint8Array(segment2);
- const data = [ init, segment1, init, segment2 ];
- const length = data.map(d => d.byteLength).reduce((a, b) => a + b);
- const arrayBuffer = new Uint8Array(length);
- let pos = 0;
- data.forEach(function(buffer) {
- arrayBuffer.set(buffer, pos);
- pos += buffer.byteLength;
- });
- loadSegment.bind(null, sb, arrayBuffer)().then(function() {
- // Since we are passing multiple segments in one buffer,
- // the first durationchange event from parsing the init
- // segment will be fired before updateend.
- v.addEventListener("durationchange", function() {
- ok(v.duration, 1.601666);
- SimpleTest.finish();
- });
- ms.endOfStream();
- });
- });
- });
- });
- });
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/mp4");
+ const init = new Uint8Array(await fetchWithXHR("bipbop/bipbop_videoinit.mp4"));
+ const segment1 = new Uint8Array(await fetchWithXHR("bipbop/bipbop_video1.m4s"));
+ const segment2 = new Uint8Array(await fetchWithXHR("bipbop/bipbop_video2.m4s"));
+ const data = [ init, segment1, init, segment2 ];
+ const length = data.map(d => d.byteLength).reduce((a, b) => a + b, 0);
+ const arrayBuffer = new Uint8Array(length);
+ let pos = 0;
+ for (const buffer of data) {
+ arrayBuffer.set(buffer, pos);
+ pos += buffer.byteLength;
+ }
+ await loadSegment(sb, arrayBuffer);
+ // Since we are passing multiple segments in one buffer,
+ // the first durationchange event from parsing the init
+ // segment will be fired before updateend.
+ const p = once(v, "durationchange");
+ ms.endOfStream();
+ await p;
+ ok(v.duration, 1.601666);
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_OnEvents.html
+++ b/dom/media/mediasource/test/test_OnEvents.html
@@ -7,59 +7,36 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, v) {
- function initEvent(e) {
- v["got" + e] = false;
- }
- function receiveEvent(e) {
- v["got" + e] = true;
- }
+runWithMSE(async (ms, v) => {
+ const receiveEvent = e => v["got" + e] = true;
+
const msevents = [ "onsourceopen", "onsourceended" ];
- msevents.forEach(function(e) {
- initEvent(e);
- ms[e] = function() { receiveEvent(e); };
- });
+ msevents.forEach(e => ms[e] = () => receiveEvent(e));
const sblistevents = [ "onaddsourcebuffer", "onremovesourcebuffer" ];
- sblistevents.forEach(function(e) {
- initEvent(e);
- ms.sourceBuffers[e] = function() { receiveEvent(e); };
- });
+ sblistevents.forEach(e => ms.sourceBuffers[e] = () => receiveEvent(e));
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
- const sbevents = [ "onupdatestart", "onupdate", "onupdateend", "onabort" ];
- sbevents.forEach(function(e) {
- initEvent(e);
- sb[e] = function() { receiveEvent(e); };
- });
+ const sbevents = [ "onupdatestart", "onupdate", "onupdateend", "onabort" ];
+ sbevents.forEach(e => sb[e] = () => receiveEvent(e));
- fetchAndLoad(sb, "seek", [ "" ], ".webm")
- .then(function() {
- fetchWithXHR("seek.webm")
- .then(function(arrayBuffer) {
- sb.appendBuffer(arrayBuffer);
- ms.removeSourceBuffer(sb); // will fire abort and removesourcebuffer
- ms.endOfStream(); // will fire sourceended
- once(ms, "sourceended").then(function() {
- const events = [ "onsourceopen", "onsourceended", "onupdatestart", "onupdate", "onupdateend", "onabort", "onaddsourcebuffer", "onremovesourcebuffer" ];
- events.forEach(function(e) {
- ok(v["got" + e], "got " + e);
- });
- SimpleTest.finish();
- });
- });
- });
- });
+ await fetchAndLoad(sb, "seek", [ "" ], ".webm");
+ sb.appendBuffer(await fetchWithXHR("seek.webm"));
+ ms.removeSourceBuffer(sb); // will fire abort and removesourcebuffer
+ ms.endOfStream(); // will fire sourceended
+ await once(ms, "sourceended");
+ [ ...msevents, ...sbevents, ...sblistevents ].forEach(e => ok(v["got" + e], "got " + e));
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_PlayEvents.html
+++ b/dom/media/mediasource/test/test_PlayEvents.html
@@ -16,151 +16,100 @@ SimpleTest.waitForExplicitFinish();
// 1. Load 1.6s of data and ensure that canplay event is fired.
// 2. Load data to have a complete buffered range from 0 to duration and ensure that canplaythrough is fired.
// 3. Seek to an area with no buffered data, and ensure that readyState goes back to HAVE_METADATA
// 4. Load 1.6s of data at the seek position and ensure that canplay is fired and that readyState is now HAVE_FUTURE_DATA
// 5. Start playing video and check that once it reaches a position with no data, readyState goes back to HAVE_CURRENT_DATA and waiting event is fired.
// 6. Add 1.6s of data once video element fired waiting, that canplay is fired once readyState is HAVE_FUTURE_DATA.
// 7. Finally load data to the end and ensure that canplaythrough is fired and that readyState is now HAVE_ENOUGH_DATA
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- // Log events for debugging.
- const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
- "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
- "waiting", "pause", "durationchange", "seeking", "seeked" ];
- function logEvent(e) {
- info("got " + e.type + " event");
- }
- events.forEach(function(e) {
- el.addEventListener(e, logEvent);
- });
-
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- el.addEventListener("error", function(e) {
- ok(false, "should not fire '" + e + "' event");
- });
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const metadataPromises = [];
- metadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- metadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(metadataPromises)
- .then(function() {
- ok(true, "got loadedmetadata event");
- const canplayPromises = [];
- canplayPromises.push(once(el, "loadeddata"));
- canplayPromises.push(once(el, "canplay"));
- canplayPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"));
- return Promise.all(canplayPromises);
- })
- .then(function() {
- ok(true, "got canplay event");
- // set element duration to 3.203333s. We do so in order to guarantee that
- // the end of the buffered range will be equal to duration, causing
- // canplaythrough to be fired later.
- ms.duration = 3.203333;
- return once(el, "durationchange");
- })
- .then(function() {
- ok(true, "got durationchange event");
- const promises = [];
- promises.push(once(el, "canplaythrough"));
- // Load [0.801666, 3.203333]
- promises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s"));
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got canplaythrough event");
- // set element duration to 9.203333s, this value is set to coincide with
- // data added later (we now have an empty range from 6s to 9.203333s).
- ms.duration = 9.203333;
- return once(el, "durationchange");
- })
- .then(function() {
- ok(true, "got durationchange event");
- // An arbitrary value, so we are guaranteed to be in a range with no data.
- el.currentTime = 6;
- videosb.timestampOffset = 6;
- ok(el.seeking, "seeking started");
- return once(el, "seeking");
- })
- .then(function() {
- ok(true, "got seeking event");
- is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
- const promises = [];
- promises.push(once(el, "seeked"));
- promises.push(once(el, "canplay"));
- // Load [6+0, 6+1.601666)
- promises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"));
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got seeked and canplay event");
- is(el.currentTime, 6, "seeked to 6s");
- is(el.readyState, el.HAVE_FUTURE_DATA, "readyState is HAVE_FUTURE_DATA");
- const promises = [];
- promises.push(once(el, "canplaythrough"));
- // Load [6+1.60166, 6+3.203333]
- promises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s"));
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got canplaythrough event");
- // set element duration to 19.805s, this value is set to coincide with
- // data added later (we now have an empty range from 15 to 19.805).
- ms.duration = 19.805;
- return once(el, "durationchange");
- })
- .then(function() {
- ok(true, "got durationchange event");
- el.currentTime = 15;
- videosb.timestampOffset = 15;
- ok(el.seeking, "seeking started");
- return once(el, "seeking");
- })
- .then(function() {
- ok(true, "got seeking event");
- const promises = [];
- promises.push(once(el, "seeked"));
- // Load [15+0, 15+1.601666)
- promises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s"));
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got seeked event");
- // Load [15+1.60166, 15+3.203333]
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s");
- })
- .then(function() {
- ok(true, "data loaded");
- // Playback we play for a little while then stall.
- const promises = [];
- promises.push(once(el, "playing"));
- promises.push(once(el, "waiting"));
- el.play();
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got playing and waiting event");
- // Playback has stalled, readyState is back to HAVE_CURRENT_DATA.
- is(el.readyState, el.HAVE_CURRENT_DATA, "readyState is HAVE_CURRENT_DATA");
- const promises = [];
- promises.push(once(el, "playing"));
- promises.push(once(el, "canplay"));
- promises.push(once(el, "canplaythrough"));
- // Load [15+3.203333, 15+4.805)
- // Our final buffered range will now be [0, 3.203333)[6, 9.203333)[15, 19.805)
- promises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 7), ".m4s"));
- return Promise.all(promises);
- })
- .then(function() {
- ok(true, "got playing, canplay and canplaythrough event");
- SimpleTest.finish();
- });
+ await once(ms, "sourceopen");
+ logEvents(el);
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ el.addEventListener("error", e => {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await p;
+ ok(true, "got loadedmetadata event");
+ p = Promise.all([ once(el, "loadeddata"), once(el, "canplay") ]);
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s");
+ await p;
+ ok(true, "got canplay event");
+ // set element duration to 3.203333s. We do so in order to guarantee that
+ // the end of the buffered range will be equal to duration, causing
+ // canplaythrough to be fired later.
+ ms.duration = 3.203333;
+ await once(el, "durationchange");
+ ok(true, "got durationchange event");
+ // Load [0.801666, 3.203333]
+ p = once(el, "canplaythrough");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s");
+ await p;
+ ok(true, "got canplaythrough event");
+ // set element duration to 9.203333s, this value is set to coincide with
+ // data added later (we now have an empty range from 6s to 9.203333s).
+ ms.duration = 9.203333;
+ await once(el, "durationchange");
+ ok(true, "got durationchange event");
+ // An arbitrary value, so we are guaranteed to be in a range with no data.
+ el.currentTime = 6;
+ videosb.timestampOffset = 6;
+ ok(el.seeking, "seeking started");
+ await once(el, "seeking");
+ ok(true, "got seeking event");
+ is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ // Load [6+0, 6+1.601666)
+ p = Promise.all([ once(el, "seeked"), once(el, "canplay") ]);
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s");
+ await p;
+ ok(true, "got seeked and canplay event");
+ is(el.currentTime, 6, "seeked to 6s");
+ is(el.readyState, el.HAVE_FUTURE_DATA, "readyState is HAVE_FUTURE_DATA");
+ // Load [6+1.60166, 6+3.203333]
+ p = once(el, "canplaythrough");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s");
+ await p;
+ ok(true, "got canplaythrough event");
+ // set element duration to 19.805s, this value is set to coincide with
+ // data added later (we now have an empty range from 15 to 19.805).
+ ms.duration = 19.805;
+ await once(el, "durationchange");
+ ok(true, "got durationchange event");
+ el.currentTime = 15;
+ videosb.timestampOffset = 15;
+ ok(el.seeking, "seeking started");
+ await once(el, "seeking");
+ ok(true, "got seeking event");
+ // Load [15+0, 15+1.601666)
+ p = once(el, "seeked");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s");
+ await p;
+ ok(true, "got seeked event");
+ // Load [15+1.60166, 15+3.203333]
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(3, 5), ".m4s");
+ ok(true, "data loaded");
+ // Playback we play for a little while then stall.
+ p = Promise.all([ once(el, "playing"), once(el, "waiting") ]);
+ el.play();
+ await p;
+ ok(true, "got playing and waiting event");
+ // Playback has stalled, readyState is back to HAVE_CURRENT_DATA.
+ is(el.readyState, el.HAVE_CURRENT_DATA, "readyState is HAVE_CURRENT_DATA");
+ // Load [15+3.203333, 15+4.805)
+ // Our final buffered range will now be [0, 3.203333)[6, 9.203333)[15, 19.805)
+ p = Promise.all([ once(el, "playing"), once(el, "canplay"), once(el, "canplaythrough") ]);
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 7), ".m4s");
+ await p;
+ ok(true, "got playing, canplay and canplaythrough event");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_PlayEventsAutoPlaying.html
+++ b/dom/media/mediasource/test/test_PlayEventsAutoPlaying.html
@@ -11,67 +11,48 @@
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test checks that readyState is properly set and the appropriate events are being fired accordingly:
// 1. Ensure that play/playing aren't fired before any media data been added.
// 2. Load 1.6s of data and ensure that canplay, play and playing events are fired.
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
el.autoplay = true;
- const eventCounts = { play: 0, playing: 0};
- function ForbiddenEvents(e) {
- const v = e.target;
- ok(v.readyState >= v.HAVE_FUTURE_DATA, "Must not have received event too early");
+ const eventCounts = { play: 0, playing: 0 };
+ await once(ms, "sourceopen");
+ logEvents(el);
+ ok(true, "Receive a sourceopen event");
+
+ const forbiddenEvents = e => {
+ ok(el.readyState >= el.HAVE_FUTURE_DATA, "Must not have received event too early");
is(eventCounts[e.type], 0, "event should have only be fired once");
eventCounts[e.type]++;
- }
- once(ms, "sourceopen").then(function() {
- // Log events for debugging.
- const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
- "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
- "waiting", "pause", "durationchange", "seeking", "seeked" ];
- function logEvent(e) {
- info("got " + e.type + " event");
- }
- events.forEach(function(e) {
- el.addEventListener(e, logEvent);
- });
- el.addEventListener("play", ForbiddenEvents);
- el.addEventListener("playing", ForbiddenEvents);
+ };
+ el.addEventListener("play", forbiddenEvents);
+ el.addEventListener("playing", forbiddenEvents);
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- el.addEventListener("error", function(e) {
- ok(false, "should not fire '" + e + "' event");
- });
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const metadataPromises = [];
- metadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- metadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(metadataPromises)
- .then(function() {
- ok(true, "got loadedmetadata event");
- const playedThroughPromises = [];
- playedThroughPromises.push(once(el, "loadeddata"));
- playedThroughPromises.push(once(el, "canplay"));
- playedThroughPromises.push(once(el, "play"));
- playedThroughPromises.push(once(el, "playing"));
- playedThroughPromises.push(once(el, "ended"));
- // We're only adding 1.6s worth of data, not enough for readyState to change to HAVE_ENOUGH_DATA
- // So we end the media source so that all the playable data is available.
- playedThroughPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s")
- .then(() => ms.endOfStream()));
- return Promise.all(playedThroughPromises);
- })
- .then(function() {
- ok(true, "got all required event");
- SimpleTest.finish();
- });
+ const videosb = ms.addSourceBuffer("video/mp4");
+ el.addEventListener("error", e => {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await p;
+ ok(true, "got loadedmetadata event");
+ // We're only adding 1.6s worth of data, not enough for readyState to change to HAVE_ENOUGH_DATA
+ // So we end the media source so that all the playable data is available.
+ p = Promise.all([ "loadeddata", "canplay", "play", "playing", "ended" ].map(e => once(el, e)));
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 3), ".m4s");
+ ms.endOfStream();
+ await p;
+ ok(true, "got all required event");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_PlayEventsAutoPlaying2.html
+++ b/dom/media/mediasource/test/test_PlayEventsAutoPlaying2.html
@@ -11,66 +11,48 @@
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test checks that readyState is properly set and the appropriate events are being fired accordingly:
// 1. Ensure that play/playing aren't fired before any media data been added.
// 2. Load more than 10s of data and ensure that canplay, play and playing events are fired.
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
el.autoplay = true;
- const eventCounts = { play: 0, playing: 0};
- function ForbiddenEvents(e) {
- const v = e.target;
- ok(v.readyState >= v.HAVE_FUTURE_DATA, "Must not have received event too early");
+ const eventCounts = { play: 0, playing: 0 };
+ await once(ms, "sourceopen");
+ logEvents(el);
+ ok(true, "Receive a sourceopen event");
+
+ const forbiddenEvents = e => {
+ ok(el.readyState >= el.HAVE_FUTURE_DATA, "Must not have received event too early");
is(eventCounts[e.type], 0, "event should have only be fired once");
eventCounts[e.type]++;
- }
- once(ms, "sourceopen").then(function() {
- // Log events for debugging.
- const events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
- "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
- "waiting", "pause", "durationchange", "seeking", "seeked" ];
- function logEvent(e) {
- info("got " + e.type + " event");
- }
- events.forEach(function(e) {
- el.addEventListener(e, logEvent);
- });
- el.addEventListener("play", ForbiddenEvents);
- el.addEventListener("playing", ForbiddenEvents);
+ };
+ el.addEventListener("play", forbiddenEvents);
+ el.addEventListener("playing", forbiddenEvents);
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- el.addEventListener("error", function(e) {
- ok(false, "should not fire '" + e + "' event");
- });
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const metadataPromises = [];
- metadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- metadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(metadataPromises)
- .then(function() {
- ok(true, "got loadedmetadata event");
- const playingPromises = [];
- // We shift the timestamps slightly to create a small gaps at the start.
- // one that should normally be ignored.
- videosb.timestampOffset = 0.1;
- playingPromises.push(once(el, "loadeddata"));
- playingPromises.push(once(el, "canplay"));
- playingPromises.push(once(el, "play"));
- playingPromises.push(once(el, "playing"));
- playingPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 14), ".m4s"));
- return Promise.all(playingPromises);
- })
- .then(function() {
- ok(true, "got all required event");
- SimpleTest.finish();
- });
+ const videosb = ms.addSourceBuffer("video/mp4");
+ el.addEventListener("error", e => {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await p;
+ ok(true, "got loadedmetadata event");
+ // We shift the timestamps slightly to create a small gaps at the start.
+ // one that should normally be ignored.
+ videosb.timestampOffset = 0.1;
+ p = Promise.all([ "loadeddata", "canplay", "play", "playing" ].map(e => once(el, e)));
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 14), ".m4s");
+ await p;
+ ok(true, "got all required event");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html
+++ b/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html
@@ -6,50 +6,39 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let receivedSourceOpen = false;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
- receivedSourceOpen = true;
- const sb = ms.addSourceBuffer("video/mp4");
- ok(sb, "Create a SourceBuffer");
-
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4")
- .then(function() {
- const promises = [];
- promises.push(fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s"));
- promises.push(once(v, "loadeddata"));
- return Promise.all(promises);
- }).then(function() {
- // clear the entire sourcebuffer.
- sb.remove(0, 5);
- return once(sb, "updateend");
- }).then(function() {
- v.play();
- // We have nothing to play, waiting will be fired.
- return once(v, "waiting");
- }).then(function() {
- const promises = [];
- promises.push(once(v, "playing"));
- promises.push(fetchAndLoad(sb, "bipbop/bipbop", range(1, 4), ".m4s"));
- return Promise.all(promises);
- }).then(function() {
- ms.endOfStream();
- const promises = [];
- promises.push(once(ms, "sourceended"));
- promises.push(once(v, "ended"));
- return Promise.all(promises);
- }).then(SimpleTest.finish.bind(SimpleTest));
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen"));
+ const sb = ms.addSourceBuffer("video/mp4");
+ ok(sb, "Create a SourceBuffer");
+ sb.addEventListener("error", e => {
+ ok(false, "Got Error: " + e);
+ SimpleTest.finish();
});
+ await fetchAndLoad(sb, "bipbop/bipbop", [ "init" ], ".mp4");
+ let p = once(v, "loadeddata");
+ await fetchAndLoad(sb, "bipbop/bipbop", range(1, 3), ".m4s");
+ await p;
+ // clear the entire sourcebuffer.
+ sb.remove(0, 5);
+ await once(sb, "updateend");
+ v.play();
+ // We have nothing to play, waiting will be fired.
+ await once(v, "waiting");
+ p = once(v, "playing");
+ await fetchAndLoad(sb, "bipbop/bipbop", range(1, 4), ".m4s");
+ await p;
+ ms.endOfStream();
+ await Promise.all([ once(ms, "sourceended"), once(v, "ended") ]);
+ SimpleTest.finish(SimpleTest);
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_SeekNoData_mp4.html
+++ b/dom/media/mediasource/test/test_SeekNoData_mp4.html
@@ -7,65 +7,51 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-// Avoid making trouble for people who fix rounding bugs.
-function fuzzyEquals(a, b) {
- return Math.abs(a - b) < 0.01;
-}
-
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- const videosb = ms.addSourceBuffer("video/mp4");
- el.addEventListener("error", function(e) {
- ok(false, "should not fire '" + e + "' event");
- });
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- try {
- el.currentTime = 3;
- } catch (e) {
- ok(false, "should not throw '" + e + "' exception");
- }
- is(el.currentTime, 3, "currentTime is default playback start position");
- is(el.seeking, false, "seek not started with HAVE_NOTHING");
- const metadataPromises = [];
- metadataPromises.push(fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4"));
- metadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- metadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(metadataPromises)
- .then(function() {
- const p = once(el, "seeking");
- el.play();
- el.currentTime = 5;
- is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
- is(el.seeking, true, "seek not started with HAVE_METADATA");
- is(el.currentTime, 5, "currentTime is seek position");
- return p;
- })
- .then(function() {
- ok(true, "Got seeking event");
- const seekedPromises = [];
- seekedPromises.push(once(el, "seeked"));
- seekedPromises.push(fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 9), ".m4s"));
- seekedPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", range(6, 10), ".m4s"));
- return Promise.all(seekedPromises);
- })
- .then(function() {
- ok(true, "Got seeked event");
- ok(el.currentTime >= 5, "Time >= 5");
- once(el, "ended").then(SimpleTest.finish.bind(SimpleTest));
- ms.endOfStream();
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ el.addEventListener("error", e => {
+ ok(false, `should not fire ${e.type} event`);
+ SimpleTest.finish();
});
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ must_not_throw(() => el.currentTime = 3, "setting currentTime is valid");
+ is(el.currentTime, 3, "currentTime is default playback start position");
+ is(el.seeking, false, "seek not started with HAVE_NOTHING");
+ await Promise.all([
+ fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4"),
+ fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"),
+ once(el, "loadedmetadata")
+ ]);
+ const p = once(el, "seeking");
+ el.play();
+ el.currentTime = 5;
+ is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ is(el.seeking, true, "seek not started with HAVE_METADATA");
+ is(el.currentTime, 5, "currentTime is seek position");
+ await p;
+ ok(true, "Got seeking event");
+ await Promise.all([
+ once(el, "seeked"),
+ fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(5, 9), ".m4s"),
+ fetchAndLoad(videosb, "bipbop/bipbop_video", range(6, 10), ".m4s")
+ ]);
+ ok(true, "Got seeked event");
+ ok(el.currentTime >= 5, "Time >= 5");
+ ms.endOfStream();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_SeekToEnd_mp4.html
+++ b/dom/media/mediasource/test/test_SeekToEnd_mp4.html
@@ -7,51 +7,49 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- const audiosb = ms.addSourceBuffer("audio/mp4");
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"))
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4"))
- .then(function() {
- is(videosb.buffered.length, 1, "continuous buffered range");
- // Ensure we have at least 2s less audio than video.
- audiosb.appendWindowEnd = videosb.buffered.end(0) - 2;
- return fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 6), ".m4s");
- }).then(function() {
- ms.endOfStream();
- return Promise.all([ once(el, "durationchange"), once(ms, "sourceended") ]);
- }).then(function() {
- ok(true, "endOfStream completed");
- // Seek to the middle of the gap where audio is missing. As we are in readyState = ended
- // seeking must complete.
- el.currentTime = videosb.buffered.end(0) / 2 + audiosb.buffered.end(0) / 2;
- ok(el.currentTime - audiosb.buffered.end(0) > 1, "gap is big enough");
- is(el.buffered.length, 1, "continuous buffered range");
- is(el.buffered.end(0), videosb.buffered.end(0), "buffered range end is aligned with longest track");
- ok(el.seeking, "element is now seeking");
- ok(el.currentTime >= el.buffered.start(0) && el.currentTime <= el.buffered.end(0), "seeking time is in buffered range");
- ok(el.currentTime > audiosb.buffered.end(0), "seeking point is not buffered in audio track");
- return once(el, "seeked");
- }).then(function() {
- ok(true, "we have successfully seeked");
- // Now ensure that we can play to the end, even though we are missing data in one track.
- el.play();
- once(el, "ended").then(SimpleTest.finish.bind(SimpleTest));
- });
- });
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ is(videosb.buffered.length, 1, "continuous buffered range");
+ // Ensure we have at least 2s less audio than video.
+ audiosb.appendWindowEnd = videosb.buffered.end(0) - 2;
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 6), ".m4s");
+ ms.endOfStream();
+ await Promise.all([ once(el, "durationchange"), once(ms, "sourceended") ]);
+ ok(true, "endOfStream completed");
+ // Seek to the middle of the gap where audio is missing. As we are in readyState = ended
+ // seeking must complete.
+ el.currentTime = videosb.buffered.end(0) / 2 + audiosb.buffered.end(0) / 2;
+ ok(el.currentTime - audiosb.buffered.end(0) > 1, "gap is big enough");
+ is(el.buffered.length, 1, "continuous buffered range");
+ is(el.buffered.end(0), videosb.buffered.end(0),
+ "buffered range end is aligned with longest track");
+ ok(el.seeking, "element is now seeking");
+ ok(el.currentTime >= el.buffered.start(0) && el.currentTime <= el.buffered.end(0),
+ "seeking time is in buffered range");
+ ok(el.currentTime > audiosb.buffered.end(0),
+ "seeking point is not buffered in audio track");
+ await once(el, "seeked");
+ ok(true, "we have successfully seeked");
+ // Now ensure that we can play to the end, even though we are missing data in one track.
+ el.play();
+ await once(el, "ended");
+ SimpleTest.finish(SimpleTest);
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_SeekToLastFrame_mp4.html
+++ b/dom/media/mediasource/test/test_SeekToLastFrame_mp4.html
@@ -6,35 +6,29 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const sb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s"))
- .then(function() {
- el.play();
- // let seek to the last audio frame.
- el.currentTime = 1.532517;
- return once(el, "seeked");
- })
- .then(function() {
- ok(true, "seek completed");
- ms.endOfStream();
- return once(el, "ended");
- }).then(function() {
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const sb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", [ "init" ], ".mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop_480_624kbps-video", range(1, 3), ".m4s");
+ el.play();
+ // let seek to the last audio frame.
+ el.currentTime = 1.532517;
+ await once(el, "seeked");
+ ok(true, "seek completed");
+ ms.endOfStream();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_SeekTwice_mp4.html
+++ b/dom/media/mediasource/test/test_SeekTwice_mp4.html
@@ -7,48 +7,39 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-// Avoid making trouble for people who fix rounding bugs.
-function fuzzyEquals(a, b) {
- return Math.abs(a - b) < 0.01;
-}
-
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- const videosb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"))
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(7, 14), ".m4s"))
- .then(function() {
- const p = once(el, "seeking");
- el.play();
- el.currentTime = 4.5; // Seek to a gap in the video
- return p;
- }).then(function() {
- ok(true, "Got seeking event");
- const p = once(el, "seeked");
- el.currentTime = 6; // Seek past the gap.
- return p;
- }).then(function() {
- ok(true, "Got seeked event");
- ok(el.currentTime >= 6, "Time >= 6");
- once(el, "ended").then(SimpleTest.finish.bind(SimpleTest));
- ms.endOfStream();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(7, 14), ".m4s");
+ let p = once(el, "seeking");
+ el.play();
+ el.currentTime = 4.5; // Seek to a gap in the video
+ await p;
+ ok(true, "Got seeking event");
+ p = once(el, "seeked");
+ el.currentTime = 6; // Seek past the gap.
+ await p;
+ ok(true, "Got seeked event");
+ ok(el.currentTime >= 6, "Time >= 6");
+ ms.endOfStream();
+ await once(el, "ended");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_SeekedEvent_mp4.html
+++ b/dom/media/mediasource/test/test_SeekedEvent_mp4.html
@@ -7,72 +7,42 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- el._seeked = false;
- el._loadeddata = false;
- el._playing = false;
- el.addEventListener("seeked", function() {
- ok(true, "got seeked event");
- is(el._loadeddata, false, "can't have received loadeddata prior seeked");
- is(el._playing, false, "can't be playing prior seeked");
- el._seeked = true;
- });
- el.addEventListener("loadeddata", function() {
- ok(true, "got loadeddata event");
- is(el._seeked, true, "must have received seeked prior loadeddata");
- is(el._playing, false, "can't be playing prior playing");
- el._loadeddata = true;
- });
- el.addEventListener("playing", function() {
- ok(true, "got playing");
- is(el._seeked, true, "must have received seeked prior playing");
- is(el._loadeddata, true, "must have received loadeddata prior playing");
- el._playing = true;
- });
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
- const metadataPromises = [];
- metadataPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"));
- metadataPromises.push(once(el, "loadedmetadata"));
- Promise.all(metadataPromises)
- .then(function() {
- el.play();
- videosb.timestampOffset = 2;
- is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
- // Load [2, 3.606).
- const playPromises = [];
- playPromises.push(once(el, "play"));
- playPromises.push(fetchAndLoad(videosb, "bipbop/bipbop_video", [ "1" ], ".m4s"));
- return Promise.all(playPromises);
- })
- .then(function() {
- return fetchAndLoad(videosb, "bipbop/bipbop_video", [ "2" ], ".m4s");
- })
- .then(function() {
- // TODO: readyState should be at least HAVE_CURRENTDATA, see bug 1367993.
- ok(el.readyState >= el.HAVE_METADATA, "readyState is HAVE_METADATA");
- el.currentTime = 2;
- const seekedAndPlayingPromises = [];
- seekedAndPlayingPromises.push(once(el, "seeked"));
- seekedAndPlayingPromises.push(once(el, "playing"));
- return Promise.all(seekedAndPlayingPromises);
- })
- .then(function() {
- ok(true, "completed seek");
- SimpleTest.finish();
- });
- });
+ const events = [ "seeked", "loadeddata", "playing" ];
+ let eventCount = 0;
+ events.forEach(type => el.addEventListener(type,
+ () => is(events[eventCount++], type, "events must come in order")));
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
+ let p = once(el, "loadedmetadata");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await p;
+ el.play();
+ videosb.timestampOffset = 2;
+ is(el.readyState, el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ // Load [2, 3.606).
+ p = once(el, "play");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "1" ], ".m4s");
+ await p;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "2" ], ".m4s");
+ // TODO: readyState should be at least HAVE_CURRENTDATA, see bug 1367993.
+ ok(el.readyState >= el.HAVE_METADATA, "readyState is HAVE_METADATA");
+ el.currentTime = 2;
+ await Promise.all([ once(el, "seeked"), once(el, "playing") ]);
+ ok(true, "completed seek");
+ is(eventCount, events.length, "Received expected number of events");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_Sequence_mp4.html
+++ b/dom/media/mediasource/test/test_Sequence_mp4.html
@@ -6,34 +6,32 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-let receivedSourceOpen = false;
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- ok(true, "Receive a sourceopen event");
- ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
- receivedSourceOpen = true;
- const sb = ms.addSourceBuffer("video/mp4");
- ok(sb, "Create a SourceBuffer");
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- sb.mode = "sequence";
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ ms.addEventListener("sourceopen", () => ok(false, "No more sourceopen"));
+ const sb = ms.addSourceBuffer("video/mp4");
+ ok(sb, "Create a SourceBuffer");
+ sb.addEventListener("error", e => {
+ ok(false, "Got Error: " + e);
+ SimpleTest.finish();
+ });
+ sb.mode = "sequence";
- fetchAndLoad(sb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop_video", [ "5" ], ".m4s"))
- .then(fetchAndLoad.bind(null, sb, "bipbop/bipbop_video", [ "2" ], ".m4s"))
- .then(function() {
- is(v.buffered.length, 1, "Continuous buffered range");
- is(v.buffered.start(0), 0, "Buffered range starts at 0");
- ok(sb.timestampOffset > 0, "SourceBuffer.timestampOffset set to allow continuous range");
- SimpleTest.finish();
- });
- });
+ await fetchAndLoad(sb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(sb, "bipbop/bipbop_video", [ "5" ], ".m4s");
+ await fetchAndLoad(sb, "bipbop/bipbop_video", [ "2" ], ".m4s");
+ is(v.buffered.length, 1, "Continuous buffered range");
+ is(v.buffered.start(0), 0, "Buffered range starts at 0");
+ ok(sb.timestampOffset > 0, "SourceBuffer.timestampOffset set to allow continuous range");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_Threshold_mp4.html
+++ b/dom/media/mediasource/test/test_Threshold_mp4.html
@@ -7,78 +7,67 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
-
+runWithMSE(async (ms, el) => {
const threshold = 0.5; // gap threshold in seconds.
const fuzz = 0.000001; // fuzz when comparing double.
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const videosb = ms.addSourceBuffer("video/mp4");
- const vchunks = [ {start: 0, end: 3.203333}, { start: 3.203333, end: 6.406666} ];
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ const vchunks = [ {start: 0, end: 3.203333}, { start: 3.203333, end: 6.406666} ];
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"))
- .then(function() {
- // We will insert a gap of threshold
- videosb.timestampOffset = threshold;
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
- }).then(function() {
- // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
- // has notified it of available data. Make sure that we get 'playing' before
- // we starting waiting for 'waiting'.
- info("Invoking play()");
- const p = once(el, "playing");
- el.play();
- return p;
- }).then(function() {
- return once(el, "waiting");
- }).then(function() {
- // We're waiting for data after the start of the last frame.
- // 0.033333 is the duration of the last frame.
- ok(el.currentTime >= vchunks[1].end - 0.033333 + threshold - fuzz
- && el.currentTime <= vchunks[1].end + threshold + fuzz, "skipped the gap properly: " + el.currentTime + " " + (vchunks[1].end + threshold));
- is(el.buffered.length, 2, "buffered range has right length");
- // Now we test that seeking will succeed despite the gap.
- el.currentTime = el.buffered.end(0) + (threshold / 2);
- return once(el, "seeked");
- }).then(function() {
- // Now we test that we don't pass the gap.
- // Clean up our sourcebuffer by removing all data.
- videosb.timestampOffset = 0;
- videosb.remove(0, Infinity);
- el.currentTime = 0;
- el.pause();
- return once(videosb, "updateend");
- }).then(function() {
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s");
- }).then(function() {
- // We will insert a gap of threshold + 1ms
- videosb.timestampOffset = threshold + 1 / 1000;
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
- }).then(function() {
- info("Invoking play()");
- const p = once(el, "playing");
- el.play();
- return p;
- }).then(function() {
- return once(el, "waiting");
- }).then(function() {
- // We're waiting for data after the start of the last frame.
- // 0.033333 is the duration of the last frame.
- ok(el.currentTime >= vchunks[0].end - 0.033333 - fuzz
- && el.currentTime <= vchunks[0].end + fuzz, "stopped at the gap properly: " + el.currentTime + " " + vchunks[0].end);
- SimpleTest.finish();
- });
- });
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s");
+ // We will insert a gap of threshold
+ videosb.timestampOffset = threshold;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
+ // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
+ // has notified it of available data. Make sure that we get 'playing' before
+ // we starting waiting for 'waiting'.
+ info("Invoking play()");
+ let p = once(el, "playing");
+ el.play();
+ await p;
+ await once(el, "waiting");
+ // We're waiting for data after the start of the last frame.
+ // 0.033333 is the duration of the last frame.
+ ok((el.currentTime >= vchunks[1].end - 0.033333 + threshold - fuzz &&
+ el.currentTime <= vchunks[1].end + threshold + fuzz),
+ `skipped the gap properly: ${el.currentTime} ${vchunks[1].end + threshold}`);
+ is(el.buffered.length, 2, "buffered range has right length");
+ // Now we test that seeking will succeed despite the gap.
+ el.currentTime = el.buffered.end(0) + (threshold / 2);
+ await once(el, "seeked");
+ // Now we test that we don't pass the gap.
+ // Clean up our sourcebuffer by removing all data.
+ videosb.timestampOffset = 0;
+ videosb.remove(0, Infinity);
+ el.currentTime = 0;
+ el.pause();
+ await once(videosb, "updateend");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s");
+ // We will insert a gap of threshold + 1ms
+ videosb.timestampOffset = threshold + 1 / 1000;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
+ info("Invoking play()");
+ p = once(el, "playing");
+ el.play();
+ await p;
+ await once(el, "waiting");
+ // We're waiting for data after the start of the last frame.
+ // 0.033333 is the duration of the last frame.
+ ok((el.currentTime >= vchunks[0].end - 0.033333 - fuzz &&
+ el.currentTime <= vchunks[0].end + fuzz),
+ `stopped at the gap properly: ${el.currentTime} ${vchunks[0].end}`);
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_TimestampOffset_mp4.html
+++ b/dom/media/mediasource/test/test_TimestampOffset_mp4.html
@@ -7,80 +7,71 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-function range(start, end) {
- const rv = [];
- for (let i = start; i < end; ++i) {
- rv.push(i);
- }
- return rv;
-}
+runWithMSE(async (ms, el) => {
-const eps = 0.01;
-runWithMSE(function(ms, el) {
+ const eps = 0.01;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- const videosb = ms.addSourceBuffer("video/mp4");
- // We divide the video into 3 chunks:
- // chunk 0: segments 1-4
- // chunk 1: segments 5-8
- // chunk 2: segments 9-13
- // We then fill the timeline so that it seamlessly plays the chunks in order 0, 2, 1.
- const vchunks = [ {start: 0, end: 3.2033}, { start: 3.2033, end: 6.4066}, { start: 6.4066, end: 10.01} ];
- const firstvoffset = vchunks[2].end - vchunks[2].start; // Duration of chunk 2
- const secondvoffset = -(vchunks[1].end - vchunks[1].start); // -(Duration of chunk 1)
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ // We divide the video into 3 chunks:
+ // chunk 0: segments 1-4
+ // chunk 1: segments 5-8
+ // chunk 2: segments 9-13
+ // We then fill the timeline so that it seamlessly plays the chunks in order 0, 2, 1.
+ const vchunks = [ {start: 0, end: 3.2033},
+ { start: 3.2033, end: 6.4066},
+ { start: 6.4066, end: 10.01} ];
+ const firstvoffset = vchunks[2].end - vchunks[2].start; // Duration of chunk 2
+ const secondvoffset = -(vchunks[1].end - vchunks[1].start); // -(Duration of chunk 1)
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"))
- .then(function() {
- is(videosb.buffered.length, 1, "No discontinuity");
- isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
- isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "Chunk end");
- videosb.timestampOffset = firstvoffset;
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
- })
- .then(function(data) {
- is(videosb.buffered.length, 2, "One discontinuity");
- isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "First Chunk start");
- isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "First chunk end");
- isfuzzy(videosb.buffered.start(1), vchunks[1].start + firstvoffset, eps, "Second chunk start");
- isfuzzy(videosb.buffered.end(1), vchunks[1].end + firstvoffset, eps, "Second chunk end");
- videosb.timestampOffset = secondvoffset;
- return fetchAndLoad(videosb, "bipbop/bipbop_video", range(9, 14), ".m4s");
- })
- .then(function() {
- is(videosb.buffered.length, 1, "No discontinuity (end)");
- isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
- isfuzzy(videosb.buffered.end(0), vchunks[2].end, eps, "Chunk end");
- audiosb.timestampOffset = 3;
- }).then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4"))
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(1, 12), ".m4s"))
- .then(function() {
- is(audiosb.buffered.length, 1, "No audio discontinuity");
- isfuzzy(audiosb.buffered.start(0), 3, eps, "Audio starts at 3");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s");
+ is(videosb.buffered.length, 1, "No discontinuity");
+ isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
+ isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "Chunk end");
+ videosb.timestampOffset = firstvoffset;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(5, 9), ".m4s");
+ is(videosb.buffered.length, 2, "One discontinuity");
+ isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "First Chunk start");
+ isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "First chunk end");
+ isfuzzy(videosb.buffered.start(1), vchunks[1].start + firstvoffset, eps, "Second chunk start");
+ isfuzzy(videosb.buffered.end(1), vchunks[1].end + firstvoffset, eps, "Second chunk end");
+ videosb.timestampOffset = secondvoffset;
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(9, 14), ".m4s");
+ is(videosb.buffered.length, 1, "No discontinuity (end)");
+ isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
+ isfuzzy(videosb.buffered.end(0), vchunks[2].end, eps, "Chunk end");
+ audiosb.timestampOffset = 3;
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 12), ".m4s");
+ is(audiosb.buffered.length, 1, "No audio discontinuity");
+ isfuzzy(audiosb.buffered.start(0), 3, eps, "Audio starts at 3");
- // Trim the rest of the audio.
- audiosb.remove(videosb.buffered.end(0), Infinity);
- videosb.remove(videosb.buffered.end(0), Infinity);
- return Promise.all([ audiosb.updating ? once(audiosb, "updateend") : Promise.resolve(),
- videosb.updating ? once(videosb, "updateend") : Promise.resolve() ]);
- }).then(function() {
- info("waiting for play to complete");
- el.play();
- el.currentTime = el.buffered.start(0);
- ms.endOfStream();
- Promise.all([ once(el, "ended"), once(el, "seeked") ]).then(SimpleTest.finish.bind(SimpleTest));
- });
- });
+ // Trim the rest of the audio.
+ audiosb.remove(videosb.buffered.end(0), Infinity);
+ videosb.remove(videosb.buffered.end(0), Infinity);
+ if (audiosb.updating) {
+ await once(audiosb, "updateend");
+ }
+ if (videosb.updating) {
+ await once(videosb, "updateend");
+ }
+ info("waiting for play to complete");
+ el.play();
+ el.currentTime = el.buffered.start(0);
+ ms.endOfStream();
+ await Promise.all([ once(el, "ended"), once(el, "seeked") ]);
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_TruncatedDuration.html
+++ b/dom/media/mediasource/test/test_TruncatedDuration.html
@@ -15,60 +15,41 @@
// We then shorten the video to 1/3rd of its original size by modifying the
// mediasource.duration attribute.
// We ensure that the buffered range immediately reflect the truncation
// and that we've seeked to the new end of the media as per W3C spec and
// video.currentTime got updated.
SimpleTest.waitForExplicitFinish();
-function round(n) {
- return Math.round(n * 1000) / 1000;
-}
+const round = n => Math.round(n * 1000) / 1000;
+
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/webm");
-function do_seeking(e) {
- const v = e.target;
- v.removeEventListener("seeking", do_seeking);
- SimpleTest.finish();
-}
-
-function do_seeked(e) {
- const v = e.target;
- v.removeEventListener("seeked", do_seeked);
+ sb.appendBuffer(new Uint8Array(await fetchWithXHR("seek.webm")));
+ await once(sb, "updateend");
+ v.currentTime = v.duration / 2;
+ is(v.currentTime, v.duration / 2, "current time was updated");
+ ok(v.seeking, "seeking is true");
+ await once(v, "seeked");
const duration = round(v.duration / 3);
- is(v._sb.updating, false, "sourcebuffer isn't updating");
- v._sb.remove(duration, Infinity);
- once(v._sb, "updateend", function() {
- v._ms.duration = duration;
- // frames aren't truncated, so duration may be slightly more.
- isfuzzy(v.duration, duration, 1 / 30, "element duration was updated");
- v._sb.abort(); // this shouldn't abort updating the duration (bug 1130826).
- ok(v.seeking, "seeking is true");
- // test playback position was updated (bug 1130839).
- is(v.currentTime, v.duration, "current time was updated");
- is(v._sb.buffered.length, 1, "One buffered range");
- // Truncated mediasource duration will cause the video element to seek.
- v.addEventListener("seeking", do_seeking);
- });
-}
-
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/webm");
- v._sb = sb;
- v._ms = ms;
-
- fetchWithXHR("seek.webm", function(arrayBuffer) {
- sb.appendBuffer(new Uint8Array(arrayBuffer));
- once(sb, "updateend", function() {
- v.currentTime = v.duration / 2;
- is(v.currentTime, v.duration / 2, "current time was updated");
- ok(v.seeking, "seeking is true");
- v.addEventListener("seeked", do_seeked);
- });
- });
- });
+ is(sb.updating, false, "sourcebuffer isn't updating");
+ sb.remove(duration, Infinity);
+ await once(sb, "updateend");
+ ms.duration = duration;
+ // frames aren't truncated, so duration may be slightly more.
+ isfuzzy(v.duration, duration, 1 / 30, "element duration was updated");
+ sb.abort(); // this shouldn't abort updating the duration (bug 1130826).
+ ok(v.seeking, "seeking is true");
+ // test playback position was updated (bug 1130839).
+ is(v.currentTime, v.duration, "current time was updated");
+ is(sb.buffered.length, 1, "One buffered range");
+ // Truncated mediasource duration will cause the video element to seek.
+ await once(v, "seeking");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_TruncatedDuration_mp4.html
+++ b/dom/media/mediasource/test/test_TruncatedDuration_mp4.html
@@ -14,66 +14,46 @@
// of the video.
// We then shorten the video to 1/3rd of its original size.
// We ensure that the buffered range immediately reflect the truncation
// and that we've seeked to the new end of the media as per W3C spec and
// video.currentTime got updated.
SimpleTest.waitForExplicitFinish();
-function round(n) {
- return Math.round(n * 1000) / 1000;
-}
+const round = n => Math.round(n * 1000) / 1000;
+
+runWithMSE(async (ms, v) => {
+ await once(ms, "sourceopen");
+ const sb = ms.addSourceBuffer("video/mp4");
-function do_seeking(e) {
- const v = e.target;
- v.removeEventListener("seeking", do_seeking);
- SimpleTest.finish();
-}
-
-function do_seeked(e) {
- const v = e.target;
- v.removeEventListener("seeked", do_seeked);
+ sb.appendBuffer(new Uint8Array(await fetchWithXHR("bipbop/bipbop2s.mp4")));
+ await once(sb, "updateend");
+ // mp4 metadata states 10s when we only have 1.6s worth of video.
+ sb.remove(sb.buffered.end(0), Infinity);
+ await once(sb, "updateend");
+ ms.duration = sb.buffered.end(0);
+ is(v.duration, ms.duration, "current time updated with mediasource duration");
+ v.currentTime = v.duration / 2;
+ is(v.currentTime, v.duration / 2, "current time was updated");
+ ok(v.seeking, "seeking is true");
+ await once(v, "seeked");
const duration = round(v.duration / 3);
- is(v._sb.updating, false, "sourcebuffer isn't updating");
- v._sb.remove(duration, Infinity);
- once(v._sb, "updateend", function() {
- v._ms.duration = duration;
- // frames aren't truncated, so duration may be slightly more.
- isfuzzy(v.duration, duration, 1 / 30, "element duration was updated");
- v._sb.abort(); // this shouldn't abort updating the duration (bug 1130826).
- ok(v.seeking, "seeking is true");
- // test playback position was updated (bug 1130839).
- is(v.currentTime, v.duration, "current time was updated");
- is(v._sb.buffered.length, 1, "One buffered range");
- // Truncated mediasource duration will cause the video element to seek.
- v.addEventListener("seeking", do_seeking);
- });
-}
-
-runWithMSE(function(ms, v) {
- ms.addEventListener("sourceopen", function() {
- const sb = ms.addSourceBuffer("video/mp4");
- v._sb = sb;
- v._ms = ms;
-
- fetchWithXHR("bipbop/bipbop2s.mp4", function(arrayBuffer) {
- sb.appendBuffer(new Uint8Array(arrayBuffer));
- once(sb, "updateend", function() {
- // mp4 metadata states 10s when we only have 1.6s worth of video.
- sb.remove(sb.buffered.end(0), Infinity);
- once(sb, "updateend", function() {
- ms.duration = sb.buffered.end(0);
- is(v.duration, ms.duration, "current time updated with mediasource duration");
- v.currentTime = v.duration / 2;
- is(v.currentTime, v.duration / 2, "current time was updated");
- ok(v.seeking, "seeking is true");
- v.addEventListener("seeked", do_seeked);
- });
- });
- });
- });
+ is(sb.updating, false, "sourcebuffer isn't updating");
+ sb.remove(duration, Infinity);
+ await once(sb, "updateend");
+ ms.duration = duration;
+ // frames aren't truncated, so duration may be slightly more.
+ isfuzzy(v.duration, duration, 1 / 30, "element duration was updated");
+ sb.abort(); // this shouldn't abort updating the duration (bug 1130826).
+ ok(v.seeking, "seeking is true");
+ // test playback position was updated (bug 1130839).
+ is(v.currentTime, v.duration, "current time was updated");
+ is(sb.buffered.length, 1, "One buffered range");
+ // Truncated mediasource duration will cause the video element to seek.
+ await once(v, "seeking");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_WaitingOnMissingData.html
+++ b/dom/media/mediasource/test/test_WaitingOnMissingData.html
@@ -6,58 +6,55 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const sb = ms.addSourceBuffer("video/webm");
- fetchWithXHR("seek.webm", function(arrayBuffer) {
- sb.addEventListener("error", (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
- loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 0, 318))()
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 318, 25223 - 318)))
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 25223, 46712 - 25223)))
- /* Note - Missing |46712, 67833 - 46712| segment here */
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833)))
- .then(loadSegment.bind(null, sb, new Uint8Array(arrayBuffer, 88966)))
- .then(function() {
- // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
- // has notified it of available data. Make sure that we get 'playing' before
- // we starting waiting for 'waiting'.
- info("Invoking play()");
- const p = once(el, "playing");
- el.play();
- return p;
- }).then(function() {
- ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
- const p = once(el, "waiting");
- el.play();
- return p;
- }).then(function() {
- // currentTime is based on the current video frame, so if the audio ends just before
- // the next video frame, currentTime can be up to 1 frame's worth earlier than
- // min(audioEnd, videoEnd).
- // 0.0465 is the length of the last audio frame.
- ok(el.currentTime >= (sb.buffered.end(0) - 0.0465),
- "Got a waiting event at " + el.currentTime);
- info("Loading more data");
- const p = once(el, "ended");
- loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712)).then(() => ms.endOfStream());
- return p;
- }).then(function() {
- // These fuzz factors are bigger than they should be. We should investigate
- // and fix them in bug 1137574.
- isfuzzy(el.duration, 4.001, 0.1, "Video has correct duration: " + el.duration);
- isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime.");
- SimpleTest.finish();
- });
- });
+runWithMSE(async (ms, el) => {
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const sb = ms.addSourceBuffer("video/webm");
+ sb.addEventListener("error", e => {
+ ok(false, "Got Error: " + e);
+ SimpleTest.finish();
});
+ const arrayBuffer = await fetchWithXHR("seek.webm");
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 0, 318));
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 318, 25223 - 318));
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 25223, 46712 - 25223));
+ /* Note - Missing |46712, 67833 - 46712| segment here */
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 67833, 88966 - 67833));
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 88966));
+ // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM
+ // has notified it of available data. Make sure that we get "playing" before
+ // we starting waiting for "waiting".
+ info("Invoking play()");
+ let p = once(el, "playing");
+ el.play();
+ await p;
+ ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
+ p = once(el, "waiting");
+ el.play();
+ await p;
+ // currentTime is based on the current video frame, so if the audio ends just before
+ // the next video frame, currentTime can be up to 1 frame's worth earlier than
+ // min(audioEnd, videoEnd).
+ // 0.0465 is the length of the last audio frame.
+ ok(el.currentTime >= (sb.buffered.end(0) - 0.0465),
+ `Got a waiting event at ${el.currentTime}`);
+ info("Loading more data");
+ p = once(el, "ended");
+ await loadSegment(sb, new Uint8Array(arrayBuffer, 46712, 67833 - 46712));
+ ms.endOfStream();
+ await p;
+ // These fuzz factors are bigger than they should be. We should investigate
+ // and fix them in bug 1137574.
+ isfuzzy(el.duration, 4.001, 0.1, "Video has correct duration: " + el.duration);
+ isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime.");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_WaitingOnMissingDataEnded_mp4.html
+++ b/dom/media/mediasource/test/test_WaitingOnMissingDataEnded_mp4.html
@@ -6,48 +6,42 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- el.addEventListener("ended", function() {
- ok(false, "ended should never fire");
- SimpleTest.finish();
- });
- const videosb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 5), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(6, 8), ".m4s"))
- .then(function() {
- is(el.buffered.length, 2, "discontinuous buffered range");
- ms.endOfStream();
- return Promise.all([ once(el, "durationchange"), once(ms, "sourceended") ]);
- }).then(function() {
- // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
- // has notified it of available data. Make sure that we get 'playing' before
- // we starting waiting for 'waiting'.
- info("Invoking play()");
- el.play();
- return once(el, "playing");
- }).then(function() {
- ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
- return once(el, "waiting");
- }).then(function() {
- // waiting is fired when we start to play the last frame.
- // 0.033334 is the duration of the last frame, + 0.000001 of fuzz.
- // the next video frame, currentTime can be up to 1 frame's worth earlier than end of video.
- isfuzzy(el.currentTime, videosb.buffered.end(0), 0.033334, "waiting was fired on gap");
- SimpleTest.finish();
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ el.addEventListener("ended", function() {
+ ok(false, "ended should never fire");
+ SimpleTest.finish();
});
+ const videosb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 5), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(6, 8), ".m4s");
+ is(el.buffered.length, 2, "discontinuous buffered range");
+ ms.endOfStream();
+ await Promise.all([ once(el, "durationchange"), once(ms, "sourceended") ]);
+ // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM
+ // has notified it of available data. Make sure that we get "playing" before
+ // we starting waiting for "waiting".
+ info("Invoking play()");
+ el.play();
+ await once(el, "playing");
+ ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
+ await once(el, "waiting");
+ // waiting is fired when we start to play the last frame.
+ // 0.033334 is the duration of the last frame, + 0.000001 of fuzz.
+ // the next video frame, currentTime can be up to 1 frame's worth earlier than end of video.
+ isfuzzy(el.currentTime, videosb.buffered.end(0), 0.033334, "waiting was fired on gap");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html
+++ b/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html
@@ -6,60 +6,56 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- const videosb = ms.addSourceBuffer("video/mp4");
- fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"))
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(7, 14), ".m4s"))
- .then(function() {
- // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
- // has notified it of available data. Make sure that we get 'playing' before
- // we starting waiting for 'waiting'.
- info("Invoking play()");
- const p = once(el, "playing");
- el.play();
- return p;
- }).then(function() {
- ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
- const p = once(el, "waiting");
- el.play();
- return p;
- }).then(function() {
- // currentTime is based on the current video frame, so if the audio ends just before
- // the next video frame, currentTime can be up to 1 frame's worth earlier than
- // min(audioEnd, videoEnd).
- // 0.0465 is the length of the last audio frame.
- ok(el.currentTime >= (Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 0.0465),
- "Got a waiting event at " + el.currentTime);
- info("Loading more data");
- const p = once(el, "ended");
- const loads = Promise.all([ fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ 5 ], ".m4s"),
- fetchAndLoad(videosb, "bipbop/bipbop_video", [ 6 ], ".m4s") ]);
- loads.then(() => ms.endOfStream());
- return p;
- }).then(function() {
- // These fuzz factors are bigger than they should be. We should investigate
- // and fix them in bug 1137574.
- isfuzzy(el.duration, 10.1, 0.1, "Video has correct duration: " + el.duration);
- isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime.");
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(6, 12), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(7, 14), ".m4s");
+ // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM
+ // has notified it of available data. Make sure that we get "playing" before
+ // we starting waiting for "waiting".
+ info("Invoking play()");
+ let p = once(el, "playing");
+ el.play();
+ await p;
+ ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
+ p = once(el, "waiting");
+ el.play();
+ await p;
+ // currentTime is based on the current video frame, so if the audio ends just before
+ // the next video frame, currentTime can be up to 1 frame's worth earlier than
+ // min(audioEnd, videoEnd).
+ // 0.0465 is the length of the last audio frame.
+ ok(el.currentTime >= (Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 0.0465),
+ `Got a waiting event at ${el.currentTime}`);
+ info("Loading more data");
+ p = once(el, "ended");
+ await Promise.all([
+ fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ 5 ], ".m4s"),
+ fetchAndLoad(videosb, "bipbop/bipbop_video", [ 6 ], ".m4s")
+ ]);
+ ms.endOfStream();
+ await p;
+ // These fuzz factors are bigger than they should be. We should investigate
+ // and fix them in bug 1137574.
+ isfuzzy(el.duration, 10.1, 0.1, "Video has correct duration: " + el.duration);
+ isfuzzy(el.currentTime, el.duration, 0.1, "Video has correct currentTime.");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html
+++ b/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html
@@ -6,51 +6,43 @@
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
-runWithMSE(function(ms, el) {
+runWithMSE(async (ms, el) => {
el.controls = true;
- once(ms, "sourceopen").then(function() {
- ok(true, "Receive a sourceopen event");
- const audiosb = ms.addSourceBuffer("audio/mp4");
- const videosb = ms.addSourceBuffer("video/mp4");
- // ensure tracks end at approximately the same time to ensure ended event is
- // always fired (bug 1233639).
- audiosb.appendWindowEnd = 3.9;
- videosb.appendWindowEnd = 3.9;
- fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4")
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", [ "init" ], ".mp4"))
- .then(fetchAndLoad.bind(null, audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s"))
- .then(fetchAndLoad.bind(null, videosb, "bipbop/bipbop_video", range(1, 6), ".m4s"))
- .then(function() {
- // HTMLMediaElement fires 'waiting' if somebody invokes |play()| before the MDSM
- // has notified it of available data. Make sure that we get 'playing' before
- // we starting waiting for 'waiting'.
- info("Invoking play()");
- const p = once(el, "playing");
- el.play();
- return p;
- }).then(function() {
- ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
- const p = once(el, "waiting");
- el.play();
- return p;
- }).then(function() {
- const p = once(el, "ended");
- ms.endOfStream();
- return p;
- }).then(function() {
- is(el.duration, 3.854512, "Video has correct duration: " + el.duration);
- is(el.currentTime, el.duration, "Video has correct currentTime.");
- SimpleTest.finish();
- });
- });
+ await once(ms, "sourceopen");
+ ok(true, "Receive a sourceopen event");
+ const audiosb = ms.addSourceBuffer("audio/mp4");
+ const videosb = ms.addSourceBuffer("video/mp4");
+ // ensure tracks end at approximately the same time to ensure ended event is
+ // always fired (bug 1233639).
+ audiosb.appendWindowEnd = 3.9;
+ videosb.appendWindowEnd = 3.9;
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", [ "init" ], ".mp4");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", [ "init" ], ".mp4");
+ await fetchAndLoad(audiosb, "bipbop/bipbop_audio", range(1, 5), ".m4s");
+ await fetchAndLoad(videosb, "bipbop/bipbop_video", range(1, 6), ".m4s");
+ // HTMLMediaElement fires "waiting" if somebody invokes |play()| before the MDSM
+ // has notified it of available data. Make sure that we get "playing" before
+ // we starting waiting for "waiting".
+ info("Invoking play()");
+ let p = once(el, "playing");
+ el.play();
+ await p;
+ ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
+ await once(el, "waiting");
+ p = once(el, "ended");
+ ms.endOfStream();
+ await p;
+ is(el.duration, 3.854512, "Video has correct duration: " + el.duration);
+ is(el.currentTime, el.duration, "Video has correct currentTime.");
+ SimpleTest.finish();
});
</script>
</pre>
</body>
</html>