SlideShare a Scribd company logo
WebRTC Conference Japan 2016
WebRTC Boot Camp ハンズオン
インフォコム株式会社
がねこまさし
リソース
• スライドの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
PART 1
カメラを使ってみよう
navigator.getUserMedia()
• カメラの映像/マイクの音声を取得できます
• ベンダーブレフィックスが付いています
– Chrome: navigator.webkitGetUserMedia()
– Firefox: navigator.mozGetUserMedia()
• 最新の仕様では、navigator.MediaDevices.getUserMedia()
– ※今日は使いません
• ユーザに許可を求めるダイアログが表示されます
• 取得に成功するとMediaStream オブジェクトが得られます
• ※Chrome 47からは https://〜でしか利用できなくなりました
– http://localhost は例外として利用できます
コード例
// プレフィックスを吸収する
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
// カメラの映像を取得する場合
navigator.getUserMedia( {video : true},
function(stream) {
// 成功時のコールバック
},
function(err) {
// エラー時のコールバック
}
);
マイクの音声も取得する場合
// カメラの映像とマイクの音声を取得する場合
navigator.getUserMedia( {video : true, audio: true},
function(stream) {
// 成功時のコールバック
},
function(err) {
// エラー時のコールバック
}
);
※会場でやるとうるさいので、今日は音声無しでお願いします
映像をvideo要素で再生
• window.URL.createObjectURL(stream) でURL
を取得
– blob://〜 という表記のURLを返す
• video要素のsrc に指定して再生
video.src = window.URL.createObjectURL(stream);
video.play();
実際にやってみよう(1)(2)
• media_0.html をエディタで開いてください
• startCamera() 関数の (1), (2) を記述してみて
ください
• [start]ボタンを押して、試してみましょう
解答例
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);
}
);
}
映像の停止
• video.pause()
• window.URL.revokeObjectURL(url) でURLを解放
• ストリームを停止
– MediaStream.stop() はChrome 47から使えなくなりました
– MediaTrack.stop() を使う必要があります
MediaStream
MediaTrack
MediaTrack
実際にやってみよう(3)(4)
• 先ほどの続きで、stopCamera() 関数の (3), (4)
を記述してみてくだい
– MediaStreamを停止させるための関数を
stopStream(stream) として用意していますので、
ご利用ください
• [start]→[stop]ボタンを押して、試してみましょ
う
解答例
function stopCamera() {
// (3) localVideoの再生を停止させてください
localVideo.pause();
window.URL.revokeObjectURL(localVideo.src);
localVideo.src = ''; // Firefox ではWARNING
// (4) メディアストリームを停止させてください
stopStream(localStream);
localStream = null;
}
参考:新しい 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) {
// 例外時の処理
});
PART 2
通信してみよう
RTCPeerConnection
• WebRTC通信には、RTCPeerConnetionを使用
– ブラウザとブラウザの間で直接Peer-to-Peer通信を行う
– UDP/IPを使用
• TCP/IPのようにパケットの到着は保障しない
• オーバーヘッドが少ない
• 通信のリアルタイム性を重視
• UDPのポート番号は動的に割り振られる(49152 ~ 65535)
• ベンダーブレフィックスが付いている
– Chrome: window.webkitRTCPeerConnetion
– Firefox: window.mozRTCPeerConnection
RTCPeerConnection
• Peer-to-Peer 通信を確立するために、2種類の情報を
交換する
– SDP (Session Description Protocol)
– ICE Candidate (Interactive Connectivity Establishment
Candidate)
• SDP ... 通信するPeerの能力や、条件について
– 映像、音声、データーの有無
– 使いたいコーデック、使いたい帯域幅、など
– 通信を始める側: Offer
– 通信に応答する側: Answer
• ICE Candidate
– 通信に使う経路の情報
SDP と ICE
• ICE Candidate…経路の情報を示す。複数ある場合も多い
• P2Pによる直接通信
• STUNによる、NAT通過のためのポートマッピング
– → 最終的にはP2Pになる
• TURNによる、リレーサーバーを介した中継通信
SDP SDPICE
ご注意
• ICE Candidate を収集するには、デバイスが
ネットワークに繋がっている必要があります
– ネットワーク無し、localhostのみだとICE candidate
が収集できない
• ハンズオンは、テザリング等でデバイスをネッ
トワークに接続してから、実行してください
– 外部と実際には通信しませんが、外部と接続でき
るネットワークが必要です
シグナリング
• 最初は通信相手のことをお互い知らない
• 情報をなんらかの方法で交換する必要あり
– → シグナリング
• 通常は仲介役となるサーバーを用意
– → シグナリングサーバー
• 今日は、仲介役は「あなた」
– → 手動でシグナリング
デモ
SDPの交換の概略: Offer側
• Offer SDP を生成
– RTCPeerConnection.createOffer()
• 自分のSDPを覚える
– RTCPeerConnection.setLocalDescription()
• 相手に送る
• 相手から Answer SDP を受け取ったら、それを覚える
– RTCPeerConnection.setRemoteDescription()
※非同期処理になるので、コールバックを使って記述
SDPの交換の概略: Answer側
• 相手から Offer SDP を受け取ったら、それを覚える
– RTCPeerConnection.setRemoteDescription()
• Answer SDP を生成
– RTCPeerConnection.createAnswer()
• 自分のSDPを覚える
– RTCPeerConnection.setLocalDescription()
• 相手に送り返す
※非同期処理になるので、コールバックを使って記述
コードの概略
// プレフィックスを吸収する
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) {
// 失敗した場合
},
{} // オプション指定
);
コードの概略(続き)
// Answer SDPを生成する
peerConnection.createAnswer(
function(sessionDescription) {
// 成功した場合
},
function(err) {
// 失敗した場合
},
{} // オプション指定
);
// SDP を受け取った場合
peerConnection.setRemoteDescription(sessionDescription,
function() {
// 成功
},
function(err) {
// 失敗
}
);
ICE Candidateの交換の概略
• ICE Candidate (通信経路の候補)は複数個ある
• 非同期に順々に収集される
– RTCPeerConnection.onicecandidate()
• 早く見つかったものから随時交換… Trcikle ICE
– 早く繋がるケースが多い
• 全て見つけてから、まとめて交換… Vanilla ICE
– 処理はシンプル。※今日はこちらを利用
Trickle ICE によるシグナリング
Vanilla ICE によるシグナリング
コードの概略
peerConection.onicecandidate = function (evt) {
if (evt.candidate) {
// 個々のcandidateを収集をした時の処理
// Trikle ICE の場合、ここで処理する
} else {
// 全てのICE candidateが収集し終わったタイミング
// Vanilla ICE の場合、ここで処理する
var sdpWithICE = peerConnection.localDescription.sdp;
}
};
手動シグナリングをやってみよう
(1)〜(7)
• hand_vanilla_0.html をエディタで開いてください
• makeOffer()関数の(1),(2)を記述してみてください
• setOfferText()関数の(3),(4)を記述してみてください
• makeAnswer()関数の(5),(6)を記述してみてください
• setAnswerText()関数の(7)を記述してみてください
解答例
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);
}
解答例
// 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);
}
);
}
解答例
// 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);
}
解答例
// 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);
}
);
}
Thank you!
34
END

