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>