2011年03月26日

Stream APIで、カメラの映像をWebSocket ライブ配信



ずっと、待ち焦がれていたAPIが、ついにテスト実装されました。ブラウザから、カメラのライブストリームを取得するStream API (仕様はWHAT WGのサイトに記載)です。

この機能により、Webアプリのポテンシャルが飛躍的に向上すると期待されます。例えば、ビデオチャット。
stream0
カメラから取得した映像データを、Websocket で相互に交換すれば、ブラウザのネイティブ機能だけで、簡単に実現できます。

この機能が、実装されたのは、Opera mobileのテクニカルプレビュー(for Android)。以下のサイトの[Android build]からインストール出来ます。
http://my.opera.com/core/blog/2011/03/23/webcam-orientation-preview

また、詳しくは以下のブログ(WebOS Goodies)で紹介されています。是非、ご確認下さい。
http://webos-goodies.jp/archives/stream_api_on_opera_mobile.html

映像ストーム配信サンプル

早速、このAPIを使った映像ストリーム配信のサンプルを作りましたので、以下に紹介します。



仕組み

紹介するサンプルは、カメラ映像の各コマをJPEGに変換し、それをWebSocketで他の端末に配信するものです。送信元はGalaxy(Android2.2)のOpera Mobile Technical Previewで、受信は Mac OS版 Chrome11(βチャネル)で動作確認しています(受信は、WebSocketが動作するブラウザなら、多分大丈夫だと思います)。 stream1

Opera Mobileの設定変更

まず、事前準備です。先の Streami API が実装されている、Opera Mobile TPでは、デフォルトでカメラ映像をJPEGに変換することは出来ません。このため、opera:config の Security Prefs で

「Allow Camera To Canvas Copy」
にチェックを入れる必要があります。

これは、カメラからの映像を、自由に画像取得できてしまうと、盗撮などの用途に使えてしまうためです。最終的には、ユーザー確認(「カメラを利用します。よろしいですか?」みたいな)が走るようになると思いますが、現状は何のPermission Controlも走りませんので、ご注意下さい(サンプル利用が終わったら、チェックを外すなど)。

もう一つはデフォルトでWebSocketもdisableになっていますので、これも設定を変更する必要があります。同じく、opera:config の User Prefs で、

「Enable WebSockets」
にチェックを入れる必要があります。(この情報は、Operaのダニエルさんに頂きました。ありがとうございます)

WebSocketがなぜ、デフォルトでオフになっているか?については、僕の以前のポストを確認下さい。
http://blog.livedoor.jp/kotesaki/archives/1600864.html

サンプルコード

これから紹介するサンプルコードを
http://code.google.com/p/komasshu-demo/source/browse/#svn%2Ftrunk%2Fcamerastreaming
においておきました。

  • droid.html : スマートフォン用(カメラからの映像取得と、配信)
  • pc.html : 受信用(配信映像の表示)
  • node/server.js : WebSocketサーバ
以下に、ポイントのみ示しますので、全体は上のサイトで確認して下さい。

映像ストリームの取得と配信(droid.html)

まず、navigator.getUserMedia()で、映像ストリームの取得要求を行います。第一引数は、取得対象を表す文字列、'video', 'audio', 'video,audio'が仕様上は指定可能なようです。

navigator.getUserMedia('video', startCapture_, error_);
第二引数で、取得が成功したときのコールバック関数を指定します(第三引数は、エラー時のコールバック)。

取得が成功すると、映像ソースとして、streamオブジェクトが返されます。これを、video要素のsrc属性に与えると、カメラから取得した映像ストリームが表示されます。あとは、通常のHTML5 Videoと同じです。今回は、秒間30回(33msedおきに)

toDataURL('image/jpeg')
で、Base64エンコードされたスナップショット画像を映像から取得しています。
function startCapture_(stream){
    // video要素に対して、カメラからのストリームを設定
    video.src = stream;
    
    // 30fpsでJPEG画像を取得
    timer = setInterval(function(){
        try {
            // キャンバスノードの生成
            var cvs = document.createElement('canvas');
            cvs.width = video.width;
            cvs.height = video.height;
            var ctx = cvs.getContext('2d');
            
            // キャンバスに描画
            ctx.drawImage(video, 0, 0, 480, 640, 0, 0, video.width, video.height);
            
            // DataURLを取得し、イベントを発行する
            var data = cvs.toDataURL('image/jpeg');
            $(window).trigger("imageupdate", data);
        } catch(e) {
            // エラー時
            error_(e);
        }
    }, 33);
}

上のコードで取得した画像を WebSocket で送信します。

$(window).bind("imageupdate", function(e, data){
	// カメラ画像をWebSocketで送信する
	ws.send(data);
});
映像ストリームの受信と表示(pc.html)

