簡易ビデオチャットプログラムの解説
それでは、videochat.htmlのソースコードを見てみましょう。プログラムの主な流れは以下のとおりです。
- シグナリングサーバへの接続
- 自分のメディアストリームの取得・再生
- 自分のメディアストリームの引き渡し
- 相手のメディアストリームの取得・再生
シグナリング処理
WebRTCはブラウザ間の直接通信を行う規格なので、通信を始める際には利用可能な映像コーデックや相手のIPアドレス、ポート番号などのセッション情報が必要になります。通信に必要なそれらのセッション情報をやり取りし、通信を開始するまでのプロセスのことを「シグナリング」と呼びます。日本語では「呼制御」と表現したりします。
詳細は、次回以降で述べますが、これらセッション情報はSDP(Session Description Protocol)と呼ばれるフォーマットで記述されており、本来は、その情報のやり取りをシグナリングサーバ含め、すべて自分でコーディングする必要があります。今回使用したSkyWayはこの手間を省いてくれます。SkyWayは、これらの情報のやり取りをすべてライブラリが行うモデルとなっています。さらに、シグナリングサーバも提供されているため、容易にWebRTCプログラミングを行うことができます。
videochat.htmlのスクリプト部分の最初では、シグナリングサーバへ接続し、自分のセッション情報をサーバ上に登録する処理を行っています。
// シグナリングサーバへ接続する // key にはSkyWayを利用するためのAPI Keyを指定する var peer = new Peer({ key: '6165842a-5c0d-11e3-b514-75d3313b9d05', debug: 3}); //シグナリングサーバへの接続が確立したときの処理 peer.on('open', function(){ $('#my-id').text(peer.id); }); // リモートから発信を受けたときの処理 peer.on('call', function(call){ // 自分のストリームを渡す call.answer(localStream); // リモートのビデオを表示 showPeerVideo(call); });
peerは、SkyWayでシグナリングを行う際に使用するオブジェクトです。 peer.onでイベントが発生した際の処理を記述しています。
WebRTCの仕様では、シグナリングの方法に関しては、情報のやりとりの順序のみが規定されており(これをJSEP(Javascript Session Establish Protocol)といいます)その情報をどういった手段で互いに送るかについては一切規定していません。このため、開発者は自分でJSEP部分の実装を行う必要があります。 多くの場合、独自のシグナリングサーバを構築する必要があります。
SkyWayでは、相手のIDを指定して接続要求を行うと、ライブラリがシグナリングサーバを用いたセッション情報の交換をすべて実施してくれます。videochat.htmlで、他方のブラウザに表示されているIDをテキストボックスにコピー&ペーストした後に「Call」ボタンをクリックしているのはこのためです。
自分の映像の取得・再生
ページの読み込みが完了されると実行されるのが、showMyVideo関数です。
navigator.getUserMedia()
というAPIで、カメラやマイクからストリームを取得し始めます。
次の部分をaudio:falseやvideo:falseなどと変更すると、音声をオフにしたり、映像をオフにしたりできます。
{audio: true, video: true}
コールバックでは、
URL.createObjectURL(stream)
というコードで、取得したストリームからURLを生成します。それをvideo要素のsrc属性に渡すことで、自分の映像ストリームを表示しています。
相手の映像の取得・再生
相手のIDを入力し、「Call」をクリックすると以下のコードが実行されます。
var call = peer.call(callee_id, localStream);
peer.callが呼ばれると、シグナリングサーバを経由してセッション情報がcallee_idとの間で交換されます。その情報をもとにブラウザ間のP2P接続が完了すると、localStream で指定した自分の映像ストリームが相手に送信されます。
接続先ではP2P接続完了後、映像ストリームの受信が開始するとcallイベントが発生します。このとき、コールバック関数には送信元の情報を管理するcallオブジェクトが渡されます。 call.answerを呼ぶことで自分の映像ストリームを相手に送信しています。また、callオブジェクト内に接続元の映像ストリーム情報が格納されているため、これをshowPeerVideo関数に渡してリモート映像の表示を行っています。先ではcallイベントが発生するので、call.answerで自分のローカルストリームを接続してきた相手に渡しています。
peer.on('call', function(call){ // 自分のストリームを渡す call.answer(localStream); // リモートのビデオを表示 showPeerVideo(call); });
接続元では、リモートからの映像ストリーム送信が始まると、callオブジェクトに"stream"というイベントが発生します。これに対し、ハンドラを定義することで、接続先の映像ストリームを画面に表示しています。
call.on('stream', function(stream){ // 映像ストリームオブジェクト stream をURL.createObjectURL を用い // URLに変換した後、video 要素の src 属性に指定することで、映像が表示される $('#peer-video').prop('src', URL.createObjectURL(stream)); });
ここでは自分のビデオを表示するときと同じようにオブジェクトURLを生成し、video要素にセットしています。
以上の処理を行うことで、相手のストリームを取得・表示するビデオチャットを作ることができます。
おわりに
今回はSkyWayのライブラリを使用して、簡易なビデオチャットを作成しました。
次回は素のWebRTC APIを使ってプログラムを記述し、APIの仕様やシグナリングの処理について詳しく解説したいと思います。