Audio Output for Calls (Web)
Web (Native)
Unfortunately at this time there is no support for speaker selection. There is a proposal for the Web API, but it is currently experimental and there is insufficient mobile browser support for this at the time being.
Web (JS) (Desktop/Laptop)
Once you have a call setup if you would like to switch the the audio output it is possible using the Web API of the browser.
Step 1: Get the Audio Output Device Options
Before we can set the stream output of the call to the desired output device, we need to get a list of all user audio output devices the browser has access to. The enumerateDevices method will return a promise with an array of MediaDeviceInfo. The end user will need a way to select their desired device from this list.
const audioOutputDevices = await navigator.mediaDevices.enumerateDevices().then(devices => devices.filter(d => d.kind == "audiooutput"))
Step 2: Select HTML Audio Element
When a call is created, the Vonage Client SDK will create an HTMLAudioElement and attach the output stream of the call to it's srcObject. You can access the audio element with the following:
const audioOutputElement = client.getAudioOutputElement()
Step 3: Update the HTMLAudioElement Source
Once the user has indicated which Audio Output Device they would like to use for the call, the deviceId will need to be extracted from the MediaDeviceInfo. The HTMLAudioElement has a method called setSinkId which will take the deviceId and use that to set the desired Audio Output Device to the HTMLAudioElement source.
// Use the device selected by the user (e.g. from a dropdown)
const selectedDevice = audioOutputDevices[selectedIndex]
audioOutputElement.setSinkId(selectedDevice.deviceId)
The setSinkId method is not supported by some older browser versions. See the table below for minimum versions.
SetSinkId() Browser Support
| Browser | Minimum Version | Level of Support |
|---|---|---|
| Chrome | 49 | Full support |
| Edge | 17 | Full support |
| Firefox | 116 | Full support |
| Opera | 36 | Full support |
| Safari | 16.4 | Full support |
Using Promises Instead of Async Await
If you would like to do the above using promises instead of async await you can do the following:
navigator.mediaDevices.enumerateDevices().then(devices => {
// Get the Audio Output Device Options
const audioOutputDevices = devices.filter(d => d.kind == "audiooutput")
// Get the html audio element used by the client to attach the stream output
const audioOutputElement = client.getAudioOutputElement()
// Set the desired audio output device to be used by the audioElement
const selectedDevice = audioOutputDevices[selectedIndex]
audioOutputElement.setSinkId(selectedDevice.deviceId)
})