Source code

Revision control

Other Tools

Test Info: Warnings

  • This test gets skipped with pattern: (os == "win" && processor == "aarch64")
<!DOCTYPE HTML>
<html>
<head>
<title>Test MediaRecorder Record AudioContext Node</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968109">Mozilla Bug 968109</a>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
function setUpSource(contextType, nodeType) {
// Use contextType to choose offline or real-time context.
const context = contextType == "offline"?
new OfflineAudioContext(2 , 80920, 44100) : new AudioContext();
const buffer = context.createBuffer(2, 80920, context.sampleRate);
for (let i = 0; i < 80920; ++i) {
buffer.getChannelData(0)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
buffer.getChannelData(1)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
}
const source = context.createBufferSource();
source.buffer = buffer;
source.loop = true;
source.start(0);
// nodeType decides which node in graph should be the source of recording.
let node;
if (nodeType == "source") {
node = source;
} else if (nodeType == "splitter") {
const splitter = context.createChannelSplitter();
source.connect(splitter);
node = splitter;
} else if (nodeType == "destination") {
source.connect(context.destination);
node = context.destination;
}
// Explicitly start offline context.
if (contextType == "offline") {
context.startRendering();
}
return node;
}
async function testRecord(source, mimeType) {
const isOffline = source.context instanceof OfflineAudioContext;
const recorder = new MediaRecorder(source, 0, {mimeType});
is(recorder.mimeType, mimeType, "Mime type is set");
const extendedMimeType = `${mimeType || "audio/ogg"}; codecs=opus`;
recorder.onwarning = () => ok(false, "should not fire onwarning");
recorder.onerror = () => ok(false, "should not fire onerror");
if (!isOffline) {
recorder.onstop = () => ok(false, "should not fire stop yet");
}
recorder.start(1000);
is("recording", recorder.state, "state should become recording after calling start()");
is(recorder.mimeType, mimeType, "Mime type is not changed by start()");
await new Promise(r => recorder.onstart = r);
is(recorder.mimeType, extendedMimeType, "Mime type is fully defined");
const chunks = [];
let {data} = await new Promise(r => recorder.ondataavailable = r);
if (!isOffline) {
is(recorder.state, "recording", "Expected to still be recording");
}
is(data.type, extendedMimeType, "Blob has fully defined mimetype");
isnot(data.size, 0, "should get data and its length should be > 0");
chunks.push(data);
if (isOffline) {
await new Promise(r => recorder.onstop = r);
is(recorder.state, "inactive", "Offline context should end by itself");
} else {
is(recorder.state, "recording", "Expected to still be recording");
recorder.stop();
({data} = await new Promise(r => recorder.ondataavailable = r));
is(recorder.state, "inactive", "Expected to be inactive after last blob");
isnot(data.size, 0, "should get data and its length should be > 0");
chunks.push(data);
await new Promise(r => recorder.onstop = r);
is(recorder.state, "inactive", "state should remain inactive after stop event");
}
return new Blob(chunks, {type: chunks[0].type});
}
addLoadEvent(async () => {
const src = setUpSource();
let didThrow = false;
try {
new MediaRecorder(src);
} catch (e) {
didThrow = true;
}
ok(didThrow, "MediaRecorder(AudioNode) should be hidden behind a pref");
await SpecialPowers.pushPrefEnv({set: [
["media.recorder.audio_node.enabled", true],
]});
// Test with various context and source node types.
for (const mimeType of [
"audio/ogg",
"audio/webm",
"video/webm",
"",
]) {
for (const {context, node} of [
{context: "", node: "source"},
{context: "", node: "splitter"},
{context: "offline", node: "destination"},
]) {
info(`Testing recording ${context || "regular"} context and ${node} ` +
`node with mimeType '${mimeType}'`);
await testRecord(setUpSource(context, node), mimeType);
}
}
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>