MediaRecorder-bitrate.https.html (8668B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>MediaRecorder {audio|video}bitsPerSecond attributes</title> 5 <link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/resources/testdriver.js"></script> 9 <script src="/resources/testdriver-vendor.js"></script> 10 <script src="../mediacapture-streams/permission-helper.js"></script> 11 </head> 12 <script> 13 14 /* 15 * The bitrate handling is difficult to test, given that the spec uses text such 16 * as: "values the User Agent deems reasonable" and "such that the sum of 17 * videoBitsPerSecond and audioBitsPerSecond is close to the value of recorder’s 18 * [[ConstrainedBitsPerSecond]] slot". For cases like that this test tries to 19 * use values that are reasonable for the tested track types. Should a UA vendor 20 * see a need to update this to fit their definition of reasonable, they should 21 * feel free to do so, doing their best to avoid regressing existing compliant 22 * implementations. 23 */ 24 25 async function getStream(t, constraints) { 26 await setMediaPermission(); 27 const stream = await navigator.mediaDevices.getUserMedia(constraints); 28 const tracks = stream.getTracks(); 29 t.add_cleanup(() => tracks.forEach(tr => tr.stop())); 30 return stream; 31 } 32 33 function getAudioStream(t) { 34 return getStream(t, {audio: true}); 35 } 36 37 function getVideoStream(t) { 38 return getStream(t, {video: true}); 39 } 40 41 function getAudioVideoStream(t) { 42 return getStream(t, {audio: true, video: true}); 43 } 44 45 const AUDIO_BITRATE = 1e5; // 100kbps 46 const VIDEO_BITRATE = 1e6; // 1Mbps 47 const LOW_TOTAL_BITRATE = 5e5; // 500kbps 48 const HIGH_TOTAL_BITRATE = 2e6; // 2Mbps 49 const BITRATE_EPSILON = 1e5; // 100kbps 50 51 promise_test(async t => { 52 const rec = new MediaRecorder(await getAudioVideoStream(t)); 53 assert_not_equals(rec.audioBitsPerSecond, 0); 54 assert_not_equals(rec.videoBitsPerSecond, 0); 55 }, "Passing no bitrate config results in defaults"); 56 57 promise_test(async t => { 58 const rec = new MediaRecorder(await getAudioVideoStream(t), { 59 bitsPerSecond: 0, 60 }); 61 assert_not_equals(rec.audioBitsPerSecond, 0); 62 assert_not_equals(rec.videoBitsPerSecond, 0); 63 assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 0, 64 BITRATE_EPSILON); 65 }, "Passing bitsPerSecond:0 results in targets close to 0"); 66 67 promise_test(async t => { 68 const rec = new MediaRecorder(await getAudioVideoStream(t), { 69 audioBitsPerSecond: 0, 70 }); 71 assert_equals(rec.audioBitsPerSecond, 0); 72 assert_not_equals(rec.videoBitsPerSecond, 0); 73 }, "Passing only audioBitsPerSecond:0 results in 0 for audio, default for video"); 74 75 promise_test(async t => { 76 const rec = new MediaRecorder(await getAudioVideoStream(t), { 77 videoBitsPerSecond: 0, 78 }); 79 assert_not_equals(rec.audioBitsPerSecond, 0); 80 assert_equals(rec.videoBitsPerSecond, 0); 81 }, "Passing only videoBitsPerSecond:0 results in 0 for video, default for audio"); 82 83 promise_test(async t => { 84 const rec = new MediaRecorder(await getAudioVideoStream(t), { 85 bitsPerSecond: 0, 86 audioBitsPerSecond: AUDIO_BITRATE, 87 videoBitsPerSecond: VIDEO_BITRATE, 88 }); 89 assert_not_equals(rec.audioBitsPerSecond, 0); 90 assert_not_equals(rec.videoBitsPerSecond, 0); 91 assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 0, 92 BITRATE_EPSILON); 93 }, "Passing bitsPerSecond:0 overrides audio/video-specific values"); 94 95 promise_test(async t => { 96 const rec = new MediaRecorder(await getAudioVideoStream(t), { 97 bitsPerSecond: HIGH_TOTAL_BITRATE, 98 audioBitsPerSecond: 0, 99 videoBitsPerSecond: 0, 100 }); 101 assert_not_equals(rec.audioBitsPerSecond, 0); 102 assert_not_equals(rec.videoBitsPerSecond, 0); 103 assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 104 HIGH_TOTAL_BITRATE, BITRATE_EPSILON); 105 }, "Passing bitsPerSecond overrides audio/video zero values"); 106 107 promise_test(async t => { 108 const rec = new MediaRecorder(await getAudioVideoStream(t), { 109 bitsPerSecond: HIGH_TOTAL_BITRATE, 110 }); 111 assert_not_equals(rec.audioBitsPerSecond, 0); 112 assert_not_equals(rec.videoBitsPerSecond, 0); 113 assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 114 HIGH_TOTAL_BITRATE, BITRATE_EPSILON); 115 }, "Passing bitsPerSecond sets audio/video bitrate values"); 116 117 promise_test(async t => { 118 const rec = new MediaRecorder(await getAudioVideoStream(t), { 119 audioBitsPerSecond: AUDIO_BITRATE, 120 }); 121 assert_equals(rec.audioBitsPerSecond, AUDIO_BITRATE); 122 assert_not_equals(rec.videoBitsPerSecond, 0); 123 }, "Passing only audioBitsPerSecond results in default for video"); 124 125 promise_test(async t => { 126 const rec = new MediaRecorder(await getAudioVideoStream(t), { 127 videoBitsPerSecond: VIDEO_BITRATE, 128 }); 129 assert_not_equals(rec.audioBitsPerSecond, 0); 130 assert_equals(rec.videoBitsPerSecond, VIDEO_BITRATE); 131 }, "Passing only videoBitsPerSecond results in default for audio"); 132 133 promise_test(async t => { 134 const rec = new MediaRecorder(await getAudioStream(t), { 135 videoBitsPerSecond: VIDEO_BITRATE, 136 }); 137 assert_not_equals(rec.audioBitsPerSecond, 0); 138 assert_equals(rec.videoBitsPerSecond, VIDEO_BITRATE); 139 }, "Passing videoBitsPerSecond for audio-only stream still results in something for video"); 140 141 promise_test(async t => { 142 const rec = new MediaRecorder(await getVideoStream(t), { 143 audioBitsPerSecond: AUDIO_BITRATE, 144 }); 145 assert_equals(rec.audioBitsPerSecond, AUDIO_BITRATE); 146 assert_not_equals(rec.videoBitsPerSecond, 0); 147 }, "Passing audioBitsPerSecond for video-only stream still results in something for audio"); 148 149 promise_test(async t => { 150 const rec = new MediaRecorder(await getAudioStream(t), { 151 bitsPerSecond: HIGH_TOTAL_BITRATE, 152 }); 153 assert_not_equals(rec.audioBitsPerSecond, 0); 154 assert_not_equals(rec.videoBitsPerSecond, 0); 155 }, "Passing bitsPerSecond for audio-only stream still results in something for video"); 156 157 promise_test(async t => { 158 const rec = new MediaRecorder(await getVideoStream(t), { 159 bitsPerSecond: HIGH_TOTAL_BITRATE, 160 }); 161 assert_not_equals(rec.audioBitsPerSecond, 0); 162 assert_not_equals(rec.videoBitsPerSecond, 0); 163 }, "Passing bitsPerSecond for video-only stream still results in something for audio"); 164 165 promise_test(async t => { 166 const rec = new MediaRecorder(await getAudioVideoStream(t)); 167 t.add_cleanup(() => rec.stop()); 168 const abps = rec.audioBitsPerSecond; 169 const vbps = rec.videoBitsPerSecond; 170 rec.start(); 171 assert_equals(rec.audioBitsPerSecond, abps); 172 assert_equals(rec.videoBitsPerSecond, vbps); 173 }, "Selected default track bitrates are not changed by start()"); 174 175 promise_test(async t => { 176 const rec = new MediaRecorder(await getAudioVideoStream(t), { 177 audioBitsPerSecond: AUDIO_BITRATE, 178 videoBitsPerSecond: VIDEO_BITRATE, 179 }); 180 t.add_cleanup(() => rec.stop()); 181 const abps = rec.audioBitsPerSecond; 182 const vbps = rec.videoBitsPerSecond; 183 rec.start(); 184 assert_equals(rec.audioBitsPerSecond, abps); 185 assert_equals(rec.videoBitsPerSecond, vbps); 186 }, "Passed-in track bitrates are not changed by start()"); 187 188 promise_test(async t => { 189 const rec = new MediaRecorder(await getAudioVideoStream(t), { 190 bitsPerSecond: HIGH_TOTAL_BITRATE, 191 }); 192 t.add_cleanup(() => rec.stop()); 193 const abps = rec.audioBitsPerSecond; 194 const vbps = rec.videoBitsPerSecond; 195 rec.start(); 196 assert_equals(rec.audioBitsPerSecond, abps); 197 assert_equals(rec.videoBitsPerSecond, vbps); 198 }, "Passing bitsPerSecond for audio/video stream does not change track bitrates in start()"); 199 200 promise_test(async t => { 201 const rec = new MediaRecorder(await getAudioStream(t), { 202 bitsPerSecond: LOW_TOTAL_BITRATE, 203 }); 204 t.add_cleanup(() => rec.stop()); 205 const abps = rec.audioBitsPerSecond; 206 const vbps = rec.videoBitsPerSecond; 207 rec.start(); 208 assert_approx_equals(rec.audioBitsPerSecond, LOW_TOTAL_BITRATE, 209 BITRATE_EPSILON); 210 assert_equals(rec.videoBitsPerSecond, 0); 211 assert_not_equals(rec.audioBitsPerSecond, abps); 212 assert_not_equals(rec.videoBitsPerSecond, vbps); 213 }, "Passing bitsPerSecond for audio stream sets video track bitrate to 0 in start()"); 214 215 promise_test(async t => { 216 const rec = new MediaRecorder(await getVideoStream(t), { 217 bitsPerSecond: HIGH_TOTAL_BITRATE, 218 }); 219 t.add_cleanup(() => rec.stop()); 220 const abps = rec.audioBitsPerSecond; 221 const vbps = rec.videoBitsPerSecond; 222 rec.start(); 223 assert_equals(rec.audioBitsPerSecond, 0); 224 assert_approx_equals(rec.videoBitsPerSecond, HIGH_TOTAL_BITRATE, 225 BITRATE_EPSILON); 226 assert_not_equals(rec.audioBitsPerSecond, abps); 227 assert_not_equals(rec.videoBitsPerSecond, vbps); 228 }, "Passing bitsPerSecond for video stream sets audio track bitrate to 0 in start()"); 229 </script> 230 </html>