head.js (5922B)
1 "use strict"; 2 3 /* import-globals-from ../eme_standalone.js */ 4 5 // Opens a tab containing a blank page, returns a promise that will resolve 6 // to that tab. 7 function openTab() { 8 const emptyPageUri = 9 "https://example.com/browser/dom/media/test/browser/file_empty_page.html"; 10 return BrowserTestUtils.openNewForegroundTab(window.gBrowser, emptyPageUri); 11 } 12 13 // Creates and configures a video element for non-MSE playback in `tab`. Does not 14 // start playback for the element. Returns a promise that will resolve once 15 // the element is setup and ready for playback. 16 function loadVideo(tab, { extraEvent = undefined, loadHDR = false } = {}) { 17 return SpecialPowers.spawn( 18 tab.linkedBrowser, 19 [extraEvent, loadHDR], 20 async (_extraEvent, _loadHDR) => { 21 let video = content.document.createElement("video"); 22 video.id = "media"; 23 content.document.body.appendChild(video); 24 25 if (_loadHDR) { 26 video.src = "vp9-yuv420p10.webm"; 27 } else { 28 video.src = "gizmo.webm"; 29 } 30 video.load(); 31 32 info(`waiting 'loadeddata' event to ensure playback is ready`); 33 let promises = []; 34 promises.push(new Promise(r => (video.onloadeddata = r))); 35 if (_extraEvent != undefined) { 36 info( 37 `waiting '${_extraEvent}' event to ensure the probe has been recorded` 38 ); 39 promises.push( 40 new Promise(r => 41 video.addEventListener(_extraEvent, r, { once: true }) 42 ) 43 ); 44 } 45 await Promise.allSettled(promises); 46 } 47 ); 48 } 49 50 // Creates and configures a video element for MSE playback in `tab`. Does not 51 // start playback for the element. Returns a promise that will resolve once 52 // the element is setup and ready for playback. 53 function loadMseVideo(tab, extraEvent = undefined) { 54 return SpecialPowers.spawn( 55 tab.linkedBrowser, 56 [extraEvent], 57 async _extraEvent => { 58 async function once(target, name) { 59 return new Promise(r => 60 target.addEventListener(name, r, { once: true }) 61 ); 62 } 63 64 let video = content.document.createElement("video"); 65 video.id = "media"; 66 content.document.body.appendChild(video); 67 68 info(`starting setup MSE`); 69 const ms = new content.wrappedJSObject.MediaSource(); 70 video.src = content.wrappedJSObject.URL.createObjectURL(ms); 71 await once(ms, "sourceopen"); 72 const sb = ms.addSourceBuffer("video/webm"); 73 const videoFile = "bipbop_300-3s-no-audio.webm"; 74 let fetchResponse = await content.fetch(videoFile); 75 sb.appendBuffer(await fetchResponse.arrayBuffer()); 76 await once(sb, "updateend"); 77 ms.endOfStream(); 78 await once(ms, "sourceended"); 79 80 info(`waiting 'loadeddata' event to ensure playback is ready`); 81 let promises = []; 82 promises.push(once(video, "loadeddata")); 83 if (_extraEvent != undefined) { 84 info( 85 `waiting '${_extraEvent}' event to ensure the probe has been recorded` 86 ); 87 promises.push( 88 new Promise(r => 89 video.addEventListener(_extraEvent, r, { once: true }) 90 ) 91 ); 92 } 93 await Promise.allSettled(promises); 94 } 95 ); 96 } 97 98 // Creates and configures a video element for EME playback in `tab`. Does not 99 // start playback for the element. Returns a promise that will resolve once 100 // the element is setup and ready for playback. 101 function loadEmeVideo(tab, extraEvent = undefined) { 102 const emeHelperUri = 103 gTestPath.substr(0, gTestPath.lastIndexOf("/")) + "/eme_standalone.js"; 104 return SpecialPowers.spawn( 105 tab.linkedBrowser, 106 [emeHelperUri, extraEvent], 107 async (_emeHelperUri, _extraEvent) => { 108 async function once(target, name) { 109 return new Promise(r => 110 target.addEventListener(name, r, { once: true }) 111 ); 112 } 113 114 // Helper to clone data into content so the EME helper can use the data. 115 function cloneIntoContent(data) { 116 return Cu.cloneInto(data, content.wrappedJSObject); 117 } 118 119 info(`starting setup EME`); 120 Services.scriptloader.loadSubScript(_emeHelperUri, content); 121 let video = content.document.createElement("video"); 122 video.id = "media"; 123 content.document.body.appendChild(video); 124 let emeHelper = new content.wrappedJSObject.EmeHelper(); 125 emeHelper.SetKeySystem( 126 content.wrappedJSObject.EmeHelper.GetClearkeyKeySystemString() 127 ); 128 emeHelper.SetInitDataTypes(cloneIntoContent(["webm"])); 129 emeHelper.SetVideoCapabilities( 130 cloneIntoContent([{ contentType: 'video/webm; codecs="vp9"' }]) 131 ); 132 emeHelper.AddKeyIdAndKey( 133 "2cdb0ed6119853e7850671c3e9906c3c", 134 "808b9adac384de1e4f56140f4ad76194" 135 ); 136 emeHelper.onerror = error => { 137 is(false, `Got unexpected error from EME helper: ${error}`); 138 }; 139 await emeHelper.ConfigureEme(video); 140 141 info(`starting setup MSE`); 142 const ms = new content.wrappedJSObject.MediaSource(); 143 video.src = content.wrappedJSObject.URL.createObjectURL(ms); 144 await once(ms, "sourceopen"); 145 const sb = ms.addSourceBuffer("video/webm"); 146 const videoFile = "sintel-short-clearkey-subsample-encrypted-video.webm"; 147 let fetchResponse = await content.fetch(videoFile); 148 sb.appendBuffer(await fetchResponse.arrayBuffer()); 149 await once(sb, "updateend"); 150 ms.endOfStream(); 151 await once(ms, "sourceended"); 152 153 info(`waiting 'loadeddata' event to ensure playback is ready`); 154 let promises = []; 155 promises.push(once(video, "loadeddata")); 156 if (_extraEvent != undefined) { 157 info( 158 `waiting '${_extraEvent}' event to ensure the probe has been recorded` 159 ); 160 promises.push( 161 new Promise(r => 162 video.addEventListener(_extraEvent, r, { once: true }) 163 ) 164 ); 165 } 166 await Promise.allSettled(promises); 167 } 168 ); 169 }