개발공작소
article thumbnail
728x90

이전글에 이어서 목록에서 썸네일을 클릭했을 때, 실제 동영상을 플레이 해보자.

 

[연습장] Youtube Data API를 통한 유튜브 동영상 리스트를 만들어 보자. (3) API를 통해 가져 온 데이터

이전글에서 fetch함수를 통해 데이터를 가져왔다. 이제 그 데이터를 화면에 뿌려주도록 하자 저번에도 말했듯이, 받아온 데이터를 더미데이터로 만들어서 사용 할 생각이다. 그냥 화면만 만드는

bongra.tistory.com

우리가 유튜브 페이지에서 썸네일을 클릭했을 때, 실제로 API를 통해 데이터를 가져오는 것과 같이

우리도 썸네일을 클릭했을 때 API요청을 하는 기능을 구현해야 한다.

 

아래를 보면 실제 유튜브에서 썸네일을 클릭했을 시, URL + id값을 통해 동영상을 찾고 있는 것을 볼 수 있다.

개발자가 아닌 일반인을 위해 유튜브에서 썸네일을 클릭하는 것만으로 API요청을 하도록 기능을 구현하였기에

가능한 것이다. ( API 글 참조 )

 

 

 

이미 이전에 나는 API통신을 통해 동영상 목록을 가져 왔고 거기에 id값도 포함되어 있다.

 

videoId

 

유튜브 URL에 저 videoId를 파라메터로 보내주면, 실제 해당 동영상을 재생 할 수 있는 페이지로 이동한다. 

대충 구조가 이해 되었으니, 실제로 썸네일 클릭시 동영상이 재생될 수 있는 기능을 구현 해보도록 하자.

 

 

 

동영상 재생 기능 구현

============================================================================

 

나는 따로 페이지 이동은 하지 않고 그냥 팝업으로 띄워보도록 하겠다. Youtube 동영상 API는

iframe태그로 동영상 플레이어를 지원하는데, 나는 iframe을 안쓰고 그냥 div 팝업을 이용해 동영상을 표출하려 한다.

( 그냥 iframe이 싫어서.. )

 

--이번 글의 핵심 ( 동영상 플레이어 로드 함 )
<div class=video-container style="TEXT-ALIGN: center">
    <object type="text/html" width="1000" height="500" data="//www.youtube.com/embed/[비디오id]?rel=0" allowFullScreen/>
</div>

 

결과화면..

 

이런 식으로 모달을 통해 동영상 플레이어를 실행하려고 한다. 근데, 구현하다보니 뭔가 잘못 된 것을 느낌..

목록에 있는 것 중에 videoId가 없는 데이터가 있었다. 그래서 찾아보니, API통신시, 파라메터로 받는 type이
3가지 있는데,

 

  • channel
  • playlist
  • video

나는 아무것도 설정을 안해줘서, 저 3개를 같이 가져온 것이었다.. 내가 필요한 건 video인데.. 그래서 다시

URL을 아래와 같이 바꿔, 비동기 통신을 해주었다..

 

-- type=video 추가
newUrl = url + '?part=snippet&q=kpop+music&type=video&key=' + key;

 

그렇게 다시 가져오니, 제대로 동영상만 가져왔다.. 채널이나, 플레이리스트는 빼고..

 

 

그렇게 새로 가져온 동영상 목록을 통해 모달을 구현하는 코드는 아래와 같다. 

모달은 videoPop.js라는 파일에 새로 컴포넌트를 생성해주었다.

 

 

videoPop.js

export default{
	template : `
    <div class="modal" tabindex="-1" style="display:block" v-show="isVisible">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Modal title</h5>
                    // [닫기] 버튼 누르면 thisHide 함수 호출
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" @click="thisHide()"></button>
                </div>
                <div class="modal-body">
                    <div class=video-container style="TEXT-ALIGN: center">
                        <object type="text/html" width="100%" height="500" :data="url" allowFullScreen/>
                    </div>
                </div>
            </div>
        </div>
    </div>
	`,
    data () {
        return {
            url : '',
            isVisible : false
        }
    },
    methods : {
        thisHide () {
            this.isVisible = false;
        }
    }
}

 

실제 동영상 플레이어가 노출되는 <div>태그안에 <object>를 두고, data에 데이터를 바인딩하여, url을 넣어주고 있다.

 

 

youList.js

const url = 'https://www.googleapis.com/youtube/v3/search';
const key = 'AIzaSyBoB2booooooooooo--9pEUOj5Nfo'

import dummyData from './data.js';
import videoPop from './videoPop.js'; // 모달 컴포넌트 import

const video_pop = videoPop;

export default{
    components : { 
        'video_pop' : video_pop // 모달 컴포넌트를 지역 컴포넌트로 등록함
    },
	template : `
    <main>
        <section class="py-5 text-center container">
        <div class="row py-lg-5">
            <div class="col-lg-6 col-md-8 mx-auto">
            <h1 class="fw-light">Album example</h1>
            <p class="lead text-muted">Something short and leading about the collection below—its contents, the creator, etc. Make it short and sweet, but not too short so folks don’t simply skip over it entirely.</p>
            <p>
                <a href="#" class="btn btn-primary my-2">Main call to action</a>
                <a href="#" class="btn btn-secondary my-2">Secondary action</a>
            </p>
            </div>
        </div>
        </section>
        <div class="album py-5 bg-light">
            <div class="container">
                <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
                    <div class="col" v-for="item in videoList">
                    	// 동영상 클릭시 loadVideo 함수 호출
                        <div class="card shadow-sm" @click="loadVideo(item)">
                            <img class="imageStyle" :src="item.snippet.thumbnails.high.url" style="width:100%; height:300px;">
                            <div class="card-body">
                                <h5 class="card-text" v-text="loadTxt(item.snippet.title,'title')"></h5>
                                <div class="d-flex justify-content-between align-items-center">
                                <small class="text-muted" v-text="loadTxt(item.snippet.publishedAt,'date')"></small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <video_pop></video_pop> // 모달 컴포넌트 넣음
        </div>
    </main>
	`,
    data () {
        return {
            videoList : {}
        }
    },
    mounted () {
        //this.getYoutubeList();
        this.videoList = dummyData.items;
    },
	methods : {
		getYoutubeList () {
             let newUrl = '';
             newUrl = url + '?part=snippet&q=kpop+music&type=video&key=' + key;
             let loadYoutubeList = fetch(newUrl, {
                 method : 'GET',
             }).then(res => res.json()).then((res2)=>{
                 console.log(res2);
             })
		},
        loadTxt (data, type) {

            if(type =='title' && data.length>30){
                return data.slice(0,30) + '....';
            }else if(type == 'date'){
                return data.slice(0,10);
            }else{
                return data;
            }
            
        },
        loadVideo (item) {
        	// url 세팅 
            let url = '//www.youtube.com/embed/'+item.id.videoId+'?rel=0';
            this.$children[0]._data.url = url;
            // 모달이 보이도록 isVisible을 true로 치환
            this.$children[0]._data.isVisible = true;
        }
	}
}

 

 

이렇게 하고, 동영상을 클릭하면 아래와 같이 모달이 뜨면서 동영상이 제대로 재생되는 것을 확인 할 수 있다.

 

728x90
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!