Final project - Dev17

Jaemin Jung·2021년 9월 28일
0

Final Project

목록 보기
17/27
post-thumbnail

Visualizer 구현-3

레퍼런스를 찾다

AudioContext와 canvas를 중심 키워드로 구글링을 하였다.
리액트를 이용한 Visualizer 소스코드를 발견했다.
해당 블로그는 Create an Audio Visualizer with React and Canvas라는
제목을 가지고 있으며, tutorial 코드도 제공했다.
우선 블로그를 따라가며 코드를 작성해보고, 이해 안가는 코드는 하나씩 뜯어 보기로 했다.

  • 블로그의 내용중 WEB-AUDIO-API에 관해서만 작성해봤다.

Part1

Part1에서는 오디오 파일을 재생을 위한 로직을 구현하는 방향이다.

오디오 파일을 다른 디렉토리에 저장시켜 불러온 뒤,
new Audio() 생성자를 이용해 오디오 파일을 재생시킨다.
이후 버튼을 하나 만들어 onClick 이벤트에 전달할 togglePlay 함수를 만든다.

... 
  if(audio.paused) { 
    audio.play(); 
  } else { 
    audio.paused(); 
  } 
... 
render() { 
  return <> 
     <button onClick={this.togglePlay}>재생/일시중지</button> 
   </> 
}

Part2

Part2에서는 AudioContext를 이용해 주파수 배열을 생성하고,
이를 canvas를 이용해 그리는 방향이다.

WEB-AUDIO-API의 AudioContext를 생성하여, audio source node를 생성한다.
createMediaElementSource 메서드를 이용해 Part1에서 생성한 audio객체를 전달해준다.
여기서 createMediaElementSource 메서드는 AudioContext의
새 MediaElementAudioSourceNode를 만드는 데 사용된다.

그 다음, 목표로한 주파수 배열을 생성하기 위해 createAnalyser 메서드를 사용한다.
createAnalyser 메서드는 오디오 시간 및 주파수 데이터를 노출하고,
데이터 시각화를 만드는 데 사용된다.
Analyzer 노드를 이전에 생성한 MediaElementAudioSourceNode에 연결 시키고,
AudioContext의 destination을 Analyzer 노드에 연결 시킨다.

componentDidMount 함수 내부에서 이뤄진다.

    componentDidMount() {
        this.context = new (window.AudioContext || window.webkitAudioContext)();
        this.source = this.context.createMediaElementSource(this.audio);

        this.analyser = this.context.createAnalyser();
        this.source.connect(this.analyser);
        this.analyser.connect(this.context.destination);
        this.frequency_array = new Uint8Array(this.analyser.frequencyBinCount);
    }

그 다음으로 canvas태그를 이용해 애니메이션을 구현하는 내용으로 이어진다.

AudioContext.resume()

코드를 실행시키고 오디오 재생을 하려했는데, 다음과 같은 에러가 발생했다.

이 에러 어디서 많이 봤는데... 싶었는데, 이전에 Clone 받았었던
다른 Visualizer 모듈들과 똑같은 경고 문구였다.
아.. 이전에는 그냥 노란 경고 문구여서 그냥 지나쳤었는데,
재생에서 에러나는 이유가 이것이었다.
stack overflow에서는 오디오를 재생하기 이전에 onClick과 같은 제스쳐에서
resume()메서드를 호출해야한다고 설명했다.

그리고 Chrome의 자동 재생 정책의 링크를 첨부하여 확인 해보니 마찬가지로 다음과 같이 설명했다.

If an AudioContext is created before the document receives a user gesture, it will be created in the "suspended" state, and you will need to call resume() after the user gesture.

이전에 AudioContext는 3가지 state를 가지고 있다고 했는데,
user가 제스쳐를 하기 이전에 AudioContext가 생성 되었다면, state는 suspended인 것이다.
이 때문에 경고 문구와 함께 오디오가 재생이 되질 않았다.

오디오를 재생하기 이전 resume()메서드를 사용하니 오디오가 재생이 되었다!!

... 
 this.context.resume()
  if(audio.paused) { 
    audio.play(); 
  } else { 
    audio.paused(); 
  } 
... 
render() { 
  return <> 
     <button onClick={this.togglePlay}>재생/일시중지</button> 
   </> 
}

오늘은 여기까지..

솔직히 visualizer를 구현하자! 라고 추상적으로 생각만 하고,
실제 로직이 어떻게 될지는 생각해보질 않아서 많이 막막했는데 역시 죽으라는 법은 없는거같다.
로직에 대해서 이해를 완벽히 하지는 않았지만, 그래도 하나하나 풀려가는듯 해서 재미를 느끼는 중이다.
우선은 어느정도 가닥이 나온 Visualizer는 잠시 keep해두고,
1분 미리듣기 기능을 먼저 구현해볼생각이다.

참고사이트

https://medium.com/swlh/create-an-audio-visualizer-with-react-and-canvas-part-1-of-3-da414a1edfed
https://stackoverflow.com/questions/55026293/google-chrome-javascript-issue-in-getting-user-audio-the-audiocontext-was-not
https://developer.chrome.com/blog/autoplay/

profile
내가 보려고 쓰는 블로그

0개의 댓글