완성하면 완성기를 올리려고 했는데, 거의 일주일째 헤매고 있어서 미루고 미루다 중간 과정에서 글을 작성한다.
혼자 리액트 앱을 만들던 중 background를 동영상으로 꽉 차게 만들고 싶어서 반드시 유튜브 영상이 필요했다.
iframe 태그로 동영상을 가져오는 게 첫번째 시도였는데, 원하는대로 잘 출력되긴 했으나 콘솔에 cors 에러가 반드시 등장했다.
구글링해서 알게 된 방법을 적용해도 모두 안되고 sandbox="allow-same-origin allow-scripts"
이런 프로퍼티 적용도 안되고...
결국 간단한 서버를 만들어서 CORS 설정 및 API 요청을 보내야겠다는 생각이 들었다.
언제 뜬 건지 기억 안 나지만 캡쳐해 두었던 CORS 에러
-> 기존 client단만 있었기에 'server를 만들고, youtube에서 API 키를 발급받아 GET 요청을 보내서 API를 받아와야겠다'고 판단했다.
공식문서를 확인하면 세팅부터 활용까지 정말 자세한 설명을 볼 수 있다.
API를 활용하려면 API Key 발급은 필수다.
Youtube API key는 아래와 같이 일일 쿼리 한도가 채워지면 사용할 수 없다.
강제 휴식...
생각보다 금방 채워진다. 요청 데이터가 많을 수록 금방 채워지는 것 같다.
공식문서에서 위와 같이 API 요청 및 응답을 확인할 수 있으니 충분히 시도한 뒤에 프로젝트에 적용시키도록 하자
위 링크에서 연습한 대로 요청을 보내서 응답받은 결과!
제대로 들어와서 기뻤다.
forEach로 들어오는 data 중 원하는 데이터(사진 속에서는 title)만 추출할 수도 있다.
이렇게 잘 들어오는 게 보인다!
문제점
- 내 앱에 접속하면 메인 화면 배경에 영상을 띄우기 위해
메인화면에서 useEffect(() => 5초뒤에 GET 요청과 함께 서버로 리디렉션 ) -> 서버에서 Youtube로 API key를 포함한 데이터 요청 -> 유튜브 서버에서 응답 -> 서버에서 클라이언트로 응답
과 같은 과정을 거쳐야 했으며 가장 중요한 CORS 에러가 해결되지도 않았다.- 나는 정확히 원하는 영상 1개를 재생하길 원했는데, 정확히 니즈를 충족하는 리소스 유형이 없어서
원하는 영상을 찾을 수 있는 넓은 범위 -> 조금 좁은 범위 -> 조금 더 좁은 범위 -> 그 중 첫 번째 영상 -> 그 url로 영상을 재생하는 함수 작성 (-> 그러면 다시 CORS 에러...?)
이런 식으로 over-fetching 데이터를 가져와야만 했다.
$ npm install react-youtube
import YouTube from 'react-youtube';
Youtube iframe player API를 리액트 컴포넌트 환경에 만들어진 유튜브 공식 모듈이 있었다.
이 역시 자세한 내용은 깃허브에서 확인할 수 있다.
조금 더 내가 원하는 대로 간단하게 동작하지 않을까 해서 모듈 사용하게 됐다.
server말고 client에서 직접 <Youtube />
컴포넌트를 사용하면 돼서 Youtube API를 가져오는 과정이 비교적 간단해지긴 했다.
그리고 iframeClassName
프로퍼티를 설정해서 iframe에도 css를 적용할 수 있어서 좋다!
문제점
하지만, 이 역시 데이터 뽑아내는 과정이 1번과 다를 바 없어서 내가 구현하고 싶은 상황에 fit하지 않다고 판단했다.
더 좋은 방법이 있을 것 같았다.
그래도 해놓은 게 아까워서 다른 컴포넌트에서 유튜브 동영상 목록을 활용하기 위해 일단 keep해놨다.
$ npm install react-player
동영상 url을 설정하여 재생에 초점을 맞춘 모듈이 있었다.
물론 유튜브 url도 지원한다!
깃허브를 보고 요구에 맞는 ReactPlayer 컴포넌트를 import할 수 있다.
나는 ReactPlayer를 lazy load하기 위해 import ReactPlayer from 'react-player/lazy';
해왔다.
공식데모페이지에서 미리보기가 가능해서 좋다!
<ReactPlayer className="react-player" url='https://www.youtube.com/watch?v=동영상ID'
playing muted loop config={{youtube: {
playerVars: { controls: 0, start:시작시간 }
}}}/>
이렇게 유튜브 iframe player 매개변수도 사용할 수 있다.
개발자도구에서 요소를 확인해보니 enablejsapi
, origin
설정을 하지 않아도 자동으로 설정된다.
그리고 CORS 에러가 발생하지 않는다!
문제점은 아니고 특이사항
ReactPlayer 컴포넌트의 root는 div 요소이고, 내가 설정한 프로퍼티를 통해 하위에 iframe 요소가 생성된다.
iframeClassName
과 같은 프로퍼티가 없어서 iframe에 css 적용하기가 비교적 직관적이지 않다.
개발자도구에서 iframe 요소를 긁어오면 모듈 없이 사용 가능하지 않을까 생각이 들었다.
iframe 요소에 직접 css를 적용할 수도 있고 이게 더 좋을 것 같다고 판단했다.
//allow
accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture;
//src 링크에 포함된 요소들
autoplay=1
mute=1
controls=0
start=18
/*이 위에는 내가 설정한 매개변수다*/
origin=http://localhost:3000 //enavblejsapi와 함께 쓰인다
playsinline=1 //iOS의 HTML5 플레이어에서 동영상을 인라인으로 재생
showinfo=0 //지원 중단되었으므로 삭제
rel=0 //관련 동영상 표시 여부
iv_load_policy=3 //동영상 특수효과 표시여부
modestbranding=1 //컨트롤바에 YouTube 로고 표시여부
enablejsapi=1 //IFrame 또는 JavaScript Player API 호출을 통해 플레이어가 제어
자세한 매개변수 소개는 공식문서에서 볼 수 있다.
문제점
자동재생이 안 된다...!
ReactPlayer 컴포넌트에서는 자동 재생이 잘 되는데, 저거만 똑 떼어오면 안되나 싶다.
ReactPlayer 태그에 바로 width='100%' height='100%'
프로퍼티를 적용해주면 원하는 대로 화면에 꽉 찬 영상이 보인다.
개발자 도구를 확인해 보니 div 요소에 아래와 같이 inline style이 적용돼 있었다.
<div class="video" style="width: 100%; height: 100%;">
<div style="width: 100%; height: 100%;">
<iframe .... /></iframe>
</div>
</div>
iframe에서는
https://www.youtube-nocookie.com/embed/동영상id
또는
https://www.youtube.com/embed/동영상id
와 같이 embed로 설정해 주어야 한다.
유튜브 공유할 때 확인할 수 있는 uri다.
안 그러면 X-Frame-Options 에러가 발생한다.
ReactPlayer에서는
위 uri도 가능하고,
https://www.youtube.com/watch?v=동영상id
와 같이 유튜브 스트리밍할 때 확인할 수 있는 uri로 설정해도 된다.
나는 css 적용도 잘 되고, 플레이어로써 기능도 원하는 대로 입혀지는, 그리고 간편한 react-player
를 사용하기로 했다.
react-youtube
는 그동안 많이 공부해놨으니 다른 컴포넌트에서 활용해서 앱에 꼭 쓸 거다.
혹시 애초에 localhost:3000에서 쿠키를 삭제하지 않아서 발생한 에러였을까 싶기도 하지만
돌고 돌아 많이 배울 수 있었던 시도였다!!
나 같은 경우는 검색해도 딱 들어맞는 정보가 잘 나오지 않았는데
누군가에게 도움이 되길 바라면서 긴 글을 마친다.
iframe API
https://developers.google.com/youtube/iframe_api_reference
Youtube data API
https://developers.google.com/youtube/v3/docs/videos
도움 되는 블로그 글
https://mslilsunshine.tistory.com/99