본문 바로가기
jQuery, CSS, HTML

[jQuery + HTML + CSS] 오디오 플레이어 만들기 - 2

by 집탱구리 2020. 8. 12.
반응형

이전 포스팅 

[jQuery + HTML + CSS] 오디오 플레이어 만들기 - 1

[jQuery + HTML + CSS] 오디오 플레이어 만들기 - 0 

 

* 목차 *

1. youtube 링크 삽입 화면

2. 음원파일 삽입 화면

3. Youtube API

4. 오디오 플레이어 관련 js 함수

 

 

먼저 관리자 등록화면에 대해 설명하도록 하겠다.

관리자 화면에서는 음원과 유튜브 링크를 등록할 수 있다.

오디오 플레이어에 마우스 오버하면 생기는 툴박스에 등록 버튼이 생기도록 하였다.

재생이 시작되면 반복 재생되도록 설정 해놓았다.

 

1. youtube 링크 삽입

링크삽입 버튼을 클릭하면 youtube url을 삽입하는 팝업이 뜬다.

'링크삽입' 팝업창

youtube 영상의 주소창에 있는 url 또는 공유 url 삽입이 가능하다.

youtube 공유 팝업
팝업창에 url 삽입

적용하기 버튼을 클릭하면 팝업창이 닫히고

오디오 플레이어에 동영상 제목이 삽입되고 재생시간이 표기된다.

볼륨은 70으로 셋팅.

재생버튼을 클릭하면 재생시간이 시작되면서 로딩바가 작동한다.

 

2. 음원 파일 업로드

시스템 파일 선택창이 뜬다.

선택 가능한 파일이 지정되어있다. (*.mp3, *.opus, *.ogg, *oga, *.wav)

음원파일을 선택하면 링크삽입과 마찬가지로 음원파일의 제목과 재생시간이 표기된다.

파일 업로드 성공시 audio-player요소 안에 audio태그가 삽입된다.

<div id="audio-player">
	<audio loop="" id="bgm-audio-player">
    	<source src="../파일명.mp3">
    </audio>
</div>

 

 

3. Youtube API

유튜브 영상 컨트롤에 필요한 API가 있다.

iframe을 이용하여 유튜브를 삽입하고 해당 영상을 컨트롤 할 수 있는 API가 있는데

아래 링크에 자세히 나와있다.

developers.google.com/youtube/iframe_api_reference#Playback_controls

 

iframe 삽입에 대한 YouTube Player API 참조 문서  |  YouTube IFrame Player API

Embed a YouTube player in your application.

developers.google.com

developers.google.com/youtube/player_parameters?playerVersion=HTML5&hl=ko#Embedding_a_Player

 

YouTube 내장 플레이어 및 플레이어 매개변수  |  YouTube IFrame Player API

개요 이 문서에서는 애플리케이션에 YouTube 플레이어를 삽입하는 방법을 설명하고 YouTube 내장 플레이어에서 사용할 수 있는 매개변수를 정의합니다. IFrame URL에 매개변수를 추가하여 애플리케이

developers.google.com

onYouTubePlayerAPIReady 함수는 IFrame Player API 코드가 로드되면 자동으로 호출된다.

따라서 이름을 바꾸지 않고 그대로 사용한다.

 

// 유튜브 API iframe 생성
function onYouTubeIframeAPIReady() {
	// 오디오 플레이어 속성(재생버튼, 제목, 재생시간, 볼륨 등) 초기화
    audioPlayerInit();
    
    // 유튜브 동영상 아이디
    var youtube_id = $("#youtube-player").data('id');
    window.YT.ready(function(){
        youTubePlayer1 = new YT.Player('youtube-player', {
            videoId: youtube_id,
            width: '0',
            height: '0',
            playerVars: {
                width: 0,
                height: 0,
                rel: 0,             		// 추천영상 false
                autoplay: 0,         		// 자동재생 false
                controls: 0,         		// 컨트롤러 false
                showinfo: 1,
                loop: 1,             		// 반복재생 true
                playlist: youtube_id,  		// 단일 영상 반복재생을 위해 동일한 ID를 넣는다.
            },
            events: {
                'onReady': onPlayerReady, 			//로딩할때 이벤트 실행
                'onStateChange': onPlayerStateChange 	//플레이어 상태 변화시 이벤트실행
            }
        }); //youTubePlayer1셋팅
    });
}

 

onPlayerReady 함수는 유튜브 플레이어가 로딩될 때 실행되는데 이때 동영상의 정보를 추출해서

제목, 재생시간, 볼륨을 출력한다.

