Bug 1553215 - Start testing MediaStreamAudioSourceNode in WPT. r=karlt,pehrsons

It's not complete I think, but it covers the constructor and some bits of
behaviour.

Differential Revision: https://phabricator.services.mozilla.com/D32175

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Adenot 2019-06-11 09:51:14 +00:00
Родитель e990bc2fe0
Коммит f86c650449
2 изменённых файлов: 207 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html class="a">
<head>
<title>MediaStreamAudioSourceNode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body class="a">
<div id="log"></div>
<script>
setup({explicit_done: true});
// Wait until the DOM is ready to be able to get a reference to the canvas
// element.
window.addEventListener("load", function() {
const ac = new AudioContext();
const emptyStream = new MediaStream();
test(function() {
assert_throws(
"InvalidStateError",
function() {
ac.createMediaStreamSource(emptyStream);
},
`A MediaStreamAudioSourceNode can only be constructed via the factory
method with a MediaStream that has at least one track of kind "audio"`
);
}, "MediaStreamAudioSourceNode created with factory method and MediaStream with no tracks");
test(function() {
assert_throws(
"InvalidStateError",
function() {
new MediaStreamAudioSourceNode(ac, { mediaStream: emptyStream });
},
`A MediaStreamAudioSourceNode can only be constructed via the constructor
with a MediaStream that has at least one track of kind "audio"`
);
}, "MediaStreamAudioSourceNode created with constructor and MediaStream with no tracks");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const videoOnlyStream = canvas.captureStream();
test(function() {
assert_throws(
"InvalidStateError",
function() {
ac.createMediaStreamSource(videoOnlyStream);
},
`A MediaStreamAudioSourceNode can only be constructed via the factory with a
MediaStream that has at least one track of kind "audio"`
);
}, `MediaStreamAudioSourceNode created with the factory method and MediaStream with only a video track`);
test(function() {
assert_throws(
"InvalidStateError",
function() {
new MediaStreamAudioSourceNode(ac, {
mediaStream: videoOnlyStream,
});
},
`A MediaStreamAudioSourceNode can only be constructed via the factory with a
MediaStream that has at least one track of kind "audio"`
);
}, `MediaStreamAudioSourceNode created with constructor and MediaStream with only a video track`);
done();
});
</script>
</body>
<canvas></canvas>
</html>

Просмотреть файл

@ -0,0 +1,134 @@
<!DOCTYPE html>
<html class="a">
<head>
<title>MediaStreamAudioSourceNode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body class="a">
<div id="log"></div>
<script>
function binIndexForFrequency(frequency, analyser) {
return (
1 +
Math.round(
(frequency * analyser.fftSize) / analyser.context.sampleRate
)
);
}
const t = async_test(
"MediaStreamAudioSourceNode captures the right track."
);
const ac = new AudioContext();
// Test that the right track is captured. Set up a MediaStream that has two
// tracks, one with a tone at 100Hz and one with a tone at 1000Hz.
const dest0 = ac.createMediaStreamDestination();
const dest1 = ac.createMediaStreamDestination();
const osc0 = ac.createOscillator();
const osc1 = ac.createOscillator();
osc0.frequency.value = 100;
osc1.frequency.value = 1000;
osc0.connect(dest0);
osc1.connect(dest1);
osc0.start(0);
osc1.start(0);
const track0 = dest0.stream.getAudioTracks()[0];
const track0id = track0.id;
const track1 = dest1.stream.getAudioTracks()[0];
const track1id = track1.id;
let ids = [track0id, track1id];
ids.sort();
let targetFrequency;
let otherFrequency;
if (ids[0] == track0id) {
targetFrequency = 100;
otherFrequency = 1000;
} else {
targetFrequency = 1000;
otherFrequency = 100;
}
let twoTrackMediaStream = new MediaStream();
twoTrackMediaStream.addTrack(track0);
twoTrackMediaStream.addTrack(track1);
const twoTrackSource = ac.createMediaStreamSource(twoTrackMediaStream);
const analyser = ac.createAnalyser();
twoTrackSource.connect(analyser);
const indexToCheckForHighEnergy = binIndexForFrequency(
targetFrequency,
analyser
);
const indexToCheckForLowEnergy = binIndexForFrequency(
otherFrequency,
analyser
);
let frequencyData = new Float32Array(1024);
let checkCount = 0;
let numberOfRemovals = 0;
let stopped = false;
function analyse() {
analyser.getFloatFrequencyData(frequencyData);
// there should be high energy in the right bin, higher than 40dbfs because
// it's supposed to be a sine wave at 0dbfs
if (frequencyData[indexToCheckForHighEnergy] > -40 && !stopped) {
assert_true(true, "Correct track routed to the AudioContext.");
checkCount++;
}
if (stopped && frequencyData[indexToCheckForHighEnergy] < -40) {
assert_true(
true,
`After stopping the track, low energy is found in the
same bin`
);
checkCount++;
}
// Don't assert(false) immediately here if the bin is still higher than
// -40db the analyzer node has a window and it's expecte that it takes some
// time for the volume of this bin to decrease.
if (frequencyData[indexToCheckForLowEnergy] < -80) {
assert_true(true, "Correct track routed to the AudioContext.");
} else {
assert_true(
false,
"Other track seem to be routed to the AudioContext?"
);
}
if (checkCount > 5 && checkCount < 20) {
twoTrackMediaStream.getAudioTracks().forEach(track => {
if (track.id == ids[0]) {
numberOfRemovals++;
window.removedTrack = track;
twoTrackMediaStream.removeTrack(track);
}
});
assert_true(
numberOfRemovals == 1,
`The mediastreamtrack can only be
removed once from the mediastream`
);
} else if (checkCount >= 20 && checkCount < 30) {
window.removedTrack.stop();
stopped = true;
} else if (checkCount >= 30) {
assert_true(
numberOfRemovals == 1,
`After removing the track from the
mediastream, it's still routed to the graph.`
);
// After some time, consider that it worked.
t.done();
return;
}
t.step_timeout(analyse, 100);
}
t.step_timeout(analyse, 100);
</script>
</body>
</html>