webRTCでP2Pの動画チャットを頑張れば試せるデモ作ってみた。

WebRTCって、P2Pで動画チャットできるって聞いたからためしみた。ら、案の定、動作が安定していないのと、
知らないプロトコルとか出てきて泣いた。

www.webrtc.orgに紹介されている http://apprtc.appspot.com/ のデモコードだと
大きすぎて何しているのかわけわからない。
だから、シンプルにするために
 ・最低限のコードにする
 ・サーバをつかわない(本来、P2Pする前にクライアント間でメディア形式を決めるのに使います)
を目標にデモを書いてみた。
なので、手動でコピペを頑張ってもらう部分がありますw

デモを作る前提知識と参考にしたもの

サーバからのPUSHが必要

http://apprtc.appspot.com/ のデモを参考にしています。
デモコードを見るかぎり、サーバからのPUSHが必要です。
このコードは、Google App EngineのChannel APIで実現していますが、
大体は、WebSocketが前提になるんじゃないかと思います。(ハードル高いw)
今回のデモは、この通信を手動で・・・

STUNサーバ

ブラウザ同士がP2Pするには、大体NATを越える必要があるので、STUNサーバが必要です。
グローバル側から見たブラウザのIPなどの情報を教えてくれるものです。
しかし、構築するのにIPが2つ必要らしいので自前で作るのは難しいため
公開STUNサーバを利用することにしました。
http://www.voip-info.org/wiki/view/STUN
(jpはないのですか?)

コード(sample03.html)

<html>
<head>
<title>sample03</title>
</head>
<body>
<script type="text/javascript">

var local;
var remote;
var pc;
var localstream;

var init = function() {
  local = document.getElementById("local");
  remote = document.getElementById("remote");
  navigator.webkitGetUserMedia("video", gotStream, noStream);
}

var sendSignalingChannel = function(message) {
  console.log("sendSignalingChannel:" + message);
  document.form_test.sdp_out.value = message;
}

var gotStream = function(stream) {
  local.src = webkitURL.createObjectURL(stream);
  localstream = stream;
}

var createPC = function() {
  pc = new webkitPeerConnection('STUN stun.ekiga.net', sendSignalingChannel);
  pc.addStream(localstream);
  pc.onaddstream = function (event) {
    remote.src = webkitURL.createObjectURL(event.stream);
  };
}

var noStream = function(error) {
  alert("noStream");
}

var setSDP = function() {
  var text = document.form_test.sdp_in.value;
  text = text.replace(/^\n/g,"");
  pc.processSignalingMessage(text);
}

setTimeout(init,1);

</script>
<video id="local" width="320" height="240" autoplay></video>
<video id="remote" width="320" height="240" autoplay></video><br>
<form name="form_test">
<button onclick="createPC(); return false;">1 createPeerConnection</button><br>
<button onclick="createPC(); setSDP(); return false;">2 input Offer</button><br>
<button onclick="setSDP(); return false;">3 input Answer</button><br>
<button onclick="setSDP(); return false;">4 input OK</button><br>
SDP input<br>
<textarea name="sdp_in" cols="50" rows="5"></textarea><br>
SDP output<br>
<textarea name="sdp_out" cols="50" rows="10"></textarea><br>
</form>
</body>
</html>


デモ

以下にデモページを用意しています。
3月28日現在、WebRTCは、Google Chromeの開発版(DEV Channel)等でしか動作しないので、
Chromeの開発版でMediaStreamを有効にして試してください。
(味見部で試してもらった結果、Chrome Canaryだと動作しないようです)
あと、Webカメラが必要です。

ただし!手順どおり実行しないと動きませんー!
http://alumican.ddo.jp/webrtc/sample03.html
※動作確認は、Google Chrome Version 19.0.1068.1 devでしました。
※動画データなどは、サーバに送信されません。

操作手順

1.http://alumican.ddo.jp/webrtc/sample03.htmlを2つのウィンドウで開く。
 (以下、ブラウザAとブラウザBと呼称)
2.おもむろにブラウザAの「1 createPeerConnection」ボタンを押す。
3.ブラウザAの「SDP output」に表示されたテキストをコピー
4.ブラウザBの「SDP input」にペースト
5.ブラウザBの「2 input Offer」ボタンを押す。
6.ブラウザBの「SDP output」に表示されたテキストをコピー
7.ブラウザAの「SDP input」にペースト
8.ブラウザAの「3 input Answer」ボタンを押す。
9.ブラウザAの「SDP output」に表示されたテキストをコピー
10.ブラウザBの「SDP input」にペースト(※前に入ってたデータは消す)
11.ブラウザBの「4 input OK」ボタンを押す。

この手順を素早く!(時間制限があるみたいだから)
うまくいけば、これでブラウザAもBもカメラの動画がローカルとリモートの2つ表示されます。

f:id:alumican:20120327183354p:plain


基本的に、手順操作に失敗したら、状態依存があるらしく2度と同じ結果が得られないことが多いので
開発版のChromeを再起動するのがいいかなと思います。
他でコーディング試している人はどうしてるんだろう。教えて偉い人m(_ _)m

最期までやってくれた方、お疲れさまでした。
次は、ちゃんとサーバ立ててWebSocket込みのデモを作ろうとおもいます。

 ローカルでしか試していないので不具合とかあったらコメントください。