このページの本文へ

WebRTCでブラウザーが防犯カメラに! (3/4)

2012年06月20日 13時17分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

Google Chromeで映像を定期的に取り込む

 カメラから映像を取り込めたので、今度は映像を静止画として定期的に保存してページ上に出力します。出力間隔は2秒に1枚とし、最大20枚保存して古いものから上書きするようにします。

 画像を表示するコンテナを以下のように用意します。


<div id="camData"></div>

 ページが読み込まれたらスクリプトでimg要素を20個出力します。以下のコードのmaxCamDataの値を変更すれば100個でも200個でもページに出力できます。


// 保存しておく画像を用意
var maxCamData = 20;    // 20枚まで保存
var content = document.getElementById("camData");
for(var i=0; i<maxCamData; i++){
content.innerHTML += '<img src="images/black.png" width="160" height="120">'; 
}

 video要素に表示されている映像をimg要素に出力します。簡易防犯カメラとして利用できるように撮影した日時を画像上に書き込むため、video要素の内容をいったんcanvas要素に出力し、その後、Canvasに書かれた内容をimg要素に出力します。

 video要素に表示されている画像はdrawImage()メソッドでCanvasに描画できます。drawImage()メソッドの第1引数にvideo要素を指定し、第2〜5引数に描画座標と描画サイズを指定します。

 Canvasに描画された画像はtoDataURL()メソッドを使ってDataURIに変換します。img要素のsrc属性にtoDataURL()で変換したデータを代入すると、カメラから取り込んだ映像を画像としてページに表示されます。

 定期的に古い画像から上書きする処理は以下のようになります。camNoは書き換える画像の番号(img要素の出現順番)、maxCamDataは最大表示枚数(20枚)です。

camNo = ( camNo + 1 ) % maxCamData;

 タイマーを使ってこの処理を定期的に呼び出します。実際のプログラムはサンプル3です。2秒ごとに取り込まれた画像がページに表示されます。

2秒ごとに画像が取り込まれページ上に表示されていく

2秒ごとに画像が取り込まれページ上に表示されていく

サンプル3[HTML]


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Google ChromeのWebRTC</title>
    <script>
      window.addEventListener("load", function(){
        // 映像と音声を指定。新仕様では{ video : true, audio: true }
          navigator.webkitGetUserMedia("video, audio",
            function(stream){ // カメラからの取り込みがOKな場合
            // 映像を表示するvideo要素にURLとして代入
            var myVideo = document.getElementsByTagName("video")[0];
            myVideo.src = webkitURL.createObjectURL(stream);
          }, 
          function(error){  // エラーの場合
            console.log("エラー:"+error.code);
          }
        );
        // 保存しておく画像を用意
        var maxCamData = 20;  // 20枚まで保存
        var content = document.getElementById("camData");
        for(var i=0; i<maxCamData; i++){
          content.innerHTML += '<img src="images/black.png" width="160" height="120">'; 
        }
        // 2秒ごとに撮影
        var camNo = 0;
        setInterval(function(){
          var myVideo = document.getElementsByTagName("video")[0];
          var myCanvas = document.getElementsByTagName("canvas")[0];
          var myImage = document.getElementsByTagName("img")[camNo];
          var context = myCanvas.getContext("2d");
          context.drawImage(myVideo, 0, 0, 320, 240);
          myImage.src = myCanvas.toDataURL();
          camNo = ( camNo + 1 ) % maxCamData;
        }, 2*1000);
      }, false);
    </script>
  </head>
  <body>
    <video width="320" height="240" autoplay style="border:1px solid black"></video>
    <canvas width="320" height="240" style="opacity:1"></canvas>
    <hr>
    <div id="camData"></div>
  </body>
</html>

日時を画像上に書き込む

 画像がいつ撮影されたかわかるように、赤い文字で画像の上に日時を書き込みましょう。文字はfillText()メソッドを使ってCanvas上に書き込みます。fillText()メソッドの第1引数は描画する文字、第2引数はX座標、第3引数はY座標です。

 文字のサイズや書体はfontプロパティに、文字の色はfillStyleプロパティに設定します。いずれもCSSで指定できるものと同じです。単純に赤い文字で表示すると表示される画像によっては見づらい場合がありますので、以下のように文字のまわりに黒い影を描画することで文字を認識しやすくします。

context.shadowBlur = 8;
context.shadowColor = "black";
context.fillStyle = "red";
context.font = "20px Arial";

 描画する撮影日時はDateオブジェクトを使って求められます。Dateオブジェクトに関してはJavaScriptの基本的な部分ですので、ここでは省略します。

 実際のプログラムがサンプル4です。定期的に画像が取り込まれ、画像の下に取り込んだ日時が表示されます。

定期的に画像が取り込まれ日時も同時に描画される

定期的に画像が取り込まれ日時も同時に描画される

サンプル4[HTML]

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Google ChromeのWebRTC</title>
    <script>
      window.addEventListener("load", function(){
        // 映像と音声を指定。新仕様では{ video : true, audio: true }
        navigator.webkitGetUserMedia("video, audio",
          function(stream){ // カメラからの取り込みがOKな場合
            // 映像を表示するvideo要素にURLとして代入
            var myVideo = document.getElementsByTagName("video")[0];
            myVideo.src = webkitURL.createObjectURL(stream);
          }, 
          function(error){  // エラーの場合
            console.log("エラー:"+error.code);
          }
        );
        // 保存しておく画像を用意
        var maxCamData = 20;  // 20枚まで保存
        var content = document.getElementById("camData");
        for(var i=0; i<maxCamData; i++){
          content.innerHTML += '<img src="images/black.png" width="160" height="120">'; 
        }
        // 2秒ごとに撮影
        var camNo = 0;
        setInterval(function(){
          var myVideo = document.getElementsByTagName("video")[0];
          var myCanvas = document.getElementsByTagName("canvas")[0];
          var myImage = document.getElementsByTagName("img")[camNo];
          var context = myCanvas.getContext("2d");
          context.drawImage(myVideo, 0, 0, 320, 240);
          camNo = ( camNo + 1 ) % maxCamData;
          // 現在の時刻を取得
          var dateObj = new Date();
          var y = dateObj.getFullYear();
          var m = dateObj.getMonth() + 1;
          var d = dateObj.getDate();
          var H = dateObj.getHours();
          var M = dateObj.getMinutes();
          var S = dateObj.getSeconds();
          var dateString = y+"年"+m+"月"+d+"日 "+H+"時"+M+"分"+S+"秒";
          // Canvasに描画
          context.shadowBlur = 8;
          context.shadowColor = "black";
          context.fillStyle = "red";
          context.font = "20px Arial";
          context.fillText(dateString, 10, 230);
          // img要素に転送
          myImage.src = myCanvas.toDataURL();
        }, 2*1000);
      }, false);
    </script>
  </head>
  <body>
    <video width="320" height="240" autoplay style="border:1px solid black"></video>
    <canvas width="320" height="240" style="opacity:1"></canvas>
    <hr>
    <div id="camData"></div>
  </body>
</html>

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています