test_getUserMedia_mediaStreamTrackClone.html (7594B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script type="application/javascript" src="mediaStreamPlayback.js"></script> 5 </head> 6 <body> 7 <pre id="test"> 8 <script type="application/javascript"> 9 "use strict"; 10 11 createHTML({ 12 title: "MediaStreamTrack.clone()", 13 bug: "1208371" 14 }); 15 16 var testSingleTrackClonePlayback = constraints => 17 getUserMedia(constraints).then(stream => { 18 info("Test clone()ing an " + constraints + " gUM track"); 19 var track = stream.getTracks()[0]; 20 var clone = track.clone(); 21 22 checkMediaStreamTrackCloneAgainstOriginal(clone, track); 23 24 info("Stopping original track"); 25 track.stop(); 26 27 info("Creating new stream for clone"); 28 var cloneStream = new MediaStream([clone]); 29 checkMediaStreamContains(cloneStream, [clone]); 30 31 info("Testing playback of track clone"); 32 var test = createMediaElement('video', 'testClonePlayback'); 33 var playback = new MediaStreamPlayback(test, cloneStream); 34 return playback.playMedia(false); 35 }); 36 37 runTest(() => Promise.resolve() 38 .then(() => pushPrefs( 39 ["media.getusermedia.camera.fake.force", true], 40 ["media.video_loopback_dev", ""], 41 )) 42 .then(() => testSingleTrackClonePlayback({audio: true})) 43 .then(() => testSingleTrackClonePlayback({video: true})) 44 .then(() => getUserMedia({video: true})).then(stream => { 45 info("Test cloning a track into inception"); 46 var track = stream.getTracks()[0]; 47 var clone = track; 48 var clones = Array(10).fill().map(() => clone = clone.clone()); 49 var inceptionClone = clones.pop(); 50 checkMediaStreamTrackCloneAgainstOriginal(inceptionClone, track); 51 52 var cloneStream = new MediaStream(); 53 cloneStream.addTrack(inceptionClone); 54 55 // cloneStream is now essentially the same as stream.clone(); 56 checkMediaStreamCloneAgainstOriginal(cloneStream, stream); 57 58 var test = createMediaElement('video', 'testClonePlayback'); 59 var playback = new MediaStreamPlayback(test, cloneStream); 60 return playback.playMedia(false).then(() => { 61 info("Testing that clones of ended tracks are ended"); 62 cloneStream.clone().getTracks().forEach(t => 63 is(t.readyState, "ended", "Track " + t.id + " should be ended")); 64 }) 65 .then(() => { 66 clones.forEach(t => t.stop()); 67 track.stop(); 68 }); 69 }) 70 .then(() => getUserMedia({audio: true, video: true})).then(stream => { 71 info("Test adding many track clones to the original stream"); 72 73 const LOOPS = 3; 74 for (var i = 0; i < LOOPS; i++) { 75 stream.getTracks().forEach(t => stream.addTrack(t.clone())); 76 } 77 is(stream.getVideoTracks().length, Math.pow(2, LOOPS), 78 "The original track should contain the original video track and all the video clones"); 79 stream.getTracks().forEach(t1 => is(stream.getTracks() 80 .filter(t2 => t1.id == t2.id) 81 .length, 82 1, "Each track should be unique")); 83 84 var test = createMediaElement('video', 'testClonePlayback'); 85 var playback = new MediaStreamPlayback(test, stream); 86 return playback.playMedia(false); 87 }) 88 .then(() => { 89 info("Testing audio content routing with MediaStreamTrack.clone()"); 90 var ac = new AudioContext(); 91 92 var osc1kOriginal = createOscillatorStream(ac, 1000); 93 var audioTrack1kOriginal = osc1kOriginal.getTracks()[0]; 94 var audioTrack1kClone = audioTrack1kOriginal.clone(); 95 96 var osc5kOriginal = createOscillatorStream(ac, 5000); 97 var audioTrack5kOriginal = osc5kOriginal.getTracks()[0]; 98 var audioTrack5kClone = audioTrack5kOriginal.clone(); 99 100 return Promise.resolve().then(() => { 101 info("Analysing audio output enabled and disabled tracks that don't affect each other"); 102 audioTrack1kOriginal.enabled = true; 103 audioTrack5kOriginal.enabled = false; 104 105 audioTrack1kClone.enabled = false; 106 audioTrack5kClone.enabled = true; 107 108 var analyser = 109 new AudioStreamAnalyser(ac, new MediaStream([audioTrack1kOriginal, 110 audioTrack5kOriginal])); 111 return analyser.waitForAnalysisSuccess(array => 112 array[analyser.binIndexForFrequency(50)] < 50 && 113 array[analyser.binIndexForFrequency(1000)] > 200 && 114 array[analyser.binIndexForFrequency(3000)] < 50 && 115 array[analyser.binIndexForFrequency(5000)] < 50) 116 .then(() => analyser.disconnect()) 117 .then(() => { 118 var cloneAnalyser = 119 new AudioStreamAnalyser(ac, new MediaStream([audioTrack1kClone, 120 audioTrack5kClone])); 121 return cloneAnalyser.waitForAnalysisSuccess(array => 122 array[cloneAnalyser.binIndexForFrequency(1000)] < 50 && 123 array[cloneAnalyser.binIndexForFrequency(3000)] < 50 && 124 array[cloneAnalyser.binIndexForFrequency(5000)] > 200 && 125 array[cloneAnalyser.binIndexForFrequency(10000)] < 50) 126 .then(() => cloneAnalyser.disconnect()); 127 }) 128 // Restore original tracks 129 .then(() => [audioTrack1kOriginal, 130 audioTrack5kOriginal, 131 audioTrack1kClone, 132 audioTrack5kClone].forEach(t => t.enabled = true)); 133 }).then(() => { 134 info("Analysing audio output of 1k original and 5k clone."); 135 var stream = new MediaStream(); 136 stream.addTrack(audioTrack1kOriginal); 137 stream.addTrack(audioTrack5kClone); 138 139 var analyser = new AudioStreamAnalyser(ac, stream); 140 return analyser.waitForAnalysisSuccess(array => 141 array[analyser.binIndexForFrequency(50)] < 50 && 142 array[analyser.binIndexForFrequency(1000)] > 200 && 143 array[analyser.binIndexForFrequency(3000)] < 50 && 144 array[analyser.binIndexForFrequency(5000)] > 200 && 145 array[analyser.binIndexForFrequency(10000)] < 50) 146 .then(() => { 147 info("Waiting for tracks to stop"); 148 stream.getTracks().forEach(t => t.stop()); 149 return analyser.waitForAnalysisSuccess(array => 150 array[analyser.binIndexForFrequency(50)] < 50 && 151 array[analyser.binIndexForFrequency(1000)] < 50 && 152 array[analyser.binIndexForFrequency(3000)] < 50 && 153 array[analyser.binIndexForFrequency(5000)] < 50 && 154 array[analyser.binIndexForFrequency(10000)] < 50); 155 }).then(() => analyser.disconnect()); 156 }).then(() => { 157 info("Analysing audio output of clones of clones (1kx2 + 5kx4)"); 158 var stream = new MediaStream([audioTrack1kClone.clone(), 159 audioTrack5kOriginal.clone().clone().clone().clone()]); 160 161 var analyser = new AudioStreamAnalyser(ac, stream); 162 return analyser.waitForAnalysisSuccess(array => 163 array[analyser.binIndexForFrequency(50)] < 50 && 164 array[analyser.binIndexForFrequency(1000)] > 200 && 165 array[analyser.binIndexForFrequency(3000)] < 50 && 166 array[analyser.binIndexForFrequency(5000)] > 200 && 167 array[analyser.binIndexForFrequency(10000)] < 50) 168 .then(() => analyser.disconnect()); 169 }); 170 })); 171 </script> 172 </pre> 173 </body> 174 </html>