01
26

1. 아래 코드를 </head> 위에 넣는다.

youtubeVideoKey는 반드시 있어야하고(기본값 그대로 둘 것을 권장, 다른 비디오에서 가져와도 됨),
youtubePlayListKey는 유튜브 재생목록 URL에서 playlist?list= 라는 키워드 바로 뒤에 오는 걸 복사해오면 된다.

<script>
//////////////////////////////////////////////////////////////////////
//                      BLOG BGM With Youtube 
//                   BY. https://d-dl.tistory.com/
//////////////////////////////////////////////////////////////////////

// [  SETTING  ]

const youtubeVideoKey = "cfTLvQ9TZhg";
const youtubePlayListKey = "PLSaAi5XOwA7O1eDCn1lMZ4L1YGNZwXvvu";
const URLChange = true;
const setShuffle = true;
const volumeUpDownValue = 10; // 0~100
const config = {
    'loop': 1,
    'autoplay': 1,
    'controls': 1,
    'disablekb': 1,
    'enablejsapi': 1,
    'iv_load_policy': 3,
	'origin': document.location.origin
};

//////////////////////////////////////////////////////////////////////

// [  BODY  ]

let YTplayer = null;

window.addEventListener('DOMContentLoaded', (event) => {
	console.clear();
	if (parent[0].name !== '') return;

	let docIframe = document.createElement("iframe");
	docIframe.style.cssText = `width: 100vw; height: 100vh; overflow: auto; border: 0; margin: 0; position: absolute;`;
	docIframe.name = "MAIN";
	docIframe.id = "BGM_DOC_IFRAME";
	docIframe.src = document.location;
	docIframe.addEventListener("load", function(e) {
		const iframePath = docIframe.contentDocument.location.pathname;
		if (URLChange && document.location.pathname !== iframePath){
			history.replaceState(null, null, iframePath);
		}
	});

	let musicDiv = document.createElement("div");
	musicDiv.name = "MUSIC";
	musicDiv.id = "Youtube_Music_Iframe";

	document.body.style.overflow = "hidden";
	document.body.innerHTML = "";
	document.body.prepend(docIframe);
	document.body.prepend(musicDiv);

	let tag = document.createElement('script');
	tag.src = "https://www.youtube.com/iframe_api";
	var firstScriptTag = document.getElementsByTagName('script')[0];
	firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});

function onYouTubeIframeAPIReady() {
    YTplayer = new YT.Player('Youtube_Music_Iframe', {
        videoId: youtubeVideoKey,
        playerVars: config,
        height: '0',
        width: '0',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange,
			'onError': onPlayerError
        }
    });
}

let listSet = false;
function onPlayerReady(event) {
	if (!listSet && youtubePlayListKey !== null) {
        YTplayer.loadPlaylist({
			list:youtubePlayListKey,
			listType:'playlist',
			index:0,
			startSeconds:0,
			suggestedQuality:'small'
			});
		YTplayer.setShuffle(setShuffle);
		listSet = true;
    }
    event.target.playVideo();
}

function onPlayerStateChange(event) {
	if (event.data == YT.PlayerState.ENDED) {
		if (listSet)
			YTplayer.nextVideo();
		else
			YTplayer.playVideo();
    }
}

function onPlayerError(event) {
	console.error(event.data);
}

function receiveBGMMessage(event)
{
	let state = event.data.BGM;
	if (!state) return;
	switch (state.toString().toLowerCase()) {
		case 'play':
			YTplayer.playVideo();
			break;
		case 'pause':
			YTplayer.pauseVideo();
			break;
		case 'previous':
			YTplayer.previousVideo();
			YTplayer.playVideo();
			break;
		case 'next':
			YTplayer.nextVideo();
			YTplayer.playVideo();
			break;
		case 'volumeup':
			YTplayer.setVolume(YTplayer.getVolume() + volumeUpDownValue);
			break;
		case 'volumedown':
			YTplayer.setVolume(YTplayer.getVolume() - volumeUpDownValue);
			break;
	}
	console.log(`%c♬ BGM : NOW "${state.toUpperCase()}"`, 'color:blue');
}
addEventListener("message", receiveBGMMessage, false);
</script>

 

2. BODY 태그 내부에 아래 코드를 넣어준다.

<!-- IN HTML Button -->

<button onclick="parent.postMessage({BGM:'play'}, '*')">재생</button>
<button onclick="parent.postMessage({BGM:'pause'}, '*')">정지</button>
<button onclick="parent.postMessage({BGM:'previous'}, '*')">이전</button>
<button onclick="parent.postMessage({BGM:'next'}, '*')">다음</button>
<button onclick="parent.postMessage({BGM:'volumeup'}, '*')">볼륨업</button>
<button onclick="parent.postMessage({BGM:'volumedown'}, '*')">볼륨다운</button>

 

3. button들을 눌러 정상 작동을 확인한다.

 

 

이 코드를 썼을 때 장점은

  1. Iframe을 이용한 눈속임이지만 URL이 자동으로 바뀐다.
  2. 추가는 안했지만 유튜브 API를 대다수 쓸 수 있을 듯.
  3. 블로그 내에서 페이지 이동을 하더라도 노래가 끊기지 않는다.
  4. 예제에선 button으로 넣었지만 저 onclick 요소만 그대로 복사하면 다른 태그에도 붙일 수 있다. 즉, 꾸미기 쉽다.

 

단점은

  1. URL 자동 바뀜이 약간 늦다.
  2. target="_blank"가 아닌 타 사이트로 이동하면 그대로 작동할 듯...?
  3. 모바일 작동 안할 듯...? (테스트X)

 

 

리액트 공부하다 문의받았던 게 생각나서 시작했는데, 몇몇 요소가 헷갈리기도 했고 자동재생 문제로 삽질하다 생각보다 오래 걸렸다.

크롬 정책 때문에 이제 BGM 자동 재생은 무조건 불가능하고, 사용자가 한 번 이상 클릭해야 작동하는 모양이다. setTimeout 같은 거로 속임수를 써보려그랬는데도 다 막혀있었다... 아쉽긴 하지만 사용자 웹 환경 개선/데이터 소비량 축소를 위해서라고 하니 반박할 거리는 없는 듯.

여기서 더 기능 추가/오류 수정을 할 수 있을진 모르겠지만 제보받으면 추가 예정.

 


참고 문서

https://developers.google.com/youtube/iframe_api_reference

 

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

Embed a YouTube player in your application.

developers.google.com

 

COMMENT