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 przypadku <video> i <audio> z HTMLMediaElement.setSinkId(). W Web Audio interfejs AudioContext używał urządzenia domyślnego, więc użytkownik musiał ręcznie zmieniać urządzenie wyjściowe audio w systemie.

Od wersji Chrome 110 możesz używać interfejsu AudioContext.setSinkId() do programowego kierowania wyjścia audio w 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 używać tego interfejsu do programowego kierowania wyjścia do określonego urządzenia wyjściowego audio, takiego jak słuchawki Bluetooth lub głośnik.

Przekierowywanie wyjścia audio na określone urządzenie

Najpierw musisz uzyskać identyfikator wyjściowego urządzenia audio, którego chcesz użyć jako miejsca docelowego. Pobierz listę dostępnych urządzeń multimedialnych za pomocą navigator.mediaDevices.enumerateDevices(), odfiltruj tylko urządzenia wyjściowe audio i pobierz atrybut deviceId wybranego urządzenia wyjściowego audio. Pusty ciąg "" może też być używany jako urządzenie domyślne dla deviceId.

Gdy uzyskasz identyfikator wyjściowego urządzenia audio, utwórz AudioContext i wywołaj audioContext.setSinkId(deviceId). Jeśli operacja się powiedzie, zwrócony obiekt Promise zostanie rozwiązany, gdy dźwięk zostanie przekierowany na wybrane połączone urządzenie wyjściowe. Może się nie udać, jeśli obiekt AudioContext jest zamknięty.

Poniższy przykład pokazuje, jak w razie potrzeby poprosić o dostęp do mikrofonu i skierować wyjście audio w Web Audio do pierwszego dostępnego urządzenia wyjściowego.

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ć deviceId jako parametr sinkId.

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

Renderowanie dźwięku za pomocą wyciszonego interfejsu AudioContext

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

Pamiętaj, że zegar audio dostępny po kliknięciu audioContext.currentTime będzie nadal odmierzać czas, aby wyrenderować wykres audio. Głównym celem tego wyciszonego interfejsu AudioContext jest renderowanie wykresu audio bez generowania słyszalnego dźwięku. Głównym zastosowaniem byłaby analiza danych wejściowych z mikrofonu bez wydawania dźwięków.

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

Wykrywanie cech

Aby sprawdzić, czy znak AudioContext.setSinkId() jest obsługiwany, użyj tego kodu:

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

Przykład

Wersja demonstracyjna, w której możesz wypróbować AudioContext.setSinkId(), jest dostępna na stronie https://codepen.io/web-dot-dev/pen/emNwEaN/.

Obsługa przeglądarek

AudioContext.setSinkId() jest dostępna w Chrome w wersji 110 lub nowszej.

Prześlij opinię

Zespół Chrome i społeczność zajmująca się standardami internetowymi chcą poznać Twoje wrażenia związane z AudioContext.setSinkId(). Opinie możesz przesyłać, komentując istniejące lub zgłaszając nowe problemy w GitHub.

Podziękowania

Dziękujemy Hongchanowi ChoiMichaelowi Wilsonowi za sprawdzenie tego artykułu.

Zdjęcie kalendarza: Steve Harvey, Unsplash.