The Dolby.io Communications API provides an extensive suite of tools that enables creating unified communications and collaboration applications. As a developer, you can use this API to create an integrated conference solution—with video, audio, and messaging—in a way that uniquely adapts to the needs of your users.
This article aims to show you how to leverage Dolby.io Communications API to control the media devices in your video conferencing applications. This control will allow your end-users to manage/switch their media devices (microphone, webcam, or speaker) used during conferences.
Note: This guide is a continuation of the getting started tutorial. So you should definitely check that out first if you haven’t already. Also to follow along, go over to the GitHub repository.
Pre-Requisites
- Create Dolby.io account.
- Have a working webcam, speaker, and a microphone.
- Read the documentation for creating a basic conference application with Dolby.io Communications API
Before we get started, here is a quick overview of what we want to accomplish. We want our video conferencing application to display a list of media devices for audio and video. We also want to be able to select what device to use during the conference.

Getting Started
The first thing you should do is to clone the GitHub repository that contains the code sample in the Create a Basic Audio Conference Application documentation. This will serve as a video conference boilerplate app we can build on to create the media devices controls feature.
$ git clone https://github.com/voxeet/voxeet-sdk-browser-gettingstarted
Here’s what the folder structure should look like after you have successfully cloned the repository.
├── src/
│ ├── scripts/
│ │ └── client.js
│ │ └── ui.js
└── └── index.html
Adding the User Interface for the Controls
Now you have the repository cloned locally, you can start off by adding the media controls dropdown lists and buttons to the index.html file. The location of these controls doesn’t matter but a great place to put them is right under the recording div block.
Note: … means some lines of code were omitted to keep the code samples concise. See the GitHub repos to view the full source code outlined in this article.
index.html
<!DOCTYPE html>
<html>
...
<div id="recording">
<button id="start-recording-btn" disabled>Start recording</button>
<button id="stop-recording-btn" disabled>Stop recording</button>
<p id="record-status" style="color: red;"></p>
</div>
<!-- Start Media Devices Controls -->
<div id="media-devices-controls">
<h3>Media Devices</h3>
<!-- Video Devices -->
<div class="form">
<label for="video-devices">Video Devices:</label>
<select id="video-devices" class="custom-select"></select>
<button id="set-video-device-btn" type="button" disabled>Set</button>
</div>
<!-- Input Audio Devices -->
<div class="form">
<label for="input-audio-devices">Input Audio Devices:</label>
<select id="input-audio-devices" class="custom-select"></select>
<button id="set-input-audio-device-btn" type="button" disabled>Set</button>
</div>
<!-- Output Audio Devices -->
<div class="form">
<label for="output-audio-devices">Output Audio Devices:</label>
<select id="output-audio-devices" class="custom-select"></select>
<button id="set-output-audio-device-btn" type="button" disabled>Set</button>
</div>
</div>
<!-- End Media Devices Controls -->
...
</html>
In the HTML code above, the three different blocks represent controls for videos devices (webcams), input audio devices (microphones), and output audio devices (speakers). The select tag in each of these blocks will contain a list of all available media device. A user can then use the set button to choose any of the devices displayed in the dropdown list.
Selecting the HTML Elements
After adding the media control elements to the index.html file, the next thing you should do is open the ui.js file to add JavaScript code that will select the HTML elements you have defined. This selection will allow you to define the logic that will listen for events in the user interface and execute code accordingly. You can add your selectors right under the existing ones in the code.
ui.js
const initUI = () => {
const nameMessage = document.getElementById('name-message');
...
const setVideoDeviceBtn = document.getElementById("set-video-device-btn");
const setInputAudioDeviceBtn = document.getElementById("set-input-audio-device-btn");
const setOutputAudioDeviceBtn = document.getElementById("set-output-audio-device-btn");
const videoDevices = document.getElementById("video-devices");
const inputAudioDevices = document.getElementById("input-audio-devices");
const outputAudioDevices = document.getElementById("output-audio-devices");
...
};
Logic Implementation for Enumerating Media Devices
When a conference has been created all the available media devices should be loaded as options in the select tag you have defined in the index.html file. You need to use the enumerateVideoDevices and enumerateAudioDevices method to accomplish this. These methods should ideally be placed after the “conference join” event.
ui.js
const initUI = () => {
...
// 1. Create a conference room with an alias
VoxeetSDK.conference.create(conferenceOptions)
.then((conference) => {
...
// 2. Join the conference
VoxeetSDK.conference.join(conference, joinOptions)
.then((conf) => {
...
})
.then(() => {
// Load the Output Audio devices
VoxeetSDK.mediaDevice.enumerateAudioDevices("output")
.then(devices => {
devices.forEach(device => {
outputAudioDevices.append(new Option(device.label, device.deviceId));
});
setOutputAudioDeviceBtn.disabled = false;
})
.catch(err => console.error(err));
// Load the Input Audio devices
VoxeetSDK.mediaDevice.enumerateAudioDevices("input")
.then(devices => {
devices.forEach(device => {
inputAudioDevices.append(new Option(device.label, device.deviceId));
});
setInputAudioDeviceBtn.disabled = false;
})
.catch(err => console.error(err));
// Load the Video devices
VoxeetSDK.mediaDevice.enumerateVideoDevices("input")
.then(devices => {
devices.forEach(device => {
videoDevices.append(new Option(device.label, device.deviceId));
});
setVideoDeviceBtn.disabled = false;
})
.catch(err => console.error(err));
})
.catch((err) => console.error(err));
})
.catch((err) => console.error(err));
};
...
};
Note: The enumerateAudioDevices(“output”) will return nothing on some macOS browsers like Safari and Firefox, because audio output on macOS can only be controlled at the OS level. However, you can run your code on Chrome to test this feature.
Similarly, the functions to enumerate media devices will return nothing on some macOS browsers until after the conference has been joined.
Logic Implementation for Media Device Selection
The final thing you need to do in the ui.js file is attach onclick() event listeners to all the set buttons defined in the HTML code. This will allow the set buttons to trigger code that will choose the media device displayed on their respective dropdown list.
You can add this last piece of code at the end of the initUI() function.
ui.js
const initUI = () => {
...
setVideoDeviceBtn.onclick = async () => {
let selectedVideoDevice = videoDevices.options[videoDevices.selectedIndex];
alert(`Your video device has been set to: ${selectedVideoDevice.text}`);
await VoxeetSDK.mediaDevice.selectVideoInput(selectedVideoDevice.value);
}
setInputAudioDeviceBtn.onclick = async () => {
let selectedInputAudioDevice = inputAudioDevices.options[inputAudioDevices.selectedIndex];
alert(`Your input audio device (mic) has been set to: ${selectedInputAudioDevice.text}`)
await VoxeetSDK.mediaDevice.selectAudioInput(selectedInputAudioDevice.value);
}
setOutputAudioDeviceBtn.onclick = async () => {
let selectedOutputAudioDevice = outputAudioDevices.options[outputAudioDevices.selectedIndex];
alert(`Your output audio device (speaker) has been set to: ${selectedOutputAudioDevice.text}`)
await VoxeetSDK.mediaDevice.selectAudioOutput(selectedOutputAudioDevice.value);
}
};
Setting Your Dolby.io Communications API Key & Secret
Before you can run this application, you need to replace the consumerKey and consumerSecret placeholder with your Dolby.io Communications API key and secret. You can find this line of code at the bottom of the client.js file.
client.js
VoxeetSDK.initialize('customerKey', 'customerSecret');
Warning: It is best practice to use the VoxeetSDK.initializeToken function to initialize the SDK. Please read the documentation at: https://docs.dolby.io/communications-apis/docs/initializing-javascript.
Running the Video Conference Application
After setting your API key and secret in the client.js file, you can now start a HTTP server to access your conference application by following these steps.
- Download and install Node.js here: https://nodejs.org/en/download/
- Go to the root directory of your project and run the command below
$ cd src && npx http-server -a localhost -p 8000 -c-1 -o ./
Your server is now running and you can access your video conferencing application at localhost:8000
Why Start a HTTP Server?
At this point, you might be wondering why you have to start a HTTP server when you can simply click on the index.html file to view the web application.
Chrome has deprecated support for accessing media devices through insecure origins (https://) and visiting a local web page through it’s HTML file is not recognized as a secure origin (https://). However, you can test the Communications API’s media devices feature through your machine’s localhost since it is treated as a secure origin on Chrome and other Chromium browsers.
Safari on macOS (as of v15.0) still supports accessing media devices through insecure origins, so you can open the index.html file on there for testing purposes without starting a HTTP server.