DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (0c3bc698f640)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
<!doctype html>
<html>
<head>
<title>MediaRecorder {audio|video}bitsPerSecond attributes</title>
<link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<script>

/*
 * The bitrate handling is difficult to test, given that the spec uses text such
 * as: "values the User Agent deems reasonable" and "such that the sum of
 * videoBitsPerSecond and audioBitsPerSecond is close to the value of recorder’s
 * [[ConstrainedBitsPerSecond]] slot". For cases like that this test tries to
 * use values that are reasonable for the tested track types. Should a UA vendor
 * see a need to update this to fit their definition of reasonable, they should
 * feel free to do so, doing their best to avoid regressing existing compliant
 * implementations.
 */

async function getStream(t, constraints) {
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
  const tracks = stream.getTracks();
  t.add_cleanup(() => tracks.forEach(tr => tr.stop()));
  return stream;
}

function getAudioStream(t) {
  return getStream(t, {audio: true});
}

function getVideoStream(t) {
  return getStream(t, {video: true});
}

function getAudioVideoStream(t) {
  return getStream(t, {audio: true, video: true});
}

const AUDIO_BITRATE = 1e5;      // 100kbps
const VIDEO_BITRATE = 1e6;      // 1Mbps
const LOW_TOTAL_BITRATE = 5e5;  // 500kbps
const HIGH_TOTAL_BITRATE = 2e6; // 2Mbps
const BITRATE_EPSILON = 1e5;    // 100kbps

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t));
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing no bitrate config results in defaults");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    bitsPerSecond: 0,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
  assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 0,
    BITRATE_EPSILON);
}, "Passing bitsPerSecond:0 results in targets close to 0");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    audioBitsPerSecond: 0,
  });
  assert_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing only audioBitsPerSecond:0 results in 0 for audio, default for video");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    videoBitsPerSecond: 0,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_equals(rec.videoBitsPerSecond, 0);
}, "Passing only videoBitsPerSecond:0 results in 0 for video, default for audio");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    bitsPerSecond: 0,
    audioBitsPerSecond: AUDIO_BITRATE,
    videoBitsPerSecond: VIDEO_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
  assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond, 0,
    BITRATE_EPSILON);
}, "Passing bitsPerSecond:0 overrides audio/video-specific values");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
    audioBitsPerSecond: 0,
    videoBitsPerSecond: 0,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
  assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond,
    HIGH_TOTAL_BITRATE, BITRATE_EPSILON);
}, "Passing bitsPerSecond overrides audio/video zero values");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
  assert_approx_equals(rec.audioBitsPerSecond + rec.videoBitsPerSecond,
    HIGH_TOTAL_BITRATE, BITRATE_EPSILON);
}, "Passing bitsPerSecond sets audio/video bitrate values");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    audioBitsPerSecond: AUDIO_BITRATE,
  });
  assert_equals(rec.audioBitsPerSecond, AUDIO_BITRATE);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing only audioBitsPerSecond results in default for video");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    videoBitsPerSecond: VIDEO_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_equals(rec.videoBitsPerSecond, VIDEO_BITRATE);
}, "Passing only videoBitsPerSecond results in default for audio");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioStream(t), {
    videoBitsPerSecond: VIDEO_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_equals(rec.videoBitsPerSecond, VIDEO_BITRATE);
}, "Passing videoBitsPerSecond for audio-only stream still results in something for video");

promise_test(async t => {
  const rec = new MediaRecorder(await getVideoStream(t), {
    audioBitsPerSecond: AUDIO_BITRATE,
  });
  assert_equals(rec.audioBitsPerSecond, AUDIO_BITRATE);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing audioBitsPerSecond for video-only stream still results in something for audio");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing bitsPerSecond for audio-only stream still results in something for video");

promise_test(async t => {
  const rec = new MediaRecorder(await getVideoStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
  });
  assert_not_equals(rec.audioBitsPerSecond, 0);
  assert_not_equals(rec.videoBitsPerSecond, 0);
}, "Passing bitsPerSecond for video-only stream still results in something for audio");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t));
  t.add_cleanup(() => rec.stop());
  const abps = rec.audioBitsPerSecond;
  const vbps = rec.videoBitsPerSecond;
  rec.start();
  assert_equals(rec.audioBitsPerSecond, abps);
  assert_equals(rec.videoBitsPerSecond, vbps);
}, "Selected default track bitrates are not changed by start()");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    audioBitsPerSecond: AUDIO_BITRATE,
    videoBitsPerSecond: VIDEO_BITRATE,
  });
  t.add_cleanup(() => rec.stop());
  const abps = rec.audioBitsPerSecond;
  const vbps = rec.videoBitsPerSecond;
  rec.start();
  assert_equals(rec.audioBitsPerSecond, abps);
  assert_equals(rec.videoBitsPerSecond, vbps);
}, "Passed-in track bitrates are not changed by start()");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioVideoStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
  });
  t.add_cleanup(() => rec.stop());
  const abps = rec.audioBitsPerSecond;
  const vbps = rec.videoBitsPerSecond;
  rec.start();
  assert_equals(rec.audioBitsPerSecond, abps);
  assert_equals(rec.videoBitsPerSecond, vbps);
}, "Passing bitsPerSecond for audio/video stream does not change track bitrates in start()");

promise_test(async t => {
  const rec = new MediaRecorder(await getAudioStream(t), {
    bitsPerSecond: LOW_TOTAL_BITRATE,
  });
  t.add_cleanup(() => rec.stop());
  const abps = rec.audioBitsPerSecond;
  const vbps = rec.videoBitsPerSecond;
  rec.start();
  assert_approx_equals(rec.audioBitsPerSecond, LOW_TOTAL_BITRATE,
    BITRATE_EPSILON);
  assert_equals(rec.videoBitsPerSecond, 0);
  assert_not_equals(rec.audioBitsPerSecond, abps);
  assert_not_equals(rec.videoBitsPerSecond, vbps);
}, "Passing bitsPerSecond for audio stream sets video track bitrate to 0 in start()");

promise_test(async t => {
  const rec = new MediaRecorder(await getVideoStream(t), {
    bitsPerSecond: HIGH_TOTAL_BITRATE,
  });
  t.add_cleanup(() => rec.stop());
  const abps = rec.audioBitsPerSecond;
  const vbps = rec.videoBitsPerSecond;
  rec.start();
  assert_equals(rec.audioBitsPerSecond, 0);
  assert_approx_equals(rec.videoBitsPerSecond, HIGH_TOTAL_BITRATE,
    BITRATE_EPSILON);
  assert_not_equals(rec.audioBitsPerSecond, abps);
  assert_not_equals(rec.videoBitsPerSecond, vbps);
}, "Passing bitsPerSecond for video stream sets audio track bitrate to 0 in start()");
</script>
</html>