More Related Content

PDF
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
PPTX
WebRTC meetup Tokyo 1
PPTX
2013 WebRTC node
PDF
2013 WebRTC 概説 & ワークショップ
PPTX
ブラウザでWebRTC - iOSゲートウェイ作ってみた
PDF
Node.js with WebRTC DataChannel
PPTX
Infocom webrtc conference japan
PPTX
WebRTC NextVersion時代のJavaScript開発
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
WebRTC meetup Tokyo 1
2013 WebRTC node
2013 WebRTC 概説 & ワークショップ
ブラウザでWebRTC - iOSゲートウェイ作ってみた
Node.js with WebRTC DataChannel
Infocom webrtc conference japan
WebRTC NextVersion時代のJavaScript開発

What's hot (17)

PDF
WebRTC Boot Camp (WebRTC Conference Japan 2016) 事前公開版
PDF
ラズパイでWebRTC ヾ(*´∀`*)ノキャッキャ uv4l-webrtc 軽くハックしてみたよ!
PDF
5分でわかるWebRTCの仕組み - html5minutes vol.01
PDF
WebRTC/ORTCの最新動向まるわかり!
PPTX
WebRTC SFU Mediasoup Sample update
PDF
WebRTCとPeer.jsを使った実装
PDF
SkyWayとWebRTC開発者コミュニティ4年間の軌跡とCMC_Meetupで学んだこと、実践したこと
PPTX
ORTCの仕様書をざっくり斜め読みする
PPTX
MediaRecorder と WebM で、オレオレ Live Streaming
PPTX
H.264で相互接続 - WebRTC Meetup Tokyo #10
PDF
HTML5と WebSocket / WebRTC / Web Audio API / WebGL 技術解説
PDF
WebRTCの技術解説 第二版 公開版 本編
PPTX
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
PPTX
WebRTCのオーディオ処理の謎、誰か教えて!
PPTX
WebRTCを利用した遠隔リアルタイム映像処理フレームワークの実装
PPTX
SkyWayで作るボイスチャット
PDF
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
WebRTC Boot Camp (WebRTC Conference Japan 2016) 事前公開版
ラズパイでWebRTC ヾ(*´∀`*)ノキャッキャ uv4l-webrtc 軽くハックしてみたよ!
5分でわかるWebRTCの仕組み - html5minutes vol.01
WebRTC/ORTCの最新動向まるわかり!
WebRTC SFU Mediasoup Sample update
WebRTCとPeer.jsを使った実装
SkyWayとWebRTC開発者コミュニティ4年間の軌跡とCMC_Meetupで学んだこと、実践したこと
ORTCの仕様書をざっくり斜め読みする
MediaRecorder と WebM で、オレオレ Live Streaming
H.264で相互接続 - WebRTC Meetup Tokyo #10
HTML5と WebSocket / WebRTC / Web Audio API / WebGL 技術解説
WebRTCの技術解説 第二版 公開版 本編
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTCのオーディオ処理の謎、誰か教えて!
WebRTCを利用した遠隔リアルタイム映像処理フレームワークの実装
SkyWayで作るボイスチャット
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Ad

