Cambia el dispositivo de salida de destino en Audio web

François Beaufort
François Beaufort

Hasta ahora, solo era posible configurar el dispositivo de salida de audio de destino para <video> y <audio> con HTMLMediaElement.setSinkId(). En Web Audio, AudioContext usaba el dispositivo predeterminado, lo que permitía al usuario cambiar el dispositivo de salida de audio del sistema de forma manual.

A partir de Chrome 110, puedes usar AudioContext.setSinkId() para dirigir de forma programática la salida de audio en Web Audio a cualquier dispositivo permitido.

Esto es especialmente útil en una variedad de situaciones de comunicación en tiempo real. Por ejemplo, una app web puede usar esto para dirigir de forma programática la salida a un dispositivo de salida de audio específico, como auriculares Bluetooth o un altavoz.

Envía la salida de audio a un dispositivo específico

Primero, necesitas el identificador del dispositivo de salida de audio que deseas usar como destino. Obtén la lista de dispositivos multimedia disponibles con navigator.mediaDevices.enumerateDevices(), filtra solo los dispositivos de salida de audio y obtén el atributo deviceId del dispositivo de salida de audio que elijas. El valor "" de cadena vacía también se puede usar como dispositivo predeterminado para deviceId.

Una vez que tengas el identificador del dispositivo de salida de audio, crea un AudioContext y llama a audioContext.setSinkId(deviceId). Si se realiza correctamente, la promesa que se muestra se resuelve cuando el audio se enruta al dispositivo de salida conectado elegido. Puede fallar si se cierra AudioContext.

En el siguiente ejemplo, se muestra cómo solicitar acceso al micrófono si es necesario y dirigir la salida de audio en Web Audio al primer dispositivo de salida disponible.

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);

Ten en cuenta que también puedes pasar el deviceId como un parámetro sinkId cuando creas un AudioContext.

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

Renderiza audio con un AudioContext silenciado

Ahora puedes especificar un "dispositivo de salida silencioso" en Web Audio para minimizar el consumo de energía. Esta vez, en lugar de un valor de cadena, pasa { type: "none" } a AudioContext.setSinkId().

Ten en cuenta que el reloj de audio al que se puede acceder a través de audioContext.currentTime seguirá avanzando para renderizar el gráfico de audio. El objetivo principal de este AudioContext silenciado es renderizar el gráfico de audio sin producir sonido audible. El caso de uso principal sería analizar la entrada del micrófono sin emitir sonidos.

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

Detección de atributos

Para verificar si AudioContext.setSinkId() es compatible, usa lo siguiente:

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

Muestra

Hay una demostración disponible en https://sinkid.glitch.me/ para jugar con AudioContext.setSinkId().

Navegadores compatibles

AudioContext.setSinkId() está disponible en Chrome 110 o versiones posteriores.

Comentarios

El equipo de Chrome y la comunidad de estándares web quieren conocer tus experiencias con AudioContext.setSinkId(). Para enviar comentarios, haz comentarios en los problemas de GitHub existentes o presenta nuevos.

Agradecimientos

Agradecemos a Hongchan Choi y Michael Wilson por revisar este artículo.

Imagen del calendario de Steve Harvey en Unsplash.