Измените целевое устройство вывода в веб-аудио

Франсуа Бофор
François Beaufort

До сих пор установка целевого устройства вывода звука была возможна только для <video> и <audio> с помощью HTMLMediaElement.setSinkId() . В Web Audio AudioContext использовал устройство по умолчанию, позволяя пользователю вручную изменить устройство вывода звука системы.

В Chrome 110 вы можете использовать AudioContext.setSinkId() для программного направления вывода звука в веб-аудио на любое разрешенное устройство.

Это особенно полезно в различных сценариях общения в реальном времени. Например, веб-приложение может использовать это для программного направления вывода на определенное устройство вывода звука, такое как гарнитура Bluetooth или громкая связь.

Направить аудиовыход на определенное устройство

Во-первых, вам нужен идентификатор устройства вывода звука, которое вы хотите использовать в качестве места назначения. Получите список доступных мультимедийных устройств с помощью navigator.mediaDevices.enumerateDevices() , отфильтруйте только устройства вывода звука и получите атрибут deviceId устройства вывода звука по вашему выбору. Пустая строка "" также может использоваться в качестве устройства по умолчанию для deviceId .

Получив идентификатор устройства вывода звука, создайте AudioContext и вызовите audioContext.setSinkId(deviceId) . В случае успеха возвращенное обещание разрешается, когда звук направляется на выбранное подключенное устройство вывода. Это может привести к сбою, если AudioContext закрыт.

В приведенном ниже примере показано, как при необходимости запросить доступ к микрофону и направить аудиовыход в веб-аудио на первое доступное устройство вывода.

const permission = await navigator.permissions.query({ name: "microphone" });
if (permission.state == "prompt") {
  // More audio outputs are available when user grants access to the mic.
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  stream.getTracks().forEach((track) => track.stop());
}

// Request a list of media devices and filter audio output devices.
const devices = await navigator.mediaDevices.enumerateDevices();
const audioOutputs = devices.filter(device => device.kind == "audiooutput");

const audioContext = new AudioContext();

// Pick the first available audio output.
const deviceId = audioOutputs[0].deviceId;
await audioContext.setSinkId(deviceId);

Обратите внимание, что вы также можете передать deviceId в качестве параметра sinkId при создании AudioContext .

const audioContext = new AudioContext({ sinkId: deviceId });

Рендеринг звука с отключенным AudioContext

Теперь вы можете указать «тихое устройство вывода» в веб-аудио, чтобы минимизировать энергопотребление. На этот раз вместо строкового значения передайте { type: "none" } в AudioContext.setSinkId() .

Обратите внимание, что звуковые часы, доступные через audioContext.currentTime , по-прежнему будут выполнять визуализацию аудиографика. Основная цель этого отключенного AudioContext — отобразить аудиографик без воспроизведения слышимого звука. Основным вариантом использования будет анализ входного сигнала микрофона без создания звуков.

// Silent Web Audio output.
await audioContext.setSinkId({ type: "none" });

Обнаружение функций

Чтобы проверить, поддерживается ли AudioContext.setSinkId() , используйте:

if ("setSinkId" in AudioContext.prototype) {
  // AudioContext.setSinkId() is supported.
}

Образец

Демо-версия доступна по адресу https://sinkid.glitch.me/, в которой можно поиграть с AudioContext.setSinkId() .

Поддержка браузера

AudioContext.setSinkId() доступен в Chrome 110 или более поздней версии.

Обратная связь

Команда Chrome и сообщество веб-стандартов хотят услышать о вашем опыте использования AudioContext.setSinkId() . Пожалуйста, оставляйте отзывы, комментируя существующие или сообщая о новых проблемах GitHub .

Благодарности

Спасибо Хонгчану Чою и Майклу Уилсону за рецензирование этой статьи.

Фотография календаря, сделанная Стивом Харви на Unsplash .