test_streams_element_capture.html (4126B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test that a MediaStream captured from one element plays back in another</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 <script type="text/javascript" src="manifest.js"></script> 8 </head> 9 <body> 10 <pre id="test"> 11 <script class="testbody" type="text/javascript"> 12 const manager = new MediaTestManager(); 13 14 function checkDrawImage(vout, msg) { 15 const canvas = document.createElement("canvas"); 16 const ctx = canvas.getContext("2d"); 17 ctx.drawImage(vout, 0, 0); 18 const imgData = ctx.getImageData(0, 0, 1, 1); 19 is(imgData.data[3], 255, msg); 20 } 21 22 function maybeTodoGreaterThanOrEqual(a, b, msg) { 23 const isExpected = a >= b; 24 (isExpected ? ok : todo)( 25 isExpected, 26 `Got ${a}, expected at least ${b}; ${msg}` 27 ); 28 } 29 30 async function startTest(test, token) { 31 manager.started(token); 32 const v = document.createElement('video'); 33 const vout = document.createElement('video'); 34 35 v.token = token; 36 v.id = "MediaDecoder"; 37 vout.id = "MediaStream"; 38 39 document.body.appendChild(vout); 40 41 // Log events for debugging. 42 const events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", 43 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", 44 "waiting", "pause"]; 45 function logEvent(e) { 46 Log(token, `${e.target.id} got ${e.type}`); 47 } 48 for (const e of events) { 49 v.addEventListener(e, logEvent); 50 vout.addEventListener(e, logEvent); 51 }; 52 53 v.src = test.name; 54 v.preload = 'metadata'; 55 await new Promise(r => v.onloadedmetadata = r); 56 57 const stream = v.mozCaptureStreamUntilEnded(); 58 vout.srcObject = stream; 59 is(vout.srcObject, stream, 60 `${token} set output element .srcObject correctly`); 61 62 isnot(stream.getTracks().length, 0, `${token} results in some tracks`); 63 const hadVideoTracks = stream.getVideoTracks().length >= 1; 64 // Wait for the resource fetch algorithm to have run, so that the media 65 // element is hooked up to the MediaStream and ready to go. If we don't do 66 // this, we're not guaranteed to render the very first video frame, which 67 // can make this test fail the drawImage test when a video resource only 68 // contains one frame. 69 await new Promise(r => vout.onloadstart = r); 70 v.play(); 71 vout.play(); 72 73 await Promise.race([ 74 Promise.all([ 75 new Promise(r => vout.onended = r), 76 new Promise(r => v.onended = r), 77 ]), 78 new Promise((res, rej) => vout.onerror = () => rej(new Error(vout.error.message))), 79 new Promise((res, rej) => v.onerror = () => rej(new Error(v.error.message))), 80 ]); 81 82 let duration = test.duration; 83 if (typeof(test.contentDuration) == "number") { 84 duration = test.contentDuration; 85 } 86 if (duration) { 87 // Unexpected results are tracked in bug 1839502 88 maybeTodoGreaterThanOrEqual(vout.currentTime, duration, 89 `${token} current time at end`); 90 } 91 is(vout.readyState, vout.HAVE_CURRENT_DATA, 92 `${token} checking readyState`); 93 ok(vout.ended, `${token} checking playback has ended`); 94 if (hadVideoTracks) { 95 ok(test.type.match(/^video/), `${token} is a video resource`); 96 checkDrawImage(vout, `${token} checking video frame pixel has been drawn`); 97 } 98 vout.remove(); 99 removeNodeAndSource(v); 100 } 101 102 (async () => { 103 SimpleTest.requestCompleteLog(); 104 SimpleTest.waitForExplicitFinish(); 105 await SpecialPowers.pushPrefEnv( 106 { "set": [ 107 ["privacy.reduceTimerPrecision", false], 108 ]}); 109 let tests = gPlayTests; 110 // Filter out bug1377278.webm due to bug 1541401. 111 tests = tests.filter(t => !t.name.includes("1377278")); 112 // bug 1372457, bug 1526207 for drawImage -- restrict to codecs that can be 113 // decoded in software. 114 if (navigator.userAgent.includes("Android")) { 115 tests = tests.filter(t => !t.name.includes("mp4")); 116 } 117 118 manager.runTests(tests, async (test, token) => { 119 try { 120 await startTest(test, token); 121 } catch(e) { 122 ok(false, `Caught exception for ${token}: ${e}`); 123 } 124 manager.finished(token); 125 }); 126 })(); 127 </script> 128 </pre> 129 </body> 130 </html>