taock'sサイト

自称Web系組み込みエンジニアの技術情報などを書いています。

WebRTC getUserMediaを使ってみる(1)

こんばんは、taockです。

最近、HTML5で簡単アプリを作ることが多くなってきたので、面白いものを紹介いこうと思います。

にしても、HTML5によるイノベーションでこれからIT系会社の人員配置、スキルも破壊的に変わってくるのでしょうね。これからも変化だらけの楽しい業界です(Web系から、組み込み系に転職した私はどうなることやらww)

はじめに - HTML5とは -

今までのブラウザでは出来なかったことが、最近のブラウザでは出来るようになってきました。それを可能にする「ブラウザの新しいルール(規格)」がHTML5です。(少し正確に言うと、ここで言うHTML5は、HTML5 + CSS3 + JavaScript APIです。)

ただ、新しいルールなので、ブラウザによっては動かなかったり、ルールが変更になり少し前の記事の情報では動かないといったことも起こります。

最近は、まだマシになってきた方ですが、新しいルールなのでそこらへんは柔軟に対応していきましょう。

今回は、2013年11月24日現在、Chrome31、Firefox25で動く方法をご紹介します。

WebRTCとは

HTML5のルールでWeb RTCというものがあります。Web RTCは、Web RealTimeCommunicationの略です。

Web RTCにより、以下の二つのことが可能になります。

  • カメラ、マイクから動画、音声を取り込む
  • ブラウザ間で相互通信P2P(Peer to Peer)

さっそく動かしてみよう

 [Start]ボタンを押してみてください。するとブラウザ上部にカメラとオーディオのアクセス(または共有)許可を確認するメッセージが表示されますので、許可(または共有)をクリックしてください。(マイクとスピーカが近いとハウリングするので気をつけてください。)

対応ブラウザ:ChromeFirefox

カメラ、マイクから動画、音声が出力されていれば、お使いのブラウザは、動画、音声と取り込むAPI=getUserMedia が使用可能です。

もし、「カメラ未対応のブラウザです。」というメッセージが表示された場合は、

  • ブラウザを最新バージョンにする
  • (Chromeの場合)ブラウザ上部のビデオイメージ画像(URLの右の方)が表示され、赤で×となっている場合は、クリックして、許可してあげてください。

少し前のブラウザでは、設定画面(chrome://flagsなど)でゴニョゴニョしないとgetUserMediaは使用できませんでしたが、現在(2013/11/24)の最新バージョンChrome or Firefoxであれば問題ないです。

 

 

ソース説明

//① getUserMediaのAPIをすべてnavigator.getUserMediaに統一
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
//② window.URLのAPIをすべてwindow.URLに統一
window.URL = window.URL || window.webkitURL;

// ③ 変数
var video = document.querySelector("#video"),
    btnStart = document.querySelector("#start"),
    btnStop = document.querySelector("#stop"),
    videoObj = {
        video: true,
        audio: true
    };

// ④ Startボタンのクリックで動画を取得する
btnStart.addEventListener("click", function() {
    var localMediaStream;//⑥Stream格納変数
    
    // ⑤ カメラ対応ブラウザをチェック
    if (!navigator.getUserMedia) {
        alert("カメラ未対応のブラウザです。");
    }
    navigator.getUserMedia(
        // 使用するデバイスの情報(少し昔は、'video, audio'のように文字列で渡していました。)
        videoObj,
        // ⑥ 成功時の処理
        function(stream) {
            localMediaStream = stream;
            video.src = window.URL.createObjectURL(localMediaStream);
            
        },
        // ⑦ 失敗時の処理
        function(error) {
            console.error("getUserMedia error: ", error);
            alert("エラーが発生しました。:" + error.name);
        });
    // ⑧ 停止処理
    btnStop.addEventListener("click", function() {
        localMediaStream.stop();
    });
});

①動画、音声と取り込むAPIであるgetUserMediaは、ブラウザにより名前が若干違います。そのため、正式のAPIであるnavigator.getUserMediaに上書きして統一しています。現在は新しいルールなので、まだAPIが確立していないため、このようになっていますが、将来的には、すべてのブラウザでnavigator.getUserMediaを呼び出すことで使用可能になるはずです。

ちなみに、慣習的に新しいAPIもしくは独自APIの前に、

Chrome(webkit系)はAPIの前に「webkit」、

FireFox(mozira Gecko)は「moz」、

IE(MicroSoft)は「ms」

が付きます。

② ①と同様にwindow.URLというAPIを使用するためにAPIを統一しています。現在は、Chrome(webkit系)はまだ「webkit」の付いたAPIのみが実装されている状態です。

③ 変数を宣言しています。サンプルなので、グローバル変数にしています。

    videoObjは、getUserMediaの引数に使用する変数です。

④[Start]ボタンのクリックイベントでgetUserMediaを使って、動画と音声を取得しています。

 getUserMediaの引数は、以下です。

  • 第一引数
    動画取得、音声取得を指定オブジェクト
    変数videoObjは、両方取得しています。当然、falseにすればいずれか一方のみの指定も可能です。少し前は、'video, audio'という風に文字列で渡していたため、サンプルによっては、以下のようにtoStringで文字列を返すように書いて汎用的にしているものもあります。
        videoObj = {
            video: true,
            audio: true,
            toString: function(){return 'video audio';}
        };
    
  • 第二引数
    カメラ、マイク接続成功時に実行する関数を指定します。この関数の引数には、MediaStream オブジェクトが渡されます。

  • 第三引数
    カメラ、マイク接続失敗時に実行する関数を指定します。この関数の引数には、sequence<MediaStreamTrack>が渡されます。

⑤getUserMediaが実装されているかでカメラ対応ブラウザか判別しています。

⑥ MediaStream を格納しておく変数を用意しておく。この変数から、カメラの停止などを実行する。

⑦ カメラ、マイク接続に成功したら、⑥で用意した変数にMediaStream を代入しておく。また、videoタグのsrc属性にMediaStream オブジェクトのURLを指定します。
MediaStream オブジェクトからURLを作成するために、window.URL.createObjectURLを使っています。

サンプルには、書いていませんが、window.URL.createObjectURLを使ってURLを作成した場合、必要なくなったタイミングで window.URL.revokeObjectURL(objectURL)を使って参照を破棄しましょう。(unloadの時に自動で参照は破棄されるらしいですが、念のため)

⑧ カメラ、マイク接続に失敗した場合の処理

⑨ ⑥で用意した変数を使って、カメラ、マイクの出力を停止しています。

    

 

 

以上です。

Canvasを使って、カメラのスナップショットを取るサンプルもjsdo.itで公開しています。

http://jsdo.it/taock/webcamera