HTML5手習い

Videoのサムネイル取得

全333コースを10日間無料で

ぜひご覧ください。

無料で視聴する すべての加入プランを見る
または
loadedmetadata,seekedといったイベントとcurrentTimeプロパティを組み合わせて、動画ファイルの各フレームの画像にアクセスする方法について学びます。
講師:
14:42

字幕

このレッスンでは HTML5 で 動画に含まれるフレームを 画像に変換する方法について説明します HTML5 のビデオオブジェクトそのものには 各フレームを画像データに変換するという 機能はありません しかし Canvas とビデオオブジェクトを 組み合わせることによって これが可能になります そのやり方は先ずサムネイルを取得したい フレームに動画をシークします そしてシークができたら Canvas に drawImage メソッドを使って ビデオオブジェクトを描画します ビデオオブジェクトは image オブジェクト のように扱うことができるので drawImage の第1パラメータに そのまま渡すことが可能です そして Canvas にビデオのフレームを 描画できたら Canvas の toDataURL メソッドを使って Canvas を画像に変換します これによって動画に含まれる各フレームを 画像に変換することができるのです 動画オブジェクトで 再生中のフレームを指定するには オブジェクトの currentTime プロパティを 使います currentTime プロパティを代入すれば その時刻に動画がシークします シーク可能な範囲は seekable プロパティの start メソッドと end メソッドを使用します seekable プロパティは timeRanges という データ型をとって そのプロパティの中に 複数の時間の範囲が含まれています これに index として 0 を渡すことで その動画の開始時刻 それから終了時刻 最後の時間が取得できます ではコードを書いていきましょう まずアセットの canvas_basic.html と sample.mp4 を用意して下さい テキストエディタで canvas_basic.html を 開いて下さい それから今回作るアプリケーションは ローカルファイルをそのまま ダブルクリックして実行すると Cross-Origin ポリシーに抵触してしまう為 Node を使って HTTP サーバー上から 読み込ませる必要があります Cross-Origin ポリシーに抵触する部分は Canvas を画像データに変換する toDataURL を使うタイミングです Canvas の基本的なポリシーとして 外部サイトから取得した 画像や動画といったソースを Canvas にそのまま描画することは できるのですが そのソースの具体的なピクセル値を 取得することは禁止されています その為 今回のアプリケーションでは Same-Origin ポリシーを 考慮する必要があるのです それでは canvas_basic.html がある ファイルディレクトリで HTTP サーバーを起動しましょう http-server. ですね このディレクトリには canvas_basic.html と sample.mp4 があります これで HTTP サーバーは 起動できましたので アクセスしてみましょう localhost:8080 canvas_basic.html これで準備は整いました ではコードを書いていきましょう 先ずはビデオオブジェクトを dom に追加しましょう video の id イコール video あとで JavaScript から参照する為 id をふっておきます そして source は sample.mp4 です type は video/mp4 それから取得したサムネイルを表示する為のー div タグも用意しておきましょう id は thumbnails としておきます この div タグの中に 動画をデコードして得られた画像のデータを img 要素としてどんどん追加して いくことにしましょう 一旦リロードします このように動画が表示されました 今回動画の表示そのものは video 要素では行いませんので display none にしておきましょう video という id の要素を display none それから キャンバスも表示させる 必要はないので 同時に display none にしておきます canvas の id は sketch ですね これで OK です では次にキャンバス やビデオを dom として取得しましょう video は document getElementById の video それから canvas は getElementById の sketch それから Context オブジェクトも ついでに取得しておきましょう canvas の getContext 2d さてこの JavaScirpt が読み込まれて この script タグに到達した時点では おそらくまだビデオのデータそのものは ロードされていません そこでビデオのデータのロードを待つ為に イベントハンドラを使用しましょう ビデオオブジェクトの addEventListener ここでビデオ用の特別なイベントを使用します loadedmetadata です loaded meta data このイベントはその動画ファイルのメタデータ 例えば 解像度や どの程度の時間の長さがあるのか ― といったメタデータのロードを待ちます そしてメタデータがロードされた時点で このイベントが発火されます そしてこの中でサムネイルを生成したい 時間のポイントを配列に格納しましょう その時間のポイントを格納する配列は points という名前にします それからサムネイルを取得する個数も 変数に入れておきましょう その変数 n は 10 で初期化します これでループを回して変数に値を 格納していきます i が n より小さい場合は i ++ そして points の i に対して ここでビデオの seekable プロパティを使います seekable プロパティの end を 使うことによって そのビデオの一番最後の timestamp が 取得できます そこから video の seekable プロパティの start を使うことによって そのビデオの一番最初の timestamp が取得できます これによって この部分でそのビデオの総長 長さの合計が取得できます そしてその長さの合計を n で割って これに i を掛けることによって n 等分した各ポイントを points 変数の中に 格納しておくことができます それから video の currentTime プロパティを 設定することによって ビデオのサムネイルの 最初の時刻を設定しましょう そしてサムネイルを取得する為に もう一つ Event Listener を設定します video の addEventListener で 今度は seeked というイベントを使います このイベントはビデオオブジェクトが シークされた時に そのシークが完了されたタイミングで 呼び出されます この中でサムネイルに関する処理を記述すれば そのサムネイルのフレームのデータに アクセスすることができます このようにシークで 実際に currentTime を設定してから そのフレームが有効になるまで 時間差がありますので注意してください そしてこの中に画像の生成処理を書くのですが seeked イベントは二回同じ timestamp に 対して発火される場合があるので それに対して二度同じ処理を してしまうことを防ぐ為に prevTime という変数を使って もし prevTime が 現在時刻と異なるならば 処理を実行という形にします そして prevTime には毎回 seeked 発火時に currentTime を代入しておきます このようにすることによって 同じフレームに対する重複処理を 防ぐことが可能です それでは実際に画像のオブジェクトを 作成しましょう canvas のレンダリング context に対して drawImage で video をまず渡してやります 2番目と3番目のパラメータは 描画先の基点です そして3番目と4番目で描画先の幅と高さ scale 後の幅と高さですね canvas の width キャンバスサイズで ビデオをそのまま描画します キャンバスのサイズが今 300 × 300 になっていますが これだとアスペクト比が崩れてしまうので 例えば 720 掛ける 480 あるいはもっと小さめでもいいですね 640 掛ける 360 このくらいの大きさにしておきましょう これで img という変数に対して document createElement で 新しい dom オブジェクトを作成します dom オブジェクトの型は img 型です そしてそのソースに canvas の toDataURL を使って BASE64 エンコードされた画像のデータを ソース のプロパティに設定します そして最後に getElementById の thumbnails で 取得された div タグの中に appendChild で 今作成した画像オブジェクトを足してやります それから seeked が毎回発火されたたびに このように currentTime を変更してやります index を インクリメントして 新しい index を使って 次のポイントに currentTime を設定 そしてこの if で 繰り返しを制限します つまり index が n-1 よりも小さい場合まで currentTime の変更を実行ですね prevTime の代入も この外ではなく if の中に入れておきましょう この方が分かり易いですね さてこれでリロードしてみましょう 何かエラーがあるようです 丸カッコを閉じていませんでした canvas のスペルが間違っていますね canvas これでリロードすると 今度は index が定義されていない ポイントの現在位置を指す変数を 用意するのを忘れていました ポイントの現在位置を指す index という変数を ここの位置に記述しておきます そして再度リロードすると 今度はどうやらできたようです このように動画の中に含まれる各画像が 10 枚取り出せました このレッスンではビデオオブジェクトと Canvas を組み合わせて 動画に含まれるサムネイルを画像化する 方法について説明しました

HTML5手習い

このコースではHTML5 APIを中心に、HTML5でのプログラミングについて学びます。HTTPや文字コード、バイナリデータやアニメーションの原理など実際のアプリケーション開発で必要となる基本的な知識を学びます。HTML5 Canvasを中心として、Web APIとの通信やWebフォントなどWebプログラミングで必要な技術を習得します。

6時間01分 (44 ビデオ)
現在、カスタマーレビューはありません…
 
ソフトウェア・トピック
価格: 3,990
発売日:2015年04月22日

このコースは、「オンデマンド」でご利用可能であり、ダウンロードすることもオンラインで見ることもできます。

ダウンロードすると、オフラインでコースを使用し、豊富なインターフェースをフルに活用できます。複数のデバイスを使用したり、 一度に全コースをダウンロードしたくない場合は、アカントにログインして、ストリーミング・ビデオとしてコースのレッスンを視聴してください。

ビデオトレーニングをお楽しみいただけますように! お問い合わせは、cs-jp@lynda.com宛までご連絡ください。