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

[Web Auio API #19] 오디오 그래프(오디오 노드) 출력 저장하기

by 영바이트 2021. 8. 18.

이전 포스팅들에서 MediaRecorder 객체를 이용해서 마이크 입력을 녹음하는 방법을 살펴봤었다. MediaRecorder 객체는 AudioContext의 메서드를 이용해서 생성했던 AudioNode들과는 전혀 다르다.

interface MediaRecorder : EventTarget {
    constructor(MediaStream stream, optional MediaRecorderOptions options = {});
    readonly attribute MediaStream stream;
    readonly attribute DOMString mimeType;
    readonly attribute RecordingState state;
    attribute EventHandler onstart;
    attribute EventHandler onstop;
    attribute EventHandler ondataavailable;
    attribute EventHandler onpause;
    attribute EventHandler onresume;
    attribute EventHandler onerror;
    readonly attribute unsigned long videoBitsPerSecond;
    readonly attribute unsigned long audioBitsPerSecond;
    readonly attribute BitrateMode audioBitrateMode;

    undefined start(optional unsigned long timeslice);
    undefined stop();
    undefined pause();
    undefined resume();
    undefined requestData();

    static boolean isTypeSupported(DOMString type);
};

 

interface AudioNode : EventTarget {
    AudioNode connect (AudioNode destinationNode,
                        optional unsigned long output = 0,
                        optional unsigned long input = 0);
    undefined connect (AudioParam destinationParam, optional unsigned long output = 0);
    undefined disconnect ();
    undefined disconnect (unsigned long output);
    undefined disconnect (AudioNode destinationNode);
    undefined disconnect (AudioNode destinationNode, unsigned long output);
    undefined disconnect (AudioNode destinationNode,
                        unsigned long output,
                        unsigned long input);
    undefined disconnect (AudioParam destinationParam);
    undefined disconnect (AudioParam destinationParam, unsigned long output);
    readonly attribute BaseAudioContext context;
    readonly attribute unsigned long numberOfInputs;
    readonly attribute unsigned long numberOfOutputs;
    attribute unsigned long channelCount;
    attribute ChannelCountMode channelCountMode;
    attribute ChannelInterpretation channelInterpretation;
};

 

MediaRecorder 객체는 생성할 때 전달하는 인자(argument)인 MediaStream 객체를 통해 데이터를 전달받는다. 반면에 AudioNode 객체는 connect() 메서드를 호출할 때 전달하는 인자인 AudioNode 형식의 다른 오디오 노드들과 연결되어 오디오 버퍼 노드 혹은 이전 오디오 노드로부터 데이터를 전달받는다. 결과적으로 MediaRecorder와 AudioNode 사이에는 공통점이 없다.

 

만약 오디오 그래프의 처리 결과를 녹음해서 보관할 필요가 생기면 AudioNode와 MediaRecorder를 연결해야 한다. 이 때 사용되는 오디오 노드가 MediaStreamAudioDestinationNode다. MediaStreamAudioDestinationNode는 AudioNode 클래스를 상속받은 오디오 노드이지만 다른 노드들과 달리 MediaStreamAudioDestination.stream 프로퍼티로  MediaStream 객체를 출력해준다. 예를 들어 아래와 같은 오디오 그래프 출력을 녹음한다면 아래 예와 같이 코드를 구성할 수 있다.

 

const audioContext = new(window.AudioContext || window.webkitAudioContext)();

//    오디오 노드를 생성한다
var bufferSource = audioContext.createBufferSource();
bufferSource.buffer = audioBuffer;

var dynamicRangeCompressor = audioContext.createDynamicsCompressor();

const gainNode = audioContext.createGain();

const mediaStreamDestination = audioContext.createMediaStreamDestination();

//    오디오 그래프를 구성한다
bufferSource.connect(dynamicRangeCompressor);
dynamicRangeCompressor.connect(gainNode);
gainNode.connect(mediaStreamDestination);

//    오디오 그래프 출력을 받는 미디어 레코더를 생성한다
var mediaRecorder = new MediaRecorder(mediaStreamDestination.stream);

 

오디오 그래프로부터 입력 스트림을 받는 경우에도 MediaRecorder 객체를 사용하는 방법은 동일하다. 만약 녹음이 이루어지지 않는다면 오디오 그래프가 출력을 만들어 내고 있는지, 즉 오디오 그래프를 'running' 상태로 두었는지 확인해 볼 필요가 있다.

if(audioContext.state === 'suspended'){
    audioContext.resume();
}

 

 

 

댓글