// 유튜브 플레이어 로딩
function onPlayerReady(event) {
    //로딩할때 실행될 동작을 작성한다.
    var audio_info = event.target.getVideoData();

	// 올바른 동영상일 경우
    if(audio_info.title != '') {
        BGM_TYPE = 'YOUTUBE';
        //togglePlay($(".audio-control-btn.btn-play"));
        $(".audio_modal_wrap").remove();
        // 제목 넣기
        $(".audio-title-wrap #audio-title").replaceWith('<marquee id="audio-title" behavior="scroll" direction="left" scrollamount="3">'+audio_info.title+'</marquee>');
        // 재생시간 출력
        maxTime = Math.floor(event.target.getDuration());
        var duration = setTimeFormat(maxTime);
        // 볼륨 설정
        youTubePlayer1.setVolume(70);
        $(".play-time.end").text(duration);
    } else {
    // 동영상 정보를 얻을 수 없을 경우
        $(".audio-title-wrap").empty().append('<span id="audio-title"> 제목</span>');
    }

}

onPlayerStateChange 함수는 플레이어에 변화가 있을 때 일어나는 이벤트에 따라 다른 이벤트를 실행 할 수 있다.

// 유튜브 플레이어 상태변화
function onPlayerStateChange(event) {
	
    if (event.data == YT.PlayerState.PLAYING) {
    	// 재생중
        startAudioTimer(); // 오디오 재생시 타이머 시작, 재생바 진행, 재생시간 시작
    } else if(event.data == YT.PlayerState.PAUSED) {
    	// 일시정지
        stopAudioTimer(); // 오디오 재생시 타이머 중지
    } else if (event.data == YT.PlayerState.ENDED) {
        // 중지
        togglePlay($(".audio-control-btn.btn-play"));	// 재생버튼 토글
        $(".play-time.start").text('00:00');	// 타이머 중지
        $(".play-time.end").text('00:00');
        $(".play-progress-bar").width(0);	// 재생바 초기화
    }
}

 

 

