Cambia el dispositivo de salida de destino en Audio web

Francisco Beaufort
François Beaufort

Hasta ahora, solo se podía configurar el dispositivo de salida de audio de destino para <video> y <audio> con HTMLMediaElement.setSinkId(). En Web Audio, AudioContext usó el dispositivo predeterminado, lo que permitió que el usuario cambiara 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 escenarios de comunicación en tiempo real. Por ejemplo, una app web puede usar esto para dirigir la salida de manera programática a un dispositivo de salida de audio específico, como auriculares Bluetooth o un altavoz.

Enruta la salida de audio a un dispositivo específico

Primero, necesitas el identificador del dispositivo de salida de audio que quieres usar como destino. Obtén la lista de dispositivos multimedia disponibles con navigator.mediaDevices.enumerateDevices(), filtra solo en dispositivos de salida de audio y obtén el atributo deviceId del dispositivo de salida de audio que elijas. El valor "" de la 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 ejecuta de forma correcta, 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 de 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 deviceId como 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 accesible a través de audioContext.currentTime seguirá avanzando para renderizar el gráfico de audio. El objetivo principal de este AudioContext silenciado es procesar 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.
}

Ejemplo

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 de la Web quieren conocer tu experiencia con AudioContext.setSinkId(). Para enviar comentarios, comenta problemas de GitHub existentes o informa nuevos.

Agradecimientos

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

Foto del calendario de Steve Harvey en Unsplash.