diff options
Diffstat (limited to 'dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html')
-rw-r--r-- | dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html b/dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html new file mode 100644 index 000000000..8d4d5e559 --- /dev/null +++ b/dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html @@ -0,0 +1,251 @@ +<!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> |