4. 오디오 플레이어 관련 js 함수

  • 오디오 플레이어 초기화
    Youtbe 링크 삽입 후 음원 파일로 바꾸거나 그반대일 경우
    또는 어떤 오류 상황에서 초기화가 필요한 경우를 위해 생성한 함수
    // 오디오 플레이어 초기화
    function audioPlayerInit(){
        // 공통사항 
    	// : 타이머중지, 재생버튼으로 초기화, 볼륨버튼 초기화, 재생시간 초기화
        stopAudioTimer();
        togglePlay($(".audio-control-btn.btn-pause"));
        togglePlay($(".audio-control-btn.btn-mute"));
        $(".play-time.start").text('00:00');
        $(".play-time.end").text('00:00');
        $(".play-progress-bar").width(0);
        $(".play-volume-slider").slider({'value' : '70'});
        
        if(BGM_TYPE == 'YOUTUBE'){
    		// youtube 링크 삽입일 경우 iframe을 지우고 div로 초기화
            $("#audio-player").remove();
            if($("#out_wrapper .bgm-wrap #youtube-player").length == 0){
                $('#out_wrapper .bgm-wrap').append('<div id="youtube-player"></div>');
            }
        } else {
        	// 음원 삽입일 경우 audio태그를 지우고 div로 초기화
            $("#youtube-player").remove();
            if($("#out_wrapper .bgm-wrap #audio-player").length == 0){
                $('#out_wrapper .bgm-wrap').append('<div id="audio-player"></div>');
            }
        }
    }



  • 재생 / 일시정지
    재생/일시정지 버튼 클릭시 해당 버튼의 아이콘 클래스에 따라 토글 되도록함
    // 재생버튼 토글
    function togglePlay(obj) {
        if(obj.hasClass('btn-play')){ 
        	// 재생 -> 일시정지
            obj.addClass('btn-pause');
            obj.removeClass('btn-play');
            obj.find('i').attr('class','fa fa-pause');
        } else if(obj.hasClass('btn-pause')){
        	// 일시정지 -> 재생
            obj.addClass('btn-play');
            obj.removeClass('btn-pause');
            obj.find('i').attr('class','fa fa-play');
        }
    }


  • 음소거 / 음소거 해제
    음소거버튼 클릭시 해당 아이콘 클래스에 따라 볼륨 음소거와 음소거 해제가 토글 되도록함
    // 음소거버튼 토글
    function toggleMute(obj) {
        if(obj.hasClass('btn-volume')) {
        	// 볼륨 -> 음소거
            obj.addClass('btn-mute');
            obj.removeClass('btn-volume');
            obj.find('i').attr('class','fa fa-volume-off');
        } else if(obj.hasClass('btn-mute')){
        	// 음소거 -> 볼륨
            obj.addClass('btn-volume');
            obj.removeClass('btn-mute');
            obj.find('i').attr('class','fa fa-volume-up');
        }
    }



  • 볼륨 조절
    jQuery slider를 사용하여 사용자가 볼륨을 조절 할 경우 BGM타입(유튜브 링크, 음원)에 따라 볼륨 설정 분기
    	// 음량조절
        $(document).on('mouseup', '.play-volume-slider', function(){
        	// jQuery slider
            $(".play-volume-slider").slider({
                slide:function(event,ui){
                    var volume = ui.value;
                    if(volume > 0){ // 볼륨 up
                        if(BGM_TYPE == 'YOUTUBE') {			// Youtube 링크 삽입
                            youTubePlayer1.unMute();
                            // youtube API 재생컨트롤러 사용
                            youTubePlayer1.setVolume(volume);
                        } else if(BGM_TYPE == 'AUDIO') {	// 음원 파일 삽입
                            var bgm_player = document.getElementById("bgm-audio-player");
                            volume = volume/100;
                            volume = volume.toFixed(1);
                            console.log(volume);
                            bgm_player.muted = false;
                            bgm_player.volume = volume;
                        }
                         // 음소거 아이콘 토글
                        toggleMute($(".audio-control-btn.btn-mute"));
                    } else {	// 음소거
                        if(BGM_TYPE == 'YOUTUBE') {				// Youtube 링크 삽입
                            youTubePlayer1.mute();	
                        } else if(BGM_TYPE == 'AUDIO') {		// 음원 파일 삽입
                            var bgm_player = document.getElementById("bgm-audio-player");
                            bgm_player.muted = true;
                        }
                        // 음소거 아이콘 토글
                        toggleMute($(".audio-control-btn.btn-volume"));
    
                    }
                }
            });
        });


  • 재생시간
    재생버튼을 클릭하면 재생시간이 초단위로 변경되며 배경음 진행상태가 progress bar로 표현된다.
    초단위 출력을 위해 setInterval을 사용한다.
    /* 오디오 재생시 인터벌 시작
       : 재생 로딩바 시작
       : 재생시간 포멧 변경 시작 */
    function startAudioTimer(){
        //플레이어가 재생중일때 실시간재생 시간을 초단위로 출력
        var progressBar = $(".play-progress-bar");
        var progress_val = 0;	// 재생 progress bar 값
        var playtime = 0;		// 재생 시간
        audioTimer = setInterval(function(){
            if(BGM_TYPE == 'YOUTUBE') {
            	// youtube 링크 삽입일 경우
                // 해당 동영상의 정보중 현재 재생시간을 가져온다.
                currentTime = Math.floor(youTubePlayer1.getCurrentTime());
                // 00:00의 형식으로 표기하기위해 포맷변경
                playtime = setTimeFormat(Math.floor(youTubePlayer1.getCurrentTime()));
            } else if(BGM_TYPE == 'AUDIO') {
            	// 음원파일 삽입일 경우
                var player = document.getElementById('bgm-audio-player');
                // audio 태그에서 현재 재생시간을 가져온다.
                currentTime = Math.round(player.currentTime);
                // 00:00의 형식으로 표기하기위해 포맷변경
                playtime = setTimeFormat(currentTime);
            }
            
            // 가져온 현재 재생시간을 progress bar에 표기하기위해 currentTime가공
            // 재생 완료를 100으로 잡고 현재 재생시간을 계산
            // 소수점 첫번째 자리까지 계산
            progress_val = (currentTime/maxTime)*100;
            progress_val = progress_val.toFixed(1);
            $(".play-time.start").text(playtime);
            progressBar.css('width', progress_val+"%");
        }, 1000);
    }

    일시정지를 클릭하면 재생시간이 멈추고 progress bar가 진행이 멈춘다.


    재생시간 포멧 변경
    // 재생시간 포멧변경
    function setTimeFormat(sec_time){
        var sec_num = parseInt(sec_time);
        var minutes = Math.floor(sec_num / 60);
        var seconds = sec_num - (minutes * 60);
    
        if (minutes < 10) {minutes = "0"+minutes;}
        if (seconds < 10) {seconds = "0"+seconds;}
    
        return minutes + ':' + seconds;
    }
  • // 오디오 정지시 인터벌 중지 function stopAudioTimer(){ clearInterval(audioTimer); $(".play-progress-bar").css('width',0); }

마치면서...


Youtube API가 로드되면 iframe이 자동으로 삽입되는데

음원 삽입으로 BGM을 바꾸고 싶을 때 iframe을 아예 삭제하지않으면 재생이 겹치는 경우가 발생 했다.

그래서 임의의 빈 <div>를 생성하고 BGM 타입에 따라 해당 <div>를비우고 태그를 삽입하였다.


크롬정책상 음소거된 자동재생만이 허용되어 재생버튼을 클릭해야 youtube 재생이 되도록 하였다.

그래서 재생버튼을 눌러야 onYouTubeIframeAPIReady가 로드되도록 하였고

이미 로드된 경우엔 영상을 재생하도록 하였다.

 

Youtube API 때문에 삽질 많이했다.

그래도 하면서 재미는 있었다.

클라이언트를 원망하지 않는다....

반응형

댓글