プラグインは要らない!音声/動画対応したHTML5 - <audio>/<video>要素

2013年1月26日(土)
山田 祥寛(YAMADA, Yoshihiro)

HTML5では、新たに

あとから述べるように、ブラウザによって対応する音声/ビデオ形式にバラツキがあるなどの問題もありますが、メディア要素を利用することでメディアファイルの扱いがぐんとカンタンになるでしょう。

[第6回目次]
  • TIPS 041:音声ファイルを再生する
  • TIPS 042:動画ファイルを再生する
  • TIPS 043:音声/動画ファイルの再生を複数ブラウザ対応する
  • TIPS 044:音声ファイルをスクリプトから再生する
  • TIPS 045:動画ファイルをスクリプトから再生する
  • TIPS 046:ボリュームや再生速度を変更する
  • TIPS 047:動画を全画面表示する
  • TIPS 048:音声/動画ファイルの情報/状態を取得する
  • TIPS 049:音声/動画ファイルの取得状況に応じて処理を実行する
  • TIPS 050:音声/動画ファイルの状態に応じて処理を実行する
  • TIPS 051:音声/動画ファイル再生時のエラーを処理する
  • TIPS 052:音声/動画に対するユーザの操作を検出する

以下は、メディア要素のブラウザごとの対応状況です。

表1:メディア要素の対応バージョン

ブラウザ 対応バージョン
Internet Explorer 9以降
Firefox 3.6以降
Google Chrome 3以降
Safari 3以降
Opera 10.5以降

サンプル一式は、会員限定特典としてダウンロードできます。記事末尾をご確認ください。

TIPS 041:音声ファイルを再生する

[リスト01].mp3ファイルを再生するコード(audio.html)

<audio src="./audio/sample.mp3" controls autoplay loop preload="auto">
  ご利用のブラウザでは、音声の再生はできません
  [<a href="./audio/sample.mp3">ダウンロード</a>]
</audio>
図1:指定された音声ファイルが再生される

表2:

属性 概要
src 音声ファイルのパス
type コンテンツタイプ
*controls 再生コントローラを出力
*autoplay 自動再生を有効にするか
*loop ループ再生するか
preload 音声ファイルを自動で読み込むか(autoplay属性の指定時は無視)
設定値 概要
auto 全ての情報を読み込む
metadata メタデータだけを読み込む
none 再生までは読み込まない(事前読み込み無効)

controls属性によって表示される再生コンローラの見た目は、ブラウザによって異なります。

preload属性を有効にすることで、音声ファイルを事前に取り込めるため、再生がスムーズとなります。現在ではpreload属性を指定しなくても、事前読み込みを行うブラウザが多くなっているようです。ただし、逆にスマホ環境の多くではリソース消費を節約するためにpreload属性を無効にしていますので注意してください。

TIPS 042:動画ファイルを再生する

動画ファイルを再生するには、

[リスト02].ogvファイルを再生するコード(video.html)

<video src="./video/sample.ogv" controls autoplay
  width="320" height="180" poster="wings.jpg">
  ご利用のブラウザでは、動画の再生はできません
  [<a href="./video/sample.ogv">ダウンロード</a>]
</video>
図2:読み込み待ちでは画像ファイルを表示
図3:読み込み完了すると、自動で動画ファイルを再生開始

表3:

属性 概要
src 動画ファイルのパス
type コンテンツタイプ
*controls 再生コントローラを出力

*autoplay
自動再生を有効にするか
*loop ループ再生するか
preload 動画ファイルを自動で読み込むか
設定値 概要
auto 全ての情報を読み込む
metadata メタデータだけを読み込む
none 再生までは読み込まない(事前読み込み無効)
width 再生画面の幅
height 再生画面の高さ
poster 再生待ちの画像

ほとんどの属性は

一般的には、動画の一部を示した静止画など、内容を類推できるようなものを指定します。

TIPS 043:音声/動画ファイルの再生を複数ブラウザ対応する

現時点で、

表4:音声形式の対応状況

ブラウザ MP3 OGG WAV
IE × ×
Chrome
Firefox ×
Opera ×
Safari ×

表5:動画形式の対応状況

ブラウザ MP4 OGV WEBM
IE × ×
Chrome
Firefox ×
Opera ×
Safari × ×

