NEW 282939
getUserMedia({audio: true}) does not return system selected device
https://bugs.webkit.org/show_bug.cgi?id=282939
Summary getUserMedia({audio: true}) does not return system selected device
mattieruth
Reported 2024-11-11 09:49:14 PST
When calling getUserMedia({audio: true}), I would expect the track that gets returned to belong to the currently selected audio device. Instead, it appears to _almost_ always return the built-in Microphone. A simple test is to connect AirPods or wired headphones and run the following in the console: getAudio = () => { navigator.mediaDevices.getUserMedia({audio: true}).then( (stream) => { deviceId = stream.getAudioTracks()[0].getSettings().deviceId; navigator.mediaDevices.enumerateDevices().then( (dev) => { chosenDevice = dev.filter((d)=>d.deviceId === deviceId); console.log(`Selected Device: ${chosenDevice[0].label}`); } ) stream.getTracks().forEach((t)=>t.stop()) } ) }; getAudio(); The result will log 'iPhone Microphone'. What makes this worse is that making this call also switches the output device, so all audio for the page switches to the iPhone speaker. I have reproduced this on iOS 17.6.1 and 18.1. I'm still investigating to hopefully provide more helpful information and code snippets but wanted to submit this quickly to get eyes on it.
Attachments
getUserMedia() test #1 (3.41 KB, text/html)
2024-11-11 13:54 PST, mattieruth
no flags
getUserMedia() test #2 (5.94 KB, text/html)
2024-11-11 13:55 PST, mattieruth
no flags
getUserMedia() test #3 (3.85 KB, text/html)
2024-11-11 13:55 PST, mattieruth
no flags
mattieruth
Comment 1 2024-11-11 13:54:11 PST
Created attachment 473195 [details] getUserMedia() test #1
mattieruth
Comment 2 2024-11-11 13:54:40 PST
I am attaching three basic html pages the use getUserMedia() to grab audio and demonstrate the issue. The first simply performs the `getAudio()` I had in my original comment on a 5 second loop, reports what device was used and then discards the tracks and stream. In general, I find that it mostly returns the 'iPhone Microphone', but can occasionally get it to temporarily pick up my Air Pods if I switch between tabs. Subsequent getUserMedia() calls typically end up back on the iPhone Mic, though, so it's short-lived. The second snippet steps through playing an audio file before calling `getUserMedia({audio: true})`, demonstrating how the audio will initially play from the headphones, but will switch to the iPhone speakers once `getUserMedia()` is called. It has some other toggles for testing like manually switching devices and adding the microphone track to an audio element to hear it played back. The third snippet is almost identical to the first except instead of immediately stopping the tracks and throwing away the stream, it keeps the stream around and stops the tracks 2 seconds later. With this test, I was once able to get getUserMedia() to get into a state where it would inconsistently switch back and forth between the built-in mic and the AirPods. It doesn't happen always so I'm a bit baffled how/when/why it can get into that state (which still isn't ideal), but thought it worth including.
mattieruth
Comment 3 2024-11-11 13:55:17 PST
Created attachment 473196 [details] getUserMedia() test #2
mattieruth
Comment 4 2024-11-11 13:55:37 PST
Created attachment 473197 [details] getUserMedia() test #3
Radar WebKit Bug Importer
Comment 5 2024-11-18 09:50:14 PST
Note You need to log in before you can comment on or make changes to this bug.