뉴히의 개발 로그
[TIL] 20230831 - Youtube API 사용 동영상 삽입, 유튜브 썸네일 사이즈별 추출 본문
유튜브 공식 문서 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() |
동영상의 상태를 반환합니다
|
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는 손봐야함 ㅎㅎ
추가로
유튜브 썸네일 사이즈별로 추출하기
- 120×90: https://i1.ytimg.com/vi/VIDEO-ID/default.jpg
- 320×180: https://i1.ytimg.com/vi/VIDEO-ID/mqdefault.jpg
- 480×360: https://i1.ytimg.com/vi/VIDEO-ID/hqdefault.jpg
- 640×480: https://i1.ytimg.com/vi/VIDEO-ID/sddefault.jpg
- 1920×1080: https://i1.ytimg.com/vi/VIDEO-ID/maxresdefault.jpg
참고
https://www.youtube.com/watch?v= jXOWzFr-a_Q&list=PLs7TzBwHKDjJo8eTOVe4cok_k_SPgDis1&index=5
아이디는 요기