Zmień docelowe urządzenie wyjściowe w Web Audio

François Beaufort
François Beaufort

Do tej pory ustawienie docelowego urządzenia wyjściowego audio było możliwe tylko w systemach <video> i <audio> przy użyciu HTMLMediaElement.setSinkId(). W sekcji Web Audio użyto urządzenia domyślnego, a użytkownik mógł ręcznie zmienić systemowe urządzenie wyjściowe audio.

Od Chrome 110 możesz użyć elementu AudioContext.setSinkId(), aby automatycznie kierować wyjście audio z Web Audio na dowolne dozwolone urządzenie.

Jest to szczególnie przydatne w różnych scenariuszach komunikacji w czasie rzeczywistym. Na przykład aplikacja internetowa może wykorzystać to, aby automatycznie kierować wyjście do określonego urządzenia wyjściowego audio, takiego jak zestaw słuchawkowy Bluetooth lub głośnik.

Kieruj wyjście audio na konkretne urządzenie

Po pierwsze, potrzebujesz identyfikatora wyjściowego urządzenia audio, którego chcesz używać jako miejsca docelowego. Sprawdź listę dostępnych urządzeń multimedialnych z funkcją navigator.mediaDevices.enumerateDevices(), filtruj tylko urządzenia wyjściowe audio i uzyskaj atrybut deviceId wybranego urządzenia wyjściowego audio. Pusta wartość "" w postaci ciągu znaków może też służyć jako urządzenie domyślne w deviceId.

Po uzyskaniu identyfikatora urządzenia wyjściowego audio utwórz AudioContext i wywołaj audioContext.setSinkId(deviceId). W przypadku powodzenia zwracana obietnica znika, gdy dźwięk jest kierowany do wybranego połączonego urządzenia wyjściowego. Może zakończyć się niepowodzeniem, jeśli środowisko AudioContext jest zamknięte.

Przykład poniżej pokazuje, jak w razie potrzeby poprosić o dostęp do mikrofonu i przekierować wyjście audio z Web Audio na pierwsze dostępne urządzenie wyjściowe.

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

Pamiętaj, że podczas tworzenia AudioContext możesz też przekazać parametr deviceId jako parametr sinkId.

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

Renderuj dźwięk z wyciszonym kontekstem audio

W Web Audio możesz teraz określić „wyciszone urządzenie wyjściowe”, aby zminimalizować zużycie energii. Tym razem zamiast wartości ciągu znaków prześlij parametr { type: "none" } do funkcji AudioContext.setSinkId().

Pamiętaj, że zegar audio dostępny na platformie audioContext.currentTime nadal będzie przewijać się w celu renderowania audiografu. Głównym celem tego wyciszonego elementu AudioContext jest wyrenderowanie wykresu audio bez generowania dźwięku. Głównym przypadkiem użycia jest analizowanie danych wejściowych mikrofonu bez generowania dźwięków.

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

Wykrywanie funkcji

Aby sprawdzić, czy funkcja AudioContext.setSinkId() jest obsługiwana, użyj:

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

Przykład

Na stronie https://sinkid.glitch.me/ dostępna jest wersja demo, w której możesz zagrać w AudioContext.setSinkId().

Obsługiwane przeglądarki

Aplikacja AudioContext.setSinkId() jest dostępna w Chrome 110 i nowszych.

Prześlij opinię

Zespół Chrome i społeczność zajmująca się standardami internetowymi chcą poznać Twoją opinię na temat AudioContext.setSinkId(). Przekaż nam swoją opinię, komentując istniejące lub przesyłając nowe problemy z GitHubem.

Podziękowania

Dziękujemy Hongchan Choi i Michaelowi Wilsonowi za przeczytanie tego artykułu.

Zdjęcie z kalendarza: Steve Harvey, strona Unsplash.