HTMLとjavascriptを利用し、アップロードする動画ファイルの再生時間をクライアント側で取得する方法

こんにちは。システム事業部の三浦です。

最近動画のアップロードをする入力フォームを作る機会がありました。

アップロード可能な動画ファイルの条件として、再生時間が300秒以内という条件がありました。(ファイル形式他諸々もチェックしましたが、今回は割愛します)

初めは、アップロードする動画ファイルをサーバサイドでffmpegを利用し解析し、duretionを取得してチェックするような実装を行いました。

しかし、この方法ではアップロードの時間を待たされた上、失敗するといったユーザビリティがとても悪いものになっていました・・・

「入力フォームの段階でjavascriptを利用して、再生時間をチェックしよう!」という方針になったのですが、
その方法で少しつまずくこととなったので、
最終的に完成した方法を簡略化し共有させていただきます。

以下のようなコードで実現可能です。(モダンな書き方でなくすみません・・・)

<!DOCTYPE html>
<html>
  <script type="text/javascript">

    // 動画の再生時間上限
    MAX_DURATION = 300

    window.onload = function() {
      // ファイル選択時のイベントを設定
      document.getElementById("movie-input").onchange = function(e){
        var file = e.target.files[0];
        // 選択されたファイルをチェック用のメソッドに渡す
        checkVideoDuration(file);
      }
    }

    // 再生時間チェック用メソッド
    var checkVideoDuration = function(file) {
      var video = document.createElement('video');
      var fileURL = URL.createObjectURL(file);
      video.src = fileURL;
      video.ondurationchange = function() {
        if(parseInt(this.duration) > MAX_DURATION) {
          alert("動画長さが" + MAX_DURATION + "秒を超えています。");
        } else {
          alert(this.duration);
        }
        URL.revokeObjectURL(this.src);
      };
      console.log("この部分は非同期処理");
    }

  </script>

  <head>
    <meta charset="utf-8">
    <title>動画時間チェック</title>
  </head>

  <body>
    <input type="file" id="movie-input" name="movie-input">
  </body>

</html>

処理の流れは以下のようになっています。

  1. アップロードされたファイルを、onchangeイベントで取得
  2. ファイルをURL.createObjectURLでローカルに展開、そのURLを取得
  3. 2で取得したurlを、videoタグのsrcに設定
  4. その後videoタグのondurationchangeイベントにて検知し、再生時間を表示
  5. ローカルに展開された動画をURL.revokeObjectURLで削除

※注意点

  • createObjectURLによりデータはメモリ上に展開されるため、ファイル容量によってはフリーズ等が起きる可能性もあります。
  • 上記の実装では、動画ファイル以外がアップロードされることは考慮していません。
  • MP4形式のファイル以外は確認していません。

このようにして、無事再生時間の取得に成功しました!! f:id:zenet-tech:20180129191544p:plain

以上です。