34
WebRTC Conference Japan 2016 WebRTC Boot Camp ハハハハハ ハハハハハハハハハハ ハハハハハハ

Webrtc bootcamp handson

  • Upload
    mganeko

  • View
    890

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Webrtc bootcamp handson

WebRTC Conference Japan 2016WebRTC Boot Camp ハンズオン

インフォコム株式会社がねこまさし

Page 2: Webrtc bootcamp handson

リソース• スライドの URL– http://www.slideshare.net/mganeko/webrtc-bootcamp-

handson– 短縮 http://goo.gl/cA9CV5

• 元になるソースコード– https://github.com/mganeko/bootcamp– 短縮 https://goo.gl/HfXTmT

• 参考– WebRTC を試すために必要なもの (Qiita)

• http://goo.gl/hSfYc9– お手軽な Web サーバーの立て方 (Qiita)

• http://goo.gl/0C18j5

Page 3: Webrtc bootcamp handson

PART 1カメラを使ってみよう

Page 4: Webrtc bootcamp handson

navigator.getUserMedia()• カメラの映像 / マイクの音声を取得できます• ベンダーブレフィックスが付いています

– Chrome: navigator.webkitGetUserMedia()– Firefox: navigator.mozGetUserMedia()

• 最新の仕様では、 navigator.MediaDevices.getUserMedia()– ※ 今日は使いません

• ユーザに許可を求めるダイアログが表示されます• 取得に成功すると MediaStream オブジェクトが得られます• ※Chrome 47 からは https:// 〜でしか利用できなくなりました

– http://localhost は例外として利用できます

Page 5: Webrtc bootcamp handson

コード例// プレフィックスを吸収するnavigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

// カメラの映像を取得する場合navigator.getUserMedia( {video : true}, function(stream) { // 成功時のコールバック }, function(err) { // エラー時のコールバック });

Page 6: Webrtc bootcamp handson

マイクの音声も取得する場合// カメラの映像とマイクの音声を取得する場合navigator.getUserMedia( {video : true, audio: true}, function(stream) { // 成功時のコールバック }, function(err) { // エラー時のコールバック });

※ 会場でやるとうるさいので、今日は音声無しでお願いします

Page 7: Webrtc bootcamp handson

映像を video 要素で再生• window.URL.createObjectURL(stream) で URLを取得– blob:// 〜 という表記の URL を返す

• video 要素の src に指定して再生video.src = window.URL.createObjectURL(stream);video.play();

Page 8: Webrtc bootcamp handson

実際にやってみよう (1)(2)

• media_0.html をエディタで開いてください• startCamera() 関数の (1), (2) を記述してみてください• [start] ボタンを押して、試してみましょう

Page 9: Webrtc bootcamp handson

