131 lines
4.7 KiB
HTML
131 lines
4.7 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test AudioCapture </title>
|
|
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
|
</head>
|
|
<body>
|
|
<pre id="test">
|
|
<script>
|
|
|
|
(async () => {
|
|
await createHTML({
|
|
bug: "1156472",
|
|
title: "Test AudioCapture with regular HTMLMediaElement, AudioContext, " +
|
|
"and HTMLMediaElement playing a MediaStream",
|
|
visible: true
|
|
});
|
|
|
|
await runTestWhenReady(async () => {
|
|
// Reduce noise for when --use-test-media-devices is not in use.
|
|
await SpecialPowers.pushPrefEnv({ set: [[ "media.volume_scale", "0.0" ]] });
|
|
/**
|
|
* Get two HTMLMediaElements:
|
|
* - One playing a sine tone from a blob (of an opus file created on the fly)
|
|
* - One being the output for an AudioContext's OscillatorNode, connected to
|
|
* a MediaSourceDestinationNode.
|
|
*
|
|
* Also, use the AudioContext playing through its AudioDestinationNode another
|
|
* tone, using another OscillatorNode.
|
|
*
|
|
* Capture the output of the document, feed that back into the AudioContext,
|
|
* with an AnalyserNode, and check the frequency content to make sure we
|
|
* have recorded the three sources.
|
|
*
|
|
* The three sine tones have frequencies far apart from each other, so that we
|
|
* can check that the spectrum of the capture stream contains three
|
|
* components with a high magnitude.
|
|
*/
|
|
const decodedTone = createMediaElement("audio", "decodedTone");
|
|
decodedTone.muted = false;
|
|
const decodedToneMuted = createMediaElement("audio", "decodedToneMuted");
|
|
const acTone = createMediaElement("audio", "audioContextTone");
|
|
acTone.muted = false;
|
|
const acToneMuted = createMediaElement("audio", "audioContextToneMuted");
|
|
const micTone = createMediaElement("audio", "audioContextTone");
|
|
micTone.muted = false;
|
|
const ac = new AudioContext();
|
|
const constraints = {audio: {mediaSource: "audioCapture"}};
|
|
const stream = await getUserMedia(constraints);
|
|
const analyser = new AudioStreamAnalyser(ac, stream);
|
|
|
|
const osc200 = ac.createOscillator();
|
|
osc200.frequency.value = analyser.frequencyForBinIndex(200);
|
|
const osc250 = ac.createOscillator();
|
|
osc250.frequency.value = analyser.frequencyForBinIndex(250);
|
|
const oscThroughAudioDestinationNode = ac.createOscillator();
|
|
oscThroughAudioDestinationNode.frequency.value =
|
|
analyser.frequencyForBinIndex(100);
|
|
const msDest200 = ac.createMediaStreamDestination();
|
|
const msDest250 = ac.createMediaStreamDestination();
|
|
|
|
osc200.connect(msDest200);
|
|
osc250.connect(msDest250);
|
|
oscThroughAudioDestinationNode.connect(ac.destination);
|
|
|
|
acTone.srcObject = msDest200.stream;
|
|
acToneMuted.srcObject = msDest250.stream;
|
|
|
|
// The fake microphone uses signed 16-bit audio data:
|
|
await SpecialPowers.pushPrefEnv({ set: [
|
|
[
|
|
"media.navigator.audio.fake_frequency",
|
|
analyser.frequencyForBinIndex(300)
|
|
]
|
|
]});
|
|
const micStream = await navigator.mediaDevices.getUserMedia({
|
|
'audio': true, 'fake': true
|
|
});
|
|
micTone.srcObject = micStream;
|
|
|
|
decodedTone.src = "/tests/dom/media/test/sin-441-1s-44100.flac";
|
|
decodedToneMuted.src = "/tests/dom/media/test/sin-441-1s-44100.flac";
|
|
decodedTone.preservesPitch = false;
|
|
decodedToneMuted.preservesPitch = false;
|
|
decodedTone.playbackRate = analyser.frequencyForBinIndex(20) / 441;
|
|
ok(decodedTone.playbackRate >= 1/16, "within firefox min playback rate");
|
|
decodedToneMuted.playbackRate = analyser.frequencyForBinIndex(40) / 441;
|
|
ok(decodedToneMuted.playbackRate <= 16, "within firefox max playback rate");
|
|
osc200.start();
|
|
osc250.start();
|
|
oscThroughAudioDestinationNode.start();
|
|
decodedTone.loop = true;
|
|
decodedToneMuted.loop = true;
|
|
decodedTone.play();
|
|
decodedToneMuted.play();
|
|
acTone.play();
|
|
acToneMuted.play();
|
|
|
|
let frequencyBytes;
|
|
try {
|
|
analyser.enableDebugCanvas();
|
|
await analyser.waitForAnalysisSuccess(array => {
|
|
// We want to find three frequency components here.
|
|
// Frequencies are logarithmic. Also make sure we have low
|
|
// energy in between, not just a flat white noise.
|
|
if (array[10] == 0 &&
|
|
array[20] == 255 &&
|
|
array[40] == 0 &&
|
|
array[70] == 0 &&
|
|
array[100] == 255 &&
|
|
array[150] == 0 &&
|
|
array[200] == 255 &&
|
|
array[300] > 240) {
|
|
frequencyBytes = new Uint8Array(array);
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
} finally {
|
|
await ac.close();
|
|
for (let t of [...stream.getTracks(), ...micStream.getTracks()]) {
|
|
t.stop();
|
|
}
|
|
}
|
|
todo(frequencyBytes[250] < 50, "muted MediaStream srcObject - bug 1864067");
|
|
});
|
|
})();
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|