HTML5では新しくvideoタグが追加されました。videoタグを利用することで、HTML文書内に手軽に動画ファイルを埋め込むことができます。
今回はそんなvideoタグに対して様々な方法で再生、リソースを適用する方法について紹介します。

JavaScriptから再生する基本的な方法

一番基本的な再生方法は次のようなコードです。videoタグを取得してplayメソッドを実行するだけです。

<video id="video1" src="video/sample1.mp4" width="320" height="240" controls></video>

<script>
  var video = document.getElementById("video1");
  video.play();
</script>

ループ再生させる

動画を繰り返し再生させるのもJavaScriptから操作できます。loop要素にtrueを指定するだけです。

var video1 = document.getElementById("video1");
video1.setAttribute('loop', true);
video1.play();

同時に複数の動画を再生する

こちらは実験です。videoタグで2つの動画を再生しようとするとどうなるでしょうか。この場合、後から再生したものが優先されます。

<video id="video1" src="video/sample1.mp4" width="320" height="240" controls></video>
<video id="video2" src="video/sample2.mp4" width="320" height="240" controls></video>

<script>
  var video1 = document.getElementById("video1");
  var video2 = document.getElementById("video2");

  video1.play();
  video2.play(); // こちらが再生されます
</script>

ダウンロードした動画を再生する(FileTransferを使った方法)

動画リソースをあらかじめアプリ内に入れるのではなく、外部から取得する方法もあります。

まずはFileTransferプラグイン(Monacaで標準提供しています)を利用した方法を紹介します。
fileTransfer.download メソッドを使って動画ファイルをダウンロードします。ダウンロード先は cdvfile として、Cordovaアプリ用のURLスキームの中に保存します。

// ダウンロード元
var uri = encodeURI("http://example.com/sample1.mp4");
// ダウンロード先
var fileURL = "cdvfile://localhost/temporary/sample1.mp4";

// ファイルのダウンロード
var fileTransfer = new FileTransfer();
fileTransfer.download(
    uri,
    fileURL,
    function(fileSyatem) {
      // videoタグのsrc要素に適用
      downloadFileURL = fileSyatem.toURL();
      var video = document.getElementById("video1");
      video.setAttribute('src', downloadFileURL);
      video.play(); 
    },
    function(error) {
      // エラー
    },
    false,
    {}
);

しかし動画のダウンロードはバッファーに時間がかかることがあり、利用者にとってはストレスになります。ダウンロード処理はあらかじめバックグラウンドで行っておくと、スムーズに再生することができるようになります。

ダウンロードした動画を再生する(Ajaxを使った方法)

FileTransferはプラグインなので、もう少し使いやすいAjaxを使った実装は次のようになります。このように実装することであらかじめコンテンツがキャッシュされた状態で再生できますので、バッファーで悩むことがありません。

なお、POSTメソッドを使う場合はCORSに対応している必要があります。

// ソース元
var uri = encodeURI("http://example.com/sample1.mp4");

var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.onreadystatechange = function() {
  var READYSTATE_COMPLETED = 4;
  var HTTP_STATUS_OK = 200;

  if (this.readyState == READYSTATE_COMPLETED && this.status == HTTP_STATUS_OK) {
    var video = document.getElementById("video1");
    video.setAttribute('src', uri);
  } else {
    // エラー
  }
}

// openメソッドをGETで実行した場合:Origin:設定なし
xmlHttpRequest.open('GET', uri);
xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttpRequest.send();

// openメソッドをPOSTで実行した場合:Origin:file://
// xmlHttpRequest.open('POST', uri);
// xmlHttpRequest.setRequestHeader('Access-Control-Allow-Origin', 'file://');

動画ではなくCanvasタグを使う

さらに変わった方法としてvideoタグではなくCanvasタグを使って動画を描画する方法があります。この場合のメリットとして全画面表示ではなく、埋め込み再生が可能になります。Canvasタグ単独では音声は出ませんが、Audioタグを使うことでカバーできます。

var audio = new Audio();
var video = document.getElementById("video1");
var canvas = document.getElementById("canvas1");

video.load();

// Androidの場合
if (monaca.isAndroid) {
  video.loop = true;
  video.play();

  video.addEventListener('canplay',function(){
    setInterval(function(){
      canvas.getContext("2d").drawImage(video, 0, 0, 320, 240);
    }, 1000/30);
  },false);
}

// iOSの場合
if (monaca.isIOS) {
  audio.src = 'sample1.mp4';
  audio.load();
  audio.play();

  video.addEventListener('canplay',function() {
    lastTime = Date.now();
    setInterval(function() {
      video.currentTime = audio.currentTime;
      canvas.getContext("2d").drawImage(video, 0, 0, 320, 240);
      if(video.duration <= video.currentTime) {
        // ループ
        audio.play();
      }
    }, 1000/30);
  },false);
}

このように実装することで音声の位置(audio.currentTime)に合わせてvideoの内容を取得(video.currentTime)し、Canvas上に描画できます。

注意点

  • Android4.4以下の場合は、Crosswalkを有効にすることで再生可能です。
  • 日本語の動画ファイル名は、認識されません。
  • Content-Security-Policyに media-src * cdvfile:;img-src * android-webview-video-poster:; が必要です。
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; media-src * cdvfile:; img-src * android-webview-video-poster:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">    

videoタグだけでも動画を再生することはできますが、JavaScriptと組み合わせることでよりインタラクティブに操作できるようになります。ぜひ今回紹介したテクニックを使って動画を楽しめるアプリを作成してみてください。

今回のプロジェクトはhttps://github.com/goofmint/monaca_video_sampleにアップロードしてあります。実装時の参考にしてください。