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

François Beaufort
François Beaufort

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

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

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

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

먼저 대상으로 사용할 오디오 출력 기기의 식별자가 필요합니다. 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://codepen.io/web-dot-dev/pen/emNwEaN/에서 확인할 수 있습니다.

브라우저 지원

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

의견

Chrome팀과 웹 표준 커뮤니티는 AudioContext.setSinkId() 사용 경험에 관한 의견을 듣고 싶습니다. 기존 GitHub 문제에 댓글을 달거나 새 문제를 제출하여 의견을 제공해 주세요.

감사의 말씀

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

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