よって、TIPS 041、042で紹介したサンプルも、実はChromeはじめ、特定のブラウザでしか再生できません。

当然、これでは困りますので、

[リスト03]主要なブラウザで再生できるように対応したコード(video_all.html)

<video controls autoplay width="320" height="180"
  poster="wings.jpg">
  <source src="./video/sample.mov">
  <source src="./video/sample.mp4">
  <source src="./video/sample.ogv">
  <source src="./video/sample.webm">
  ご利用のブラウザでは、動画の再生はできません
</video>
図4:動画を再生

TIPS 044:音声ファイルをスクリプトから再生する

Audioオブジェクトを利用することで、音声ファイルをスクリプトから操作することもできます。アプリで効果音を鳴らしたい場合などに利用できるでしょう。

[リスト04]指定された音声ファイルを再生するコード(media_audio.html)

window.addEventListener('DOMContentLoaded',
  function() {
    // オーディオ機能に対応しているかをチェック(1)
    if (HTMLAudioElement) {
      // 音声ファイルを準備(2)
      var a = new Audio('./audio/sample.mp3');
      // 音声ファイルをサポートしているかをチェック(3)
      var result = a.canPlayType('audio/mp3');
      if (result.match(/^(probably|maybe)$/)) {
        a.play();  // 再生開始(4)
      }
    }
  }
);

※サンプルを実行すると、音声だけが再生されます。

オーディオ機能は新しい命令なので、利用する前にまず、ブラウザが対応しているかをチェックしなければなりません。これを行っているのが(1)です。

HTMLAudioElementは、

オーディオ機能を利用できることが確認できたら、続いてAudioオブジェクトをインスタンス化します(2)。コンストラクタには、再生したい音声ファイルのパスを指定します。

続いて、canPlayTypeメソッドで音声ファイルを再生できるかをチェックします(3)。引数には調べたいコンテンツタイプを指定してください。さきほども述べたように、現時点ではブラウザによってサポートするファイル形式が異なりますので要注意です。

canPlayTypeメソッドの戻り値は、以下のとおりです。

表6:canPlayTypeメソッドの戻り値

戻り値 概要
probably 再生可能(より可能性が高い)
maybe 再生可能
空文字列 再生不可

よって、サンプルではifブロックで戻り値がprobablyかmaybeであることをチェックし、その場合のみ、再生を開始しているわけです。再生を開始するには、playメソッドを呼び出します(4)。

また、サンプルでは利用していませんが、再生を停止するにはpauseメソッドを呼び出してください。

TIPS 045:動画ファイルをスクリプトから再生する

前のTIPSと同じく、今度は動画ファイルをスクリプトから再生してみましょう。

[リスト05]指定された動画ファイルを再生するコード(media_video.html)

window.addEventListener('DOMContentLoaded',
  function() {
    // ビデオ機能に対応しているかをチェック(1)
    if (HTMLVideoElement) {
      // 動画ファイルを準備(2)
      var v = document.createElement('video');
      // 動画ファイルをサポートしているかをチェック(3)
      var result = v.canPlayType('video/ogg');
      if (result.match(/^(probably|maybe)$/)) {
        // 動画ファイルを準備&登録(4)
        v.setAttribute('src', './video/sample.ogv');
        v.setAttribute('controls', '');
        v.setAttribute('width', '320');
        v.setAttribute('height', '180');
        document.body.appendChild(v);
        // 再生を開始(5)
        v.play();
      }
    }
  }
);
図5:動画ファイルの再生を開始

まず、ビデオ機能に対応しているかをHTMLVideoElementオブジェクトの有無でチェックしているのは、前のTIPSと同じです(1)。HTMLVideoElementオブジェクトは

続いて、ビデオ操作のためのオブジェクトを作成します。この際、Audioに対応するVideoのようなオブジェクトはなく、createElementメソッドで直接に

(3)では動画ファイルへの対応状況をチェックします。そして、指定のビデオ形式が対応している場合には、

再生は、playメソッドで開始できます(5)。

TIPS 046:ボリュームや再生速度を変更する

たとえば以下は、スライダーでボリュームと再生速度を変化し、同じくチェックボックスでミュートをオンオフするサンプルです。

