Skip to main content

Selecting an output device (Web)

A desktop user has a USB audio interface plugged in for practice, Bluetooth headphones for the couch, and the built-in speakers for casual listening โ€” they want to pick where alphaTab's audio comes out. Build a device dropdown, hand the selection back to alphaTab, and the audio graph re-routes without stopping playback.

00:00 / 00:00
press refresh to list devices

Web-only. Runs against the browser's Audio Output Devices API โ€” the same experimental setSinkId support used by <audio> and <video> elements. Browser coverage is uneven; see caniuse. On .NET the output device is chosen through NAudio; on Android through AudioTrack. Point native readers at those pages.

Three async methodsโ€‹

  • api.enumerateOutputDevices() โ€” returns a Promise<ISynthOutputDevice[]>. Each device exposes deviceId and label. Requesting the list triggers a browser permission prompt when needed; without permission you get an empty array.
  • api.setOutputDevice(device) โ€” accepts one of the returned entries or null to fall back to the system default. Returns a Promise that resolves once the audio graph is rewired.
  • api.getOutputDevice() โ€” returns the device previously set through setOutputDevice, or null when alphaTab is still on the default. Useful for restoring UI state after a page reload.

Devices can appear and disappear at runtime โ€” a Bluetooth headset connects, a USB interface unplugs. Enumerate again when you know the environment changed, or listen for the navigator.mediaDevices.devicechange event and refresh your dropdown from there.

Show it in codeโ€‹

import * as alphaTab from '@coderline/alphatab';

const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledSynthesizer,
},
});

async function buildDeviceDropdown(select) {
const devices = await api.enumerateOutputDevices();
select.replaceChildren();
const defaultOption = new Option('System default', '');
select.append(defaultOption);
for (const device of devices) {
select.append(new Option(device.label, device.deviceId));
}

const current = await api.getOutputDevice();
select.value = current ? current.deviceId : '';

select.addEventListener('change', async () => {
const picked = devices.find((d) => d.deviceId === select.value) ?? null;
await api.setOutputDevice(picked);
});
}

navigator.mediaDevices.addEventListener('devicechange', () => {
buildDeviceDropdown(document.querySelector('#audio-out'));
});

buildDeviceDropdown(document.querySelector('#audio-out'));

getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target โ€” on Web that's a <div> alphaTab attaches to.

Where to look nextโ€‹