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)
})