[リスト06]スライダー/チェックボックスで動画を操作するコード(ope.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLVideoElement) {
      // ページ上の要素を取得
      var v = document.querySelector('#v');
      var vol = document.querySelector('#vol');
      var mute = document.querySelector('#mute');
      var speed = document.querySelector('#speed');
 
      // スライダーvolの値が変化した時、ボリュームを変化
      vol.addEventListener('change', function (e) {
        v.volume = vol.value;
      });
 
      // チェックボックスをオンオフした時にミュート切り替え
      mute.addEventListener('change', function (e) {
        v.muted = mute.checked;
      });
 
      // スライダーspeedの値が変化した時、再生速度を変化
      speed.addEventListener('change', function (e) {
        v.playbackRate = speed.value;
      });
      ...中略...
    }
  }
);
...中略...
<video id="v" src="./video/sample.ogv" autoplay loop
width="320" height="180"></video>
<!--コントロールのためのスライダー/チェックボックスを準備-->
<div>
  音量:<input id="vol" type="range" min="0" max="1" step="0.01" value="1" />
  (ミュート<input id="mute" type="checkbox" />)<br />
  速度:<input id="speed" type="range" min="0" max="2" step="0.01" value="1" />
</div>
図6:スライダー/チェックボックスに応じてボリューム/再生速度を調整

HTMLAudioElement/HTMLVideoElementオブジェクトでアクセスできる主なプロパティには、以下のようなものがあります。

表7:HTMLAudioElement/HTMLVideoElementオブジェクトの主なプロパティ

プロパティ 概要
currentTime 現在の再生位置(秒数)
playbackRate 再生速度(デフォルトは1.0。大きいほど早い)
volume ボリューム(0.0~1.0)
muted ミュートされているか(true/false)
preload 自動読み込みを有効にするか(true/false)
loop 繰り返し再生するか(true/false)
controls コントローラを表示するか(true/false)

ここでは、それぞれスライダーの値やチェックボックスの状態に応じて、volume、playbackRate、mutedプロパティの値を操作しています。なお、volumeプロパティは0~1の間で、playbackRateプロパティは0(停止)~2(倍速)の間で変化できるように、スライダーの最大/最小値も設定しています。

TIPS 047:動画を全画面表示する

enterFullScreenメソッドを利用することで、動画の表示をフルスクリーンに切り替えることもできます。

たとえば以下は、[全画面表示]ボタンをクリックすることで動画をフルスクリーンモードに切り替える例です。

[リスト07]動画をフルスクリーンモードで再生するコード(full.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLVideoElement) {
      // ボタンクリック時の処理を定義
      document.querySelector('#full').addEventListener('click', function (e) {
        // 動画をフルスクリーンモードに切り替え
        var v = document.querySelector('#v');
        v.webkitEnterFullScreen();
      });
    }
  }
);
</script>
</head>
<body>
<video id="v" src="./video/sample.ogv" width="320" height="180"></video>
<input id="full" type="button" value="全画面表示" />
図7:フルスクリーンモードで動画を再生

現時点でフルスクリーンモードに対応しているブラウザは、Webkit系ブラウザであるChromeとSafariのみです。よって、enterFullScreenメソッドの呼び出しに際しても、ベンダープレフィックスを付けて「webkitEnterFullScreen()」としなければならない点に注意してください。

フルスクリーンモードは、[Esc]キーを押すことで解除できます。

TIPS 048:音声/動画ファイルの情報/状態を取得する

スクリプトから、音声/動画ファイルの情報(状態)を取得することもできます。

たとえば以下のサンプルは、1000ミリ秒おきに動画の情報を取得し、ページに反映する例です。

[リスト08]動画に関する情報を定期的に取得するコード(info.html)

window.addEventListener('DOMContentLoaded',
  function() {
    var v = document.querySelector('#v');
    // 1000ミリ秒おきに動画情報を更新
    setInterval(function() {
      // 取得した動画情報をページに反映
      document.querySelector('#src').innerHTML = v.currentSrc;
      document.querySelector('#dur').innerHTML = v.duration;
      document.querySelector('#start').innerHTML = v.startTime;
      document.querySelector('#end').innerHTML = v.ended;
      document.querySelector('#pause').innerHTML = v.paused;
      document.querySelector('#seek').innerHTML = v.seeking;
    }, 1000);
  }
);
...中略...
<video id="v" src="./video/sample.ogv" controls width="320" height="180">
</video>
<ul>
  <li>ファイル名:<span id="src"></span></li>
  <li>再生時間:<span id="dur"></span>秒</li>
  <li>開始時間:<span id="start"></span>秒</li>
  <li>終了済?:<span id="end"></span></li>
  <li>停止中?:<span id="pause"></span></li>
  <li>シーク中?:<span id="seek"></span></li>
</ul>
図8:動画再生中の情報を定期的に更新&表示

HTMLAudioElement/HTMLVideoElementオブジェクトでアクセスできる音声/動画ファイルの情報には、以下のようなものがあります。

表8:HTMLAudioElement/HTMLVideoElementオブジェクトの主なプロパティ

プロパティ 概要
currentSrc 再生中のファイル(URL)
duration 再生時間(秒)
startTime 再生開始が可能な時間(秒)
ended 再生が終了済みか
paused 一時停止中であるか
seeking 再生位置をシーク中であるか

いずれのプロパティも参照できるのみで、値の変更はできません。

TIPS 049:音声/動画ファイルの取得状況に応じて処理を実行する

readyStateプロパティを利用することで、音声/動画ファイルの読み込み状況を感知できます。たとえば、以下は動画の画面をクリックした時に、動画ファイルの読み込み状況をチェックし、ダウンロード済みの場合のみ再生を開始する例です。

[リスト09]画面クリック時に動画を再生するコード(ready.html)

window.addEventListener('DOMContentLoaded',
  function() {
    var v = document.querySelector('#v');
    v.addEventListener('click', function (e) {
      // 動画ファイルがダウンロード済みの場合のみ再生開始
      if (v.readyState === 4) {
        v.play();
      }
    });
  }
);
図9:画面クリックで再生を開始

readyStateプロパティの戻り値は、以下のとおりです。

表9:readyStateプロパティの戻り値

定数 概要
HAVE_NOTHING 0 ファイルを未取得
HAVE_METADATA 1 メタ情報を取得
HAVE_CURRENT_DATA 2 現在の再生位置の直近データを取得(ただし、再生するとすぐにHAVE_METADATAに戻る状態)
HAVE_FUTURE_DATA 3 現在の再生位置の直近データを取得
HAVE_ENOUGH_DATA 4 スムーズな再生に十分なデータを取得

サンプルでは、readyStateプロパティが4を返した(=十分なデータがダウンロード済みである)場合のみ、再生を開始しています。

TIPS 050:音声/動画ファイルの状態に応じて処理を実行する

HTMLAudioElement/HTMLVideoElementオブジェクトには、さまざまなイベントが用意されています。これらイベントを利用することで、音声/動画再生の状況に応じた処理を実施できます。

たとえば以下は、動画の再生/停止時にページ先頭に[再生中]というメッセージを表示/非表示する例です。

[リスト10]動画の再生/停止時にメッセージを表示するコード(event.html)

window.addEventListener('DOMContentLoaded',
  function() {
    var mark = document.querySelector('#mark');
    var v = document.querySelector('#v');
    // 再生開始時にメッセージを表示
    v.addEventListener('play', function (e) {
      mark.style.display = 'block';
    });
    // 停止時にメッセージを非表示
    v.addEventListener('pause', function (e) {
      mark.style.display = 'none';
    });
  }
);
...中略...
<div id="mark" style="background-color:Yellow">再 生 中</div>
<video id="v" src="./video/sample.ogv"
  controls autoplay width="320" height="180"></video>
図10:動画の再生時にメッセージを表示

HTMLAudioElement/HTMLVideoElementオブジェクトで利用できる再生関連のイベントには、以下のようなものがあります。

表10:再生関連のイベント

イベント 発生タイミング
loadstart データの読み込みを開始した
progress データの読み込み中
loadmetadata メタデータの読み込みが完了した
loadeddata 現在の再生位置で読み込みを完了した
load データの読み込みを完了した
canplay 再生を開始可能になった
canplaythrough 最後まで再生可能になったと判断した
play 再生を開始した
playing 再生中
timeupdate 再生位置が変更された
pause 再生を停止した

サンプルでは、この中からplay/pauseイベントを利用して、再生開始/一時停止時に[再生中]メッセージの表示/非表示を切り替えています。