WebSocketサーバのコード(node.js)は、WebSocketで良く見られるものですので、説明は割愛します。ただし、node-websocket-serverの最新版は、requireの時点でエラーになってしまったため、以前のバージョン(1.4.01)を利用しています。

受信側でのコードは、以下のようになります。onmessage()で受信した画像(Base64によるDataURL)を、その都度imgタグのsrc属性に与えているだけです。

ws.onmessage = function(e){
	// imgeノードのsrcを受信データ(DataURL)とする(画像の描画)
	document.getElementById('videoout').src = e.data;
}

非常に簡単に実現できることが分かりますね。これからの進展が楽しみです。更に、Audio Data APIのようなAPIが乗ってきて、audio streamingも連携できるようになると、Video 会議なんかも、簡単に作れるようになるでしょう。

もちろん、現状のままではMotion JPEGでのストリーム配信になっており、本格的なアプリケーションとして使うには色々と問題があります。ですが、WHAT WGの「9 Video conferencing and peer-to-peer communication」を見ると、この辺りについても、既に検討が始まっていることが伺えます。これらの動きは、"HTML5" というより、"post HTML5" (HTML6?) の流れとみたほうがいいかもしれないですね。



人気ブログランキングへ
kotesaki at 21:54│Comments(8)TrackBack(0)clip!html5 | websocket

トラックバックURL

この記事へのコメント

1. Posted by 中村   2011年04月04日 00:41
はじめまして。
中村と申します。

本日、小松さん著のJavaScript Coading BEST PRACTICEを購入させていただきました。

自身javascriptの経験がまだまだ浅いので色々とためになる情報が載っておりとても勉強になっています。

そのなかでCSS3を使ったアニメーションに関する記述(7章)をされているのが小松さんでしたので今回コメントさせていただきました。


CSS3を使ったアニメーションで、同じHTML要素に並列のアニメーションを設定することはできますでしょうか?
例えば常に回転しているdivタグをマウスドラッグで移動させるといった場合などです(ドラッグして移動している最中も回転している)

突然の質問で申し訳ございません。
もしよろしければぜひご教授ください。

よろしくお願い致します。
2. Posted by 小松   2011年04月05日 09:59
コメントありがとうございます。>中村さん

なるほど、、、ちょっと試してみます。

分かったら、本ブログにPOSTしますね:)
3. Posted by 中村   2011年04月05日 13:34
小松さん

わざわざありがとございます!

よろしくお願い致します。
4. Posted by lancel pas cher   2012年11月13日 16:22
コメントありがとうございます。>中村さん

なるほど、、、ちょっと試してみます。

分かったら、本ブログにPOSTしますね:)
5. Posted by gw2 gold   2013年05月14日 12:33
5 本日、小松さん著のJavaScript Coading BEST PRACTICEを購入させていただきました。

自身javascriptの経験がまだまだ浅いので色々とためになる情報が載っておりとても勉強になっています。

そのなかでCSS3を使ったアニメーションに関する記述(7章)をされているのが小松さんでしたので今回コメントさせていただきました。
6. Posted by イヴサンローラン ベルト メンズ   2014年07月28日 10:51
ポロラルフローレン ポロシャツ カスタムフィット,ラルフローレン ポロシャツ,ラルフローレンポロシャツ,ラルフローレン ポロ,ラルフローレン 通販,ポロラルフローレン シャツ,ポロシャツ ラルフローレン,ラルフローレン パンツ,ラルフローレン シャツ,
7. Posted by boutique celine   2014年09月06日 01:31
Un vendeur a une histoire de 2 des ventes vendu. Vendeur B avait un total de 17 ventes vendu. Les vendeurs 茅taient des magasins de taille moyenne, avec 99% des commentaires. Les deux listes 茅taient d'aspect professionnel. Ils 茅taient les seuls vendeurs de cette veste particulier. Pourtant vendeur B avait fait 15 plus de ventes que le vendeur A, et cela doit ?tre attribu茅 ? la client猫le amical T sur les rendements. Maintenant, c'est l? que 莽a devient encore plus int茅ressant. Vendeur B a vendu pour un total de 36,40, et le vendeur A vendait pour un total de 33,98. Nous parlons ici une diff茅rence de la somme de 2,42. Ce n'est pas une grande diff茅rence, mais une diff茅rence que les acheteurs eBay 茅taient pr?ts ? payer pour avoir la paix de l'esprit que si l'enveloppe ne convient pas, ils peuvent le retourner pour un 茅change sans aucune obligation de payer plus pour le repeuplement et l'affranchissement de retour.
8. Posted by Gronkowski Jerseys   2014年09月23日 10:32
This can be a really amazing powerful resource that you’re offering and you just provide it away cost-free!! I that can compare with discovering websites that view the particular property value giving you a wonderful learning resource for zero cost. We truly dearly loved examining this site. Regards!

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