HTMLのvideo要素で動画フレームをサムネイル画像として設定する方法



HTMLのvideo要素では、poster属性を利用することで動画再生前のサムネイル画像を設定することができますが、読み込む動画のフレームをサムネイル画像とすることもできます。

サムネイル画像を準備するのが大変な場合や、動画内でサムネイルとして利用できそうなフレームがある場合には、画像の準備の手間も省けるので、手軽に動画コンテンツをWebページに利用していくことができるでしょう。

今回ご紹介する方法では、HTMLでの記述だけで完結できることもあれば、JavaScriptでコントロールする必要が出てくる場合もあります。

ここでは、HTMLのvideo要素で動画フレームをサムネイル画像として設定する方法について、JavaScriptでの調整も含めてご紹介します。

通常のvideo要素のサムネイル画像の設定


まずはvideo要素の基本的な機能として、poster属性を指定して動画再生前のサムネイル画像を設定します。

poster属性は、動画の読み込みなど再生準備の時や、読み込みが失敗して動画が表示されない場合に、代替画像として表示するために指定しますが、アクセス時に自動再生(autoplay muted)ではない時の最初の停止状態でのサムネイル画像として適用されます。

HTML

<video controls poster="video/thumbnail.jpg">
  <source src="video/sample.mp4" type='video/mp4'>
</video>


こだわりのあるサムネイル画像を設定する場合は、画像編集ツール等でサムネイル画像を頑張って作成する必要があります。

もし動画の再生時間のフレームがそのままサムネイル画像として利用できそうな場合は、自分で画像を準備する必要はなく、動画のフレームをサムネイル画像とすることができます。

動画のフレームをサムネイル画像として設定する


src属性に指定している動画の読み込みで、ファイル名の末尾に「#t=0.1」といったパラメータを追加することで、設定した再生時間のフレームをサムネイル画像とすることができます。
「#t=0.1」の場合は、再生開始すぐの最初のフレーム画像となります。

以下、パラメータを追加したサンプルになります。

HTML

<video controls>
  <source src="video/sample.mp4#t=0.1" type='video/mp4'>
</video>



パラメータの追加だけで再生時間のフレームをサムネイル画像とすることができるので、かなり手軽にできるかなと思います。

ただここで問題なのが、10秒「#t=10」や30秒「#t=30」のフレームを指定した場合です。
この場合は、動画の再生ボタンを選択すると、10秒や30秒から動画が始まってしまい、最初から観ることができません。

この問題はJavaScriptでコントロールすることができます。

動画を最初から再生できるようにする


JavaScriptではインターフェイスのメソッドが用意されており、video要素では動画の再生状況を把握することができます。
動画の再生状況に合わせてプログラムを作ることで、動画の再生をコントロールすることができます。

ではまず、HTMLから見ていきます。
例として、再生時間の22秒の部分「#t=22」のフレームをサムネイル画像とします。

HTML

<video controls>
  <source src="video/sample.mp4#t=22" type='video/mp4'>
</video>


ここまでは、先ほどのパラメータの追加の内容です。

続いてはJavaScriptです。
まず初めに、「document.querySelector(“video”);」でvideo要素を取得して、変数または定数に格納します。
サンプルではconst定数「video」に格納しました。
そして、videoオブジェクトに対してaddEventListenerメソッドで、特定のイベントが配信されるたびに呼び出される関数の処理を行う流れでプログラムを作ります。

以下、サンプルコードになります。

JavaScript

const video = document.querySelector("video");

video.addEventListener("playing", (event) => {
  video.currentTime = 0;
}, { once: true });


videoオブジェクトに対してaddEventListenerメソッドを使い、引数にはplayingイベントとし、イベントを受け取って関数を定義します。
関数内の処理では、videoオブジェクトに対し「currentTime = 0」として、動画が最初の0秒から再生されるようにします。

そしてこのプログラムの肝は、addEventListenerメソッドのonceオプションを設定することです。
再生中はイベントリスナーが呼び出され続けるので常にcurrentTimeが0になります。そうなると再生ボタンを選択して動画を最初から再生し始めても、再生時間を0から進めることができません。
onceオプションをtrueとすることで、イベントリスナーを1度だけ実行するようにできます。これにより再生ボタンを選択したら1度だけ再生時間を0として、動画の最初から再生時間を進めて流すことができます。

最後に


ファーストビューで見える位置に動画コンテンツがある場合は、動画のフレームの読み込みに少し時間がかかるので、パフォーマンスを考えるとposter属性の設定は必要になるでしょう。
ちなみにWebP形式の画像も扱えるので、なるべくファイルサイズの小さい画像を設定することをおすすめします。

<video controls poster="video/thumbnail.webp">
  <source src="video/sample.mp4#t=22" type='video/mp4'>
</video>


上記のHTMLのように、poster属性と動画ファイルの末尾のパラメータと両方設定した場合は、動画のフレームが読み込まれれば動画フレームが優先されます。

HTMLのvideo要素でサムネイル画像の設定方法は複数ありますが、もしパラメータを追加で最初意外の再生時間の動画フレームをサムネイル画像として利用する場合は、JavaScriptでコントロールするようにしましょう。
addEventListenerメソッドを使ってplayingイベントで再生時間を0とする処理を実行するように、そしてonceオプションをtrueとして1度だけ実行するようにしてください。