зеркало из https://github.com/mozilla/gecko-dev.git
252 строки
12 KiB
HTML
252 строки
12 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
|
</head>
|
|
<body>
|
|
<pre id="test">
|
|
<script type="application/javascript">
|
|
"use strict";
|
|
|
|
createHTML({
|
|
title: "MediaStream.clone()",
|
|
bug: "1208371"
|
|
});
|
|
|
|
runTest(() => Promise.resolve()
|
|
.then(() => getUserMedia({audio: true, video: true})).then(stream => {
|
|
info("Test clone()ing an audio/video gUM stream");
|
|
var clone = stream.clone();
|
|
|
|
checkMediaStreamCloneAgainstOriginal(clone, stream);
|
|
checkMediaStreamTrackCloneAgainstOriginal(clone.getAudioTracks()[0],
|
|
stream.getAudioTracks()[0]);
|
|
checkMediaStreamTrackCloneAgainstOriginal(clone.getVideoTracks()[0],
|
|
stream.getVideoTracks()[0]);
|
|
|
|
isnot(clone.id.length, 0, "Stream clone should have an id string");
|
|
isnot(clone.getAudioTracks()[0].id.length, 0,
|
|
"Audio track clone should have an id string");
|
|
isnot(clone.getVideoTracks()[0].id.length, 0,
|
|
"Audio track clone should have an id string");
|
|
|
|
info("Stopping original tracks");
|
|
stream.getTracks().forEach(t => t.stop());
|
|
|
|
info("Playing from track clones");
|
|
var test = createMediaElement('video', 'testClonePlayback');
|
|
var playback = new MediaStreamPlayback(test, clone);
|
|
return playback.playMedia(false);
|
|
})
|
|
.then(() => getUserMedia({video: true})).then(stream =>
|
|
getUserMedia({video: true}).then(otherStream => {
|
|
info("Test addTrack()ing a video track to a stream without affecting its clone");
|
|
var track = stream.getTracks()[0];
|
|
var otherTrack = otherStream.getTracks()[0];
|
|
|
|
var streamClone = stream.clone();
|
|
var trackClone = streamClone.getTracks()[0];
|
|
checkMediaStreamContains(streamClone, [trackClone], "Initial clone");
|
|
|
|
stream.addTrack(otherTrack);
|
|
checkMediaStreamContains(stream, [track, otherTrack],
|
|
"Added video to original");
|
|
checkMediaStreamContains(streamClone, [trackClone],
|
|
"Clone not affected");
|
|
|
|
stream.removeTrack(track);
|
|
streamClone.addTrack(track);
|
|
checkMediaStreamContains(streamClone, [trackClone, track],
|
|
"Added video to clone");
|
|
checkMediaStreamContains(stream, [otherTrack],
|
|
"Original not affected");
|
|
|
|
// Not part of streamClone. Does not get stopped by the playback test.
|
|
otherTrack.stop();
|
|
otherStream.stop();
|
|
|
|
var test = createMediaElement('video', 'testClonePlayback');
|
|
var playback = new MediaStreamPlayback(test, streamClone);
|
|
return playback.playMedia(false)
|
|
.then(() => stream.getTracks().forEach(t => t.stop()))
|
|
.then(() => stream.stop());
|
|
}))
|
|
.then(() => getUserMedia({audio: true, video: true})).then(stream => {
|
|
info("Test cloning a stream into inception");
|
|
var clone = stream;
|
|
var clones = Array(10).fill().map(() => clone = clone.clone());
|
|
var inceptionClone = clones.pop();
|
|
checkMediaStreamCloneAgainstOriginal(inceptionClone, stream);
|
|
stream.getTracks().forEach(t => (stream.removeTrack(t),
|
|
inceptionClone.addTrack(t)));
|
|
is(inceptionClone.getAudioTracks().length, 2,
|
|
"The inception clone should contain the original audio track and a track clone");
|
|
is(inceptionClone.getVideoTracks().length, 2,
|
|
"The inception clone should contain the original video track and a track clone");
|
|
|
|
var test = createMediaElement('video', 'testClonePlayback');
|
|
var playback = new MediaStreamPlayback(test, inceptionClone);
|
|
return playback.playMedia(false)
|
|
.then(() => clones.forEach(c => c.getTracks().forEach(t => t.stop())));
|
|
})
|
|
.then(() => getUserMedia({audio: true, video: true})).then(stream => {
|
|
info("Test adding tracks from many stream clones to the original stream");
|
|
|
|
const LOOPS = 3;
|
|
for (var i = 0; i < LOOPS; i++) {
|
|
stream.clone().getTracks().forEach(t => stream.addTrack(t));
|
|
}
|
|
is(stream.getAudioTracks().length, Math.pow(2, LOOPS),
|
|
"The original track should contain the original audio track and all the audio clones");
|
|
is(stream.getVideoTracks().length, Math.pow(2, LOOPS),
|
|
"The original track should contain the original video track and all the video clones");
|
|
stream.getTracks().forEach(t1 => is(stream.getTracks()
|
|
.filter(t2 => t1.id == t2.id)
|
|
.length,
|
|
1, "Each track should be unique"));
|
|
|
|
var test = createMediaElement('video', 'testClonePlayback');
|
|
var playback = new MediaStreamPlayback(test, stream);
|
|
return playback.playMedia(false);
|
|
})
|
|
.then(() => {
|
|
info("Testing audio content routing with MediaStream.clone()");
|
|
var ac = new AudioContext();
|
|
|
|
var osc1kOriginal = createOscillatorStream(ac, 1000);
|
|
var audioTrack1kOriginal = osc1kOriginal.getTracks()[0];
|
|
var audioTrack1kClone = osc1kOriginal.clone().getTracks()[0];
|
|
|
|
var osc5kOriginal = createOscillatorStream(ac, 5000);
|
|
var audioTrack5kOriginal = osc5kOriginal.getTracks()[0];
|
|
var audioTrack5kClone = osc5kOriginal.clone().getTracks()[0];
|
|
|
|
return Promise.resolve().then(() => {
|
|
info("Analysing audio output of original stream (1k + 5k)");
|
|
var stream = new MediaStream();
|
|
stream.addTrack(audioTrack1kOriginal);
|
|
stream.addTrack(audioTrack5kOriginal);
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => {
|
|
info("Waiting for original tracks to stop");
|
|
stream.getTracks().forEach(t => t.stop());
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
// WebAudioDestination streams do not handle stop()
|
|
// XXX Should they? Plan to resolve that in bug 1208384.
|
|
// array[analyser.binIndexForFrequency(1000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
// array[analyser.binIndexForFrequency(5000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(10000)] < 50);
|
|
})
|
|
.then(() => analyser.disconnect());
|
|
}).then(() => {
|
|
info("Analysing audio output of stream clone (1k + 5k)");
|
|
var stream = new MediaStream();
|
|
stream.addTrack(audioTrack1kClone);
|
|
stream.addTrack(audioTrack5kClone);
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => analyser.disconnect());
|
|
}).then(() => {
|
|
info("Analysing audio output of clone of clone (1k + 5k)");
|
|
var stream = new MediaStream([audioTrack1kClone, audioTrack5kClone]).clone();
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => analyser.disconnect());
|
|
}).then(() => {
|
|
info("Analysing audio output of clone() + addTrack()ed tracks (1k + 5k)");
|
|
var stream =
|
|
new MediaStream(new MediaStream([ audioTrack1kClone
|
|
, audioTrack5kClone
|
|
]).clone().getTracks());
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => analyser.disconnect());
|
|
}).then(() => {
|
|
info("Analysing audio output of clone()d tracks in original stream (1k) " +
|
|
"and clone()d tracks in stream clone (5k)");
|
|
var stream = new MediaStream([audioTrack1kClone, audioTrack5kClone]);
|
|
var streamClone = stream.clone();
|
|
|
|
stream.getTracks().forEach(t => stream.removeTrack(t));
|
|
stream.addTrack(streamClone.getTracks()[0]);
|
|
streamClone.removeTrack(streamClone.getTracks()[0]);
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] < 50)
|
|
.then(() => {
|
|
analyser.disconnect();
|
|
var cloneAnalyser = new AudioStreamAnalyser(ac, streamClone);
|
|
return cloneAnalyser.waitForAnalysisSuccess(array =>
|
|
array[cloneAnalyser.binIndexForFrequency(1000)] < 50 &&
|
|
array[cloneAnalyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[cloneAnalyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[cloneAnalyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => cloneAnalyser.disconnect());
|
|
});
|
|
}).then(() => {
|
|
info("Analysing audio output enabled and disabled tracks that don't affect each other");
|
|
var stream = new MediaStream([audioTrack1kClone, audioTrack5kClone]);
|
|
var clone = stream.clone();
|
|
|
|
stream.getTracks()[0].enabled = true;
|
|
stream.getTracks()[1].enabled = false;
|
|
|
|
clone.getTracks()[0].enabled = false;
|
|
clone.getTracks()[1].enabled = true;
|
|
|
|
var analyser = new AudioStreamAnalyser(ac, stream);
|
|
return analyser.waitForAnalysisSuccess(array =>
|
|
array[analyser.binIndexForFrequency(50)] < 50 &&
|
|
array[analyser.binIndexForFrequency(1000)] > 200 &&
|
|
array[analyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[analyser.binIndexForFrequency(5000)] < 50)
|
|
.then(() => {
|
|
analyser.disconnect();
|
|
var cloneAnalyser = new AudioStreamAnalyser(ac, clone);
|
|
return cloneAnalyser.waitForAnalysisSuccess(array =>
|
|
array[cloneAnalyser.binIndexForFrequency(1000)] < 50 &&
|
|
array[cloneAnalyser.binIndexForFrequency(3000)] < 50 &&
|
|
array[cloneAnalyser.binIndexForFrequency(5000)] > 200 &&
|
|
array[cloneAnalyser.binIndexForFrequency(10000)] < 50)
|
|
.then(() => cloneAnalyser.disconnect());
|
|
})
|
|
// Restore original tracks
|
|
.then(() => stream.getTracks().forEach(t => t.enabled = true));
|
|
});
|
|
}));
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|