動画実装のベストプラクティス2023
videoタグで動画を実装する時のベストプラクティス(たぶん)2023。
HTMLはこんな感じで、JavaScriptを使用してvideoタグを生成し挿入するやり方です。
代替画像や動画が始まったかときを監視するので、videoタグの生成自体もJavaScriptで行います。
<section class="home-kv"></section>
const root = './';
const playVideo = {
kv : document.querySelector('.home-kv'),
sourcePc : root + 'assets/video/pv-pc.mp4',
sourceSp : root + 'assets/video/pv-sp.mp4',
img : root + 'assets/img/home/kv_bg.jpg',
videoClass: 'home-kv__video',
imgClass : 'home-kv__bg',
init: function(){
const _this = playVideo;
if( document.querySelector('.' + _this.videoClass) ){
return false;
}
_this.setVariable();
_this.createVideo();
_this.onPlaying();
},
setVariable: function(){
const _this = playVideo;
/* ---------- sourse ---------- */
if( navigator.userAgent.match(/(iPhone|Android)/) ){
_this.source = _this.sourceSp;
} else{
_this.source = _this.sourcePc;
}
},
createVideo: function(){
const _this = playVideo;
const videoTag = '<video muted webkit-playsinline playsinline loop preload="auto" type="video/mp4" src="' + _this.source + '" class="c-objectfit-video '+ _this.videoClass +'"></video>';
_this.kv.insertAdjacentHTML('beforeend', videoTag );
_this.video = document.querySelector('.' + _this.videoClass);
/* ---------- 低電力モードなら画像に代替 ---------- */
_this.video.play()
.then(() => {
})
.catch((error) => {
const img = '<img src="'+ _this.img +'" alt="" decoding="async" class="c-objectfit -cover '+ _this.imgClass +'">';
_this.kv.insertAdjacentHTML('beforeend', img );
_this.kv.removeChild( _this.video );
_this.kv.classList.add('type-img');
});
},
onPlaying: function(){
const _this = playVideo;
/* ---------- playing ---------- */
const onPlaying = function(){
_this.kv.classList.add('is-shown');
_this.video.classList.add('is-shown');
_this.video.removeEventListener('playing',onPlaying);
}
_this.video.addEventListener('playing',onPlaying);
}
}
window.addEventListener('DOMContentLoaded',function(){
playVideo.init();
});
ポイント1: userAgentを使用して動画を振り分ける
パフォーマンスや再生品質の向上の為、閲覧環境によって、適切な動画を提供することが重要です。
JavaScriptのuserAgentを使って、閲覧者のデバイスやブラウザ情報を取得し、適切な動画ファイルを振り分けます。
setVariable: function(){
const _this = playVideo;
/* ---------- sourse ---------- */
if( navigator.userAgent.match(/(iPhone|Android)/) ){
_this.source = _this.sourceSp;
} else{
_this.source = _this.sourcePc;
}
},
ポイント2: playingイベントを利用して動画に開始クラスを付与する
動画の再生を開始した時に特定のクラスを追加することで、カスタムスタイルを適用したり、アニメーションを開始したりすることができます。
playingイベントを監視し、動画が再生された瞬間に開始クラスを付与する方法が効果的です。
onPlaying: function(){
const _this = playVideo;
/* ---------- playing ---------- */
const onPlaying = function(){
_this.kv.classList.add('is-shown');
_this.video.classList.add('is-shown');
_this.video.removeEventListener('playing',onPlaying);
}
_this.video.addEventListener('playing',onPlaying);
}
ポイント3: 自動再生がブロックされる場合の処理
iPhoneの低電力モードなどの状況では、動画の自動再生がブロックされることがあります。
その場合、再生アイコンが中央に表示され不恰好です。
この問題を回避するために、video.play().catch((error) => {のようなコードを使用して、動画が再生されない場合にはvideoタグを削除し、代替画像を表示するようにしています。
/* ---------- 低電力モードなら画像に代替 ---------- */
_this.video.play()
.then(() => {
})
.catch((error) => {
const img = '<img src="'+ _this.img +'" alt="" decoding="async" class="c-objectfit -cover '+ _this.imgClass +'">';
_this.kv.insertAdjacentHTML('beforeend', img );
_this.kv.removeChild( _this.video );
_this.kv.classList.add('type-img');
});