Skip to main content

Call control devices - WebHID API

· 3 min read
Stefan Benicke

Call Control allows you to control the meeting directly from your USB or Bluetooth devices.

It is an addition to your existing meeting app as it synchronizes the call and mute states between meeting and paired devices. It's available in eyeson-js 1.8.9.

Picture of a headset and it's call control device where light indicators for active call and mute are on

info

The Call Control Devices feature is built on the WebHID browser API and is currently supported on Chrome and Chromium-based browsers like Edge and Opera. The functionality depends on whether your device supports the WebHID protocol.

Read about how it is used in our default UI.

Initializing

import { WebHIDManager } from 'eyeson';

if (WebHIDManager.supported) {
const manager = await WebHIDManager.initialize(); // with options: initialize({ verbose: false })

if (manager.blocked) {
// already used in another tab or window
return;
}

manager.onEvent(event => {
const { type } = event;
if (type === 'devicelist') {
console.log(event.devices); // list device { id, vendorId, productId, productName }
}
else if (type === 'error') {
console.log(event.id, event.message); // initialize_failed (WebHID initializing failed), pair_request_failed (Device pair request failed), invalid_device (Invalid device)
}
else if (type === 'togglemute') {
console.log(event.active); // true/false
}
else if (type === 'togglecall') {
console.log(event.active); // true/false
}
});
}

Simplified script for initializing the WebHID manager

Initilializing is asynchronious, because it runs a check to avoid conflicts if used in multiple tabs or windows at the same time.

Please note that WebHIDManager.supported is static on WebHIDManager class, but blocked is only available after the class has been initialized.

Devices

The devices parameter of the devicelist event is an array of devices with { id, vendorId, productId, productName }.

This event is triggered automatically after initialization and gives all connected devices that are remembered from the last pairing. It also fires when a paired device gets disconnected or connected again or when a device is removed and no longer paired.

If you need a fresh list of devices at any time later, you can trigger it with:

manager.emitDeviceList();

To pair a new device, you need a user event like a click of a button and then call the following function to trigger the browser's pairing dialog.

button.addEventListener('click', async () => {
await manager.pairDeviceRequest();
});

Toggle call and mute

If the state on the device changes - user clicked a button - the togglecall or togglemute event is emitted and the current state is active=true|false. You can use this to join or leave the meeting or mute/unmute the microphone.

The other way around, if one of the states changes in the meeting, you can forward the state to all devices.

manager.setMuteActive(true|false);
manager.setCallActive(true|false);

Removal

To remove a specific device you need its id, which you get out of the devicelist event.

await manager.removeDevice(deviceId);

Events can be removed, either a specific listener or all together.

manager.offEvent();
// OR
const webhidEventHandler = event => {...};
manager.onEvent(webhidEventHandler);
// later
manager.offEvent(webhidEventHandler);

And last but not least you can turn down the whole manager and device connections.

manager.destroy();

Errors

The event type "error" has an id and message, where message is just a default english description of the error.

  • initialize_failed - "WebHID initializing failed"
  • pair_request_failed - "Device pair request failed"
  • invalid_device - "Invalid device"

Contact

If you have a question or want to share any feedback, do not hesitate to create a ticket on GitHub.