こんにちは。システム事業部の三浦です。
最近動画のアップロードをする入力フォームを作る機会がありました。
アップロード可能な動画ファイルの条件として、再生時間が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>
処理の流れは以下のようになっています。
- アップロードされたファイルを、onchangeイベントで取得
- ファイルをURL.createObjectURLでローカルに展開、そのURLを取得
- 2で取得したurlを、videoタグのsrcに設定
- その後videoタグのondurationchangeイベントにて検知し、再生時間を表示
- ローカルに展開された動画をURL.revokeObjectURLで削除
※注意点
- createObjectURLによりデータはメモリ上に展開されるため、ファイル容量によってはフリーズ等が起きる可能性もあります。
- 上記の実装では、動画ファイル以外がアップロードされることは考慮していません。
- MP4形式のファイル以外は確認していません。
このようにして、無事再生時間の取得に成功しました!!
以上です。