Repository: electron
Issue: Requesting a capture device (`MediaDevices.getUserMedia`) without constraints always returns the first device
Labels: enhancement :sparkles:

### Preflight Checklist

- [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.

### Problem Description

The first audio device is always selected when no constraints are passed to the API by the application developer.

It would be desirable to

1. try to sniff out system-specific default selections (such as the device default status flags provided by system APIs like PulseAudio) and only use the first element as a fallback,
2.  have some interface for a sufficiently knowledgeable end user to override this behaviour anyway, such as an environment variable.

The focus is on requirement 2, as 1 would require implementing many tests and lookups that would have to look for various combinations of not only OS, but also available backend audio services, like the many audio services available in Linux.

**Note A:** This issue is almost impossible to notice for an application developer or end user on a setup with only one media device, and might be hard to notice on multi-device setups. However, a good example of a setup where the 1st device in the list may not be the preferred device, is the case where the system registers a headphone microphone being plugged and unplugged as logically a second device, whereas a hardwired, lower quality built-in microphone, and thus not preferable device, stays in the first place.

### Proposed Solution

Ideally requirement 2 would be achieved by a centralized object that keeps track of such user preferences, checking environment variables and maybe config locations (perhaps even Electron-wide, not just app-specific, though that might entail security considerations), as well as an utility method which sources information from that object to select between available media devices, which would be used by `MediaCaptureDevicesDispatcher::GetPreferredAudioDeviceForBrowserContext`.

### Alternatives Considered

In the meantime, a simple override, by checking an environment variable and acting depending on its presence or absence, using a probably already existing system-agnostic environment variable API, would be just fine.

Finally, if it is undesired to have any such logic be placed inside the browser shell, give the application developer a warning if they do not pass constraints, asking them to enumerate devices and implement their own selection logic (or user selection prompt), due to note A.

### Additional Information

When no constraints are found, `front()` is called. This is easily visible in the following snippet from the native browser shell:

https://github.com/electron/electron/blob/15151c68533f5d8d1c9b57dbd7953e805f7719c9/shell/browser/media/media_capture_devices_dispatcher.cc#L33-L41

This should be a very, very last resort, not a fallback for every time a developer fails to pass constraints or enumerate devices on their end. A notable example of this, and in fact the catalyst of this particular inquiry in this particular instance, is [Signal for Desktop](https://github.com/signalapp/Signal-Desktop/blob/92d22d0827b4686c0e4a5bd14c4692c3ad92cd31/ts/services/audioRecorder.ts#L73-L77). ([I just bugged them about it, too.](https://github.com/signalapp/Signal-Desktop/issues/6606#issuecomment-2451423643))

https://github.com/signalapp/Signal-Desktop/blob/92d22d0827b4686c0e4a5bd14c4692c3ad92cd31/ts/services/audioRecorder.ts#L73-L77

But it is reasonable to believe there are many more such cases, since it is not entirely obvious (see note A).

I understand that relying on the developers to be thorough with giving users a friendly interface to choice might help reduce the thickness of the middle layer in Electron's browser shell _and_ encourage developers to be more proactive in implementing their own interfaces. However, when all such tasks are off-loaded to the application developer, this can not only lead to end user frustration, but compromise on the functionality and versatility of use of the final products.

In either case, I am greatly thankful of the team's consideration in what may seem like a niche issue, but one which I can imagine is bugging more people than myself. I would love to try and contribute something myself, but I lack the understanding of the guts of Electron that the developers have. But hey, maybe there's something else I can help with!