Re: [mediacapture-main] Bug in spec: circular dependency for enumerateDevices() (#709)

> I am unclear with some details in your scenario, like whether only one webcam is connected (720p) and web page wants user to connect the 1080p camera. Here is a potential flow:
> 
> ```
> const previousDeviceId = await getDeviceIdFromIDB();
> let stream = await navigator.mediaDevices.getUserMedia({ video : { deviceId : previousDeviceId, width : 1920 } });
> // Browser will try using the previous device, if not possible, it will try selecting any 1080p camera.
> if (stream.getVideoTracks()[0].getSettings().width < 1920) {
>     // Chances are high there is no 1080p camera otherwise it would have been selected in the first place. Let's still check just in case.
>     const devices = await navigator.mediaDevices.enumerateDevices();
>     const newDeviceId = select1080pCamera(devices);
>     if (!deviceId) {
>         // Ask user to connect a 1080p camera through some UI.
>         ....
>         navigator.mediaDevices.ondevicechange = trySelecting1080pCamera;
>         return;
>     }
>     // Optional step: switch immediately to the 1080p camera. It might be bad if the user selected the other camera explicitly through a device picker (say Firefox picker).
>     stream = await navigator.mediaDevices.getUserMedia({ video : { deviceId : newDeviceId, width : 1920 } });
> }
> // Proceed with using the stream
> ...
> ```
> 
> Another approach:
> 
> ```
> try {
>     const stream = await navigator.mediaDevices.getUserMedia({ video : { deviceId : { exact : await getDeviceIdFromIDB() } } });
>     stream.getVideoTracks()[0].applyConstraints({ width : 1920 });
>     return stream;
> } catch (e) {
>     return navigator.mediaDevices.getUserMedia({ video : { width : 1920 } })
> }
> ```

The issue here is that if a wrong camera is opened, or a wrong setting is used, re-open/update it is very costly. It's strongly desired to open the correct camera with correct settings with one shot, since
* opening a camera is a slow operation and might pop-up a dialog every time
* blinking wrong camera LED is bad UX

For example, if the app want to open "Cam A with setting X", or "Cam B with setting Y", depends on which camera is available now. There is an always available "Cam C which supports both setting X and Y", but the app/user don't want to use it for some reason (such as a built-in USB camera on a laptop with quality or wrong facing).
* If `enumerateDevices()` is available, it's easy to open the correct camera with correct settings.
* Without `enumerateDevices()`, running `getUserMedia()` with constraint `A/B/X/Y` might open the wrong camera. The app would need to try `getUserMedia({video: A + X})` and `getUserMedia({video: B + Y})`, which is far from ideal imo.

Note that `getUserMedia({audio: true})` (~10ms level) is much faster than `getUserMedia({video: ...})` (~1s level) on many platforms. So just run `getUserMedia({audio: true})` to grant the permission for `enumerateDevices()` is a very attractive simple mitigation for this spec change, which is not a recommended way to use this API if I understand correctly.

-- 
GitHub Notification of comment by ShikChen
Please view or discuss this issue at https://github.com/w3c/mediacapture-main/issues/709#issuecomment-687543780 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Saturday, 5 September 2020 04:00:45 UTC