19. 主な2つの仕様
Media Capture and Streams
ブラウザからカメラやマイクの
メディアストリームを取得するための仕様
WebRTC 1.0: Real-time
Communication Between
Browsers
ブラウザとブラウザをP2Pで接続し
通信を行なうための仕様
20. Media Capture and Streams
(getUserMedia)
ブラウザからマイクやカメラにアクセス
利用範囲はWebRTC以外とも
音声処理(with Web Audio API)
ボイスチェンジャー etc.
画像処理(with Canvas)
顔検出 etc.
顔認識ができるようになるのも時間の問題。
107. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
WebSocketに
イベントハンドラを指定。
initialize内
108. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
WSのメッセージ受信時の処理を指定。
(SDP用)
initialize内
109. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
SDPが含まれているか判定。
RTCSessionDescriptionを生成。
initialize内
110. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
RTCSessionDescriptionを
PeerConnectionに登録。
合わせてcallbackを指定。
initialize内
111. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
受け取ったSDPがofferだった場合、
自動的にanswer処理を実行。
answerの内容は後述。
initialize内
112. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
initialize内
WSのメッセージ受信時の処理を指定。
(経路情報用)
113. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
initialize内
経路情報が含まれているか判定。
RTCIceCandidateを生成。
114. ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.sdp) {return;}
var sdp = data.sdp;
var description = new RTCSessionDescription(sdp);
peer.setRemoteDescription(description, function() {
if (description.type === 'offer') {
answer();
}
});
});
ws.addEventListener('message', function(evt) {
var data = JSON.parse(evt.data);
if (!data.candidate) {return;}
var candidate = new RTCIceCandidate(data.candidate);
peer.addIceCandidate(candidate);
});
initialize内
RTCIceCandidateを
PeerConnectionに登録。
115. peer.addEventListener('icecandidate', function(evt) {
if (!evt.candidate) {return;}
var candidate = evt.candidate;
ws.send(JSON.stringify({candidate: candidate}));
});
peer.addEventListener('addstream', function(evt) {
var video = document.getElementById('remote');
video.src = URL.createObjectURL(evt.stream);
video.play();
});
initialize内
RTCPeerConnectionに
イベントハンドラを指定。
116. peer.addEventListener('icecandidate', function(evt) {
if (!evt.candidate) {return;}
var candidate = evt.candidate;
ws.send(JSON.stringify({candidate: candidate}));
});
peer.addEventListener('addstream', function(evt) {
var video = document.getElementById('remote');
video.src = URL.createObjectURL(evt.stream);
video.play();
});
RTCPeerConnectionの
経路候補取得時の処理を指定。
initialize内
117. peer.addEventListener('icecandidate', function(evt) {
if (!evt.candidate) {return;}
var candidate = evt.candidate;
ws.send(JSON.stringify({candidate: candidate}));
});
peer.addEventListener('addstream', function(evt) {
var video = document.getElementById('remote');
video.src = URL.createObjectURL(evt.stream);
video.play();
});
経路候補が含まれているか判定。
経路候補を対向に送信。
initialize内
118. peer.addEventListener('icecandidate', function(evt) {
if (!evt.candidate) {return;}
var candidate = evt.candidate;
ws.send(JSON.stringify({candidate: candidate}));
});
peer.addEventListener('addstream', function(evt) {
var video = document.getElementById('remote');
video.src = URL.createObjectURL(evt.stream);
video.play();
});
RTCPeerConnectionの
Stream(対向)取得時の処理を指定。
initialize内
119. peer.addEventListener('icecandidate', function(evt) {
if (!evt.candidate) {return;}
var candidate = evt.candidate;
ws.send(JSON.stringify({candidate: candidate}));
});
peer.addEventListener('addstream', function(evt) {
var video = document.getElementById('remote');
video.src = URL.createObjectURL(evt.stream);
video.play();
});
対向のMediaStreamを表示。
initialize内
181. var PEERJS_API_KEY = '[PEERJS_API_KEY]';
var SKYWAY_API_KEY = '[SKYWAY_API_KEY]';
var REST_API_LIST = 'https://skyway.io/v2/active/list/';
API KeyをSkyWay用に変更。
接続しているPeerIDの
一覧を取得するRestAPIのURL。
SkyWay の API Key 取得は以下のURLから。
http://nttcom.github.io/skyway/registration.html
182. ...
var ws = null;
...
function initializeWebSocket(callback) {
var secure = location.protocol === 'https:';
var protocol = secure ? 'wss' : 'ws';
var url = protocol + '://' + location.host + '/';
ws = new WebSocket(url);
ws.addEventListener('open', function() {
callback();
});
ws.addEventListener('message', function(evt) {
var remoteid = evt.data;
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
});
}
...
183. ...
var ws = null;
...
function initializeWebSocket(callback) {
var secure = location.protocol === 'https:';
var protocol = secure ? 'wss' : 'ws';
var url = protocol + '://' + location.host + '/';
ws = new WebSocket(url);
ws.addEventListener('open', function() {
callback();
});
ws.addEventListener('message', function(evt) {
var remoteid = evt.data;
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
});
}
...
WebSocketの処理は削除。
184. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}
RestAPIからPeerIDの一覧を取得し、
全てに発信。
185. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}RestAPIのURL + API Key。
186. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}
Ajax(XHR)お決まりの記述。
187. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}接続しているPeerIDの一覧を取得。
188. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}
RestAPIからPeerIDの一覧を取得し、
全てに自動発信。
189. function callRemoteAll() {
var url = REST_API_LIST + SKYWAY_API_KEY;
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState != 4) {return;}
if (xhr.status != 200) {return;}
var remoteids = JSON.parse(xhr.responseText);
for (var i = 0; i < remoteids.length; i++) {
var remoteid = remoteids[i];
var mediaConnection =
peer.call(remoteid, localStream);
settingMediaConnection(mediaConnection);
}
});
xhr.open('GET', url);
xhr.send();
}
MediaConnectionの設定。