HTML5
HTML's video element is a tag used to embed and play videos on a web page.
video 要素
HTMLの video要素は、Webページに動画を表示し、再生するためのタグです。このタグを利用することで、ユーザーは動画の再生、停止、音量調整、シーク(早送り・巻き戻し)などの操作を直感的に行うことができます。video要素は、動画ファイルを埋め込むために特化して設計されており、画像を表示するための img要素と似た役割を果たしますが、動画専用の機能を持つ点で異なります。
HTMLの video要素には、以下のような属性を使用することができます。
- src
- 動画ファイルのURLを指定します。
- controls
- ユーザーが動画の再生・停止・シーク・音量調整などの操作をできるコントロールを表示します。
- autoplay
- ページが読み込まれたときに動画を自動的に再生します。
- loop
- 動画の再生が終了したら、再び最初から自動的に再生します。
- muted
- 初期状態で動画の音をミュートにします。
- poster
- 動画が読み込まれる前や再生が開始される前に表示される画像を指定します。
- preload
- 動画の読み込み方法を指定します。値は以下のいずれかです。
-
- auto
- 動画の全データを自動的にプリロードします。
- metadata
- 動画のメタデータのみをプリロードします(例: 動画の長さなど)。
- none
- プリロードを行いません。
- width
- 動画の表示幅をピクセル単位で指定します。
- height
- 動画の表示高さをピクセル単位で指定します。
- playsinline
- 動画をフルスクリーンモードではなく、インラインで再生するよう指示します(主にモバイルデバイスで使用)。
- crossorigin
- 他のドメインからリソースを読み込む際のクロスオリジンリクエストの設定を指定します。値は以下のいずれかです:
-
- anonymous
- 認証情報を送信せずにリソースをリクエストします。
- use-credentials
- 認証情報を含めてリソースをリクエストします。
- disableremoteplayback
- ビデオをリモートデバイスでの再生(例: Chromecast)を無効にします。
video要素の基本的な使い方
video要素の基本的な使い方は以下の通りです。このコードは、Webページ上に動画を埋め込み、再生、停止、音量調整などのコントロールを提供します。
HTML
<div class="videoPlace">
<video controls>
<source src="sample.mp4" type="video/mp4">
<p>お使いのブラウザはvideoタグに対応していません。</p>
</video>
</div>
CSS
div.videoPlace {
text-align: center;
}
video {
max-width: 96%;
height: auto;
margin-top: 1em;
}
もっと動画を見たい方はこちら >> Gravure Idol
- <video controls></video>
- video要素を定義し、コントロール(再生、停止、音量調整など)を有効にします。
- <source src="sample.mp4" type="video/mp4">
- 動画ファイルのソースを指定します。この例では、MP4形式の動画ファイルを指定しています。
- <p></p>
- ブラウザが video要素をサポートしていない場合に表示されるメッセージです。
- a要素を使って、動画をダウンロードできるようにしておくのもいいかもしれません。
- なお、この仕組みは、video要素に対応しているものの、ビデオファイルを読み取れなかったり、ビデオファイルの形式をサポートしていないなどの理由で、ビデオが再生されなかった場合のフォールバックコンテンツとしては機能しません。あくまでも、video要素を全くサポートしていないブラウザ向けのコンテンツとなることに留意してください。
動画の指定方法について
video要素で動画(sample.mp4)を指定する場合、src属性を使う方法とsource要素を使う方法があります。それぞれの違いとメリット、デメリットについて説明します。
src属性を使う方法
HTML
<video src="sample.mp4" controls>
<p>お使いのブラウザはvideoタグに対応していません。</p>
</video>
メリット
- シンプルで直感的
- コードが短く、初心者でも理解しやすい。
- 迅速な実装
- 1つの動画ファイルを指定するだけなので、すぐに実装できる。
デメリット
- 互換性の問題
- 異なるブラウザがサポートする動画フォーマットが異なるため、互換性が低い。例えば、MP4をサポートしないブラウザでは動画が再生されない可能性がある。
- フォールバックの欠如
- src属性のみでは複数のフォーマットを指定できず、ブラウザ間での互換性が確保しにくい。
source要素を使う方法
HTML
<video controls>
<source src="sample.mp4" type="video/mp4">
<source src="sample.webm" type="video/webm">
<p>お使いのブラウザはvideoタグに対応していません。</p>
</video>
メリット
- ブラウザ互換性の向上
- 複数のフォーマットを指定できるため、異なるブラウザでの再生互換性が高まる。例えば、MP4と WebMの両方を指定することで、ほとんどのブラウザで再生可能になる。
- 柔軟なフォールバック
- 一つのフォーマットがサポートされていない場合でも、他のフォーマットで再生できるため、ユーザー体験が向上する。
デメリット
- コードが複雑になる
- 複数の source要素を追加するため、コードが長くなり、初心者には少し理解しづらいかもしれない。
- 管理が煩雑
- 複数の動画ファイルを準備し、管理する必要があるため、制作と管理の手間が増える。
まとめ
- src属性は簡単で速い実装が可能ですが、ブラウザ互換性が低い。
- source要素はブラウザ互換性が高く、柔軟なフォールバックが可能ですが、コードが複雑になり、管理の手間が増える。
選択する方法は、使用するプロジェクトの要件や対象とするユーザーのブラウザ環境に応じて判断すると良いでしょう。
controls
controls属性は、ユーザーに動画の再生、停止、音量調整、シーク(時間を移動する)などの基本的な操作を可能にするためのコントロールを表示するために使用されます。video要素にこの属性を追加することで、ブラウザが自動的に標準のコントロールインターフェースを表示します。
HTML
<video src="sample.mp4" controls>
<p>お使いのブラウザはvideoタグに対応していません。</p>
</video>
この例では、controls属性が指定されているため、動画再生のコントロールが表示されます。
上記の「video要素の基本的な使い方」でのサンプル動画でも controls属性を指定しています。もし、controls属性がなかった場合は動画を再生することができなくなってしまいます。
HTML
<video src="sample.mp4">
<p>お使いのブラウザはvideoタグに対応していません。</p>
</video>
controls属性の詳細
表示されるコントロール
controls属性を指定すると、ブラウザは以下のようなコントロールを表示します。
- 再生/一時停止ボタン
- 動画の再生と一時停止を切り替えるボタン。
- シークバー
- 動画の再生位置を示し、ユーザーが特定の位置に移動できるバー。
- 音量コントロール
- 音量を調整するためのスライダーやボタン。
- ミュートボタン
- 音を消すためのボタン。
- 全画面表示ボタン
- 動画を全画面表示に切り替えるボタン。
属性の有無による違い
- あり(controls属性が指定されている場合)
-
- ユーザーが動画を操作するためのインターフェースが表示されます。
- ブラウザによって表示されるコントロールのデザインや機能に若干の違いがある場合があります。
- なし(controls属性が指定されていない場合)
-
- コントロールが表示されず、ユーザーは動画を再生することができません。ただし、JavaScriptを使用してカスタムコントロールを作成することも可能です。
メリット
- 使いやすさ
- ユーザーが直感的に動画を操作できる。
- 即時性
- コーディングの手間をかけずに、動画に基本的なコントロールを追加できる。
- 互換性
- ブラウザが提供する標準のコントロールは、ほとんどのデバイスで一貫して動作する。
デメリット
- カスタマイズの制限
- ブラウザ標準のコントロールはデザインや機能のカスタマイズが難しい。
- 一貫性の欠如
- ブラウザによってコントロールの外観や操作感が異なる場合がある。
autoplay
autoplay属性を使うと、ビデオ再生の準備ができ次第すぐにビデオが再生されます。
HTML
<video src="sample.mp4" controls autoplay>
<p>ご利用のブラウザでは再生出来ません。</p>
</video>
特に理由がない限りは、autoplay属性をセットしないことをお勧めします。
ビデオ再生の専用ページを別に用意し、元のページからリンクをたどることで再生が開始されるのであれば、自動再生は問題ないでしょう。しかし、例えば、ブログの記事にビデオを貼り付けた場合、いきなりビデオが再生されると、ユーザーによっては迷惑に感じることがあります。そのため、利用シーンを十分考慮して、コンテンツ属性の利用を検討するようにしましょう。
ポスター・フレーム
ポスター・フレームとは、ビデオ生成の準備ができる前に表示させたい画像を表します。ポスター・フレームには、基本的には、該当のビデオを表すようなイメージを使います。
video 要素には、poster コンテンツ属性が規定されており、このコンテンツ属性に画像ファイルの URL を指定しておくことで、ポスター・フレームをセットすることができます。
HTML
<video src="vdos/total_solar_eclipse.mp4" controls="controls" poster="poster.png">
<p>ご利用のブラウザでは再生出来ません。<a href="vdos/total_solar_eclipse.mp4" title="皆既日食動画">こちら</a>からダウンロードして下さい。</p>
</video>
通常は、ポスター・フレームは、ビデオ再生の準備が整う直前までしか表示されません。もちろん、poster コンテンツ属性で指定した画像のファイルのロードが完了するまでは何も表示されません。そのため、実際に目にできるのは、さほど長い時間ではありません。
しかし、video 要素はサポートしているけれども、指定のビデオ・データの形式には対応しておらず、該当のビデオが再生できないブラウザでは、ポスター・フレームが表示されることになります。このようなブラウザを利用しているユーザーのためにも、何かしら意味のあるイメージを用意するのが良いでしょう。
なお、HTML5 仕様では、ビデオ開始位置で停止している状態でもポスター・フレームを表示しても良いことになっていますが、実際に表示するかどうかは、ブラウザ・ベンダーに任されています。
ループ再生
loop コンテンツ属性を使うと、自動的にビデオを繰り返し再生します。このコンテンツ属性は論理属性です。
HTML
<video src="vdos/total_solar_eclipse.mp4" controls="controls" loop="loop">
<p>ご利用のブラウザでは再生出来ません。<a href="vdos/total_solar_eclipse.mp4" title="皆既日食動画">こちら</a>からダウンロードして下さい。</p>
</video>
loop コンテンツ属性が指定された場合、一度ビデオの再生が開始されると、その後は、ビデオが停止されるまで、何度も繰り返しビデオが再生し続けます。
ビデオのサイズ
width コンテンツ属性と height コンテンツ属性には、それぞれ、video 要素によってレンダリングされる領域の横幅と縦幅を指定することができます。
ビデオは、この領域の中心にピッタリ収まる形で伸縮されて表示されます。ビデオの実際の縦横比と、width コンテンツ属性と height コンテンツ属性の縦横比が異なっていたとしても、ビデオの縦横比が変更されるわけではありません。したがって縦横比が異なる場合は、上下、もしくは、左右に余白ができることになります。
HTML
<video src="vdos/total_solar_eclipse.mp4" controls="controls" width="100" height="100">
<p>ご利用のブラウザでは再生出来ません。<a href="vdos/total_solar_eclipse.mp4" title="皆既日食動画">こちら</a>からダウンロードして下さい。</p>
</video>
ビデオの種類
ビデオの形式には、様々なものがありますが、ブラウザが対応しているビデオ形式でないと再生できません。したがって、実際にビデオ・データを用意するに当たり、ビデオ形式を十分に理解していないと、ブラウザで再生できないデータを作ってしまうことになります。
よく、ファイルの拡張子を見て、そのファイル形式を判断しますが、映像や音声に関しては、それだけでは完全に区別することができません。例えば、.mp4
という拡張子のファイルなら、すべてのファイルのビデオ形式が同じであるとは限らないのです。
一般によく使われる MIME タイプも同様です。通常、拡張子 .mp4
に対して video/mp4 が割り当てられますが、この情報だけでは、ビデオ形式を完全に区別することができません。ビデオ形式を完全に区別するためには、映像のコーデック、音声のコーデック、コンテナの情報が必要なのです。
まず、映像や音声は、コーデックというものが重要な要素となります。コーデックとは、映像や音声を、いかにしてデジタルデータに収めるかを決めた方式のことを指します。コーデックは、場合によっては、ソフトウェアなどを指す場合もありますが、ここでは、方式を指すものとして使います。
コーデックには、さまざまな種類があります。なぜなら、映像や音声をデータに収めるといっても、映画のフィルムのように1コマずつ静止画像データを集めれば良いというものではないからです。そのようなことをしてしまうと、ビデオデータのサイズが非常に大きくなってしまいます。そのため、いかに人の目に出来る限りわかりにくい所で情報を減らして、できる限り小さいデータで動画を再現できるかが重要なのです。データを小さく、しかし、映像や音声クォリティーを下げないという相反する課題に、多くのソフトウェア・ベンダーやコミュニティーがしのぎを削って取り組み、さまざまなコーデックを開発しています。
なお、ビデオは、映像と音声の両方を伴います。そのため、このコーデックも、映像用と音声用がそれぞれ必要になります。
mp4 形式には、映像コーデックなら、H.264 Simple baseline profile、H.264 Extended Profile、MPEG-4 Visual Simple Profile Level 0、MPEG-4 Advanced Simple Profile Level 0 など、さまざまなものがあります。MPEG-4 という規格がありますが、この規格は非常に広範囲な領域を含んでいますので、ビデオの形式を表すには不適切です。例えば、この MPEG-4 という規格には、もともと映像コーデックが規定されています。これも MPEG-4 と呼ばれているため、混乱するのですが、さらに、もうひとつ別の映像コーデックも規定されています。これも MPEG-4 と呼ばれているため、混乱するのですが、さらに、もうひとつ別の映像コーデックも規定されています。それは H.264 です。H.264 はもともとは ITU-T(国際電気通信連合電気通信標準化部門)によって勧告されたものですが、現在は MPEG-4 にも加えられ、MPEG-4 AVC と呼ばれます。
音声に関しては、皆さんがよくご存知の AAC や MP3 といった方式があります。
次に、コーデックが決まって、映像と音声をデータ化できたとしても、今度はそれをどのようにファイルとして格納するのかが問題になってきます。このデータを格納するのがコンテナと呼ばれるものです。ビデオ・ファイルの拡張子は、主にコンテナの種類を表しています。.mp4
であれば MP4 というコンテナを表します。それ以外にも、Ogg といったものがあります。
コンテナの種類によって、映像と音声のコーデックは絞られますが、必ずしも 1 対 1 で結び付けられるわけではありません。MP4 には、映像コーデックに H.264 や MPEG-4 などを使うことができますし、音声コーデックに ACC や MP3 を使うことができます。
以上の、映像のコーデック、音声のコーデック、コンテナのすべてにブラウザが対応していないと再生できないのです。
ブラウザがサポートするビデオ形式
すでに、Firefox、Safari、Chrome は video 要素に対応しています。とはいえ、すべてのビデオ形式を再生できるわけではありません。さらに、現状ではブラウザによってサポートするビデオ形式が統一されていないという問題があります。
そのため、現在のところ、さまざまなブラウザからアクセスされるパソコン向けのサイトで video 要素を使うのは難しいといえるでしょう。しかし、iPhone のような特定のデバイス向けのサイトであれば、ブラウザの差異を考慮する必要がないため、現時点でも利用価値があると言えます。
当初、HTML5 仕様に、ブラウザがサポートするべきビデオ・コーデックを規定しようという試みがありました。そうすることで、1つのビデオ形式に対応したビデオ・ファイルを用意するだけで、HTML5 に対応したブラウザであれば、どれでも再生可能となるわけです。HTML5 では、映像コーデック、音声コーデック、コンテナの組み合わせとして、H.264 - ACC - MP4 や Theora - Vorbis - Ogg などが候補に挙がっています。
ところが、各ブラウザ・ベンダーの意見がまとまらず、現在のところは HTML5 仕様からビデオ・コーデックの規定が削除されています。将来的に、ビデオ・コーデックが規定されることが望ましいと言えますが、現在のところ、それはどうなるかわかりません。
現時点で video 要素に対応しているブラウザがサポートする代表的なビデオ形式は以下のとおりです。
映像 | 音声 | コンテナ | Firefox | Safari | Chrome |
---|---|---|---|---|---|
H.264 | AAC | MP4 | × | ○ | ○ |
H.264 | MP3 | MP4 | × | ○ | ○ |
MPEG-4 | AAC | MP4 | × | ○ | × |
Theora | Vorbis | Ogg | ○ | × | ○ |
映像コーデックとしては、Firefox は Theora のみに、Safari は H.264 と MPEG-4 に、Chrome は Theora、H.264 に対応しています。
スクリプトによるビデオ操作
video 要素の醍醐味の 1つは、スクリプトから自由にビデオを操作できることです。
ここでは、ブラウザが用意するビデオ・コントロール・インタフェースを使わずに、独自のインターフェースをスクリプトを使って用意してみましょう。このままでは役に立つサンプルではありませんが、video 要素のスクリプティングを習得するには効果的です。
このインタフェースには、いくつかの表示欄があります。
再生ファイル欄では、実際に、どのビデオ・ファイルがブラウザに採用されたのかを表示します。
状態の欄では、ビデオが再生中なのか停止中なのか、また、エラーがあった場合には、そのメッセージを表示します。
ボリュームの欄では、ボリューム(音量)のコントロールを用意します。音量を上げ下げするボタンに加え、ミュート(消音)の切り替えボタンも用意します。
再生位置の欄では、ビデオの総再生時間に加え、現在、どの位置を再生しているのかもリアルタイムで表示します。
コントロールの欄では、再生と停止のボタンに加え、コマボタンを加えています。コマボタンを押すと、ビデオ再生を一時停止し、ボタンを押すごとに 1秒ずつ表示するコマの位置を進めます。
HTML
<video id="video">
<p>ご利用のブラウザでは再生出来ません。<a href="vdos/total_solar_eclipse.mp4" title="皆既日食動画">こちら</a>からダウンロードして下さい。</p>
</video>
<dl>
<dt>再生ファイル</dt>
<dd id="src">-</dd>
<dt>状態</dt>
<dd id="state">-</dd>
<dt>ボリューム</dt>
<dd>
<button id="voldn">↓</button>
<span id="vol">-</span> / 10
<button id="volup">↑</button>
<button id="volmt">ミュート</button>
</dd>
<dt>再生位置</dt>
<dd><span id="time">0</span>秒 / <span id="duration">-</span>秒</dd>
<dt>コントロール</dt>
<dd>
<button id="play">再生</button>
<button id="pause" disabled="disabled">停止</button>
<button id="step">コマ</button>
</dd>
</dl>
video 要素には、controls コンテンツ属性を指定していません。そのため、この例では、ブラウザが実装しているコントロール・インタフェースは表示されません。
また、video 要素に src コンテンツ属性を指定していません。さらに、video 要素の中に、source 要素を入れていません。つまり、マークアップ上は、ビデオ・ファイルが一切指定されていないことになります。これは、後ほど、スクリプト側で、どのようにして再生可能なファイルを判別できるのかをご覧頂くために、あえて、そうしています。特にスクリプトを使って再生ファイルの選定をする必要がなければ、source 要素を使うのが良いでしょう。
次に、ここで使ったスクリプトですが、head 要素の中の script 要素の中に直接入れても構いませんし、別ファイルとして用意して、それを script 要素の src コンテンツ属性でロードしても構いません。どちらでも動作するように作られています。
JavaScript
(function () {
var video = null;
window.addEventListener("load", function() {
video = document.getElementById("video");
/* 状態表示 */
video.addEventListener("loadstart", updateState, false);
video.addEventListener("loadeddata", updateState, false);
video.addEventListener("play", updateState, false);
video.addEventListener("playing", updateState, false);
video.addEventListener("pause", updateState, false);
video.addEventListener("ended", updateState, false);
video.addEventListener("waiting", updateState, false);
video.addEventListener("error", updateState, false);
/* 再生ファイル表示 */
video.addEventListener("loadeddata", showSrc, false);
/* 音量表示 */
showVol();
video.addEventListener("volumechange", showVol, false);
/* ミュート */
document.getElementById("volmt").addEventListener("click", volMt, false);
/* 音量上げ */
document.getElementById("volup").addEventListener("click", volUp, false);
/* 音量下げ */
document.getElementById("voldn").addEventListener("click", volDn, false);
/* 総再生秒数表示 */
showDuration();
video.addEventListener("loadeddata", showDuration, false);
/* 現在再生秒数表示 */
video.addEventListener("timeupdate", showTime, false);
/* 再生 */
document.getElementById("play").addEventListener("click", playVideo, false);
/* 停止 */
document.getElementById("pause").addEventListener("click", pauseVideo, false);
/* コマ */
document.getElementById("step").addEventListener("click", stepVideo, false);
/* ビデオ・ファイルの選定 */
var files = {
"video/mp4" : "vdos/total_solar_eclipse.mp4",
"video/ogg" : "vdos/total_solar_eclipse.ogg"
};
for( var type in files ) {
if( /^(maybe|probably)/.test( video.canPlayType(type) ) ) {
video.src = files[type];
break;
}
}
if( ! video.src ) { return; }
video.load();
}, false);
/* 状態表示 */
function updateState(evt) {
var msg = "";
var t = "loadeddata";
if( evt && evt.type ) {
t = evt.type;
}
if( video.error ) {
var errs = {
1: "ユーザー操作によりフェッチを終了しました。",
2: "ネットワークエラーが発生しました。",
3: "デコードに失敗しました。",
4: "指定のビデオは再生することができません。"
};
msg = errs[video.error.code];
} else if( t == "loadstart" ) {
msg = "ロードを開始しました。";
} else if( t == "loadeddata" ) {
msg = "再生の準備ができました。";
} else if( t == "play" ) {
msg = "再生を開始しました。";
} else if( t == "playing" ) {
msg = "再生しています。";
} else if( t == "pause" ) {
msg = "再生を停止しています。";
} else if( t == "ended" ) {
msg = "再生が終了しました。";
} else if( t == "waiting" ) {
msg = "サーバーからの応答を待っています。";
}
document.getElementById("state").innerHTML = msg;
}
/* 再生ファイル表示 */
function showSrc(evt) {
document.getElementById("src").innerHTML = video.currentSrc;
}
/* 音量表示 */
function showVol(evt) {
document.getElementById("vol").innerHTML = video.volume.toFixed(1) * 10;
document.getElementById("volmt").innerHTML = video.muted ? "消音解除" : "消音";
}
/* ミュート */
function volMt(evt) {
video.muted = video.muted ? false : true;
}
/* 音量上げ */
function volUp(evt) {
vol = video.volume + 0.1;
vol = vol.toFixed(1);
if( vol > 1 ) { vol = 1; }
video.volume = vol;
}
/* 音量下げ */
function volDn(evt) {
vol = video.volume - 0.1;
vol = vol.toFixed(1);
if( vol < 0 ) { vol = 0; }
video.volume = vol;
}
/* 総再生秒数表示 */
function showDuration() {
var el = document.getElementById("duration");
el.innerHTML = video.duration.toFixed(3);
}
/* 現在再生秒数表示 */
function showTime(evt) {
var el = document.getElementById("time");
el.innerHTML = video.currentTime.toFixed(3);
}
/* 再生 */
function playVideo(evt) {
evt.target.disabled = true;
document.getElementById("pause").disabled = false;
video.play();
}
/* 停止 */
function pauseVideo(evt) {
evt.target.disabled = true;
document.getElementById("play").disabled = false;
video.pause();
}
/* コマ */
function stepVideo(evt) {
video.pause();
video.currentTime += 1;
}
})();
このスクリプトで使われている IDL 属性やメソッドを詳しく見て行きましょう。
イベント
ビデオをスクリプトで扱うためには、イベントが重要です。例では、次のようなコードで、イベント・リスナーをセットしています。
JavaScript
video.addEventListener("pause", updateState, false);
video要素や audio要素には、数多くのイベントが規定されていますが、ここでは、例で使ったイベントに絞って紹介します。
イベント名 | 概要 |
---|---|
loadstart | このイベントは、ブラウザが、どのメディア・ファイルを採用するのかを選定し始めた時に発生します。この時点では、どのファイルを採用するのか決まっていない状態です。 |
loadeddata | このイベントは、ブラウザがメディア・ファイルをダウンロードして、最初のフレームを表示できた時点で発生します。この時点で、メディア・ファイルの再生の準備が整ったことになります。ただし、まだ次のフレームの状態をダウンロードできているわけではないため、再生ボタンを押しても、待たされる可能性はあります。 |
play | このイベントは、メディア・ファイルの再生が開始された時に発生します。このイベントが発生したタイミングで、pause IDL 属性の値が true から false に切り替わります。 |
playing | このイベントは、メディア・ファイルの再生が開始された時に発生します。play イベントとは違い、このイベントが発生した時には、すでに次のフレームも再生可能な状態になったことを表します。 |
pause | このイベントは、メディア・ファイルの再生が停止された時に発生します。 |
ended | このイベントは、メディア・ファイルが最後まで再生された時に発生します。 |
waiting | このイベントは、次に再生しようとしたフレームがまだ利用可能になっていないときに発生します。このイベントが発生した時には、一時的にメディア・ファイルの再生が停止した状態になります。この状況の例としては、メディア・ファイルのダウンロードが、再生の速度に追いつかない時が挙げられます。 |
error | このイベントは、メディア・ファイルのダウンロードにおいてエラーに遭遇した時に発生します。 |
volumechange | このイベントは、音量が変更された時、または、ミュート状態が変更された時に、発生します。具体的には、volume IDL 属性または muted IDL 属性の値が変わった時に、このイベントが発生します。 |
timeupdate | このイベントは、メディア・ファイルの再生位置が変わっている最中に連続して発生します。つまり、メディア・ファイルが再生されている間は、常にこのイベントが発生します。フレームごとに発生するのではありませんので、注意してください。ブラウザによって、このイベントの発生タイミングは異なります。 |
ビデオ・ファイルの選定
ブラウザによって、どのようなコーデックのメディア・ファイルを再生できるのかが違うため、スクリプトによって、それを判定する必要が出てくる場合もあるでしょう。その場合、canPlayType() メソッドを使います。
JavaScript
var files = {
"video/ogg" : "test.ogg",
"video/mp4" : "test.mp4"
};
for( var type in files ) {
if( /^(maybe|probably)/.test( video.canPlayType(type) ) ) {
video.src = files[type];
break;
}
}
if( ! video.src ) { return; }
video.load();
canPlayType() メソッドは、引数に MIME タイプを指定します。そして、このメソッドは、指定のタイプのメディア・ファイルを再生することができるかどうかをを文字列で返します。もし再生できそうだと判断されれば、maybe または probably を返し、再生できないと判断されれば空文字列が返されます。
前述のとおり、MIME タイプだけではコーデックが判別できないため、maybe または probably といった曖昧な表現で返されるのです。"video/ogg" や "video/mp4" のような MIME タイプを指定した場合、通常は maybe が返されます。それに対して、"video/mp4; codecs=avc1.42E01E, mp4a.40.2" のように、コーデックまで指定した MIME タイプであれば、probably が返される可能性があります。コーデックを指定した MIME タイプについては、source 要素のページで説明予定です。
例では、canPlayType() メソッドが maybe または probably のいずれかを返せば、それは再生可能と見なして処理しています。処理可能であれば、そのメディア・ファイルのアドレスを video 要素の src IDL 属性にセットします。
通常は、src IDL 属性にメディア・ファイルのアドレスをセットした時点で、そのファイルのロードが開始されますが、例では、念のために、明示的に load() メソッドを使ってロードを指示しています。
状態表示
メディア・要素の再生に関して、その状態を把握するために、例では様々なイベントの発出をトリガーに、その時点の状況をレポートしています。
JavaScript
function updateState(evt) {
var msg = "";
var t = "loadeddata";
if( evt && evt.type ) {
t = evt.type;
}
if( video.error ) {
var errs = {
1: "ユーザー操作によりフェッチを終了しました。",
2: "ネットワークエラーが発生しました。",
3: "デコードに失敗しました。",
4: "指定のビデオは再生することができません。"
};
msg = errs[video.error.code];
} else if( t == "loadstart" ) {
msg = "ロードを開始しました。";
} else if( t == "loadeddata" ) {
msg = "再生の準備ができました。";
} else if( t == "play" ) {
msg = "再生を開始しました。";
} else if( t == "playing" ) {
msg = "再生しています。";
} else if( t == "pause" ) {
msg = "再生を停止しています。";
} else if( t == "ended" ) {
msg = "再生が終了しました。";
} else if( t == "waiting" ) {
msg = "サーバーからの応答を待っています。";
}
document.getElementById("state").innerHTML = msg;
}
ここで注目してほしいのは、エラーの把握です。video 要素には error IDL 属性が規定されています。この IDL 属性は、メディア・ファイルのロードにおいて、何かしらエラーが発生した時だけにオブジェクトとして読み取ることができるようになります。もし何もエラーがなければ、null になります。
もしエラーが発生すると、video.error.code で、そのエラー・コードを取り出すことができます。エラー・コードは 1 から 4 までの整数のいずれかとなり、それぞれの値の意味は下表のとおりです。
コード | 意味 |
---|---|
1 | ユーザーのリクエストによって、メディア・ファイルのロードが中止された |
2 | ネットワーク・エラー |
3 | デコード・エラー |
4 | src IDL 属性の値が不適切 |
再生ファイル表示
ブラウザによって、どのメディア・ファイルが選択されて再生されてるのかをスクリプトから把握するには、currentSrc IDL 属性を使います。
JavaScript
function showSrc(evt) {
document.getElementById("src").innerHTML = video.currentSrc;
}
この IDL 属性では、video 要素の src コンテンツ属性の値そのものではなく、https:// から始まる URL に変換された値が返されます。
音量表示
音量は、volume IDL 属性から把握することができます。ただし、volume IDL 属性から得られる値は、0 から 1 までの浮動小数点数となります。0 は音が聞こえない状態を表し、1 は最大音量を表します。
JavaScript
function showVol(evt) {
document.getElementById("vol").innerHTML = video.volume.toFixed(1) * 10;
document.getElementById("volmt").innerHTML = video.muted ? "消音解除" : "消音";
}
この例では、ミュート(消音)についてもサポートしています。muted IDL 属性から、現在、ミュート中なのか、そうでないのかを把握することができます。この属性は、ミュート中であれば true を、そうでなければ false を返します。
なお、音量とミュートは連動するものではありませんので注意してください。ミュートが有効になっている場合、たとえ、音量が 1 (最大音量)だとしても、音が聞こえない状態になります。つまり、音量に関わらず、ミュート状態が優先されることになります。
音量の変更
音量は、volume IDL 属性に値をセットすることで変更することができます。0 から 1 までの数値を指定します。ただし、この範囲外の数値を指定するとエラーになりますので、注意してください。
JavaScript
/* 音量上げ */
function volUp(evt) {
vol = video.volume + 0.1;
vol = vol.toFixed(1);
if( vol > 1 ) { vol = 1; }
video.volume = vol;
}
/* 音量下げ */
function volDn(evt) {
vol = video.volume - 0.1;
vol = vol.toFixed(1);
if( vol < 0 ) { vol = 0; }
video.volume = vol;
}
この例では、ボタンが押されると、volume IDL 属性の値に 0.1 を足す、または 0.1 を引く処理を行なっています。ただし、0 から 1 の範囲を超えてしまった場合は、エラーにならないよう、1 もしくは 0 にセットし直しています。
総再生秒数と現在再生秒数の表示
再生中のメディア・ファイルの尺(長さ)は duration IDL 属性から、現在の再生位置は currentTime IDL 属性から、いずれも秒数で取得することができます。実際に取得される値は、浮動小数点数です。
JavaScript
/* 総再生秒数表示 */
function showDuration() {
var el = document.getElementById("duration");
el.innerHTML = video.duration.toFixed(3);
}
/* 現在再生秒数表示 */
function showTime(evt) {
var el = document.getElementById("time");
el.innerHTML = video.currentTime.toFixed(3);
}
この例では、得られた秒数をミリ秒(小数点以下 3桁)となるよう丸めています。
再生と停止
play() メソッドを呼び出すと再生が開始され、pause() メソッドを呼び出すと停止します。これらのメソッドに引数はありません。
JavaScript
/* 再生 */
function playVideo(evt) {
evt.target.disabled = true;
document.getElementById("pause").disabled = false;
video.play();
}
/* 停止 */
function pauseVideo(evt) {
evt.target.disabled = true;
document.getElementById("play").disabled = false;
video.pause();
}
再生位置の変更
currentTime IDL 属性に秒数をセットすると、現在再生位置が指定の秒数の位置に変更されます。
JavaScript
function stepVideo(evt) {
video.pause();
video.currentTime += 1;
}
この例では、「コマ」ボタンを押すことで、pause() メソッドで一時停止をして、その時点の再生位置から 1秒だけ再生位置を進めています。すでに一時停止状態になっているため、1秒進めた位置のフレームが表示され、そこで停止した状態になります。
autobuffer
autobuffer コンテンツ属性は、ブラウザに対して「ユーザーによって該当のビデオは最後まで再生されることになるだろう」ということを通知するために使います。これはブラウザ側に、ビデオ・データを事前にバッファすることを期待したものです。ただし、autoplay コンテンツ属性がセットされている場合は、無効になります。
HTML
<video src="vdos/total_solar_eclipse.mp4" controls="controls" autobuffer="autobuffer">
<p>ご利用のブラウザでは再生出来ません。<a href="vdos/total_solar_eclipse.mp4" title="皆既日食動画">こちら</a>からダウンロードして下さい。</p>
</video>
このコンテンツ属性を指定しておくことで、事前にビデオ・データがダウンロードされます。ユーザーがビデオを再生するときには、ある程度のビデオ・データがロード済みとなっているはずですので、その範囲内であれば、早送りも可能となるでしょう。
ただ、ユーザーが再生する可能性が高くないビデオに対しては、このコンテンツ属性をセットすることはお勧めできません。ブラウザ側の負担が高くなりますし、それ以上に、ネットワーク帯域や、サーバー側の負担を無駄に高くすることにつながります。ビデオ・データのサイズが大きいほど、大きな懸念材料になります。この辺の事情を考慮した上で、このコンテンツ属性を使うようにしましょう。
なお、autobuffer コンテンツ属性を指定しなかったとしても、全くサーバーにアクセスしないというわけではありません。このコンテンツ属性が指定されていなくても、通常は、ビデオ再生開始時にもたつくことがないよう、ビデオ再生が開始される前から、ある程度のビデオ・データがダウンロードされます。