ブラウザ上のJavascriptでWEBカメラとマイクから音声付ビデオの録画を行う
Javascriptを使うとライブラリなどを使用しなくても簡単に音声付ビデオ動画の録画ができます。
カメラとマイクがつながっているパソコン、又はスマホで録画可能です。
以下のソースコードでは1秒毎に録画データを配列に追加してビデオの再生とファイルのダウンロードができます。
実装手順
メディアストリームの取得
まず、メディアストリームを取得するためにnavigator.mediaDevices.getUserMedia
メソッドを使用します。
このメソッドは、ユーザーのカメラとマイクにアクセスするための許可を求めます。
ただし、iOS(iPhone)に対応するには「click」イベントでnavigator.mediaDevices.getUserMediaメソッドを呼び出す必要があります。
<button id="start" onclick="startRecording()">録画開始</button> <script> let chunks,recorder; function startRecording(){ chunks=[]; navigator.mediaDevices.getUserMedia( { audio:true, video:{facingMode:"user", width:320, height:240} } ).then( function(stream){ //ストリームからメディアレコーダーを作成する recorder = new MediaRecorder(stream); recorder.ondataavailable = function(el){ //録音録画データが届いたら配列変数 chunks に追加保存する if (el.data.size>0){ chunks.push(el.data); } } //録画の開始(1000ミリ秒録画される毎にdataavailableイベントが発生) recorder.start(1000); } ); } </script>
録画停止ボタンの設置
録画停止のボタンを設置します。録画停止ボタンクリック時のJavascriptを記述します。
<button id="stop" onclick="endRecording()">録画停止</button> <script> function endRecording(){ if(recorder){ recorder.stop(); } } </script>
録画が停止された時にstopイベントが発生するのでその時に実行するonStop関数のJavavscriptを記述します
録画停止のボタンが押されたら、recorderのstopイベント発生するのでその関数onStopを記述します。
chunks 配列変数に記録されているビデオ録画データを処理します。
<video id="video" playsInline controls></video> <script> //録画停止時に呼び出される関数 function onStop(){ //停止時の処理を行う //録画データが無かったら何もしないで関数を抜ける if (!chunks.length){return;} let obj=new Blob(chunks, {type:recorder.mimeType}); v=document.getElementById("video"); v.src=URL.createObjectURL(obj); } </script>
実際のサンプル
ソースコード
<button id="start" onclick="startRecording()">録画開始</button><br> <button id="stop" onclick="endRecording()" disabled>録画停止</button><br> <video id="video" playsInline controls></video><br> <a id="a"></a> <script> let chunks,recorder; function startRecording(){ chunks=[]; navigator.mediaDevices.getUserMedia({audio:true, video:{facingMode:"user",width:320,height:240}}).then( function(stream){ document.querySelector("#stop").removeAttribute("disabled"); document.querySelector("#start").setAttribute("disabled",""); recorder = new MediaRecorder(stream); recorder.ondataavailable = function(el){ //録画データを配列に保存する if (el.data.size>0){ chunks.push(el.data); } } recorder.onstop = onStop; //1000ミリ秒録画されるごとにdataavailableイベントが発生 recorder.start(1000); } ).catch( function(e){ console.log(e); } ); } function endRecording(){ if(recorder){recorder.stop();} } function onStop(){ if (!chunks.length){return;} document.querySelector("#stop").setAttribute("disabled",""); document.querySelector("#start").removeAttribute("disabled"); let obj=new Blob(chunks,{type:recorder.mimeType}); let a=document.getElementById("a"); let v=document.getElementById("video"); a.href=URL.createObjectURL(obj); if(recorder.mimeType.match(/x-matroska/)){ a.download="test.mkv"; }else if(recorder.mimeType.match(/mp4/)){ a.download="test.mp4"; }else if(recorder.mimeType.match(/mpg/)){ a.download="test.mpg"; }else{ a.download="test.webm"; } a.innerHTML="ダウンロード("+a.download+")"; v.src=URL.createObjectURL(obj); } </script>