tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaStreamTrack-getSettings.https.html (11185B)


      1 <!doctype html>
      2 <title>MediaStreamTrack GetSettings</title>
      3 <p class="instructions">When prompted, accept to share your video stream.</p>
      4 <meta name=timeout content=long>
      5 <script src=/resources/testharness.js></script>
      6 <script src=/resources/testharnessreport.js></script>
      7 <script src=/resources/testdriver.js></script>
      8 <script src=/resources/testdriver-vendor.js></script>
      9 <script src=permission-helper.js></script>
     10 <script>
     11  'use strict'
     12 
     13  // https://w3c.github.io/mediacapture-main/archives/20170605/getusermedia.html
     14 
     15  async function createTrackAndGetSettings(t, kind) {
     16    const constraints = {};
     17    constraints[kind] = true;
     18    const stream = await navigator.mediaDevices.getUserMedia(constraints);
     19    assert_equals(stream.getTracks().length, 1);
     20    t.add_cleanup(() => stream.getTracks()[0].stop());
     21    return stream.getTracks()[0].getSettings();
     22  }
     23 
     24  promise_test(async t => {
     25    await setMediaPermission("granted", ["camera"]);
     26    const mediaStream1 = await navigator.mediaDevices.getUserMedia({
     27      video: true,
     28      audio: false,
     29    });
     30    t.add_cleanup(() => mediaStream1.getVideoTracks()[0].stop());
     31    const settings1 = mediaStream1.getVideoTracks()[0].getSettings();
     32 
     33    const mediaStream2 = await navigator.mediaDevices.getUserMedia({
     34      video: {
     35        deviceId: {exact: settings1.deviceId},
     36      },
     37      audio: false
     38    });
     39    t.add_cleanup(() => mediaStream2.getVideoTracks()[0].stop());
     40    const settings2 = mediaStream2.getVideoTracks()[0].getSettings();
     41 
     42    assert_equals(settings1.deviceId, settings2.deviceId);
     43  }, 'A device can be opened twice and have the same device ID');
     44 
     45  promise_test(async t => {
     46    const mediaStream1 = await navigator.mediaDevices.getUserMedia({
     47      video: true,
     48      audio: false,
     49    });
     50    t.add_cleanup(() => mediaStream1.getVideoTracks()[0].stop());
     51    const settings1 = mediaStream1.getVideoTracks()[0].getSettings();
     52 
     53    const mediaStream2 = await navigator.mediaDevices.getUserMedia({
     54      video: {
     55        deviceId: {exact: settings1.deviceId},
     56        width: {
     57          ideal: settings1.width / 2,
     58        },
     59      },
     60      audio: false
     61    });
     62    t.add_cleanup(() => mediaStream2.getVideoTracks()[0].stop());
     63    const settings2 = mediaStream2.getVideoTracks()[0].getSettings();
     64 
     65    assert_equals(settings1.deviceId, settings2.deviceId);
     66    assert_between_inclusive(settings2.width, settings1.width / 2, settings1.width);
     67  }, 'A device can be opened twice with different resolutions requested');
     68 
     69  promise_test(async t => {
     70    // getUserMedia needs to be called before deviceIds and groupIds are exposed
     71    const afterGum = await navigator.mediaDevices.getUserMedia({
     72      video: true, audio: true
     73    });
     74    const devices = await navigator.mediaDevices.enumerateDevices();
     75    const inputDevices = devices.filter(({kind}) => kind != "audiooutput");
     76    assert_greater_than(inputDevices.length, 1, "have at least 2 test devices");
     77 
     78    // first check the default tracks from the already called getUserMedia()
     79    for (const track of afterGum.getTracks()) {
     80      const settings = track.getSettings();
     81      const device = inputDevices.find(({deviceId}) => deviceId == settings.deviceId);
     82      assert_not_equals(device, undefined, `track was from an enumerated device`);
     83      assert_equals(`${track.kind}input`, device.kind, `default track is the right kind.`);
     84      track.stop();
     85      assert_equals(typeof settings.deviceId, "string", "default deviceId is a string");
     86      assert_greater_than(settings.deviceId.length, 0, "default deviceId is not empty");
     87      assert_equals(settings.deviceId, device.deviceId, "default track deviceId matches device");
     88      assert_equals(typeof settings.groupId, "string", "default groupId is a string.");
     89      assert_greater_than(settings.groupId.length, 0, "default groupId is not empty");
     90      assert_equals(settings.groupId, device.groupId, "default track groupId matches device");
     91    }
     92    // then check explicitly requesting each input device
     93    for (const {kind, deviceId, groupId} of inputDevices) {
     94      const type = {videoinput: "video", audioinput: "audio"}[kind];
     95      const stream = await navigator.mediaDevices.getUserMedia({
     96        [type]: {deviceId: {exact: deviceId}}
     97      });
     98      const [track] = stream.getTracks();
     99      const settings = track.getSettings();
    100      track.stop();
    101      assert_equals(`${track.kind}input`, kind, `track is of the right kind.`);
    102      assert_equals(typeof settings.deviceId, "string", "deviceId is a string.");
    103      assert_greater_than(settings.deviceId.length, 0, "deviceId is not empty");
    104      assert_equals(settings.deviceId, deviceId, "track and device deviceIds match");
    105      assert_equals(typeof settings.groupId, "string", "groupId is a string.");
    106      assert_greater_than(settings.groupId.length, 0, "groupId is not empty");
    107      assert_equals(settings.groupId, groupId, "track and device groupId match");
    108    }
    109  }, 'deviceId and groupId are correctly reported by getSettings() for all input devices');
    110 
    111  promise_test(async t => {
    112    const settings = await createTrackAndGetSettings(t, "audio");
    113    assert_equals(typeof(settings.sampleRate), "number",
    114                  "sampleRate should exist and it should be a number.");
    115    assert_greater_than(settings.sampleRate, 0);
    116  }, 'sampleRate is reported by getSettings() for getUserMedia() audio tracks');
    117 
    118  promise_test(async t => {
    119    const settings = await createTrackAndGetSettings(t, "audio");
    120    assert_equals(typeof(settings.sampleSize), "number",
    121                  "sampleSize should exist and it should be a number.");
    122    assert_greater_than(settings.sampleSize, 0);
    123  }, 'sampleSize is reported by getSettings() for getUserMedia() audio tracks');
    124 
    125  promise_test(async t => {
    126    const settings = await createTrackAndGetSettings(t, "audio");
    127    assert_equals(typeof(settings.echoCancellation), "boolean",
    128                  "echoCancellation should exist and it should be a boolean.");
    129  }, 'echoCancellation is reported by getSettings() for getUserMedia() audio tracks');
    130 
    131  promise_test(async t => {
    132    const settings = await createTrackAndGetSettings(t, "audio");
    133    assert_equals(typeof(settings.autoGainControl), "boolean",
    134                  "autoGainControl should exist and it should be a boolean.");
    135  }, 'autoGainControl is reported by getSettings() for getUserMedia() audio tracks');
    136 
    137  promise_test(async t => {
    138    const settings = await createTrackAndGetSettings(t, "audio");
    139    assert_equals(typeof(settings.noiseSuppression), "boolean",
    140                  "noiseSuppression should exist and it should be a boolean.");
    141  }, 'noiseSuppression is reported by getSettings() for getUserMedia() audio tracks');
    142 
    143  promise_test(async t => {
    144    const settings = await createTrackAndGetSettings(t, "audio");
    145    assert_equals(typeof(settings.voiceIsolation), "boolean",
    146                  "voiceIsolation should exist and it should be a boolean.");
    147  }, 'voiceIsolation is reported by getSettings() for getUserMedia() audio tracks');
    148 
    149  promise_test(async t => {
    150    const settings = await createTrackAndGetSettings(t, "audio");
    151    assert_equals(typeof(settings.latency), "number",
    152                  "latency should exist and it should be a number.");
    153    assert_greater_than_equal(settings.latency,0);
    154  }, 'latency is reported by getSettings() for getUserMedia() audio tracks');
    155 
    156  promise_test(async t => {
    157    const settings = await createTrackAndGetSettings(t, "audio");
    158    assert_equals(typeof(settings.channelCount), "number",
    159                  "channelCount should exist and it should be a number.");
    160    assert_greater_than(settings.channelCount, 0);
    161  }, 'channelCount is reported by getSettings() for getUserMedia() audio tracks');
    162 
    163  promise_test(async t => {
    164    const settings = await createTrackAndGetSettings(t, "video");
    165    assert_equals(typeof(settings.width), "number",
    166                  "width should exist and it should be a number.");
    167    assert_true(Number.isInteger(settings.width), "width should be an integer.");
    168    assert_greater_than_equal(settings.width, 0);;
    169  }, 'width is reported by getSettings() for getUserMedia() video tracks');
    170 
    171  promise_test(async t => {
    172    const settings = await createTrackAndGetSettings(t, "video");
    173    assert_equals(typeof(settings.height), "number",
    174                  "height should exist and it should be a number.");
    175    assert_true(Number.isInteger(settings.height), "height should be an integer.");
    176    assert_greater_than_equal(settings.height, 0);
    177  }, 'height is reported by getSettings() for getUserMedia() video tracks');
    178 
    179  promise_test(async t => {
    180    const settings = await createTrackAndGetSettings(t, "video");
    181    assert_equals(typeof(settings.aspectRatio), "number",
    182                  "aspectRatio should exist and it should be a number.");
    183    assert_greater_than_equal(settings.aspectRatio, 0);
    184  }, 'aspectRatio is reported by getSettings() for getUserMedia() video tracks');
    185 
    186  promise_test(async t => {
    187    const settings = await createTrackAndGetSettings(t, "video");
    188    assert_equals(typeof(settings.frameRate), "number",
    189                  "frameRate should exist and it should be a number.");
    190    assert_greater_than_equal(settings.frameRate, 0);
    191  }, 'frameRate is reported by getSettings() for getUserMedia() video tracks');
    192 
    193  promise_test(async t => {
    194    const settings = await createTrackAndGetSettings(t, "video");
    195    // facingMode not treated as mandatory because not all platforms provide
    196    // this information.
    197    if (settings.facingMode) {
    198      assert_equals(typeof(settings.facingMode), "string",
    199                  "If facingMode is provided it should be a string.");
    200      assert_in_array(settings.facingMode,
    201                  ['user', 'environment', 'left', 'right']);
    202    }
    203  }, 'facingMode is reported by getSettings() for getUserMedia() video tracks');
    204 
    205  promise_test(async t => {
    206    const settings = await createTrackAndGetSettings(t, "video");
    207    assert_equals(typeof(settings.resizeMode), "string",
    208                "resizeMode should exist and it should be a string.");
    209    assert_in_array(settings.resizeMode, ['none', 'crop-and-scale']);
    210  }, 'resizeMode is reported by getSettings() for getUserMedia() video tracks');
    211 
    212  promise_test(async t => {
    213    const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video : true});
    214    const audioTrack = stream.getAudioTracks()[0];
    215    const videoTrack = stream.getVideoTracks()[0];
    216 
    217    const audioDeviceId = audioTrack.getSettings().deviceId;
    218    const videoDeviceId = videoTrack.getSettings().deviceId;
    219    const audioGroupId = audioTrack.getSettings().groupId;
    220    const videoGroupId = videoTrack.getSettings().groupId;
    221 
    222    audioTrack.stop();
    223    videoTrack.stop();
    224 
    225    assert_equals(audioTrack.getSettings().deviceId, audioDeviceId, "audio track deviceId");
    226    assert_equals(videoTrack.getSettings().deviceId, videoDeviceId, "video track deviceId");
    227    assert_equals(audioTrack.getSettings().groupId, audioGroupId, "audio track groupId");
    228    assert_equals(videoTrack.getSettings().groupId, videoGroupId, "video track groupId");
    229  }, 'Stopped tracks should expose deviceId/groupId');
    230 </script>