よくあるループ手法の欠点
YoutubeをWebサイトに埋め込む時に1つの動画をループさせる方法として、
URLにloop=1&playlist=xxx
を入れる方法がよく紹介されています。
<iframe id="movie-iframe" width="1280" height="320"
src="https://www.youtube.com/embed/M7lc1UVf-VE?loop=1&autoplay=1&playlist=M7lc1UVf-VE"
frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
これには3つの欠点があります。
- ループするときに一瞬読みこみアニメーションが入る
- ループした後にYoutubeアイコンが一定時間表示される
- 同じ動画を何度もダウンロードするため通信量が多い
動画の再生が終わったら動画の初めにシーク
これらを解消するために、Youtube IFrame Player APIを用います。
動画の再生が終わったら動画の初めにシークするという手法をとったところ、通信量が改善されただけでなく、ループ時の読み込みもなくなり、マウスホバーしない限りYoutubeアイコンも表示されなくなりました。
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('movie-player', {
height: '720',
width: '1280',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
controls: 0, //再生ボタンとか出さない
showinfo: 0, //動画名とか出さない
disablekb: 1, //ショートカットキー無効
rel: 0 //関連動画出さない
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
event.target.mute();
}
//ココまではほぼサンプルと同じ
var loopCount = 0;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {//動画が停止したら
if(loopCount < 20) {//ループ上限
event.target.seekTo(0,true);//動画の初めにシーク
event.target.playVideo();//動画を再生
loopCount++;
}
}
}
ついでにループ上限を設けることができました。今回は20回に定めています。
実験
従来の方法と今回の方法で通信量を比較してみましょう。
ある10秒の動画を2つの方法で10回再生し、Chromeの開発者ツールで計測した結果、こうなりました。
左が従来の方法で、右が今回の方法です。
ページの他の要素に関する通信(100KB程度)も含めた通信量です。
さらに実は従来の方法の方は間違えて3回ほど多く再生しています。
それらを考えても10倍程度の違いがあることが分かりました。
注意点
1つの動画をループ再生する場合にのみ使える方法です。
再生する動画が長い場合はキャッシュされない部分が出来るため、それほど効果が現れないだろうと予想されます。