«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
Recent Posts
Recent Comments
관리 메뉴

뉴히의 개발 로그

[TIL] 20230831 - Youtube API 사용 동영상 삽입, 유튜브 썸네일 사이즈별 추출 본문

개발일지/TIL

[TIL] 20230831 - Youtube API 사용 동영상 삽입, 유튜브 썸네일 사이즈별 추출

뉴히 2023. 8. 31. 13:11

유튜브 공식 문서 https://developers.google.com/youtube/iframe_api_reference?hl=ko 

유튜브 영상을 Youtube API로 동영상을 아주 쉽게 내 사이트에 넣을 수 있다.

 

 

1. 라이브러리 설치

npm i react-youtube

2. 사용 방법

2-1) JavaScript

import React from 'react';
import YouTube from 'react-youtube';

class Example extends React.Component {
  render() {
    const opts = {
      height: '390',
      width: '640',
      playerVars: {
        'autoplay': 1, //자동재생
        'rel': 0,
        'showinfo': 0,
        'modestbranding': 1,
        'playsinline': 1,
        'rel': 0,
        'controls': 1,	//youtube 콘트롤 표시
        'color':'white',
        'loop': 1, //반복 여부  
      },
    };

    return <YouTube videoId="비디오아이디" opts={opts} onReady={this._onReady} />;
  }

  _onReady(event) {
    event.target.pauseVideo();
  }
}
  • playerVars 객체 안에는 동영상 옵션을 설정한다. 
    - 해당 매개변수는 https://developers.google.com/youtube/player_parameters 사이트에서 참고 가능하다.
  • videoId : 동영상 ID 값을 넘겨주면 해당 동영상을 불러온다.
  • event.target을 지정하면 YouTube IFrame API 공식 문서에 있는 함수를 사용하여 동영상 재생을 제어할 수 있다.

playVideo() 동영상을 재생합니다.
pauseVideo() 재생 중인 동영상을 일시중지합니다.
stopVideo()
동영상의 로드를 중지하고 취소합니다.
nextVideo() 재생목록에서 다음 동영상을 로드하고 재생합니다.
previousVideo()  재생목록에서 이전 동영상을 로드하고 재생합니다.
playVideoAt(index:Number) 재생목록에서 지정한 동영상을 로드하고 재생합니다.
mute() 동영상 음소거합니다.
unMute() 동영상 음소거를 해제합니다.
isMuted()
동영상 음소거 상태인 경우 true를 반환하고 음소거 상태가 아닌 경우 false를 반환합니다.
setVolume(volume:Number) 볼륨을 설정합니다. 0에서 100 사이의 정수를 허용합니다.
getVolume() 동영상의 현재 볼륨을 0에서 100 사이의 정수로 반환합니다
getPlayerState()
동영상의 상태를 반환합니다
  • -1 –시작되지 않음
  • 0 – 종료
  • 1 – 재생 중
  • 2 – 일시중지
  • 3 – 버퍼링
  • 5 – 동영상 신호
getCurrentTime() 동영상 재생이 시작된 이후의 경과 시간을 초 단위로 반환

 

2-2) TypeScript

import React from 'react';
import YouTube, { YouTubeProps } from 'react-youtube';

type YoutubeIdType = {
  id: string;
};
const opts: YouTubeProps['opts'] = {
  height: '390',
  width: '640',
  playerVars: {
    fs: 1,
    controls: 0,
    playsinline: 0,
    enablejsapi: 0,
    modestbranding: 1,
    disablekb: 1,
    autohide: 1,
    autoplay: 0,
    loop: 0,
    volume: 0,
    iv_load_policy: 3,
    origin: window.location.origin,
    widget_referrer: window.location.href,
  },
};

function Youtube() {
  const onPlayerReady: YouTubeProps['onReady'] = (event) => {
    event.target.pauseVideo();
  }
  return <YouTube videoId="비디오아이디" opts={opts} onReady={onPlayerReady} />;
}

자잔 ~ ㅎㅎㅎ

 

 

 

나는 영상을 썸네일 이미지 보여주고 클릭시 모달로 크게 영상을 볼 수 있도록 만들어 보려고 더 작업했다

