Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE HTML>
<html>
<head>
<title>Test MediaRecorder Record gUM video with Timeslice, and playback of mixed memory and file blobs</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<pre id="test">
<script type="text/javascript">
function unexpected({type}) {
ok(false, `${type} unexpectedly fired`);
}
(async () => {
SimpleTest.waitForExplicitFinish();
let blobUrl = null;
let stream = null;
try {
// This is the memory limit per blob. If a blob is larger than this,
// MediaRecorder will put it in a file. For this test we need to get at
// least one blob under, and one blob over the limit.
const memoryLimit = 50000;
await SpecialPowers.pushPrefEnv({set: [
["media.recorder.max_memory", memoryLimit],
]});
// We always use fake devices since the loopback ones don't make enough
// pixels change per frame to make the encoded frames large enough.
await pushGetUserMediaTestPrefs({fakeAudio: true, fakeVideo: true});
stream = await navigator.mediaDevices.getUserMedia(
{audio: true, video: true});
const blobs = [];
let mediaRecorder = new MediaRecorder(stream);
is(mediaRecorder.stream, stream,
"Media recorder stream = element stream at the start of recording");
mediaRecorder.start();
mediaRecorder.addEventListener("warning", unexpected);
mediaRecorder.addEventListener("error", unexpected);
mediaRecorder.addEventListener("stop", unexpected);
await new Promise(r => mediaRecorder.onstart = r);
for (let hasMemory = false; !hasMemory;) {
mediaRecorder.requestData();
const {data} = await new Promise(r => mediaRecorder.ondataavailable = r);
blobs.push(data);
ok(data.size < memoryLimit, "Blob should be small enough at start");
hasMemory = data.size > 0 && data.size < memoryLimit;
info(`Blob is ${data.size} bytes.${hasMemory ? " In memory." : ""}`);
}
info("Got a memory blob");
SimpleTest.requestFlakyTimeout("Wait for file blob");
for (let hasFile = false, waitTimeMs = 500; !hasFile; waitTimeMs *= 4) {
info(`Waiting ${waitTimeMs/1000} seconds for file blob`);
await new Promise(r => setTimeout(r, waitTimeMs));
mediaRecorder.requestData();
const {data} = await new Promise(r => mediaRecorder.ondataavailable = r);
blobs.push(data);
hasFile = data.size > memoryLimit;
info(`Blob is ${data.size} bytes. In ${hasFile ? "file" : "memory"}.`);
}
info("Got a file blob");
mediaRecorder.stop();
const {data} = await new Promise(r => mediaRecorder.ondataavailable = r);
blobs.push(data);
mediaRecorder.removeEventListener("stop", unexpected);
await new Promise(r => mediaRecorder.onstop = r);
const video = document.createElement("video");
const blob = new Blob(blobs);
blobUrl = URL.createObjectURL(blob);
video.src = blobUrl;
info(`Starting playback. Blob-size=${blob.size}`);
video.play();
await Promise.race([
new Promise(res => video.onended = res),
new Promise((res, rej) => video.onerror = () => rej(video.error.message)),
]);
} catch (e) {
ok(false, e);
} finally {
if (stream) {
for (const t of stream.getTracks()) {
t.stop();
}
}
if (blobUrl) {
URL.revokeObjectURL(blobUrl);
}
SimpleTest.finish();
}
})();
</script>
</pre>
</body>
</html>