解答例function startCamera() { // (1) getUserMedia を使って、 camera からメディアストリームを取得してください // また、それを localStream にセットしておいてください navigator.getUserMedia( {video : true}, function(stream) { // success localStream = stream;

// (2) それを localVideo に表示してください localVideo.src = window.URL.createObjectURL(localStream); localVideo.play(); }, function(err) { // error console.error('getUserMedia error', err); } );}

Page 10: Webrtc bootcamp handson

映像の停止• video.pause()• window.URL.revokeObjectURL(url) で URL を解放• ストリームを停止– MediaStream.stop() は Chrome 47 から使えなくなりました– MediaTrack.stop() を使う必要があります

MediaStream

MediaTrack

MediaTrack

Page 11: Webrtc bootcamp handson

実際にやってみよう (3)(4)

• 先ほどの続きで、 stopCamera() 関数の (3), (4) を記述してみてくだい– MediaStream を停止させるための関数を

stopStream(stream) として用意していますので、ご利用ください• [start]→[stop] ボタンを押して、試してみましょう

Page 12: Webrtc bootcamp handson

解答例 function stopCamera() { // (3) localVideo の再生を停止させてください localVideo.pause(); window.URL.revokeObjectURL(localVideo.src); localVideo.src = ''; // Firefox では WARNING // (4) メディアストリームを停止させてください stopStream(localStream); localStream = null; }

Page 13: Webrtc bootcamp handson

参考:新しい getUserMedia• Media Capture and Streams では、新しい API が定義されています

– http://www.w3.org/TR/mediacapture-streams/• navigator.MediaDevices.getUserMedia()• Promise を返しますnavigator.mediaDevices.getUserMedia( {video: true}).then(function (stream) { // 成功時の処理}).catch(function (reason) { // 例外時の処理});

Page 14: Webrtc bootcamp handson

PART 2通信してみよう

Page 15: Webrtc bootcamp handson

RTCPeerConnection• WebRTC 通信には、 RTCPeerConnetion を使用– ブラウザとブラウザの間で直接 Peer-to-Peer 通信を行う– UDP/IP を使用

• TCP/IP のようにパケットの到着は保障しない• オーバーヘッドが少ない• 通信のリアルタイム性を重視• UDP のポート番号は動的に割り振られる( 49152 〜 65535 )

• ベンダーブレフィックスが付いている– Chrome: window.webkitRTCPeerConnetion– Firefox: window.mozRTCPeerConnection

Page 16: Webrtc bootcamp handson

RTCPeerConnection• Peer-to-Peer 通信を確立するために、 2 種類の情報を交換する

– SDP (Session Description Protocol)– ICE Candidate (Interactive Connectivity Establishment Candidate)

• SDP ... 通信する Peer の能力や、条件について– 映像、音声、データーの有無– 使いたいコーデック、使いたい帯域幅、など– 通信を始める側: Offer– 通信に応答する側: Answer

• ICE Candidate– 通信に使う経路の情報

Page 17: Webrtc bootcamp handson

SDP と ICE

• ICE Candidate… 経路の情報を示す。複数ある場合も多い• P2P による直接通信• STUN による、 NAT 通過のためのポートマッピング

– → 最終的には P2P になる• TURN による、リレーサーバーを介した中継通信

SDP SDPICE

Page 18: Webrtc bootcamp handson

ご注意• ICE Candidate を収集するには、デバイスがネットワークに繋がっている必要があります– ネットワーク無し、 localhost のみだと ICE

candidate が収集できない• ハンズオンは、テザリング等でデバイスをネットワークに接続してから、実行してください– 外部と実際には通信しませんが、外部と接続できるネットワークが必要です

Page 19: Webrtc bootcamp handson

シグナリング• 最初は通信相手のことをお互い知らない• 情報をなんらかの方法で交換する必要あり– → シグナリング

• 通常は仲介役となるサーバーを用意– → シグナリングサーバー

• 今日は、仲介役は「あなた」– → 手動でシグナリング

Page 20: Webrtc bootcamp handson

デモ

Page 21: Webrtc bootcamp handson

SDP の交換の概略 : Offer 側• Offer SDP を生成

– RTCPeerConnection.createOffer()• 自分の SDP を覚える

– RTCPeerConnection.setLocalDescription()• 相手に送る• 相手から Answer SDP を受け取ったら、それを覚える

– RTCPeerConnection.setRemoteDescription()

※ 非同期処理になるので、コールバックを使って記述

Page 22: Webrtc bootcamp handson

SDP の交換の概略 : Answer 側• 相手から Offer SDP を受け取ったら、それを覚える– RTCPeerConnection.setRemoteDescription()

• Answer SDP を生成– RTCPeerConnection.createAnswer()

• 自分の SDP を覚える– RTCPeerConnection.setLocalDescription()

• 相手に送り返す※ 非同期処理になるので、コールバックを使って記述

Page 23: Webrtc bootcamp handson

コードの概略// プレフィックスを吸収するRTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

// PeerConnection オブジェクトを生成するvar peerConnection = new RTCPeerConnection({"iceServers":[]}); // iceServers は NAT/Firewall 越えを行う場合に指定 // 今回は指定は空っぽで OK // Offer SDP を生成するpeerConnection.createOffer( function(sessionDescription) { // 成功した場合 }, function(err) { // 失敗した場合 }, {} // オプション指定);

Page 24: Webrtc bootcamp handson

コードの概略(続き)// Answer SDP を生成するpeerConnection.createAnswer( function(sessionDescription) { // 成功した場合 }, function(err) { // 失敗した場合 }, {} // オプション指定);

// SDP を受け取った場合peerConnection.setRemoteDescription(sessionDescription, function() { // 成功 }, function(err) { // 失敗 });

Page 25: Webrtc bootcamp handson

ICE Candidate の交換の概略• ICE Candidate ( 通信経路の候補 ) は複数個ある• 非同期に順々に収集される– RTCPeerConnection.onicecandidate()

• 早く見つかったものから随時交換… Trcikle ICE– 早く繋がるケースが多い

• 全て見つけてから、まとめて交換… Vanilla ICE– 処理はシンプル。※今日はこちらを利用

Page 26: Webrtc bootcamp handson

Trickle ICE によるシグナリング

Page 27: Webrtc bootcamp handson

Vanilla ICE によるシグナリング

Page 28: Webrtc bootcamp handson

コードの概略peerConection.onicecandidate = function (evt) { if (evt.candidate) { // 個々の candidate を収集をした時の処理 // Trikle ICE の場合、ここで処理する } else { // 全ての ICE candidate が収集し終わったタイミング // Vanilla ICE の場合、ここで処理する var sdpWithICE = peerConnection.localDescription.sdp; }};

Page 29: Webrtc bootcamp handson

手動シグナリングをやってみよう(1) 〜 (7)

• hand_vanilla_0.html をエディタで開いてください• makeOffer() 関数の (1),(2) を記述してみてください• setOfferText() 関数の (3),(4) を記述してみてください• makeAnswer() 関数の (5),(6) を記述してみてください• setAnswerText() 関数の (7) を記述してみてください

Page 30: Webrtc bootcamp handson

解答例function makeOffer() { // (1) createOffer を呼び出して、 Offer SDP を生成する peerConnection.createOffer(function (sessionDescription) { // in case of success // (2) 生成された SDP を、 peerConnetion にセットする // Vanilla ICE※ を用いるため、すぐには Offer を相手に送信しない peerConnection.setLocalDescription(sessionDescription, function() { console.log('setLocalDescription() succsess'); // Trickle ICE※ の場合は、このタイミングで Offer SDP を相手に送信する // Vanilla ICE※ の場合には、まだ送らない }, function(err) { console.error('setLocalDescription() ERROR: ', err); } ); console.log('-- Create Offer SDP --'); console.log(sessionDescription); }, function (err) { // in case of error console.error('Create Offer failed:', err); }, mediaConstraints); }

Page 31: Webrtc bootcamp handson

解答例 // Offer を受け取る function setOfferText(text) { // SDP の文字列から RTCSessionDescription のオブジェクトを生成 var offer = new RTCSessionDescription({ type : 'offer', sdp : text, }); // (3) 生成したオブジェクトを、 peerConnetion にセットする // 相手側の SDP をセットする peerConnection.setRemoteDescription(offer, function() { console.log('setRemoteDescription(offer) succsess'); // (4) さらに、適切なタイミングで用意している関数 makeAnswer() を呼び出す // コールバックが呼ばれたら、 Answer を生成する makeAnswer(); }, function(err) { console.error('setRemoteDescription(offer) ERROR: ', err); } ); }

Page 32: Webrtc bootcamp handson

解答例 // Answer を生成する function makeAnswer() { // (5) createAnswer を呼び出して、 Answer SDP を生成する peerConnection.createAnswer(function (sessionDescription) { // in case of success // (6) 生成された SDP を、 peerConnetion にセットする // Vanilla ICE※ を用いるため、すぐには Offer を相手に送信しない peerConnection.setLocalDescription(sessionDescription, function() { console.log('setLocalDescription() succsess'); // Trickle ICE※ の場合は、このタイミングで Answer SDP を相手に送信する // Vanilla ICE※ の場合には、まだ送らない }, function(err) { console.error('setLocalDescription() ERROR: ', err); } );

console.log(sessionDescription); }, function (err) { // in case of error console.error('Create Answer failed:', err); }, mediaConstraints); }

Page 33: Webrtc bootcamp handson

解答例 // Answer を受け取る function setAnswerText(text) { // SDP の文字列から RTCSessionDescription のオブジェクトを生成 var answer = new RTCSessionDescription({ type : 'answer', sdp : text, }); // (7) 生成したオブジェクトを、 peerConnetion にセットする // 相手側の SDP をセットする peerConnection.setRemoteDescription(answer, function() { console.log('setRemoteDescription(answer) succsess'); }, function(err) { console.error('setRemoteDescription(answer) ERROR: ', err); } ); }

Page 34: Webrtc bootcamp handson

Thank you!

34

END