웹 브라우저 혹은 웹 어플리케이션에서 오디오를 재생하기 위해 오디오 그래프audio graph를 구성하고 오디오 그래프 소스 노드의 start(), stop() 메서드를 호출해서 오디오를 재생하고 정지시킨다.
// decode 대상 buffer는 서버로 부터 받은 blob, 즉 파일 buffer를 의미한다.
audioContext.decodeAudioData(buffer, (buffer) => {
audioBuffer = buffer;
});
// source - destination(=오디오 출력 장치)으로 이루어진 오디오 그래프
source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
source.start(0); // 0은 지금을 의미한다
source.stop(); // 오디오 재생을 멈춘다
stop() 메서드를 호출해서 재생을 멈추면 같은 소스 노드의 start() 메서드를 다시 호출할 수 없다(오류가 발생한다).
source.start(0); // 0은 지금을 의미한다
source.stop(); // 오디오 재생을 멈춘다
source.start(0); // 오류
한 번 stop() 메서드가 호출된 소스 노드의 start() 메서드를 다시 호출 할 수 없는 이유는 소스와 소스 버퍼를 구분하는 오디오 그래프의 특성 때문이다.
audioContext.decodeAudioData(buffer, (buffer) => {
audioBuffer = buffer;
});
source = audioContext.createBufferSource();
source.buffer = audioBuffer;
위 코드에서 audioBuffer(=오디오 데이터)는 여러 번 재사용될 수 있지만 소스 노드 source는 stop() 메서드가 호출되면 다시 start() 메서드를 호출할 수 없다. 그러면 음악을 잠시 멈춘 후 이어서 재생하려면 즉, play - pause - play 패턴을 만드려면 어떻게 해야할까?
play - pause - play 패턴을 만들기 위해서는 stop() 메서드 호출 이후에 동일한 오디오 데이터를 사용하는 다른 오디오 소스를 만들어서 사용해야 한다. 그리고 새로 만든 소스 노드의 start() 메서드에 시작할 위치를 인자로 전달해준다.
source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
startTime = audioContext.currentTime;
source.start(0, elapsedTime); // start(시작 시점, 시작 위치)
시작 위치(이어서 재생할 위치)인 elapsedTime은 stop() 메서드를 호출할 때 계산해 놓는다.
elapsedTime = (elapsedTime + audioContext.currentTime - startTime)%source.buffer.duration;
source.stop();
여기서 audio context의 currentTime 개념이 등장하게 된다. audio context는 오디오 그래프를 포함하는 객체이고 audio context의 상태가 'running'인 동안 audio context의 currentTime은 계속 증가한다. 따라서 오디오의 시작 시점과 멈춤 시점을 이 currentTime을 통해 알 수 있고, '멈춤 시점 - 시작 시점'이 재생한 오디오 시간이므로 이 시간 이후의 오디오 데이터를 재생하도록 하면 잠시 멈춤 효과를 구현할 수 있다. 아래와 같이 그림으로 정리할 수 있다.
코드의 계산식에서는 재생 - 멈춤 - 재생이 여러 번 반복될 수 있기 때문에 기존 재생 시간인 elapsedTime을 더해 주었고, 여기에 더해 오디오가 계속 반복 재생(loop)될 수 있기 때문에 오디오 데이터의 길이인 source.buffer.duration로 modular 연산 %를 해주었다.
오디오 재생 이벤트가 일어날 때 마다 오디오 소스 노드를 새로 만들어야 한다. 이어질 내용에서는 어느 시점에 오디오 그래프가 구성되는지, 그리고 어느 시점에서 이어서 재생한 위치가 계산되는지 코드 전체적인 관점에서 살펴보도록 하겠다.
■
'웹 오디오 프로그래밍' 카테고리의 다른 글
[Web Audio API #6] 여러개의 웹 오디오 소스 재생 잠시멈춤 (0) | 2021.07.01 |
---|---|
[Web Audio API #5] 재생-멈춤-재생 예제 코드 (0) | 2021.06.29 |
[Web Audio API #3] 오디오 재생 - 서버 (0) | 2021.06.25 |
[Web Audio API #2] 오디오 재생 (0) | 2021.06.18 |
[Web Audio API #1] 웹에서 오디오 다루기 (0) | 2021.06.16 |
댓글