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

프랑수아 보포르
프랑수아 보포르

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

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

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

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

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

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

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

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로 오디오 렌더링

이제 웹 오디오에서 '무음 출력 장치'를 지정하여 전력 소모를 최소화할 수 있습니다. 이번에는 문자열 값 대신 { 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.
}

샘플

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

브라우저 지원

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

의견

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

감사의 말씀

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

캘린더 이미지 사진: Steve Harvey(Unsplash 제공)