Viewers also liked (8)

PDF
WebRTCの技術解説 第四版 公開版
PPTX
WebRTCとSFU
PDF
HTML5の基礎と応用 ~Open Web Platform~ WebSocket / WebRTC / Web Audio API / WebGL 第三版
PDF
Value Added Services and WebRTC
PDF
はじめてのWebRTC/ORTC
PDF
SFUの話
PDF
WebRTCの技術解説 公開版
PDF
WebRTC開発者向けプラットフォーム SkyWayの裏側
WebRTCの技術解説 第四版 公開版
WebRTCとSFU
HTML5の基礎と応用 ~Open Web Platform~ WebSocket / WebRTC / Web Audio API / WebGL 第三版
Value Added Services and WebRTC
はじめてのWebRTC/ORTC
SFUの話
WebRTCの技術解説 公開版
WebRTC開発者向けプラットフォーム SkyWayの裏側
Ad

Similar to Webrtc bootcamp handson (20)

PPTX
WebRTC on Native App
PPTX
Chromebook 「だけ」で WebRTCを動かそう
PPTX
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
PPTX
Introduction to Magnum (JP)
PDF
いよいよ始められる Java EEでのWebSocket #jjug #jjug_ccc #ccc_r21
PDF
OpenContrailのソースコードを探検しよう!
PDF
今だからこそ知りたい Docker Compose/Swarm 入門
PDF
How to run P4 BMv2
PDF
VSCodeで始めるAzure Static Web Apps開発
PDF
Let's begin WebRTC
PPTX
EchoyaGinhanazeSu_inoka.pptx
PPTX
WebRTC SFU mediasoup sample
PPTX
WebRTCと ORTCについて 整理しておこう
PDF
マルチクラウド環境でモビンギはどのようにコンテナを動かしているか
PDF
WebRTCがよく分からないから調べて試してみた
PDF
hbstudy37 doc
PDF
Clrh 20140906 lt
PDF
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
PDF
Firefox OS and Web server
ODP
130329 04
WebRTC on Native App
Chromebook 「だけ」で WebRTCを動かそう
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Introduction to Magnum (JP)
いよいよ始められる Java EEでのWebSocket #jjug #jjug_ccc #ccc_r21
OpenContrailのソースコードを探検しよう!
今だからこそ知りたい Docker Compose/Swarm 入門
How to run P4 BMv2
VSCodeで始めるAzure Static Web Apps開発
Let's begin WebRTC
EchoyaGinhanazeSu_inoka.pptx
WebRTC SFU mediasoup sample
WebRTCと ORTCについて 整理しておこう
マルチクラウド環境でモビンギはどのようにコンテナを動かしているか
WebRTCがよく分からないから調べて試してみた
hbstudy37 doc
Clrh 20140906 lt
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
Firefox OS and Web server
130329 04

