До сих пор задать целевое устройство вывода звука было возможно только для <video> и <audio> с помощью HTMLMediaElement.setSinkId() . В Web Audio AudioContext использовал устройство по умолчанию, оставляя пользователю возможность вручную изменить системное устройство вывода звука.
Начиная с Chrome 110, вы можете использовать AudioContext.setSinkId() для программного направления аудиовыхода в Web Audio на любое разрешенное устройство.
Это особенно полезно в различных сценариях обмена данными в режиме реального времени. Например, веб-приложение может использовать это для программного направления вывода звука на конкретное устройство вывода, такое как Bluetooth-гарнитура или спикерфон.
Направить аудиовыход на конкретное устройство
Во-первых, вам нужен идентификатор устройства вывода звука, которое вы хотите использовать в качестве целевого устройства. Получите список доступных медиаустройств с помощью navigator.mediaDevices.enumerateDevices() , отфильтруйте только устройства вывода звука и получите атрибут deviceId выбранного вами устройства вывода звука. В качестве устройства по умолчанию для deviceId также можно использовать пустую строку "" .
Получив идентификатор устройства вывода звука, создайте объект AudioContext и вызовите audioContext.setSinkId(deviceId) . В случае успеха возвращаемое промис-событие разрешится, когда звук будет направлен на выбранное подключенное устройство вывода. Оно может завершиться неудачей, если объект AudioContext закрыт.
В приведенном ниже примере показано, как при необходимости запросить доступ к микрофону и направить аудиовыход в Web Audio на первое доступное устройство вывода.
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
Теперь в Web Audio можно указать «бесшумное устройство вывода», чтобы минимизировать энергопотребление. На этот раз вместо строкового значения передайте в AudioContext.setSinkId() { type: "none" } .
Обратите внимание, что аудиотактовый сигнал, доступный через audioContext.currentTime , будет по-прежнему увеличиваться для отображения аудиографа. Главная цель этого отключенного AudioContext — отображение аудиографа без воспроизведения слышимого звука. Основной вариант использования — анализ входного сигнала с микрофона без воспроизведения звуков.
// Silent Web Audio output.
await audioContext.setSinkId({ type: "none" });
Обнаружение признаков
Чтобы проверить, поддерживается ли AudioContext.setSinkId() , используйте:
if ("setSinkId" in AudioContext.prototype) {
// AudioContext.setSinkId() is supported.
}
Образец
Демонстрационный пример, позволяющий поэкспериментировать с AudioContext.setSinkId() , доступен по адресу https://codepen.io/web-dot-dev/pen/emNwEaN/ .
Поддержка браузеров
AudioContext.setSinkId() доступна в Chrome версии 110 и более поздних.
Обратная связь
Команда Chrome и сообщество разработчиков веб-стандартов хотят узнать о вашем опыте использования AudioContext.setSinkId() . Пожалуйста, оставляйте отзывы, комментируя существующие или создавая новые проблемы на GitHub .
Полезные ссылки
Благодарности
Благодарим Хонгчана Чоя и Майкла Уилсона за рецензирование этой статьи.