こんにちは!がねこまさしです。今回はWebRTCの録画機能を使って、ブラウザ(Firefox)で録画してみましょう。
Media Recorder API
WebRTCでの録画機能はについては、MediaRecorder APIとしてこちらで検討が行われています。
Firefoxではすでに実装が始まっていますので、実際に使ってみることができます。
早速録画してみる
まずはいつものようにgetUserMedia()で localStreamを取得します。それを使って録画するのは、このようになります。簡単ですね!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var localStream; // getUserMedia()で取得したstreamをセットしておく var recorder = null; function startRecording() { recorder = new MediaRecorder(localStream); recorder.ondataavailable = function(evt) { // 録画が終了したタイミングで呼び出される } // 録画開始 recorder.start(); } // 録画停止 function stopRecording() { recorder.stop(); } |
私が試したところ、60分程度は問題なく録画できました。メモリ使用量が増加することもないので、ディスクのどこかにキャッシュされているのだと思います。(場所は発見できませんでした)
再生するには
録画したものを再生するには、先ほどのrecorder.ondataavaliable()で準備をしておく必要があります。Blobから、URLを生成しておきます。
1 2 3 4 5 6 |
var blobUrl = null; recorder.ondataavailable = function(evt) { var videoBlob = new Blob([evt.data], { type: evt.data.type }); blobUrl = window.URL.createObjectURL(videoBlob); } |
あとは、videoタグで再生すればOKです。
1 2 3 4 5 6 7 8 9 10 |
var playbackVideo = document.getElementById('playback_video'); function playRecorded() { playbackVideo.src = blobUrl; playbackVideo.onended = function() { playbackVideo.pause(); playbackVideo.src = ""; }; playbackVideo.play(); } |
録画を停止しないとondataavaliable()のイベントが発生しないので、再生はできません。残念ながらいわゆる「追いかけ再生」はできないようです。
保存するには
せっかく録画した映像をファイルに保存するにはどうすればよいのでしょうか? 残念ながらJavaScriptでファイルに直接書き込むAPIは今はFirefoxにはなさそうです。<a>タグを使って、ユーザにファイルを指定して保存してもらいます。
1 2 3 4 5 6 7 8 9 |
var anchor = document.getElementById('downloadlink'); recorder.ondataavailable = function(e) { var videoBlob = new Blob([e.data], { type: e.data.type }); blobUrl = window.URL.createObjectURL(videoBlob); anchor.download = 'recorded.webm'; anchor.href = blobUrl; } |
録画されたファイルはwebm形式になります。ビデオコーデックはVP8、オーディオコーデックはVorbis Audioでした。
終わりに
MediaRecorderを使えば、映像を簡単に記録することができます。サーバにポストして保存すれば、映像共有サイトも作れそうです。まだFirefoxでしか利用できませんが、今後の普及が楽しみですね。
※こちらにデモページを用意しました。
全体のソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>recording Firefox</title> </head> <body> <h2>MediaRecorder Demo for Firefox</h2> <button id="start_button" onclick="startVideo()">StartVideo</button> <button id="stop_button" onclick="stopVideo()">StopVideo</button> <button id="start_record_button" onclick="startRecording()">StartRecord</button> <button id="stop_record_button" onclick="stopRecording()">StopRecord</button> <button id="play_button" onclick="playRecorded()">Play</button> <a href="#" id="downloadlink" class="download">Download</a> <br /> <video id="local_video" width="320px" height="240px" autoplay="1" style="border: 1px solid;"></video> <video id="playback_video" width="320px" height="240px" autoplay="1" style="border: 1px solid;"></video> </body> <script> navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; var localVideo = document.getElementById('local_video'); var playbackVideo = document.getElementById('playback_video'); var anchor = document.getElementById('downloadlink'); var localStream = null; var recorder = null; var blobUrl = null; function startRecording() { if (! localStream) { console.warn("no stream"); return; } if (recorder) { console.warn("recorder already exist"); return; } recorder = new MediaRecorder(localStream); recorder.ondataavailable = function(evt) { console.log("data available, start playback"); var videoBlob = new Blob([evt.data], { type: evt.data.type }); blobUrl = window.URL.createObjectURL(videoBlob); playbackVideo.src = blobUrl; playbackVideo.onended = function() { playbackVideo.pause(); playbackVideo.src = ""; }; anchor.download = 'recorded.webm'; anchor.href = blobUrl; playbackVideo.play(); } recorder.start(); console.log("start recording"); } function stopRecording() { if (recorder) { recorder.stop(); console.log("stop recording"); } } function playRecorded() { if (blobUrl) { playbackVideo.src = blobUrl; playbackVideo.onended = function() { playbackVideo.pause(); playbackVideo.src = ""; }; playbackVideo.play(); } } // Request the usermedia function startVideo() { navigator.getUserMedia({video: true, audio: true}, showMedia, errCallback); } function showMedia(stream) { localStream = stream; localVideo.src = window.URL.createObjectURL(stream); } var errCallback = function(e) { console.log('media error', e); }; function stopVideo() { if (localStream) { localVideo.pause(); localVideo.src = ""; localStream.stop(); localStream = null; } } </script> </html> |