More from mganeko (15)

PPTX
Amazon Kinesis Video Streams WebRTC 使ってみた
PPTX
Build Node.js-WASM/WASI Tiny compiler with Node.js
PPTX
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
PPTX
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
PPTX
WebRTC mediasoup on raspberrypi3
PDF
Inside of 聖徳玉子 by O2
PPTX
WebRTC Build MCU on browser
PPTX
PeerConnectionリレーとMediaRecorder
PPTX
ここがつらいよWebRTC - WebRTC開発の落とし穴
PPTX
WebRTC multitrack / multistream
PDF
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
PDF
WebRTC multistream
PPTX
Inside WebM
PPTX
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
PDF
WebRTC Summit 2014 NewYork 参加報告
Amazon Kinesis Video Streams WebRTC 使ってみた
Build Node.js-WASM/WASI Tiny compiler with Node.js
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
WebRTC mediasoup on raspberrypi3
Inside of 聖徳玉子 by O2
WebRTC Build MCU on browser
PeerConnectionリレーとMediaRecorder
ここがつらいよWebRTC - WebRTC開発の落とし穴
WebRTC multitrack / multistream
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC multistream
Inside WebM
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
WebRTC Summit 2014 NewYork 参加報告

Webrtc bootcamp handson

  • 1. WebRTC Conference Japan 2016 WebRTC Boot Camp ハンズオン インフォコム株式会社 がねこまさし
  • 2. リソース • スライドの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
  • 4. navigator.getUserMedia() • カメラの映像/マイクの音声を取得できます • ベンダーブレフィックスが付いています – Chrome: navigator.webkitGetUserMedia() – Firefox: navigator.mozGetUserMedia() • 最新の仕様では、navigator.MediaDevices.getUserMedia() – ※今日は使いません • ユーザに許可を求めるダイアログが表示されます • 取得に成功するとMediaStream オブジェクトが得られます • ※Chrome 47からは https://〜でしか利用できなくなりました – http://localhost は例外として利用できます
  • 5. コード例 // プレフィックスを吸収する navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; // カメラの映像を取得する場合 navigator.getUserMedia( {video : true}, function(stream) { // 成功時のコールバック }, function(err) { // エラー時のコールバック } );
  • 6. マイクの音声も取得する場合 // カメラの映像とマイクの音声を取得する場合 navigator.getUserMedia( {video : true, audio: true}, function(stream) { // 成功時のコールバック }, function(err) { // エラー時のコールバック } ); ※会場でやるとうるさいので、今日は音声無しでお願いします
  • 7. 映像をvideo要素で再生 • window.URL.createObjectURL(stream) でURL を取得 – blob://〜 という表記のURLを返す • video要素のsrc に指定して再生 video.src = window.URL.createObjectURL(stream); video.play();
  • 8. 実際にやってみよう(1)(2) • media_0.html をエディタで開いてください • startCamera() 関数の (1), (2) を記述してみて ください • [start]ボタンを押して、試してみましょう
  • 9. 解答例 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); } ); }
  • 10. 映像の停止 • video.pause() • window.URL.revokeObjectURL(url) でURLを解放 • ストリームを停止 – MediaStream.stop() はChrome 47から使えなくなりました – MediaTrack.stop() を使う必要があります MediaStream MediaTrack MediaTrack
  • 11. 実際にやってみよう(3)(4) • 先ほどの続きで、stopCamera() 関数の (3), (4) を記述してみてくだい – MediaStreamを停止させるための関数を stopStream(stream) として用意していますので、 ご利用ください • [start]→[stop]ボタンを押して、試してみましょ う
  • 12. 解答例 function stopCamera() { // (3) localVideoの再生を停止させてください localVideo.pause(); window.URL.revokeObjectURL(localVideo.src); localVideo.src = ''; // Firefox ではWARNING // (4) メディアストリームを停止させてください stopStream(localStream); localStream = null; }
  • 13. 参考:新しい 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) { // 例外時の処理 });
  • 15. RTCPeerConnection • WebRTC通信には、RTCPeerConnetionを使用 – ブラウザとブラウザの間で直接Peer-to-Peer通信を行う – UDP/IPを使用 • TCP/IPのようにパケットの到着は保障しない • オーバーヘッドが少ない • 通信のリアルタイム性を重視 • UDPのポート番号は動的に割り振られる(49152 ~ 65535) • ベンダーブレフィックスが付いている – Chrome: window.webkitRTCPeerConnetion – Firefox: window.mozRTCPeerConnection
  • 16. RTCPeerConnection • Peer-to-Peer 通信を確立するために、2種類の情報を 交換する – SDP (Session Description Protocol) – ICE Candidate (Interactive Connectivity Establishment Candidate) • SDP ... 通信するPeerの能力や、条件について – 映像、音声、データーの有無 – 使いたいコーデック、使いたい帯域幅、など – 通信を始める側: Offer – 通信に応答する側: Answer • ICE Candidate – 通信に使う経路の情報
  • 17. SDP と ICE • ICE Candidate…経路の情報を示す。複数ある場合も多い • P2Pによる直接通信 • STUNによる、NAT通過のためのポートマッピング – → 最終的にはP2Pになる • TURNによる、リレーサーバーを介した中継通信 SDP SDPICE
  • 18. ご注意 • ICE Candidate を収集するには、デバイスが ネットワークに繋がっている必要があります – ネットワーク無し、localhostのみだとICE candidate が収集できない • ハンズオンは、テザリング等でデバイスをネッ トワークに接続してから、実行してください – 外部と実際には通信しませんが、外部と接続でき るネットワークが必要です
  • 19. シグナリング • 最初は通信相手のことをお互い知らない • 情報をなんらかの方法で交換する必要あり – → シグナリング • 通常は仲介役となるサーバーを用意 – → シグナリングサーバー • 今日は、仲介役は「あなた」 – → 手動でシグナリング
  • 21. SDPの交換の概略: Offer側 • Offer SDP を生成 – RTCPeerConnection.createOffer() • 自分のSDPを覚える – RTCPeerConnection.setLocalDescription() • 相手に送る • 相手から Answer SDP を受け取ったら、それを覚える – RTCPeerConnection.setRemoteDescription() ※非同期処理になるので、コールバックを使って記述
  • 22. SDPの交換の概略: Answer側 • 相手から Offer SDP を受け取ったら、それを覚える – RTCPeerConnection.setRemoteDescription() • Answer SDP を生成 – RTCPeerConnection.createAnswer() • 自分のSDPを覚える – RTCPeerConnection.setLocalDescription() • 相手に送り返す ※非同期処理になるので、コールバックを使って記述
  • 23. コードの概略 // プレフィックスを吸収する 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) { // 失敗した場合 }, {} // オプション指定 );
  • 24. コードの概略(続き) // Answer SDPを生成する peerConnection.createAnswer( function(sessionDescription) { // 成功した場合 }, function(err) { // 失敗した場合 }, {} // オプション指定 ); // SDP を受け取った場合 peerConnection.setRemoteDescription(sessionDescription, function() { // 成功 }, function(err) { // 失敗 } );
  • 25. ICE Candidateの交換の概略 • ICE Candidate (通信経路の候補)は複数個ある • 非同期に順々に収集される – RTCPeerConnection.onicecandidate() • 早く見つかったものから随時交換… Trcikle ICE – 早く繋がるケースが多い • 全て見つけてから、まとめて交換… Vanilla ICE – 処理はシンプル。※今日はこちらを利用
  • 28. コードの概略 peerConection.onicecandidate = function (evt) { if (evt.candidate) { // 個々のcandidateを収集をした時の処理 // Trikle ICE の場合、ここで処理する } else { // 全てのICE candidateが収集し終わったタイミング // Vanilla ICE の場合、ここで処理する var sdpWithICE = peerConnection.localDescription.sdp; } };
  • 29. 手動シグナリングをやってみよう (1)〜(7) • hand_vanilla_0.html をエディタで開いてください • makeOffer()関数の(1),(2)を記述してみてください • setOfferText()関数の(3),(4)を記述してみてください • makeAnswer()関数の(5),(6)を記述してみてください • setAnswerText()関数の(7)を記述してみてください
  • 30. 解答例 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); }
  • 31. 解答例 // 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); } ); }
  • 32. 解答例 // 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); }
  • 33. 解答例 // 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); } ); }