본문 바로가기
웹 오디오 프로그래밍

[Web Audio API #6] 여러개의 웹 오디오 소스 재생 잠시멈춤

by 영바이트 2021. 7. 1.

오디오 컨텍스트audio context의 currentTime 속성 값을 이용해서 음원의 재생 시간을 구하고 이를 이용해서 재생과 잠시 멈춤을 반복할 수 있다. 만약 음원이 둘 이상이면 어떻게 컨트롤해야 할까.

 

결론부터 말하자면 아래 두 가지 방법이 있다.

① 각각의 음원을 따로 제어한다.

② 오디오 컨텍스트 자체를 비활성화(suspend)하거나 활성화(resume)해서 제어한다.

 

먼저 각각의 음원을 따로 제어하는 방법을 살펴보자. 먼저 획득한 오디오 버퍼를 데이터로 음원의 수 만큼 오디오 소스 노드를 생성한다. 예에서는 2개의 음원을 사용하였다.

audioSource = [];

audioBuffers.forEach((audioBuffer) => {
	var source = audioContext.createBufferSource();
	source.buffer = audioBuffer;
	source.loop = true;

	source.connect(audioContext.destination)
	audioSource.push(source);
});

 

위 코드의 실행 결과로 아래와 같은 오디오 그래프가 생성되었을 것이다.

 

 

아래와 같이 각각의 오디오 소스를 제어하여 두 개 이상의 음원을 함께 출력할 수 있다.

startTime = audioContext.currentTime;

audioSource.forEach((source) => {
	source.start(0, elapsedTime%source.buffer.duration);

	console.log('play.audioContext.startTime: ', startTime);
	console.log('play.audioSource.buffer.duration: ', source.buffer.duration);
	console.log('play.audioContext.startOffset: ', elapsedTime%source.buffer.duration);
});

 

const pause = (audioSource) => {
	audioSource.forEach((element) => {element.stop()});
	elapsedTime = elapsedTime + audioContext.currentTime - startTime;
	console.log('pause.audioContext.elapsedTime: ', elapsedTime);
}

 

만약 둘 이상의 음원을 동시에 멈추고 다시 재생한다면 오디오 그래프 자체를 활성화/비활성화 시킬 수도 있다. 아래 예를 살펴보자.

var audioContextResumed = 0;

playPauseButton.addEventListener('click', (event) => {

	if(audioContextResumed == 0){
		if(audioContext.state == 'suspended'){
			audioContext.resume();
		}
		audioContextResumed = 1;
		event.target.dataset.playing = 'true';
		event.target.innerHTML = 'Pause';
		play();
	}
	else{
		if(event.target.dataset.playing == 'false'){
			event.target.dataset.playing = 'true';
			event.target.innerHTML = 'Pause';
			audioContext.resume();
		}
		else{
			event.target.dataset.playing = 'false';
			event.target.innerHTML = 'Play';
			audioContext.suspend();
		}
	}
});

 

const play = () => {
	audioSource = [];

	audioBuffers.forEach((audioBuffer) => {
		var source = audioContext.createBufferSource();
		source.buffer = audioBuffer;
		source.loop = true;

		source.connect(audioContext.destination)
		audioSource.push(source);
	});

	startTime = audioContext.currentTime;

	audioSource.forEach((source) => {
		source.start(0, elapsedTime%source.buffer.duration);
	});
}

 

위의 예와 같이 오디오 컨텍스트의 resume(), suspend() 메서드를 이용해서 오디오 그래프를 활성화/비활성화 할 수 있다. 오디오 소스 각각을 제어하는 것과 비교해서 미세한 타이밍 차이는 있겠지만 우리 귀로 듣고 차이를 느낄 수는 없을 것이다.

 

단, 오디오 그래프를 이용해서 음원 재생을 컨트롤하면 오디오 소스 각각을 따로 제어할 수 없고, 또 같은 오디오 그래프에 연결되어 있는 모든 오디오 소스들이 영향을 받게된다.

 

 

 

댓글