const UserReviewList = () => {
  const dispatch = useDispatch();
  const handleYoutubePlayer = (id: string): void => {
    dispatch(openModal({ type: 'reviewYoutube', targetId: id }));
  };
  return <S.ReviewItemImage onClick={() => handleYoutubePlayer('비디오 아이디')} src="https://i1.ytimg.com/vi/비디오아이디/sddefault.jpg"></S.ReviewItemImage>;
};

export default UserReviewList;

클릭시 타입과 아이디를 넘겨준다

공용 모달을 사용하고 있어서 리덕스툴킷으로 상태관리를 하고 있다

// modalSlice

import { PayloadAction, createSlice } from '@reduxjs/toolkit';

type ModalState = {
  type: string;
  isOpen?: boolean;
  targetId?: string | null;
};

const initialState: ModalState = {
  type: '',
  isOpen: false,
  targetId: '',
};

const modalSlice = createSlice({
  name: 'modal',
  initialState,
  reducers: {
    openModal: (state, action: PayloadAction<ModalState>) => {
      state.type = action.payload.type;
      state.targetId = action.payload.targetId;
      state.isOpen = true;
    },

    closeModal: (state) => {
      state.isOpen = false;
    },

    setTargetId: (state, action: PayloadAction<string>) => {
      state.targetId = action.payload;
    },
  },
});

export default modalSlice.reducer;
export const { openModal, closeModal, setTargetId } = modalSlice.actions;
// global modal

import * as S from './Modal.styled';
import { Alert, Confirm, Report, ReviewForm, ReviewUpdateForm } from '..';
import { useSelector } from 'react-redux';
import { RootState } from '../../redux/config/configStore';
import YoutubeModal from '../youtube/YoutubeModal';

const GlobalModal = () => {
  const { type, isOpen } = useSelector((state: RootState) => state.modal);
  if (!isOpen) return;

  const MODAL_TYPES = {
    reviewYoutube: 'reviewYoutube',
  };

  const MODAL_COMPONENTS = [
    {
      type: MODAL_TYPES.reviewYoutube,
      component: <YoutubeModal />,
    },
  ];

  const findModal = MODAL_COMPONENTS.find((modal) => {
    return modal.type === type;
  });

  const renderModal = () => {
    return findModal?.component;
  };

  return (
    <ModalPortal>
      <S.Overlay />
      {renderModal()}
    </ModalPortal>
  );
};

export default GlobalModal;
//youtube modal

import React from 'react';
import { Container } from '../Form/reviewForm/ReviewForm.styled';
import YouTube, { YouTubeProps } from 'react-youtube';
import { closeModal } from '../../redux/modules';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../redux/config/configStore';
type YoutubeIdType = {
  id: string;
};
const opts: YouTubeProps['opts'] = {
  height: '390',
  width: '640',
  playerVars: {
    fs: 1,
    controls: 0,
    playsinline: 0,
    enablejsapi: 0,
    modestbranding: 1,
    disablekb: 1,
    autohide: 1,
    autoplay: 0,
    loop: 0,
    volume: 0,
    iv_load_policy: 3,
    origin: window.location.origin,
    widget_referrer: window.location.href,
  },
};

const YoutubeModal = () => {
  const { targetId: id } = useSelector((state: RootState) => state.modal);
  console.log(id);

  const dispatch = useDispatch();
  const handleClose = () => {
    dispatch(closeModal());
  };
  const onPlayerReady: YouTubeProps['onReady'] = (e) => {
    e.target.pauseVideo();
  };

  return (
    <Container>
      <button onClick={handleClose}>닫기</button>
      <YouTube videoId={id!} opts={opts} onReady={onPlayerReady} />
    </Container>
  );
};

export default YoutubeModal;

 

완료 ! css는 손봐야함 ㅎㅎ

 

 

추가로

유튜브 썸네일 사이즈별로 추출하기

참고

https://www.youtube.com/watch?v= jXOWzFr-a_Q&list=PLs7TzBwHKDjJo8eTOVe4cok_k_SPgDis1&index=5

아이디는 요기