웹 오디오에서 대상 출력 장치 변경

François Beaufort
François Beaufort

지금까지는 HTMLMediaElement.setSinkId()를 사용하여 <video><audio>에 대해서만 대상 오디오 출력 장치를 설정할 수 있었습니다. Web Audio에서 AudioContext는 기본 기기를 사용했기 때문에 사용자가 시스템 오디오 출력 기기를 수동으로 변경해야 했습니다.

Chrome 110부터 AudioContext.setSinkId()를 사용하여 웹 오디오의 오디오 출력을 허용된 모든 기기로 프로그래매틱 방식으로 전달할 수 있습니다.

이는 다양한 실시간 커뮤니케이션 시나리오에서 특히 유용합니다. 예를 들어 웹 앱은 이를 사용하여 블루투스 헤드셋이나 스피커폰과 같은 특정 오디오 출력 장치로 출력을 프로그래매틱 방식으로 전달할 수 있습니다.

오디오 출력을 특정 기기로 라우팅

먼저 대상으로 사용할 오디오 출력 기기의 식별자가 필요합니다. navigator.mediaDevices.enumerateDevices()를 사용하여 사용 가능한 미디어 기기 목록을 가져오고 오디오 출력 기기만 필터링한 후 선택한 오디오 출력 기기의 deviceId 속성을 가져옵니다. 빈 문자열 "" 값을 deviceId의 기본 기기로 사용할 수도 있습니다.

오디오 출력 기기의 식별자를 가져온 후 AudioContext를 만들고 audioContext.setSinkId(deviceId)를 호출합니다. 성공하면 선택된 연결된 출력 장치로 오디오가 라우팅될 때 반환된 프라미스가 확인됩니다. AudioContext가 닫히면 실패할 수 있습니다.

아래 예에서는 필요한 경우 마이크 액세스를 요청하고 Web Audio의 오디오 출력을 사용 가능한 첫 번째 출력 장치로 전달하는 방법을 보여줍니다.

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

AudioContext를 만들 때 deviceIdsinkId 매개변수로 전달할 수도 있습니다.

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

음소거된 AudioContext로 오디오 렌더링

이제 Web Audio에서 '무음 출력 기기'를 지정하여 전력 소모를 최소화할 수 있습니다. 이번에는 문자열 값 대신 { type: "none" }AudioContext.setSinkId()에 전달합니다.

audioContext.currentTime를 통해 액세스할 수 있는 오디오 시계는 오디오 그래프를 렌더링하기 위해 계속 진행됩니다. 이 음소거된 AudioContext의 주요 목표는 가청 소리를 내지 않고 오디오 그래프를 렌더링하는 것입니다. 기본 사용 사례는 소리를 내지 않고 마이크 입력을 분석하는 것입니다.

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

기능 감지

AudioContext.setSinkId()가 지원되는지 확인하려면 다음을 사용하세요.

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

샘플

AudioContext.setSinkId()를 사용해 볼 수 있는 데모는 https://sinkid.glitch.me/에서 확인할 수 있습니다.

브라우저 지원

AudioContext.setSinkId()는 Chrome 110 이상에서 사용할 수 있습니다.

의견

Chrome팀과 웹 표준 커뮤니티에서는 AudioContext.setSinkId() 사용 경험에 관한 의견을 듣고 싶어 합니다. 기존 문제에 의견을 남기거나 새 GitHub 문제를 제출하여 의견을 보내주세요.

감사의 말씀

이 도움말을 검토해 주신 홍찬 최님과 마이클 윌슨님께 감사드립니다.

캘린더 이미지 사진: Unsplash스티브 하비