その他、たとえばprogress/loadイベントを利用してデータの読み込み状況を表示したり、timeupdateイベントを利用することで、現在の再生時間(秒数)を取得し、スライダーやプログレスバーに表示するなどの効果を演出することもできるでしょう。

TIPS 051:音声/動画ファイル再生時のエラーを処理する

HTMLAudioElement/HTMLVideoElementオブジェクトのerrorイベントを利用することで、音声/動画ファイルのダウンロード時のエラーを検知することもできます。

たとえば以下は、ダウンロードエラー時にエラーメッセージを表示する例です。

[リスト11]

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLVideoElement) {
      var v = document.querySelector('#v');
      var err = document.querySelector('#error');
      // エラー発生時の処理を定義
      v.addEventListener('error', function (e) {
        // エラーメッセージを配列で管理(1)
        var msg = [
          '', 
          'ファイルの取得が中断されました。', 
          'ネットワークエラーです。', 
          'ファイルをデコードできませんでした。', 
          'ファイルを再生できません。'
        ];
        // 対応するメッセージを表示(2)
        err.innerHTML = msg[v.error.code];
      });
    }
  }
);
...中略...
<div id="error"></div>
<video id="v" src="./video/sample2.mp4" width="320" height="180"></video>
図11:ファイルが取得できない旨をエラー表示

errorイベントリスナでエラーの種類を識別するには、イベントオブジェクトのerrorプロパティを利用します。errorプロパティの戻り値は、以下のとおりです。

表11:codeプロパティの戻り値

戻り値 概要
MEDIA_ERR_ABORTED 1 ユーザによってダウンロードが中止された
MEDIA_ERR_NETWORK 2 ネットワークエラー
MEDIA_ERR_DECODE 3 データのデコードに失敗
MEDIA_ERR_SRC_NOT_SUPPORTED 4 ファイル指定が不適切/未サポート

サンプルでは、あらかじめエラーメッセージを配列msgとして用意しておきます(1)。こうしておくことで、あとは(2)のように「msg[v.error.code]」とするだけでエラーコードに対応するメッセージを取得できるというわけです(たとえばエラーコードが1であれば、msg[1]がエラーメッセージとなります)。

TIPS 052:音声/動画に対するユーザの操作を検出する

音声/動画ファイルに対するユーザの操作に応じて、処理を実行してみましょう。

たとえば以下は、ボリューム/再生速度を変更した時に、現在の値をラベル表示する例です。ボリューム/再生速度そのものを変更する方法については、TIPS 046を参照してください。

[リスト12]ボリューム/再生速度の現在値を表示するコード(ope.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLVideoElement) {
      var v = document.querySelector('#v');
      var vol = document.querySelector('#vol');
      var mute = document.querySelector('#mute');
      var speed = document.querySelector('#speed');
      ...中略...
      // ボリューム変更時に、現在のボリューム表示を更新
      v.addEventListener('volumechange', function (e) {
        document.querySelector('#vol_v').innerHTML = vol.value;
      });
 
      // 再生速度の変更時に、現在の再生速度表示を更新
      v.addEventListener('ratechange', function (e) {
        document.querySelector('#speed_v').innerHTML = speed.value;
      });
    }
  }
);
...中略...
<video id="v" src="./video/sample.ogv" autoplay loop
  width="320" height="180"></video>
<div>
  音量:<input id="vol" type="range" min="0" max="1" step="0.01" value="1" />
  <span id="vol_v">1</span>
  (ミュート<input id="mute" type="checkbox" />)<br />
  速度:<input id="speed" type="range" min="0" max="2" step="0.01" value="1" />
  <span id="speed_v">1</span>
図12:ボリューム/再生速度の変更に応じて、現在の表示も更新

HTMLAudioElement/HTMLVideoElementオブジェクトでユーザの操作に関わるイベントには、以下のようなものがあります。

表12:ユーザ操作に関わるイベント

イベント 発生タイミング
volumechange ボリュームが変更された時
ratechange 再生速度が変更された時
seeking 再生位置への移動中
seeked 再生位置への移動が完了した時

サンプルでは、このうちvolumechange/ratechangeイベントを利用して、ボリュームと再生速度が変更されたら、現在のボリューム値、速度を表示しています。

  • <audio>、<video>要素を使ってブラウザだけで音声/動画を再生するサンプル

著者
山田 祥寛(YAMADA, Yoshihiro)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています