지난 몇 개월 동안 WebKit Web Audio API가 웹의 게임 및 오디오 애플리케이션을 위한 매력적인 플랫폼으로 부상했습니다. 개발자들이 이 기능을 숙지하면서 비슷한 질문이 반복적으로 제기되는 것을 알게 되었습니다. 이번 업데이트는 Web Audio API 사용 경험을 더 쾌적하게 만들기 위해 자주 묻는 질문에 답변하기 위한 것입니다.
Q: 소리를 낼 수 없습니다.
A: Web Audio API를 처음 사용하는 경우 시작하기 튜토리얼 또는 사용자 상호작용에 기반한 오디오 재생에 관한 Eric의 레시피를 참고하세요.
Q. 오디오 컨텍스트는 몇 개가 있어야 하나요?
A: 일반적으로 페이지당 하나의 AudioContext를 포함해야 하며 단일 오디오 컨텍스트는 연결된 여러 노드를 지원할 수 있습니다. 단일 페이지에 여러 AudioContext를 포함할 수 있지만 성능에 영향을 미칠 수 있습니다.
Q: noteOn()로 방금 재생한 AudioBufferSourceNode가 있는데 다시 재생하고 싶지만 noteOn()가 아무것도 하지 않습니다. 도와주세요.
A: 소스 노드의 재생이 완료되면 더 이상 재생할 수 없습니다. 기본 버퍼를 다시 재생하려면 새 AudioBufferSourceNode를 만들고 noteOn()를 호출해야 합니다.
소스 노드를 다시 만드는 것이 비효율적으로 느껴질 수 있지만 소스 노드는 이 패턴에 맞게 크게 최적화되어 있습니다. 또한 AudioBuffer 핸들을 유지하면 동일한 소리를 다시 재생하기 위해 애셋에 다른 요청을 할 필요가 없습니다. 이 패턴을 반복해야 하는 경우 playSound(buffer)와 같은 간단한 도우미 함수로 재생을 캡슐화하세요.
Q: 사운드를 재생할 때마다 새 소스 노드를 만들어야 하는 이유는 무엇인가요?
A: 이 아키텍처의 아이디어는 오디오 애셋을 재생 상태에서 분리하는 것입니다. 레코드 플레이어에 비유하면 버퍼는 레코드에, 소스는 재생 헤드에 해당합니다. 많은 애플리케이션이 동시에 재생되는 동일한 버퍼를 여러 개 포함하므로 이 패턴은 필수입니다.
Q: audio 및 video 태그의 소리를 처리하려면 어떻게 해야 하나요?
A: MediaElementAudioSourceNode가 준비 중입니다. 사용 가능한 경우 다음과 같이 작동합니다 (오디오 태그를 통해 재생되는 샘플에 필터 효과 추가).
<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);
이 기능은 이 crbug에서 추적됩니다. 이 설정에서는 mediaSourceNode.noteOn()를 호출할 필요가 없습니다. 오디오 태그가 재생을 제어합니다.
Q: 언제 마이크에서 소리를 들을 수 있나요?
A: 이 기능의 오디오 입력 부분은 getUserMedia를 사용하여 WebRTC의 일부로 구현되며 Web Audio API에서 특수 소스 노드로 사용할 수 있습니다. createMediaElementSource와 함께 작동합니다.
Q: AudioSourceNode 재생이 완료된 시점을 어떻게 확인할 수 있나요?
A: 현재 Web Audio API는 이 기능을 지원하지 않으므로 JavaScript 타이머를 사용해야 합니다. Web Audio API 시작하기 튜토리얼의 다음 스니펫은 이 기능을 보여주는 예입니다.
// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
console.log('playback finished');
}, buffer.duration * 1000);
Web Audio API가 더 정확한 콜백을 구현하도록 하는 미해결 버그가 있습니다.
Q: 사운드를 로드하면 전체 UI 스레드가 잠기고 UI가 응답하지 않습니다. 도움이 필요합니다.**
A: 비동기 로딩을 위해 decodeAudioData API를 사용하여 기본 스레드가 차단되지 않도록 합니다. 이 예시를 참고하세요.
Q: Web Audio API를 사용하여 소리를 실시간보다 빠르게 처리할 수 있나요?
A: 예, 해결책을 마련하기 위해 노력하고 있습니다. 새로운 소식을 계속 확인해 주세요.
Q: 멋진 Web Audio API 애플리케이션을 만들었는데 실행 중인 탭이 백그라운드로 전환될 때마다 소리가 이상해집니다.
A: 페이지가 백그라운드에 있는 경우 다르게 작동하는 setTimeouts를 사용하고 있기 때문일 수 있습니다. 향후 Web Audio API는 웹 오디오의 내부 타이머 (context.currentTime 속성)를 사용하여 특정 시간에 콜백할 수 있습니다. 자세한 내용은 이 기능 요청을 참고하세요.
일반적으로 앱이 백그라운드로 전환되면 재생을 중지하는 것이 좋습니다. 페이지 가시성 API를 사용하여 페이지가 백그라운드로 전환되는 시점을 감지할 수 있습니다.
Q: Web Audio API를 사용하여 소리의 음높이를 변경하려면 어떻게 해야 하나요?
A: 소스 노드에서 playbackRate를 변경합니다.
Q: 속도를 변경하지 않고 음높이를 변경할 수 있나요?
A: Web Audio API에는 오디오 컨텍스트에 PitchNode가 있을 수 있지만 구현하기가 어렵습니다. 오디오 커뮤니티에는 간단한 피치 시프팅 알고리즘이 없기 때문입니다. 알려진 기술은 특히 음높이 이동이 큰 경우 아티팩트를 생성합니다. 이 문제를 해결하는 방법에는 두 가지가 있습니다.
- 시간 도메인 알고리즘으로 인해 세그먼트 에코 아티팩트가 반복됩니다.
- 주파수 도메인 기법으로, 잔향 사운드 아티팩트가 발생합니다.
이러한 기법을 실행하는 기본 노드는 없지만 JavaScriptAudioNode를 사용하면 됩니다. 이 코드 스니펫을 출발점으로 사용할 수 있습니다.
Q: 원하는 샘플링 비율로 AudioContext를 만들려면 어떻게 해야 하나요?
A: 현재는 지원되지 않지만 검토 중입니다. 이 기능 요청을 참고하세요.
추가 질문이 있으면 web-audio 태그를 사용하여 StackOverflow에 질문해 주세요.