test_getUserMedia_mediaElementCapture_tracks.html (6763B)
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> 9 10 createHTML({ 11 bug: "1259788", 12 title: "Test CaptureStream track output on HTMLMediaElement playing a gUM MediaStream", 13 visible: true 14 }); 15 16 let audioElement; 17 let audioCaptureStream; 18 let videoElement; 19 let videoCaptureStream; 20 let untilEndedElement; 21 let streamUntilEnded; 22 const tracks = []; 23 runTest(async () => { 24 try { 25 await pushPrefs( 26 ["media.getusermedia.camera.fake.force", true], 27 ["media.video_loopback_dev", ""], 28 ); 29 let stream = await getUserMedia({audio: true, video: true}); 30 // We need to test with multiple tracks. We add an extra of each kind. 31 for (const track of stream.getTracks()) { 32 stream.addTrack(track.clone()); 33 } 34 35 audioElement = createMediaElement("audio", "gUMAudio"); 36 audioElement.srcObject = stream; 37 38 await haveEvent(audioElement, "loadedmetadata", wait(50000, new Error("Timeout"))); 39 40 info("Capturing audio element (loadedmetadata -> captureStream)"); 41 audioCaptureStream = audioElement.mozCaptureStream(); 42 43 is(audioCaptureStream.getAudioTracks().length, 2, 44 "audio element should capture two audio tracks"); 45 is(audioCaptureStream.getVideoTracks().length, 0, 46 "audio element should not capture any video tracks"); 47 48 await haveNoEvent(audioCaptureStream, "addtrack"); 49 50 videoElement = createMediaElement("video", "gUMVideo"); 51 52 info("Capturing video element (captureStream -> loadedmetadata)"); 53 videoCaptureStream = videoElement.mozCaptureStream(); 54 videoElement.srcObject = audioElement.srcObject.clone(); 55 56 is(videoCaptureStream.getTracks().length, 0, 57 "video element should have no tracks before metadata known"); 58 59 await haveEventsButNoMore( 60 videoCaptureStream, "addtrack", 3, wait(50000, new Error("No event"))); 61 62 is(videoCaptureStream.getAudioTracks().length, 2, 63 "video element should capture two audio tracks"); 64 is(videoCaptureStream.getVideoTracks().length, 1, 65 "video element should capture one video track at most"); 66 67 info("Testing dynamically adding audio track to audio element"); 68 audioElement.srcObject.addTrack( 69 audioElement.srcObject.getAudioTracks()[0].clone()); 70 await haveEventsButNoMore( 71 audioCaptureStream, "addtrack", 1, wait(50000, new Error("No event"))); 72 73 is(audioCaptureStream.getAudioTracks().length, 3, 74 "Audio element should have three audio tracks captured."); 75 76 info("Testing dynamically adding video track to audio element"); 77 audioElement.srcObject.addTrack( 78 audioElement.srcObject.getVideoTracks()[0].clone()); 79 await haveNoEvent(audioCaptureStream, "addtrack"); 80 81 is(audioCaptureStream.getVideoTracks().length, 0, 82 "Audio element should have no video tracks captured."); 83 84 info("Testing dynamically adding audio track to video element"); 85 videoElement.srcObject.addTrack( 86 videoElement.srcObject.getAudioTracks()[0].clone()); 87 await haveEventsButNoMore( 88 videoCaptureStream, "addtrack", 1, wait(50000, new Error("Timeout"))); 89 90 is(videoCaptureStream.getAudioTracks().length, 3, 91 "Captured video stream should have three audio tracks captured."); 92 93 info("Testing dynamically adding video track to video element"); 94 videoElement.srcObject.addTrack( 95 videoElement.srcObject.getVideoTracks()[0].clone()); 96 await haveNoEvent(videoCaptureStream, "addtrack"); 97 98 is(videoCaptureStream.getVideoTracks().length, 1, 99 "Captured video stream should have at most one video tracks captured."); 100 101 info("Testing track removal."); 102 tracks.push(...videoElement.srcObject.getTracks()); 103 for (const track of videoElement.srcObject.getVideoTracks().reverse()) { 104 videoElement.srcObject.removeTrack(track); 105 } 106 is(videoCaptureStream.getVideoTracks().length, 1, 107 "Captured video should have still have one video track."); 108 109 await haveEvent(videoCaptureStream.getVideoTracks()[0], "ended", 110 wait(50000, new Error("Timeout"))); 111 await haveEvent(videoCaptureStream, "removetrack", 112 wait(50000, new Error("Timeout"))); 113 114 is(videoCaptureStream.getVideoTracks().length, 0, 115 "Captured video stream should have no video tracks after removal."); 116 117 118 info("Testing source reset."); 119 stream = await getUserMedia({audio: true, video: true}); 120 videoElement.srcObject = stream; 121 for (const track of videoCaptureStream.getTracks()) { 122 await Promise.race(videoCaptureStream.getTracks().map( 123 t => haveEvent(t, "ended", wait(50000, new Error("Timeout")))) 124 ); 125 await haveEvent(videoCaptureStream, "removetrack", wait(50000, new Error("Timeout"))); 126 } 127 await haveEventsButNoMore( 128 videoCaptureStream, "addtrack", 2, wait(50000, new Error("Timeout"))); 129 is(videoCaptureStream.getAudioTracks().length, 1, 130 "Captured video stream should have one audio track"); 131 132 is(videoCaptureStream.getVideoTracks().length, 1, 133 "Captured video stream should have one video track"); 134 135 info("Testing CaptureStreamUntilEnded"); 136 untilEndedElement = 137 createMediaElement("video", "gUMVideoUntilEnded"); 138 untilEndedElement.srcObject = audioElement.srcObject; 139 140 await haveEvent(untilEndedElement, "loadedmetadata", 141 wait(50000, new Error("Timeout"))); 142 143 streamUntilEnded = untilEndedElement.mozCaptureStreamUntilEnded(); 144 145 is(streamUntilEnded.getAudioTracks().length, 3, 146 "video element should capture all 3 audio tracks until ended"); 147 is(streamUntilEnded.getVideoTracks().length, 1, 148 "video element should capture only 1 video track until ended"); 149 150 for (const track of untilEndedElement.srcObject.getTracks()) { 151 track.stop(); 152 } 153 154 await haveEvent(untilEndedElement, "ended", wait(50000, new Error("Timeout"))); 155 for (const track of streamUntilEnded.getTracks()) { 156 await Promise.race(streamUntilEnded.getTracks().map( 157 t => haveEvent(t, "ended", wait(50000, new Error("Timeout")))) 158 ); 159 await haveEvent(streamUntilEnded, "removetrack", wait(50000, new Error("Timeout"))); 160 } 161 162 info("Element and tracks ended. Ensuring that new tracks aren't created."); 163 untilEndedElement.srcObject = videoElement.srcObject; 164 await haveEventsButNoMore( 165 untilEndedElement, "loadedmetadata", 1, wait(50000, new Error("Timeout"))); 166 167 is(streamUntilEnded.getTracks().length, 0, "Should have no tracks"); 168 } catch(e) { 169 ok(false, "Test failed: " + e + (e && e.stack ? "\n" + e.stack : "")); 170 } finally { 171 if (videoElement) { 172 tracks.push(...videoElement.srcObject.getTracks()); 173 } 174 for(const track of tracks) { 175 track.stop(); 176 } 177 } 178 }); 179 180 </script> 181 </pre> 182 </body> 183 </html>