Re: [mediacapture-output] The first "audiooutput" `MediaDeviceInfo` returned from `enumerateDevices()` is not the default device when the default device is not exposed (#133)

> E.g. if the user selectAudioOutputs their AirPods AND they're the current OS default (which is common after they put them on in macOS), then no other entry is added to enumerateDevices:
> 
> ```js
>  {label: "AirPods", deviceId: "234", ...}
> ```
> 
> If they then go to macOS's System Settings→Sounds and change the OS default to "MacBook Pro Speakers", you'll see:
> 
> ```js
>  {label: "System default audio output device", deviceId: "", ...}
>  {label: "AirPods", deviceId: "234", ...}
> ```
> 
> If they then selectAudioOutput their MacBook Pro Speakers, you'll see:
> 
> ```js
>  {label: "MacBook Pro Speakers", deviceId: "123", ...}
>  {label: "AirPods", deviceId: "234", ...}
> ```
> 
> @karlt is that right? This solves finding the default device in the spec:
> 
> ```js
> const defSpkr = await mediaDevices.enumerateDevices()
>                                   .find(d => d.kind == “audio-output”);
> ```

That's correct, and this finds a `deviceId` that can be passed to `setSinkId()` or compared with a `sinkId`. To distinguish between a virtual and physical device and so whether the physical default device is exposed, the `deviceId` would be compared with "".

> > Chromium's solution is to use "default" as device ID.
> 
> Unfortunately, this poses a competing model for finding the default device:
> 
> ```js
> const defSpkr = await mediaDevices.enumerateDevices().
>                                   .find(d => d.kind == “audio-output” && d.deviceId == "default");
> ```
> 
> > There is little difference between using "default", "" or any other constant string.
> 
> `setSinkId("")` is special and unsets the sinkId.

`setSinkId("")` and `sinkId` are the main reason for re-using "", to which the spec already gives meaning as the user-agent default device.  This is also consistent with the empty `deviceId` on the single "audioinput" (or "videoinput") `MediaDeviceInfo` provided to indicate that at least one microphone exists before "audioinput" devices are exposed.

Chrome is using `deviceId: ""` and `deviceId: "default"` in different situations.
When no "audiooutput" devices are exposed, Chrome provides
```js
{label: "", deviceId: "", groupId: ""}
```
The spec (and the proposal here, which is Gecko's behavior now) would expect no "audiooutput" devices.

When the default "audiooutput" device is exposed via `getUserMedia()`, Chrome provides (on Linux)
```js
{label: "Default", deviceId: "default", groupId: "default"}
{label: "Built-in Audio Analog Stereo", deviceId: "38cf59402979c7c92a7dfe139b46a07932288d562b1dce9bca711b1e7d2097bc", groupId: "fc5673e12055618bb6840857ef5ffaf81ae28949a50d518734c167530922a3bf"}
```

https://jan-ivar.github.io/dummy/enumerate.html is useful for testing browser behavior.

In Chrome currently `find(d => d.kind == “audio-output”)` returns the `MediaDeviceInfo` with `deviceId: "default"`, so `find(d => d.kind == “audio-output” && d.deviceId == "default")` would return the same.

AFAIK there is currently no way to create a situation where Chrome would expose a non-default "audiooutput" device without exposing the user-agent default "audiooutput" device.  If there were, then Chrome's virtual `deviceId: "default"` device would be a solution to the problem of sites that assume that the first "audiooutput" device is the default device, because in Chrome `setSinkId("default")` switches output to the user-agent default if the default is exposed.

Chrome's `deviceId: "default"` on its virtual device is not a solution to the issue of providing a client app with a means to determine which exposed physical device, if any, is the user-agent default device.

-- 
GitHub Notification of comment by karlt
Please view or discuss this issue at https://github.com/w3c/mediacapture-output/issues/133#issuecomment-2309785014 using your GitHub account


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

Received on Monday, 26 August 2024 09:38:35 UTC