본문 바로가기

코딩/ReactJS

ReactJS에서 react-youtube 라이브러리로 유튜브 영상 제어하기

반응형

지난번에 유튜브 API를 이용해서 뮤직 플레이어를 만들었었다.

 

2023.08.23 - [코딩/ReactJS] - 리액트에서 유튜브 API를 이용해 뮤직 플레이어 만들기

 

리액트에서 유튜브 API를 이용해 뮤직 플레이어 만들기

제목은 뭔가 완성된 프로그램을 만든 것처럼 보이지만 내가 만든건 프로그레스바(재생바)가 동작하지 않는 반쪽짜리 프로그램이다. UI에서부터 느껴지는 반푼이 프로그램의 기운... 주제에 반응

bebutae.tistory.com

그런데 이때 chatGPT를 통해 코드를 생성했고

생성된 코드를 제대로 이해하지 못한 상태에서

프로그램을 만들었더니 기능 추가를 한다던가

오류를 수정한다던가 하는 상황에서 상당히 어려움을 겪었다.

 

그래서 찾은게 react-youtube라는 라이브러리인데,

유튜브 api를 좀 더 쉽게 사용할 수 있도록 만든 라이브러리라고 한다.

근데 영상 보여주는건 기똥차게 쉬운데

커스텀 컨트롤러를 만들어서 영상을 제어하는 예제는 도저히 찾아보기 힘들었다.

 

react-youtube 라이브러리의 핵심은 YouTube 컴포넌트다.

import YouTube from "react-youtube";

이렇게 import를 한 뒤에 내가 영상을 보여주고 싶은 위치에

아래와 같이 Youtube 컴포넌트를 넣어주면 된다.

  <YouTube
    videoId={videoId}
    opts={opts}
    onReady={(e) => {
      setVideoTitle(e.target.videoTitle);
      console.log(e.target);
      setIsPlaying(true);
      setVolume(e.target.playerInfo.volume);
      setIsMuted(e.target.playerInfo.muted);
      setMute(e.target);
    }}
    onStateChange={(e) => {
      setOnStateChange(e);
      setVolumeControl(e.target);
    }}
  />

옵션이 상당히 많은데 제일 먼저

videoId에는 보여주고 싶은 유튜브 영상의 videoId를 넣어주면 된다.

videoId는 유튜브에서 공유 버튼을 누르면 아래와 같은 화면이 뜨는데

// http://youtu.be/<여기>?feature=shared

내가 <여기>라고 표현해둔 부분(사진에서는 kn78I8IJAwOY)이 videoId이다.

 

다음은 영상과 관련된 옵션들을 수정할 수 있는 opts가 있다.

  const opts = {
    height: "0",
    width: "0",
    playerVars: { autoplay: 1 },
  };

나는 이렇게 opts를 별도의 변수로 빼내서 설정을 만져줬다.

height와 width는 영상의 크기를 결정하는데

저 값들을 0으로 설정해주면 영상을 숨길 수 있다.

 

지금 진행중인 프로젝트가 유튜브api 기반 뮤직 플레이어이기 때문에

영상은 보여줄 필요가 없으므로 이 코드에서는 영상을 숨겨주었다.

또한 autoplay에 1을 주면 영상이 자동 재생된다.

 

다음으로 onReady와 onStateChange를 잘 봐야 한다.

왜냐하면 영상을 제어할 수 있는 코드들이기 때문이다.

 

나는 뮤직 플레이어를 만들기 위해서 영상을 숨겨주었는데

유튜브는 영상영역 안에 재생, 볼륨 등 컨트롤러가 포함되어 있으므로

영상을 숨기면 영상을 컨트롤 할 수 있는 수단이 사라진다.

 

그래서 별도의 버튼으로 영상을 제어하기 위해

onReady와 onStateChange를 설정해주었다.

 

아래 코드는 내가 못찾는건지 react-youtube 공식 문서(?)에도

이에 대한 자세한 설명이 없어서 이것저것 만져보면서

직접 작성한 코드들이다.

onReady={(e) => {
  setVideoTitle(e.target.videoTitle);
  console.log(e.target);
  setIsPlaying(true);
  setVolume(e.target.playerInfo.volume);
  setIsMuted(e.target.playerInfo.muted);
  setMute(e.target);
}}
onStateChange={(e) => {
  setOnStateChange(e);
  setVolumeControl(e.target);
}}

우선 onReady는 영상이 재생될 준비가 되면 적용되는 코드들이고

onStateChange는 영상의 상태가 변경될 때 적용되는 코드들이다.

 

아래 사진은 영상 데이터(videoId)가 없을 때의 UI를 캡쳐한 것이다.

그리고 아래 사진은 영상 데이터가 있을 때의 UI를 캡쳐한 것이다.

우선 onStateChange에서 e.target을 콘솔에 찍어보면

아래와 같은 데이터들을 확인할 수 있다.

여기에서 영상을 재생할 수 있는 playVideo() 함수와

영상을 일시정지 할 수 있는 pauseVideo() 함수를 찾을 수 있다.

나는 이 함수들을 꺼내 쓰기 위해서

setState 함수를 이용해 e.target의 값을 YouTube 컴포넌트 밖으로 빼주었다.

onStateChange={(e) => {
  setOnStateChange(e);
}}

또한 영상의 재생과 일시정지를 컨트롤 하기위해 버튼을 만들고,

해당 버튼을 클릭했을 때 함수가 실행되도록 onClick이벤트를 걸어줬다.

<IconButton
  sx={{ color: "white" }}
  onClick={() => _onStateChange(onStateChange)}
>
  {isPlaying ? <PauseIcon /> : <PlayArrowIcon />}
</IconButton>

버튼을 클릭하면 _onStateChange 함수가 실행되는데

이 함수의 매개변수에 YouTube 컴포넌트에서 빼온 e.target의 값이 들어간다.

  const _onStateChange = (event) => {
    console.log(event);
    if (event.data === 2 || null) {
      event.target.playVideo();
      setIsPlaying(true);
    } else if (event.data === 1) {
      event.target.pauseVideo();
      setIsPlaying(false);
    }
  };

위 코드와 같이 현재 재생상태에 따라

영상을 재생하거나 일시정지 할 수 있도록 코드를 작성해두었다.

 

그 외에 볼륨 컨트롤 기능도 넣어두었는데

input 태그를 이용해 입력받은 값을 setVolume함수를 이용해

youtube 서버에 전달해주었다.

  <input
    type="range"
    value={volume}
    onChange={(e) => _controlVolume(volumeControl, e.target.value)}
    min="0"
    max="100"
    style={{ margin: "auto", width: 200 }}
  />
  const _controlVolume = (setVolumeControl, volume) => {
    console.log(setVolumeControl.setVolume);
    setVolumeControl.setVolume(volume);
    setVolume(volume);
  };

다음으로 onReady가 있는데 얘도 e.target을 찍어보면

onStateChange와 같은 값을 반환한다.

재밌는건 e.target이 아니라 e를 콘솔에 찍었을때

onStateChange는 data 값에 1이나 2가 들어가있는데

onReady는 data 값에 null이 들어가있다.

여기서 data 값이 1이면 영상이 재생중인거고

2면 영상이 일시정지 상태인 것이다.

그래서 영상 재생을 위한 함수에서

e.data의 값을 체크해서 재생 여부를 결정해주었다.

  const _onStateChange = (event) => {
    console.log(event);
    if (event.data === 2 || null) {
      event.target.playVideo();
      setIsPlaying(true);
    } else if (event.data === 1) {
      event.target.pauseVideo();
      setIsPlaying(false);
    }
  };
반응형