Modifier le périphérique de sortie de destination dans Web Audio

François Beaufort
François Beaufort

Jusqu'à présent, la définition du périphérique de sortie audio de destination n'était possible que pour <video> et <audio> avec HTMLMediaElement.setSinkId(). Dans Web Audio, AudioContext utilisait l'appareil par défaut, ce qui laisserait l'utilisateur modifier manuellement le périphérique de sortie audio du système.

À partir de Chrome 110, vous pouvez utiliser AudioContext.setSinkId() pour diriger de manière programmatique la sortie audio de l'audio Web vers n'importe quel appareil autorisé.

Cette fonctionnalité est particulièrement utile dans divers scénarios de communication en temps réel. Par exemple, une application Web peut l'utiliser pour diriger par programmation la sortie vers un périphérique de sortie audio spécifique, tel qu'un casque Bluetooth ou un haut-parleur.

Acheminer la sortie audio vers un appareil spécifique

Tout d'abord, vous avez besoin de l'identifiant du périphérique de sortie audio que vous souhaitez utiliser comme destination. Obtenez la liste des périphériques multimédias disponibles avec navigator.mediaDevices.enumerateDevices(), filtrez uniquement les périphériques de sortie audio et obtenez l'attribut deviceId du périphérique de sortie audio de votre choix. La valeur de chaîne vide "" peut également être utilisée comme appareil par défaut pour deviceId.

Une fois que vous disposez de l'identifiant de l'appareil de sortie audio, créez un AudioContext et appelez audioContext.setSinkId(deviceId). En cas de réussite, la promesse renvoyée est résolue lorsque l'audio est acheminé vers le périphérique de sortie connecté choisi. Elle peut échouer si AudioContext est fermé.

L'exemple ci-dessous vous montre comment demander l'accès au micro si nécessaire et comment diriger la sortie audio de l'audio Web vers le premier périphérique de sortie 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);

Notez que vous pouvez également transmettre deviceId en tant que paramètre sinkId lorsque vous créez un AudioContext.

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

Lire le contenu audio avec le son coupé

Vous pouvez désormais spécifier un "périphérique de sortie silencieux" dans Web Audio afin de réduire la consommation d'énergie. Cette fois, au lieu d'une valeur de chaîne, transmettez { type: "none" } à AudioContext.setSinkId().

Notez que l'horloge audio accessible via audioContext.currentTime continue d'avancer pour restituer le graphique audio. Son principal objectif est d'assurer le rendu du graphique audio sans produire de son audible. Le cas d'utilisation principal consisterait à analyser l'entrée du micro sans produire de son.

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

Détection de fonctionnalités

Pour vérifier si AudioContext.setSinkId() est compatible, utilisez:

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

Échantillon

Une version de démonstration est disponible sur https://sinkid.glitch.me/ pour jouer avec AudioContext.setSinkId().

Prise en charge des navigateurs

AudioContext.setSinkId() est disponible dans Chrome 110 ou version ultérieure.

Commentaires

L'équipe Chrome et la communauté des normes Web souhaitent connaître votre avis sur AudioContext.setSinkId(). N'hésitez pas à nous faire part de vos commentaires sur les problèmes existants ou nouveaux sur GitHub.

Remerciements

Merci à Hongchan Choi et à Michael Wilson d'avoir consulté cet article.

Photo de l'agenda par Steve Harvey sur Unsplash.