SlideShare a Scribd company logo
公開版本編 
WebRTCの技術解説 第二版 
WebRTC 勉強会 @ 第1回 NTT-WEST学生向けアプリ開発コンテスト 
https://www.facebook.com/nttw.w.con 
2014/08/05 
NTT西日本 
http://ntt-west.co.jp/
資料公開にあたり 
当資料は学生向けWebRTCコンテストの 
関連イベントであるWebRTC勉強会で 
使用されたものです。 
コンテストの詳細については、 
下記URLをご参照下さい。 
第1回 NTT-WEST学生向けアプリ開発コンテスト 
https://www.facebook.com/nttw.w.con
勉強会に参加された方へ 
勉強会では完全版と分割した 
本編とサンプルコード編を 
使用しましたが、 
第二版でも同様に 
3種類用意しています。
講師紹介 
きんじょう ゆう 
金城 雄 
Twitter @youkinjoh 
GitHub @youkinjoh 
SlideShare @You_Kinjoh 
gihyo.jp 
Jettyで始めるWebSocket超入門 
http://gihyo.jp/dev/feature/01/websocket/0001
INFORMATION 
デモ参加のお願い 
INFORMATION
参加型デモ 
INFORMATION 
カメラ付きの端末でお願いします。 
できるだけ 
新しい 
Chrome 
Android 
パソコン 
INFORMATION
今日お話しすること 
WebRTCの概要 
WebRTCの2つの仕様 
PeerJS 
SkyWay 
ユーザメディアを操作する 
その他雑多な内容
質疑応答について
WebRTC
WebRTC 
Web Real-Time Communication 
リアルタイムコミュニケーションのAPI 
ボイスチャット・ビデオチャットが 
プラグインなしにブラウザでできる 
テキストデータ・バイナリデータも送信可 
P2P
これまでの 
リアルタイム 
コミュニケーション 
との違い
http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より引用
キャリア型通信 
手段の例 
市場 
ユーザ 
メリット 
事業者 
メリット 
利用方法 
固定電話 携帯電話 (TV放送) 
インフラを持つキャリアが支配 
世界中の人と会話できる 
× 
単独で利用 
http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
Over The Top 
手段の例 
市場 
ユーザ 
メリット 
事業者 
メリット 
利用方法 
Skype, WebEx 
(YouTube, Ustream) 
キャリアに縛られない独自の仕組みを 
提供する少数のベンダーが参加可能 
世界中の人と無料/安価で会話できる 
限定的なAPI提供 
一部連携可能 
ユーザが組み合わせて利用 
http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
Webブラウザ型 
手段の例 
市場 
ユーザ 
メリット 
事業者 
メリット 
利用方法 
WebRTC 
特別な仕組みは不要 
誰でも参加可能 
専用アプリ無しで会話できる 
完全にプログラマブル部品として 
利用可能 
製品/サービスに組み込んで利用 
http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
キャリア型通信Over The Top Webブラウザ型 
手段の例 
市場 
ユーザ 
メリット 
事業者 
メリット 
利用方法 
固定電話 
携帯電話 
(TV放送) 
Skype, WebEx 
(Youtube, 
Ustream) 
WebRTC 
インフラを持つ 
キャリアが支配 
キャリアに縛られない 
独自の仕組みを提供 
する少数のベンダー 
が参加可能 
特別な仕組みは不要 
誰でも参加可能 
世界中の人と 
会話できる 
世界中の人と無料/ 
安価で会話できる 
専用アプリ無しで 
会話できる 
× 限定的なAPI提供 
一部連携可能 
完全にプログラマブル 
部品として利用可能 
単独で利用ユーザが組み合わせて 
利用 
製品/サービスに 
組み込んで利用 
http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
対応ブラウザ 
※ 但し、iOSのブラウザは全て未対応 
(2014/07現在)
まだ策定中 
今後もまだ仕様が変更になる可能性がある 
ベンダープレフィックスが必要 
先行したバージョンの使用がお勧め 
Google Chrome Canary 
Firefox Bata 
Firefox Aurora
ベンダープレフィックス 
先行実装であることを示す慣習 
ブラウザベンダーによって違う 
メソッドの挙動が同じであれば、 
代入してメソッド名の違いを吸収できる 
navigator.getUserMedia = 
navigator.getUserMedia || //Specification 
navigator.webkitGetUserMedia || //for Chrome 
navigator.mozGetUserMedia ; //for Firefox 
ベンダープレフィックスの現状は以下を参照のこと。 
https://plus.google.com/app/basic/stream/z121hnjxtqq2svgni23mznm4cxnctznc5
主な2つの仕様 
Media Capture and Streams 
ブラウザからカメラやマイクの 
メディアストリームを取得するための仕様 
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
ブラウザとブラウザをP2Pで接続し 
通信を行なうための仕様
Media Capture and Streams 
(getUserMedia) 
ブラウザからマイクやカメラにアクセス 
利用範囲はWebRTC以外とも 
音声処理(with Web Audio API) 
ボイスチェンジャー etc. 
画像処理(with Canvas) 
顔検出 etc. 
顔認識ができるようになるのも時間の問題。
DEMO
SAMPLE 
音声と映像を取得 
Media Capture and Streams
navigator.getUserMedia = 
navigator.getUserMedia || 
navigator.webkitGetUserMedia || 
navigator.mozGetUserMedia ; 
window.URL = 
window.URL || 
window.webkitURL ; 
window.addEventListener('load', function() { 
navigator.getUserMedia( 
{video: true, audio: true}, 
function(stream) { 
var video = document.getElementById('video'); 
video.src = window.URL.createObjectURL(stream); 
video.play(); 
}, 
function(error) { 
console.error(error); 
} 
); 
}); 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<script src="script.js"></script> 
<title>getUserMedia Sample</title> 
</head> 
<body> 
<video id="video"></video> 
</body> 
</html>
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
ブラウザとブラウザをP2Pで接続 
通信は全て暗号化される 
P2Pの前に要シグナリング 
シグナリングサーバが必要 
WebSocketが良く使われている 
Node.jsならSocket.IO
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
APIが複雑でわかりにくい 
抽象化した仕様の多いHTML5の 
他のAPIと比べると非常に複雑 
それでも、従来のリアルタイム通信の 
処理よりは断然楽 
ジッタやパケットロス等の対策は、 
ブラウザが全て対応してくれる
DEMO
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
ICE (STUN + TURN + α) 
NAT通過・ネゴシエーション 
STUN 
P2P・UDPホールパンチング 
TURN 
P2Pが不可能ならサーバ経由で通信
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
SDP 
セッションプロトコルを記述 
セッション開始に必要な情報 
DTLS (UDP等のデータグラム向けのTLS) 
データ通信は全て暗号化される
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
MediaStream (SRTP・SRTCP) 
音声データ・映像データ 
SRTP (RTPのセキュア版) 
リアルタイムデータ配信の仕様 
SRTCP (RTCPのセキュア版) 
配信用制御プロトコル
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
DataChannel (SCTP) 
テキストデータ・バイナリデータ 
SCTP 
TCPとUDPの良いところ取りをしたプロトコル 
標準ではTCPに似た動作をする 
設定により信頼性と引き換えにリアルタイム性の 
向上が可能で、UDPに似た動作にできる
どの処理をブラウザが 
勝手にやってくれるのか、 
どの処理を自分で 
実装する必要があるのかを 
把握しないと 
実装時に大変混乱する。
どうやって 
ブラウザで 
P2Pを 
実現しているのか
?????????? ?????????? 
画面上部にメソッド名等の 
キーワードが表示されます。 
実装時にご活用下さい。
NATが邪魔して直接通信ができない。 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
HTML+JS+CSS 
Global IP/Port 
signaling 
HTML+JS+CSS 
Global IP/Port 
signaling 
data 
NAT NAT 
Browser Browser
Web Server 
ブラウザでWebRTCを使った 
ページにアクセス。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
HTTP Request 
HTTP Response 
HTML+JS+CSS 
NAT NAT 
Browser Browser
Web Server 
Signaling Serverとして利用する 
WebSocket Serverに接続。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
WebSocket open 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling 
NAT NAT 
Browser Browser
Web Server 
対向のブラウザもWebRTCを使った 
ページにアクセス。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
HTTP Request 
HTTP Response 
HTML+JS+CSS 
signaling 
NAT NAT 
Browser Browser
Web Server 
対向のブラウザも 
WebSocket Serverに接続。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling 
NAT NAT 
Browser Browser
WebSocket open 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling signaling 
NAT NAT 
Browser Browser
以後、WebSocketWeb Server 
は接続を継続する。 
この先、説明の都合上、接続中でもグレーアウトします。 
データが流れる時だけ色がつきます。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling signaling 
NAT NAT 
Browser Browser
接続を開始する側Web でofferServer 
開始。 
SDPを生成・自身に登録後送信。 
対向のブラウザは受け取ったSDPを登録。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Offer SDP 
createOffer 
SDPは以下の 
情報を含む。 
メディアタイプ 
コーデック 
帯域幅 etc.
setLocalDescription 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Offer SDP
WebSocket send 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
signaling Offer SDP 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Offer SDP 
signaling
setRemoteDescription 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Offer SDP
受け取ったofferWeb に対Server 
してanswer開始。 
SDPを生成・自身に登録後送信。 
offerした側でも対向のSDPを登録。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
createAnswer 
SDPは以下の 
情報を含む。 
メディアタイプ 
コーデック 
帯域幅 etc. 
NAT NAT 
Browser Browser 
Answer SDP
setLocalDescription 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Answer SDP
WebSocket send 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
Answer SDP signaling 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Answer SDP 
signaling
setRemoteDescription 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
Answer SDP
P2Pの為に相手Web にIPServer 
を伝える必要がある。 
その為にSTUNを使い自身のIPを調べる。 
ブラウザが裏で処理してくれる。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
ここの 
Global IP/Port 
を知りたい 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
Global 
IP/Port 
Global IP/Port 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
Global IP/Port 
NAT NAT 
Browser Browser 
Global 
IP/Port
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
ここの 
Global IP/Port 
を知りたい 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
Global 
IP/Port 
Global IP/Port 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
Global IP/Port 
NAT NAT 
Browser Browser 
Global 
IP/Port
自身のIP/PortWeb は把握Server 
。 
自身に接続できそうな経路の候補を 
相手側に伝える必要がある。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate 
ブラウザは 
これまでの 
情報を元に 
裏で経路候補 
(candidate)を 
生成。
icecandidate Event 
イベントに 
登録した 
ハンドラ経由で 
経路候補を取得。 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate
WebSocket send 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
ICE 
signaling candidate 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate 
signaling
addIceCandidate 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
ブラウザは 
STUNからの 
情報を元に 
裏で経路候補 
(candidate)を 
NAT NAT 
生成。 
Browser Browser 
ICE 
candidate
icecandidate Event 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate 
イベントに 
登録した 
ハンドラ経由で 
経路候補を取得。
WebSocket send 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
ICE 
candidate signaling 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate 
signaling
addIceCandidate 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser 
ICE 
candidate
P2Pで通信する為の情報が 
(やっと)整った。 
通信開始。 
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT data 
Browser Browser
それでもP2PがWeb 無理だServer 
った場合、 
TURNサーバが中継を行なう。 
TURN経由でもデータの暗号化は解かれずセキュア。 
ICE Server 
(STUN + TURN) 
WebSocket 
Server 
NAT NAT 
Browser Browser
Web Server 
ICE Server 
(STUN + TURN) 
data data 
WebSocket 
Server 
NAT NAT 
Browser Browser
RTCPeerConnection 
ストリーミングを扱うための 
WebRTCの中心となるオブジェクト 
RTCSessionDescription 
SDPを扱うオブジェクト 
RTCIceCandidate 
経路候補を扱うオブジェクト 
RTCDataChannel 
テキスト・バイナリ用のデータチャネル
SAMPLE 
ビデオチャット 
(二者間通信) 
WebRTC 1.0: Real-time 
Communication Between 
Browsers 
このサンプルでは細かい制御は行なっていないので注意してください。
navigator.getUserMedia = 
navigator.getUserMedia || 
navigator.webkitGetUserMedia || 
navigator.mozGetUserMedia ; 
window.URL = 
window.URL || 
window.webkitURL ; 
window.RTCPeerConnection = 
window.RTCPeerConnection || 
window.webkitRTCPeerConnection || 
window.mozRTCPeerConnection ; 
window.RTCSessionDescription = 
window.RTCSessionDescription || 
window.webkitRTCSessionDescription || 
window.mozRTCSessionDescription ; 
window.RTCIceCandidate = 
window.RTCIceCandidate || 
window.webkitRTCIceCandidate || 
window.mozRTCIceCandidate ; 
var ws = null; 
var peer = null; 
function initialize() { 
var secure = location.protocol === 'https:'; 
var protocol = secure ? 'wss' : 'ws'; 
var url = protocol + '://' + location.host + '/'; 
ws = new WebSocket(url); 
peer = new RTCPeerConnection({ 
iceServers: [ 
{url: 'stun:stun.l.google.com:19302'}, 
{url: 'stun:23.21.150.121'} 
] 
}); 
navigator.getUserMedia( 
{audio: true, video: true}, 
function(stream) { 
var video = document.getElementById('local'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
peer.addStream(stream); 
}, 
function(error) { 
console.error(error); 
} 
); 
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); 
}); 
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(); 
}); 
var offerbtn = document.getElementById('offer_button'); 
offerbtn.addEventListener('click', offer); 
} 
function offer() { 
peer.createOffer( 
function(offer) { 
peer.setLocalDescription(offer, function() { 
ws.send(JSON.stringify({sdp: offer})); 
}); 
}, 
function(error) { 
console.error(error); 
} 
); 
} 
function answer() { 
peer.createAnswer( 
function(answer) { 
peer.setLocalDescription(answer, function() { 
ws.send(JSON.stringify({sdp: answer})); 
}); 
}, 
function(error) { 
console.error(error); 
} 
); 
} 
window.addEventListener('load', initialize); 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<link rel="stylesheet" href="styles/style.css" /> 
<script src="scripts/script.js"></script> 
<title>WebRTC Sample</title> 
</head> 
<body> 
<input type="button" value="offer" id="offer_button" /> 
<video id="local" autoplay="autoplay"></video> 
<video id="remote" autoplay="autoplay"></video> 
</body> 
</html>
Library / PaaS 
APIのWrapperや、 
Signaling Server機能を含むもの、 
room機能の有無など様々。 
ICE Serverを提供しているものも。 
クライアント側の実装に 
集中したい場合は、導入の価値あり。 
サーバ側を細かく制御したい場合は 
使わないという選択肢も。
Library / PaaS 
simpleRTC 
room機能あり 
PeerJS 
日本のドキュメントあり(SkyWay内) 
SkyWay 
PeerJSを使ったPaaS 
他にもたくさんあります。 
コンテストで提供する実行環境には、PeerServerがインストールされています。
PeerJS 
Offer/Answerは 
PeerJSが裏でやってくれる。 
接続先を制御するために、 
新たにID(PeerID)の概念が増える。 
(電話番号の概念に近い。) 
通信開始には相手のIDが必要。 
IDを意識させずに自動接続するには、 
WebSocket等でID交換の必要がある。
PeerJS 
Peer 
PeerJSの本体。 
MediaConnection 
MediaStreamのWrapper。 
DataConnection 
DataChannelのWrapper。
SAMPLE 
ビデオチャット 
(多者間通信) 
PeerJS版 
with PeerServer Cloud
navigator.getUserMedia = 
navigator.getUserMedia || 
navigator.webkitGetUserMedia || 
navigator.mozGetUserMedia ; 
window.URL = 
window.URL || 
window.webkitURL ; 
var PEERJS_API_KEY = '[PEERJS_API_KEY]'; 
var ws = null; 
var peer = null; 
var selfid = null; 
var localStream = null; 
function initializePeer(callback) { 
peer = new Peer({key: PEERJS_API_KEY}); 
peer.on('open', function(id) { 
selfid = id; 
callback(); 
}); 
peer.on('call', function(mediaConnection) { 
mediaConnection.answer(localStream); 
settingMediaConnection(mediaConnection); 
}); 
peer.on('close', function() { 
peer.destroy(); 
}); 
peer.on('error', function(err) { 
console.error(err); 
}); 
} 
function initializeMedia(callback) { 
navigator.getUserMedia( 
{audio: true, video: true}, 
function(stream) { 
localStream = stream; 
var video = document.getElementById('local'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
callback(); 
}, 
function(error) { 
console.error(error); 
} 
); 
} 
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); 
}); 
} 
function settingMediaConnection(mediaConnection) { 
var remoteid = mediaConnection.peer; 
var remoteStream = null; 
var video = null; 
mediaConnection.on('stream', function(stream) { 
video = document.createElement('video'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
var parent = document.getElementById('remotes'); 
parent.appendChild(video); 
}); 
mediaConnection.on('close', function() { 
URL.revokeObjectURL(video.src); 
video.parentNode.removeChild(video); 
}); 
mediaConnection.on('error', function() { 
console.error(err); 
}); 
} 
function initialize() { 
initializePeer(function() { 
initializeMedia(function() { 
initializeWebSocket(function() { 
ws.send(selfid); 
}); 
}); 
}); 
} 
window.addEventListener('load', initialize); 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<link rel="stylesheet" href="styles/style.css" /> 
<script src="http://cdn.peerjs.com/0.3/peer.js"></script> 
<script src="scripts/script.js"></script> 
<title>PeerJS Sample</title> 
</head> 
<body> 
<video id="local"></video> 
<div id="remotes"></div> 
</body> 
</html>
SkyWay 
PeerJSを使ったPaaS。 
PeerServer Cloudで 
できることに加え、 
接続しているRemoteの一覧を 
RestAPIで取得可能。 
IDを意識させずに自動接続する場合でも、 
RestAPIでIDを取得できるため、 
静的ファイルのみで構築可能。
SkyWay 
RestAPI 
接続しているPeerIDの一覧を取得 
接続しているPeerの数を取得 
PeerServerでも、起動時に allowDiscovery オプションを指定すると、 
同様のことが可能。
SAMPLE 
ビデオチャット 
(多者間通信) 
SkyWay版 
(静的ファイルのみで動作可能)
navigator.getUserMedia = 
navigator.getUserMedia || 
navigator.webkitGetUserMedia || 
navigator.mozGetUserMedia ; 
window.URL = 
window.URL || 
window.webkitURL ; 
var SKYWAY_API_KEY = '[SKYWAY_API_KEY]'; 
var REST_API_LIST = 'https://skyway.io/v2/active/list/'; 
var peer = null; 
var selfid = null; 
var localStream = null; 
function initializePeer(callback) { 
peer = new Peer({key: SKYWAY_API_KEY}); 
peer.on('open', function(id) { 
selfid = id; 
callback(); 
}); 
peer.on('call', function(mediaConnection) { 
mediaConnection.answer(localStream); 
settingMediaConnection(mediaConnection); 
}); 
peer.on('close', function() { 
peer.destroy(); 
}); 
peer.on('error', function(err) { 
console.error(err); 
}); 
} 
function initializeMedia(callback) { 
navigator.getUserMedia( 
{audio: true, video: true}, 
function(stream) { 
localStream = stream; 
var video = document.getElementById('local'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
callback(); 
}, 
function(error) { 
console.error(error); 
} 
); 
} 
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(); 
} 
function settingMediaConnection(mediaConnection) { 
var remoteid = mediaConnection.peer; 
var remoteStream = null; 
var video = null; 
mediaConnection.on('stream', function(stream) { 
video = document.createElement('video'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
var parent = document.getElementById('remotes'); 
parent.appendChild(video); 
}); 
mediaConnection.on('close', function() { 
URL.revokeObjectURL(video.src); 
video.parentNode.removeChild(video); 
}); 
mediaConnection.on('error', function() { 
console.error(err); 
}); 
} 
function initialize() { 
initializePeer(function() { 
initializeMedia(function() { 
callRemoteAll(); 
}); 
}); 
} 
window.addEventListener('load', initialize); 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<link rel="stylesheet" href="styles/style.css" /> 
<script src="https://skyway.io/dist/v2/0.3/peer.js"></ 
script> 
<script src="scripts/script.js"></script> 
<title>SkyWay Sample</title> 
</head> 
<body> 
<video id="local"></video> 
<div id="remotes"></div> 
</body> 
</html>
ユーザメディアを 
操作する
現在の実装状況 
Web Audio 
API 
Canvas 
Media 
Stream 
Media 
Stream 
音声処理 
画像処理 
MediaStream Processing APIの中にCanvas Recordingという 
Canvas要素からstreamを取得する仕様案があったが進展なし?
処理した音声は送信可能 
処理した映像は送信不可 
Web Audio 
API 
Canvas 
Media 
Stream 
Media 
Stream 
音声処理 
画像処理 
音声処理 
API 再生 
Web Audio 
Canvas 
Media 
Stream 
画像処理 
表示 
受信側ではどちらも処理可能 
画像をバイナリデータとして 
DataChannelで送信・連続して表示することは可能ですが、 
ジッタ処理等のWebRTCのメディア処理の恩恵を受けることができません。 
必要であれば、ジッタ処理等を自分で実装することになります。
MediaStream 
Web Audio API
SAMPLE 
簡易 
ボイスチェンジャー 
MediaStream <=> Web Audio API 
当ボイスチェンジャーで変換した音声は、 
音声解析によりほぼ元の音声を復元可能であり、 
匿名性を担保するものではありません。
navigator.getUserMedia({audio: true}, 
function(inputStream) { 
var audioContext = new AudioContext(); // 要ベンダープレフィックス 
var mediastreamsource = audioContext.createMediaStreamSource(inputStream); 
var scriptProcessor = audioContext.createScriptProcessor(bufferSize, 1, 1); 
var mediastreamdestination = audioContext.createMediaStreamDestination(); 
scriptProcessor.addEventListener('audioprocess', onAudioProcess); 
mediastreamsource.connect(scriptProcessor); 
scriptProcessor.connect(mediastreamdestination); 
var outputStream = mediastreamdestination.stream; 
peer.addStream(outputStream); 
}, 
function(error) {} 
); 
function onAudioProcess(evt) { 
var input = evt.inputBuffer.getChannelData(0); 
var output = evt.outputBuffer.getChannelData(0); 
var bufferData = new Float32Array(bufferSize); 
for (var i = 0; i < bufferSize; i++) { 
bufferData[i] = ( 
(input[(i * 2) % bufferSize] + input[(i * 2 + 1) % bufferSize]) / 2 + 
input[Math.floor(i / 2) % bufferSize] 
) / 2; 
} 
output.set(bufferData); 
}
MediaStream 
Canvas
SAMPLE 
色調反転 
MediaStream => Canvas
navigator.getUserMedia = 
navigator.getUserMedia || 
navigator.webkitGetUserMedia || 
navigator.mozGetUserMedia ; 
window.URL = 
window.URL || 
window.webkitURL ; 
function initialize() { 
navigator.getUserMedia( 
{audio: true, video: true}, 
function(stream) { 
var video = document.getElementById('video'); 
video.src = URL.createObjectURL(stream); 
video.play(); 
renderStart(); 
}, 
function(error) { 
console.error(error); 
} 
); 
} 
function renderStart() { 
var video = document.getElementById('video'); 
var buffer = document.getElementById('buffer_canvas'); 
var display = document.getElementById('display_canvas'); 
var bufferContext = buffer.getContext('2d'); 
var displayContext = display.getContext('2d'); 
var render = function() { 
requestAnimationFrame(render); 
var width = video.videoWidth; 
var height = video.videoHeight; 
if (width == 0 || height == 0) {return;} 
buffer.width = display.width = width; 
buffer.height = display.height = height; 
bufferContext.drawImage(video, 0, 0); 
var imageData = bufferContext.getImageData(0, 0, width, height); 
var data = imageData.data; 
for (var i = 0; i < data.length; i += 4) { 
data[i + 0] = 255 - data[i + 0]; // Red 
data[i + 1] = 255 - data[i + 1]; // Green 
data[i + 2] = 255 - data[i + 2]; // Blue 
} 
imageData.data = data; 
displayContext.putImageData(imageData, 0, 0); 
}; 
render(); 
} 
window.addEventListener('load', initialize); 
<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<link rel="stylesheet" href="styles/style.css" /> 
<script type="text/javascript" src="scripts/script.js"></script> 
<title>Reverse with getUserMedia</title> 
</head> 
<body> 
<video id="video"></video> 
<canvas id="buffer_canvas"></canvas> 
<canvas id="display_canvas"></canvas> 
</body> 
</html>
WebRTCを使って 
何を作るのか 
アイディアがあればそれを。 
なければ考える。 
何も思いつかなければ、 
他のAPIとの組み合わせから 
考える方法も。 
日常の中で、WebRTCを使うと解決する問題や、便利になることはありませんか?
HTML5系 API
http://caniuse.com/ http://platform.html5.org/
Web API
HOT! API 
総務省 次世代統計利用システム(国勢調査、人口推計、就業構 
造、企業統計、物価統計 etc.) 
NHK番組表(※未公開) 
行政・自治体・公共サービス 
郵便番号 
郵便番号検索API(郵便番号 → 住所) 
郵便専門ネット(郵便番号 → 住所、郵便番号の簡易存在チ 
ェック) 
ぽすたん(郵便番号 → 住所、住所 → 郵便番号) 
IW3 PROJECT(郵便番号 → 住所、住所 → 郵便番号) 
宇宙 
Google+ JAXA PR(※現在一部の学生に限定公開、 
Google+にて随時情報を更新) 
ARTSAT 衛星API(芸術衛星・ARTSATの位置情報、高 
度、角速度 etc.) 
図書館 
国立国会図書館サーチ 
カーリル(全国各地の図書館の所蔵・貸出状況) 
テレビ 
テレビ局 
日テレ アプリ 
テレビ関連 
アニメマップ(アニメ番組情報) 
インフラ 
Twilio(電話) 
FullCourt(音声通話、SMS) 
NTT docomo(電話帳、文字認識、音声認識、知識Q&A) 
SNS 
Twitter 
HootSuite(SNS管理、メッセージ投稿) 
Google+ 
LinkedIn 
Instagram 
mixi 
Yammer 
はてなハイク 
Klout(影響力解析) 
Qrust(影響力解析) 
iddy 
About.me 
Pinterest(※Facebookグループにて仕様策定中) 
Timelog 
Yahoo!Japan(※新規申し込み停止中) 
プーペガール 
youRoom 
doodle 
ソーシャルブックマーク 
はてなブックマーク 
はてなブックマーク iPhoneアプリケーション 
はてなスター 
Delicious 
楽天ブックマーク 
スライド 
SlideShare 
音楽 
Last.fm 
iTunes、App Store、 iBookstore、、Mac App 
Store 
Yahoo! Music 
動画 
動画ホスティング 
YouTube 
Vimeo Developer API 
ニコニコ動画 
PANDORA.TV 
Woopie 
動画配信 
Ustream 
ニコニコ実況 
ニコ生アニメ動画API 
Stickam 
TwitCasting 
SOBA Web API 
写真 
Flickr 
Picasa 
フォト蔵 
はてなフォトライフ 
Zorg 
Panoramio 
fotochan(写真補正) 
MyPix(画像に文字を入れる) 
ゲーム 
Steam 
ブログ・グループウェア 
Tumblr 
はてなダイアリー 
はてなexist 
BizPal 
Retired(ブログ引退マークを付ける) 
Google サイト 
プラットフォーム 
OpenSocial 
Mobage 
GREE 
Facebook 
mixi 
OpenSocial 
OpenSocial Host 
infoScoop 
OpenSocial Pages for Google Apps 
認証 
Yahoo!Japan OpenID 2.0 
livedoor 
はてな 
はてな Android認証 
mixi 
Jugem 
地図・位置情報 
地図 
Google Maps 
YOLPYahoo!Japan 
ジオターゲティング(IP → 住所) 
どこどこJP(IP → アクセス元地域・組織) 
HeartRails Geo API 
Windows Virtual Earth 
マピオン 
Geocoding 
LocoSticker.jp 
Maxmind 
地図関連 
住所パワー 
プロジェクト:位置情報 
ジオどす(京都の通り名 → 緯度経度) 
逆ジオコーディングAPI(緯度経度 → ランドマーク) 
簡易逆ジオコーディング 
携帯Art Map 
インクカートリッジ里帰りAPI(インクカートリッジ回収ボ 
ックス) 
送料の虎Webサービス ‒ 送料の虎(送料計算) 
準天頂衛星システム特設サイト QZ-vision(GPS衛星群 
の位置、個数、角度、周波数をプロット) 
位置情報サービス 
foursquare 
ロケタッチ 
はてなココ 
地理 
国土地理院 電子国土Webシステム(PDF) 
http://www.find-job.net/startup/api-2013 より引用 
一覧内のサービス名の 
クリックで、各サービスの 
ページが開きます。
交通 
車・ナビゲーション 
ドコイク?-リクルート 
ナビタイムジャパン 
ガソリン価格情報 
鉄道 
RailGo 
HeartRails Express 
駅データ.jp 
バス 
鯖江市 つつじバス 
高速道路 
高速.jp 
自転車 
自転車大好きマップ 
気象・災害 
天気 
livedoor 天気情報 
天気予報API 
OpenWeatherMap 
天気API コンテンツポケット 
goo天気 
コンテンツポケット 指数API(雨傘指数、洗濯指数 etc.) 
コンテンツポケット 美容天気API 
波浪・潮汐 
Wave Hunter(波浪予測) 
全国潮汐データ 
日の出・日の入時刻 
おはこん番地は!? 
環境 
環境省大気汚染物質広域監視システムAPI 
災害対策 
Yahoo!Japan 震災関連情報 
J-SHIS Web API(地震ハザード情報、表層地盤データ) 
復旧・復興支援制度データベース 
NDL東日本大震災アーカイブ 
気象庁防災情報 
ニュース 
Yahoo! Japan ニュース 
東京証券取引所 
アキバ総研 
書籍・論文 
書籍・雑誌 
版元ドットコム(書誌情報、書影) 
hon.jp(書誌情報、書影) 
web R25(R25一部のタイトル・本文・画像) 
楽天ブックス 
Fujisan(書誌情報、書影) 
Making OPAC 2.0(大手4書店、紀伊國屋書店・旭屋書 
店・ジュンク堂書店・丸善の書店在庫) 
The Code4Lib Journal(海外書籍・雑誌) 
Open Library(海外書籍・雑誌) 
Springer(海外書籍・雑誌) 
出版社 
出版社検索API(出版社コード・ISBN → 出版社名や連絡 
先 etc.) 
論文検索 
CiNii(論文) 
AIRwayプロジェクト(論文) 
Elsevier Article API Profile(海外大手出版社・エル 
ゼビア社の論文) 
アルバム 
TOLOT+アプリ マネタイズAPI、OEM プリントAPI 
辞書 
辞書 
Wikipedia 
デ辞蔵 
ソシオヘルス(医者からもらった薬がわかる本 etc.) 
トレンドワード 
はてなキーワード 
kizasi.jp 
「今日は何の日」API 
IME 
ATOKダイレクト API 
メール・メッセージング 
メール 
Outlook.com 
Gmail 
Yahoo! Japan メール 
Lobi(認証なしでチャット可能) 
メッセージング 
Skype 
Windows Messenger 
はてなメッセージ 
ChatWork 
検索 
Bing 
Live Search 
Yahoo! Japan カテゴリ検索 
検索順位取得API.com 
API比較・マッチングサービスAPI(API自体の検索) 
reflexa(連想検索) 
goo検索 
ナレッジベース 
Qiita 
Stack Overflow(エンジニア向け英語Q&A) 
人力検索はてな 
Yahoo! Japan 知恵袋 
教えて!goo 
言語・テキスト解析 
テキスト解析 
SumibiWebAPI 
Yahoo! Japan テキスト解析 
日本語解析エンジン「なずき」(感性抽出) 
有害情報フィルタAPI 
個人情報フィルタAPI 
5W1H抽出API 
大人なツイートAPI(アダルトな表現を含むツイートの抽 
出) 
hotaru / mushikago.org 
翻訳 
Google Translate 
Microsoft Translator 
Gengo(人力翻訳) 
アカウントアグリゲーション 
Zaim(家計簿) 
決済 
クレジットカード 
Visa 
MasterCard 
Web決済 
PayPal 
WebPay 
ソフトバンク・ペイメント 
Google Commerce API 
スマホ決済 
Square API 
Coiney(※公開予定) 
Eコマース 
ショッピング 
Amazon.co.jp 
Yahoo!ショッピング 
楽天市場 
DMM 
gooショッピング 
NTT-Xストア(PC、家電) 
apicos(@cosmeのクチコミ、商品情報) 
coneco.net 
Yahoo! Japanマーケット(Androidアプリケーショ 
ン) 
カラーミーショップ 
オークション 
Yahoo!オークション 
楽天オークション 
アフィリエイト 
バリューコマース 
楽天アフィリエイト 
DWS3.0 
チケット 
チケットぴあ 
旅行 
楽天トラベルAPI一覧 
じゃらんAPI(国内ホテル空室検索、温泉検索、海外ホテル検 
索) 
AB-ROAD 
yoyaQ.com 
JTB WEBサービス 
http://www.find-job.net/startup/api-2013 より引用 
一覧内のサービス名の 
クリックで、各サービスの 
ページが開きます。
料理 
楽天レシピ 
コンテンツポケット-栄養学 
レストラン 
ぐるなびWebサービス 
食べログAPI 
ホットペッパー 
ロケタッチグルメ 
BAR-NAVI(バー検索) 
ゴルフ 
楽天GORAゴルフ(ゴルフ場検索) 
中古車検索 
カーセンサーラボ.net 
goo自動車&バイク 
不動産 
不動産検索 
住まい探しノート 
goo住宅・不動産 
住宅・家電 
ダイワハウス(住宅内の家電・設備機器のコントロール) 
ガラポンTV(機器に録画された映像の活用) 
占い・心理学 
Web ad Fortune(占い) 
コンテンツポケット-心理学API 
バラエティ 
クイズ研(クイズの出題) 
みんなのはなもげら(はなもげら短歌の生成) 
学習 
ケイコとマナブ 
ケイコとマナブ 通信講座 
リクナビ進学 
求人 
フロム・エー ナビ 
しごとナビ 
クーポン 
グルーポン 
くまポン 
オールクーポン 
ポンパレ 
クーポンサイトjp 
Shareee 
イベント 
ATND 
connpass 
お見合い・婚活パーティー日程情報API(婚活・お見合いパー 
ティー) 
ファッション 
ホットペッパーBeauty 
Art Beat API 
スケジュール・タスク 
カレンダー・スケジュール 
Google Calendar 
Google Apps Platform 
IW3 PROJECT CALENDAR 
サイボウズLive 
サイボウズ ガルーン 3 
Backlog 
曜日・祝日計算サービス 
タスク 
Google Tasks 
コンタクトリスト 
Google Contacts 
デザイン 
Dribbble 
エンジニアリング 
DeployGate(Android開発、自動ビルドと自動配布をラク 
に) 
lleval(JavaScript以外の言語をブラウザーで実行できる) 
Dozens(Dozenで管理しているドメインのゾーン、レコー 
ド etc.) 
バージョン管理システム 
GitHub 
Bitbucket 
Assembla 
Stash 
クラウドストレージ 
Google Drive 
Google Apps 
Dropbox 
Sugarsync 
SkyDrive 
Bitcasa(※公開予定) 
Evernote 
クラウドサービス 
IaaS・VPS 
Amazon Web サービス 
さくらのクラウド 
ニフティクラウド 
クラウド・エヌ 
Windows Azure Service Management API 
PaaS 
Heroku 
force.com 
Google App Engine 
Cloud Foundry 
OpenShift 
AWS Elastic Beanstalk 
dotCloud 
mitsubachi 
BaaS 
Parse 
appiaries 
Kiiクラウド(モバイル専用) 
Appcelerator Cloud Service 
Dropbox Datastore API 
広告 
Google Advertise 
RSS 
RSSナビ RSET API 
livedoor Reader 
アクセス解析 
Google Analytics 
画像認識 
顔検出 
顔ラボ(顔検出) 
PUX(顔検出、顔認識、ペット検出、オブジェクト認識、 
手書き文字認識) 
detectFace();(顔認識) 
音声認識 
Web Speech API 
w3voice Laboratory 
計算 
計算式構文解析サービス 
ユーティリティ 
スパムURLチェック 
FC2ソーシャルスパム対策 
URL短縮 
bitly 
Google URL Shortener API 
p.tl 
ワイヤフレーム作成 
Cacoo 
グラフ生成 
Google Charts(グラフやチャートを画像で取得) 
はてなグラフ 
JSChart(円グラフ、棒グラフ、選グラフ、積み上げ棒グ 
ラフ、百分率棒グラフ) 
HeartRails Graph(キュートな円グラフ) 
Webサイトサムネイル生成 
thumbalizr 
SimpleAPI 
Kikker WebAPIを強化 ‒ Ryoの開発日記 
HeartRails Capture(サムネイル画像生成、PDF ファ 
イル生成) 
Mozshot 
PDF生成 
HTML2PDF.BIZ 
はんこ画像生成 
はんこAPI 
http://www.find-job.net/startup/api-2013 より引用 
一覧内のサービス名の 
クリックで、各サービスの 
ページが開きます。
Hardware
Arduino BeagleBoard 
BeagleBone 
Raspberry Pi mbed 
Chromecast 
Leap Motion 
Controller
補足情報 
WebRTCはファイルを 
Webサーバ上に置かないと動作しない。 
アドレスが http:// か https:// で 
始まる必要がある。 
送られてくる映像の表示サイズは、 
端末のカメラ性能だけでなく、 
帯域の状態によって動的に変わる。 
表示サイズをCSSで指定しておくと良い。
その他の情報
Node.jsによる簡単な 
Web Server + WebSocket Server(Signaling Server) 
server/ 
├── app.js 
├── node_modules/ 
├── package.json 
└── public/ 
├── index.html 
├── scripts/ 
│ └── script.js 
└── styles/ 
└── style.css 
// app.js 
var WebSocketServer = require('ws').Server 
, express = require('express') 
, http = require('http') 
, path = require('path') 
, logger = require('morgan'); 
var app = express(); 
app.set('port', process.env.PORT || 3000); 
app.use(logger()); 
app.use(express.static(path.join(__dirname, 'public'))); 
var conns = []; 
var server = http.createServer(app); 
var wss = new WebSocketServer({server: server}); 
wss.on('connection', function(ws) { 
conns.push(ws); 
ws.on('message', function(data) { 
conns 
.filter(function(conn) {return conn != ws;}) 
.forEach(function(conn) {conn.send(data);}); 
}); 
ws.on('close', function() { 
conns.splice(conns.indexOf(ws), 1); 
}); 
}); 
server.listen(app.get('port'), function() { 
console.log('Express server listening on port ' + app.get('port')); 
}); 
// package.json 
{ 
"name": "SignalingServer", 
"version": "0.0.1", 
"private": true, 
"scripts": { 
"start": "node app.js" 
}, 
"dependencies": { 
"ws": "*", 
"express": "4.*.*", 
"morgan": "*" 
}, 
"engines": { 
"node": "0.10.*", 
"npm": "1.*.*" 
} 
}
ハイパフォーマンス 
ブラウザネットワーキング 
WebRTCの 
下回りを理解 
したい人にお 
勧め。 
#HPBNj 
レビュアーとして参加していますが、宣伝ではありません。念のため。 
http://www.oreilly.co.jp/books/9784873116761/
完
質疑応答
付録
ChromeのWebRTCの 
接続状態を確認するツール 
chrome://webrtc-internals/ 
chrome://webrtc-logs/
FirefoxのWebRTCの 
接続状態を確認するツール 
about:webrtc
getUserMediaの 
オプション例 
音量 
映像の縦横 
最大 / 最小 
フレームレート 
最大 / 最小 
アスペクト比 
利用するカメラ 
user(前面) 
environment(背面) 
left 
right 
etc. 
まだ仕様が固まってない? 動作が不安定。
navigator.getUserMedia( 
constraints, 
onSuccess, 
onError 
); 
// HPBNに載っている指定方法 
// Chrome : エラー / Firefox : 無視 
var constraints = { 
audio: true, 
video: { 
mandatory: { 
width: { min: 320 }, 
height: { min: 180 } 
}, 
optional: [ 
{ width: { max: 1280 }}, 
{ frameRate: 30 }, 
{ facingMode: "user" } 
] 
} 
}; 
// 仕様書に載っている指定方法 
// Chrome : エラー / Firefox : 無視 
var constraints = { 
video: { 
mandatory: { 
width: { min: 640 }, 
height: { min: 480 } 
}, 
optional: [ 
{ width: 650 }, 
{ width: { min: 650 }}, 
{ frameRate: 60 }, 
{ width: { max: 800 }}, 
{ facingMode: "user" } 
] 
} 
}; 
// 一般的な指定方法 
var constraints = { 
audio: true, 
video: true 
}; 
// 動作が確認できた指定方法 
// Chrome : 成功 / Firefox : 無視 
var constraints = { 
video: { 
mandatory: { 
maxWidth: 320, 
maxHeight: 320, 
maxFrameRate: 15 
}, 
optional: [ 
{facingMode: 'user'} 
] 
}, 
audio: true 
}; 
まだ仕様が固まってない? 動作が不安定。
createOfferの 
オプション例 
peer.createOffer(onSuccess, onError, mediaConstraints); 
// データ通信専用のコネクション作成 
var mediaConstraints = {offerToReceiveAudio: false, offerToReceiveVideo: false}; 
// 音声用のコネクション作成(DataChannelを使わなければ音声専用) 
var mediaConstraints = {offerToReceiveAudio: true, offerToReceiveVideo: false}; 
// 映像用のコネクション作成(DataChannelを使わなければ映像専用) 
var mediaConstraints = {offerToReceiveAudio: false, offerToReceiveVideo: true}; 
まだ仕様が固まってない様子。 
Working DraftとEditor's Draftで指定方法が違う。 
指定できるオプションは他にもある。
createDataChannelの 
オプション例 
peer.createDataChannel('DataChannel', dataChannelInit); 
// 順序通り 信頼性有 (like TCP) 
var dataChannelInit = {}; 
// 順不同 信頼性無 (like UDP) 
var dataChannelInit = {ordered: false, maxRetransmits: 0}; 
// 順不同 信頼性有 
var dataChannelInit = {ordered: false}; 
// 順序通り 部分的信頼性(再送カウンタの上限あり:3回) 
var dataChannelInit = {ordered: true, maxRetransmits: 3}; 
// 順不同 部分的信頼性(タイムアウトあり:1000ms) 
var dataChannelInit = {ordered: false, maxRetransmitTime: 1000}; 
指定できるオプションは他にもある。
WebRTC 
http://www.webrtc.org/ 
Media Capture and Streams 
Working Draft 
情報源 
http://www.w3.org/TR/mediacapture-streams/ 
Editor's Draft 
http://dev.w3.org/2011/webrtc/editor/getusermedia.html 
WebRTC 1.0: Real-time Communication Between Browsers 
Working Draft 
http://www.w3.org/TR/webrtc/ 
Editor's Draft 
http://dev.w3.org/2011/webrtc/editor/webrtc.html 
High Performance Browser Networking - Chapter 18. WebRTC 
ハイパフォーマンス ブラウザネットワーキングの原著のオンライン版内 (英語) 
http://chimera.labs.oreilly.com/books/1230000000545/ch18.html 
WebRTC | HTML5Experts.jp 
http://html5experts.jp/tag/webrtc/
情報源 
WebRTCのオープンソースソフトウェアまとめ - Qiita 
http://qiita.com/atskimura/items/97b2cc04e19781f4a4e6 
PeerJS 
PeerJS - Simple peer-to-peer with WebRTC 
http://peerjs.com/ 
PeerJS Documentation 
http://peerjs.com/docs/#api 
PeerJS ドキュメント(SkyWayのサイト内) 
http://nttcom.github.io/skyway/docs/ 
SkyWay 
SkyWay - WebRTCを簡単&柔軟に使えるプラットフォーム 
http://nttcom.github.io/skyway/ 
PeerJS ドキュメント(SkyWayのサイト内) 
http://nttcom.github.io/skyway/docs/
デモ一覧 
getUserMedia 
Pitch Detector with getUserMedia 
http://webaudiodemos.appspot.com/pitchdetect/index.html 
PhiloGL - Real time color 3D histogram 
http://www.senchalabs.org/philogl/PhiloGL/examples/histogram/ 
An AR Game 
https://developer.mozilla.org/ja/demos/detail/an-ar-game/launch 
Facetracking example 
http://auduno.github.io/clmtrackr/clm_video.html 
Emotion detection example 
http://auduno.github.io/clmtrackr/examples/clm_emotiondetection.html 
Face substitution 
http://auduno.github.io/clmtrackr/examples/facesubstitution.html 
Real-time Communication Between Browsers 
Video Chat with getUserMedia 
https://apprtc.appspot.com/ 
VCMap - Video Chat on The Map 
http://vcmap.net/ 
Cube Slam 
https://www.cubeslam.com/

More Related Content

PDF
WebRTCの技術解説 公開版
PDF
WebRTC入門+最新動向
PDF
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
PDF
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
PDF
Installer et configurer NAGIOS sous linux
PDF
Zabbixのパフォーマンスチューニング & インストール時の注意点
PPTX
WebRTC SFU Mediasoup Sample update
PDF
Keystone fernet token
WebRTCの技術解説 公開版
WebRTC入門+最新動向
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
Installer et configurer NAGIOS sous linux
Zabbixのパフォーマンスチューニング & インストール時の注意点
WebRTC SFU Mediasoup Sample update
Keystone fernet token

What's hot (20)

PDF
ソーシャルゲームのためのデータベース設計
PDF
WebRTCの技術解説 第二版 公開版 完全版
PDF
Zabbix最新情報 ~Zabbix 6.0に向けて~ @OSC2021 Online/Fall
PDF
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
PDF
Introduction au développement Web
PDF
Mobage を支える Ruby の技術 ~ 複数DB編 ~
PDF
Administration Linux ( PDFDrive ).pdf
PDF
[Container Runtime Meetup] runc & User Namespaces
PDF
Dalvik仮想マシンのアーキテクチャ 改訂版
PDF
ライブストリーミングの基礎知識
PPTX
PDF
なかったらINSERTしたいし、あるならロック取りたいやん?
PPTX
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
PPTX
今さら聞けない! Active Directoryドメインサービス入門
PDF
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
PDF
AWS Black Belt Online Seminar Elastic Load Balancing
PDF
10GbE時代のネットワークI/O高速化
PDF
ストリーム処理を支えるキューイングシステムの選び方
PPTX
k8s practice 2023.pptx
ソーシャルゲームのためのデータベース設計
WebRTCの技術解説 第二版 公開版 完全版
Zabbix最新情報 ~Zabbix 6.0に向けて~ @OSC2021 Online/Fall
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Introduction au développement Web
Mobage を支える Ruby の技術 ~ 複数DB編 ~
Administration Linux ( PDFDrive ).pdf
[Container Runtime Meetup] runc & User Namespaces
Dalvik仮想マシンのアーキテクチャ 改訂版
ライブストリーミングの基礎知識
なかったらINSERTしたいし、あるならロック取りたいやん?
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
今さら聞けない! Active Directoryドメインサービス入門
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
AWS Black Belt Online Seminar Elastic Load Balancing
10GbE時代のネットワークI/O高速化
ストリーム処理を支えるキューイングシステムの選び方
k8s practice 2023.pptx
Ad

Viewers also liked (14)

PPTX
getUserMedia
PDF
WebRTCハンズオン
PPTX
2013 WebRTC node
PPTX
WebRTC NextVersion時代のJavaScript開発
PPTX
WebRTC on Native App
PPTX
Echo in WebRTC; Why?
PPTX
5分で分るWebRTCコーデックウォーズ
PDF
色々なデバイスの映像を使ったWebブラウザでのWebRTC映像中継(GotAPIからのWebRTC利用)
PDF
WebSocket / WebRTCの技術紹介
PPTX
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
PPTX
Backand Presentation
PDF
WebRTC/ORTCの最新動向まるわかり!
PDF
WebRTC開発者向けプラットフォーム SkyWayの裏側
PPTX
SkyWayで作るボイスチャット
getUserMedia
WebRTCハンズオン
2013 WebRTC node
WebRTC NextVersion時代のJavaScript開発
WebRTC on Native App
Echo in WebRTC; Why?
5分で分るWebRTCコーデックウォーズ
色々なデバイスの映像を使ったWebブラウザでのWebRTC映像中継(GotAPIからのWebRTC利用)
WebSocket / WebRTCの技術紹介
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
Backand Presentation
WebRTC/ORTCの最新動向まるわかり!
WebRTC開発者向けプラットフォーム SkyWayの裏側
SkyWayで作るボイスチャット
Ad

Similar to WebRTCの技術解説 第二版 公開版 本編 (20)

PDF
WebブラウザでP2Pを実現する、WebRTCのAPIと周辺技術
PDF
WebRTCとPeer.jsを使った実装
PDF
Let's begin WebRTC
PPTX
WebRTC meetup Tokyo 1
PDF
WebRTC概説(P2P)
PDF
2013 WebRTC 概説 & ワークショップ
PPTX
WebRTCについて
PDF
About WebRTC
PDF
ビデオ通話・P2Pがコモディティ化する世界 WebRTCによるこれからを探る
PPTX
エフサミ2014 web rtcの傾向と対策
PPTX
Webrtc bootcamp handson
PPTX
WebRTC の紹介
PDF
20130216
PDF
WebRTC を利用したブラウザキャッシュ共有によるデータ配信システム
PDF
WebSocket + Node.jsでつくるチャットアプリ
PDF
HTML5によるリアルタイムコミュニケーション WebRTCの概説
PDF
注目の最新技術「WebRTC」とは? -技術概要と事例紹介-
PDF
Web socketドロンくん その後-
PDF
HTML5と WebSocket / WebRTC / Web Audio API / WebGL 技術解説
PDF
Janogia20120921 yoshinotakeshi
WebブラウザでP2Pを実現する、WebRTCのAPIと周辺技術
WebRTCとPeer.jsを使った実装
Let's begin WebRTC
WebRTC meetup Tokyo 1
WebRTC概説(P2P)
2013 WebRTC 概説 & ワークショップ
WebRTCについて
About WebRTC
ビデオ通話・P2Pがコモディティ化する世界 WebRTCによるこれからを探る
エフサミ2014 web rtcの傾向と対策
Webrtc bootcamp handson
WebRTC の紹介
20130216
WebRTC を利用したブラウザキャッシュ共有によるデータ配信システム
WebSocket + Node.jsでつくるチャットアプリ
HTML5によるリアルタイムコミュニケーション WebRTCの概説
注目の最新技術「WebRTC」とは? -技術概要と事例紹介-
Web socketドロンくん その後-
HTML5と WebSocket / WebRTC / Web Audio API / WebGL 技術解説
Janogia20120921 yoshinotakeshi

WebRTCの技術解説 第二版 公開版 本編

  • 1. 公開版本編 WebRTCの技術解説 第二版 WebRTC 勉強会 @ 第1回 NTT-WEST学生向けアプリ開発コンテスト https://www.facebook.com/nttw.w.con 2014/08/05 NTT西日本 http://ntt-west.co.jp/
  • 2. 資料公開にあたり 当資料は学生向けWebRTCコンテストの 関連イベントであるWebRTC勉強会で 使用されたものです。 コンテストの詳細については、 下記URLをご参照下さい。 第1回 NTT-WEST学生向けアプリ開発コンテスト https://www.facebook.com/nttw.w.con
  • 3. 勉強会に参加された方へ 勉強会では完全版と分割した 本編とサンプルコード編を 使用しましたが、 第二版でも同様に 3種類用意しています。
  • 4. 講師紹介 きんじょう ゆう 金城 雄 Twitter @youkinjoh GitHub @youkinjoh SlideShare @You_Kinjoh gihyo.jp Jettyで始めるWebSocket超入門 http://gihyo.jp/dev/feature/01/websocket/0001
  • 6. 参加型デモ INFORMATION カメラ付きの端末でお願いします。 できるだけ 新しい Chrome Android パソコン INFORMATION
  • 7. 今日お話しすること WebRTCの概要 WebRTCの2つの仕様 PeerJS SkyWay ユーザメディアを操作する その他雑多な内容
  • 10. WebRTC Web Real-Time Communication リアルタイムコミュニケーションのAPI ボイスチャット・ビデオチャットが プラグインなしにブラウザでできる テキストデータ・バイナリデータも送信可 P2P
  • 13. キャリア型通信 手段の例 市場 ユーザ メリット 事業者 メリット 利用方法 固定電話 携帯電話 (TV放送) インフラを持つキャリアが支配 世界中の人と会話できる × 単独で利用 http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
  • 14. Over The Top 手段の例 市場 ユーザ メリット 事業者 メリット 利用方法 Skype, WebEx (YouTube, Ustream) キャリアに縛られない独自の仕組みを 提供する少数のベンダーが参加可能 世界中の人と無料/安価で会話できる 限定的なAPI提供 一部連携可能 ユーザが組み合わせて利用 http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
  • 15. Webブラウザ型 手段の例 市場 ユーザ メリット 事業者 メリット 利用方法 WebRTC 特別な仕組みは不要 誰でも参加可能 専用アプリ無しで会話できる 完全にプログラマブル部品として 利用可能 製品/サービスに組み込んで利用 http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
  • 16. キャリア型通信Over The Top Webブラウザ型 手段の例 市場 ユーザ メリット 事業者 メリット 利用方法 固定電話 携帯電話 (TV放送) Skype, WebEx (Youtube, Ustream) WebRTC インフラを持つ キャリアが支配 キャリアに縛られない 独自の仕組みを提供 する少数のベンダー が参加可能 特別な仕組みは不要 誰でも参加可能 世界中の人と 会話できる 世界中の人と無料/ 安価で会話できる 専用アプリ無しで 会話できる × 限定的なAPI提供 一部連携可能 完全にプログラマブル 部品として利用可能 単独で利用ユーザが組み合わせて 利用 製品/サービスに 組み込んで利用 http://www.slideshare.net/mganeko/2013-web-rtctechcross/6 より改変して引用
  • 18. まだ策定中 今後もまだ仕様が変更になる可能性がある ベンダープレフィックスが必要 先行したバージョンの使用がお勧め Google Chrome Canary Firefox Bata Firefox Aurora
  • 19. ベンダープレフィックス 先行実装であることを示す慣習 ブラウザベンダーによって違う メソッドの挙動が同じであれば、 代入してメソッド名の違いを吸収できる navigator.getUserMedia = navigator.getUserMedia || //Specification navigator.webkitGetUserMedia || //for Chrome navigator.mozGetUserMedia ; //for Firefox ベンダープレフィックスの現状は以下を参照のこと。 https://plus.google.com/app/basic/stream/z121hnjxtqq2svgni23mznm4cxnctznc5
  • 20. 主な2つの仕様 Media Capture and Streams ブラウザからカメラやマイクの メディアストリームを取得するための仕様 WebRTC 1.0: Real-time Communication Between Browsers ブラウザとブラウザをP2Pで接続し 通信を行なうための仕様
  • 21. Media Capture and Streams (getUserMedia) ブラウザからマイクやカメラにアクセス 利用範囲はWebRTC以外とも 音声処理(with Web Audio API) ボイスチェンジャー etc. 画像処理(with Canvas) 顔検出 etc. 顔認識ができるようになるのも時間の問題。
  • 22. DEMO
  • 24. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ; window.URL = window.URL || window.webkitURL ; window.addEventListener('load', function() { navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document.getElementById('video'); video.src = window.URL.createObjectURL(stream); video.play(); }, function(error) { console.error(error); } ); }); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="script.js"></script> <title>getUserMedia Sample</title> </head> <body> <video id="video"></video> </body> </html>
  • 25. WebRTC 1.0: Real-time Communication Between Browsers ブラウザとブラウザをP2Pで接続 通信は全て暗号化される P2Pの前に要シグナリング シグナリングサーバが必要 WebSocketが良く使われている Node.jsならSocket.IO
  • 26. WebRTC 1.0: Real-time Communication Between Browsers APIが複雑でわかりにくい 抽象化した仕様の多いHTML5の 他のAPIと比べると非常に複雑 それでも、従来のリアルタイム通信の 処理よりは断然楽 ジッタやパケットロス等の対策は、 ブラウザが全て対応してくれる
  • 27. DEMO
  • 28. WebRTC 1.0: Real-time Communication Between Browsers ICE (STUN + TURN + α) NAT通過・ネゴシエーション STUN P2P・UDPホールパンチング TURN P2Pが不可能ならサーバ経由で通信
  • 29. WebRTC 1.0: Real-time Communication Between Browsers SDP セッションプロトコルを記述 セッション開始に必要な情報 DTLS (UDP等のデータグラム向けのTLS) データ通信は全て暗号化される
  • 30. WebRTC 1.0: Real-time Communication Between Browsers MediaStream (SRTP・SRTCP) 音声データ・映像データ SRTP (RTPのセキュア版) リアルタイムデータ配信の仕様 SRTCP (RTCPのセキュア版) 配信用制御プロトコル
  • 31. WebRTC 1.0: Real-time Communication Between Browsers DataChannel (SCTP) テキストデータ・バイナリデータ SCTP TCPとUDPの良いところ取りをしたプロトコル 標準ではTCPに似た動作をする 設定により信頼性と引き換えにリアルタイム性の 向上が可能で、UDPに似た動作にできる
  • 32. どの処理をブラウザが 勝手にやってくれるのか、 どの処理を自分で 実装する必要があるのかを 把握しないと 実装時に大変混乱する。
  • 33. どうやって ブラウザで P2Pを 実現しているのか
  • 34. ?????????? ?????????? 画面上部にメソッド名等の キーワードが表示されます。 実装時にご活用下さい。
  • 36. Web Server ICE Server (STUN + TURN) WebSocket Server HTML+JS+CSS Global IP/Port signaling HTML+JS+CSS Global IP/Port signaling data NAT NAT Browser Browser
  • 37. Web Server ブラウザでWebRTCを使った ページにアクセス。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 38. Web Server ICE Server (STUN + TURN) WebSocket Server HTTP Request HTTP Response HTML+JS+CSS NAT NAT Browser Browser
  • 39. Web Server Signaling Serverとして利用する WebSocket Serverに接続。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 40. WebSocket open Web Server ICE Server (STUN + TURN) WebSocket Server signaling NAT NAT Browser Browser
  • 41. Web Server 対向のブラウザもWebRTCを使った ページにアクセス。 ICE Server (STUN + TURN) WebSocket Server signaling NAT NAT Browser Browser
  • 42. Web Server ICE Server (STUN + TURN) WebSocket Server HTTP Request HTTP Response HTML+JS+CSS signaling NAT NAT Browser Browser
  • 43. Web Server 対向のブラウザも WebSocket Serverに接続。 ICE Server (STUN + TURN) WebSocket Server signaling NAT NAT Browser Browser
  • 44. WebSocket open Web Server ICE Server (STUN + TURN) WebSocket Server signaling signaling NAT NAT Browser Browser
  • 45. 以後、WebSocketWeb Server は接続を継続する。 この先、説明の都合上、接続中でもグレーアウトします。 データが流れる時だけ色がつきます。 ICE Server (STUN + TURN) WebSocket Server signaling signaling NAT NAT Browser Browser
  • 46. 接続を開始する側Web でofferServer 開始。 SDPを生成・自身に登録後送信。 対向のブラウザは受け取ったSDPを登録。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 47. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Offer SDP createOffer SDPは以下の 情報を含む。 メディアタイプ コーデック 帯域幅 etc.
  • 48. setLocalDescription Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Offer SDP
  • 49. WebSocket send Web Server ICE Server (STUN + TURN) WebSocket Server signaling Offer SDP NAT NAT Browser Browser
  • 50. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Offer SDP signaling
  • 51. setRemoteDescription Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Offer SDP
  • 52. 受け取ったofferWeb に対Server してanswer開始。 SDPを生成・自身に登録後送信。 offerした側でも対向のSDPを登録。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 53. Web Server ICE Server (STUN + TURN) WebSocket Server createAnswer SDPは以下の 情報を含む。 メディアタイプ コーデック 帯域幅 etc. NAT NAT Browser Browser Answer SDP
  • 54. setLocalDescription Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Answer SDP
  • 55. WebSocket send Web Server ICE Server (STUN + TURN) WebSocket Server Answer SDP signaling NAT NAT Browser Browser
  • 56. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Answer SDP signaling
  • 57. setRemoteDescription Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser Answer SDP
  • 58. P2Pの為に相手Web にIPServer を伝える必要がある。 その為にSTUNを使い自身のIPを調べる。 ブラウザが裏で処理してくれる。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 59. Web Server ICE Server (STUN + TURN) WebSocket Server ここの Global IP/Port を知りたい NAT NAT Browser Browser
  • 60. Web Server ICE Server (STUN + TURN) WebSocket Server Global IP/Port Global IP/Port NAT NAT Browser Browser
  • 61. Web Server ICE Server (STUN + TURN) WebSocket Server Global IP/Port NAT NAT Browser Browser Global IP/Port
  • 62. Web Server ICE Server (STUN + TURN) WebSocket Server ここの Global IP/Port を知りたい NAT NAT Browser Browser
  • 63. Web Server ICE Server (STUN + TURN) WebSocket Server Global IP/Port Global IP/Port NAT NAT Browser Browser
  • 64. Web Server ICE Server (STUN + TURN) WebSocket Server Global IP/Port NAT NAT Browser Browser Global IP/Port
  • 65. 自身のIP/PortWeb は把握Server 。 自身に接続できそうな経路の候補を 相手側に伝える必要がある。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 66. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate ブラウザは これまでの 情報を元に 裏で経路候補 (candidate)を 生成。
  • 67. icecandidate Event イベントに 登録した ハンドラ経由で 経路候補を取得。 Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate
  • 68. WebSocket send Web Server ICE Server (STUN + TURN) WebSocket Server ICE signaling candidate NAT NAT Browser Browser
  • 69. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate signaling
  • 70. addIceCandidate Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate
  • 71. Web Server ICE Server (STUN + TURN) WebSocket Server ブラウザは STUNからの 情報を元に 裏で経路候補 (candidate)を NAT NAT 生成。 Browser Browser ICE candidate
  • 72. icecandidate Event Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate イベントに 登録した ハンドラ経由で 経路候補を取得。
  • 73. WebSocket send Web Server ICE Server (STUN + TURN) WebSocket Server ICE candidate signaling NAT NAT Browser Browser
  • 74. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate signaling
  • 75. addIceCandidate Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser ICE candidate
  • 76. P2Pで通信する為の情報が (やっと)整った。 通信開始。 Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 77. Web Server ICE Server (STUN + TURN) WebSocket Server NAT NAT data Browser Browser
  • 78. それでもP2PがWeb 無理だServer った場合、 TURNサーバが中継を行なう。 TURN経由でもデータの暗号化は解かれずセキュア。 ICE Server (STUN + TURN) WebSocket Server NAT NAT Browser Browser
  • 79. Web Server ICE Server (STUN + TURN) data data WebSocket Server NAT NAT Browser Browser
  • 80. RTCPeerConnection ストリーミングを扱うための WebRTCの中心となるオブジェクト RTCSessionDescription SDPを扱うオブジェクト RTCIceCandidate 経路候補を扱うオブジェクト RTCDataChannel テキスト・バイナリ用のデータチャネル
  • 81. SAMPLE ビデオチャット (二者間通信) WebRTC 1.0: Real-time Communication Between Browsers このサンプルでは細かい制御は行なっていないので注意してください。
  • 82. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ; window.URL = window.URL || window.webkitURL ; window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection ; window.RTCSessionDescription = window.RTCSessionDescription || window.webkitRTCSessionDescription || window.mozRTCSessionDescription ; window.RTCIceCandidate = window.RTCIceCandidate || window.webkitRTCIceCandidate || window.mozRTCIceCandidate ; var ws = null; var peer = null; function initialize() { var secure = location.protocol === 'https:'; var protocol = secure ? 'wss' : 'ws'; var url = protocol + '://' + location.host + '/'; ws = new WebSocket(url); peer = new RTCPeerConnection({ iceServers: [ {url: 'stun:stun.l.google.com:19302'}, {url: 'stun:23.21.150.121'} ] }); navigator.getUserMedia( {audio: true, video: true}, function(stream) { var video = document.getElementById('local'); video.src = URL.createObjectURL(stream); video.play(); peer.addStream(stream); }, function(error) { console.error(error); } ); 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); }); 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(); }); var offerbtn = document.getElementById('offer_button'); offerbtn.addEventListener('click', offer); } function offer() { peer.createOffer( function(offer) { peer.setLocalDescription(offer, function() { ws.send(JSON.stringify({sdp: offer})); }); }, function(error) { console.error(error); } ); } function answer() { peer.createAnswer( function(answer) { peer.setLocalDescription(answer, function() { ws.send(JSON.stringify({sdp: answer})); }); }, function(error) { console.error(error); } ); } window.addEventListener('load', initialize); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="styles/style.css" /> <script src="scripts/script.js"></script> <title>WebRTC Sample</title> </head> <body> <input type="button" value="offer" id="offer_button" /> <video id="local" autoplay="autoplay"></video> <video id="remote" autoplay="autoplay"></video> </body> </html>
  • 83. Library / PaaS APIのWrapperや、 Signaling Server機能を含むもの、 room機能の有無など様々。 ICE Serverを提供しているものも。 クライアント側の実装に 集中したい場合は、導入の価値あり。 サーバ側を細かく制御したい場合は 使わないという選択肢も。
  • 84. Library / PaaS simpleRTC room機能あり PeerJS 日本のドキュメントあり(SkyWay内) SkyWay PeerJSを使ったPaaS 他にもたくさんあります。 コンテストで提供する実行環境には、PeerServerがインストールされています。
  • 85. PeerJS Offer/Answerは PeerJSが裏でやってくれる。 接続先を制御するために、 新たにID(PeerID)の概念が増える。 (電話番号の概念に近い。) 通信開始には相手のIDが必要。 IDを意識させずに自動接続するには、 WebSocket等でID交換の必要がある。
  • 86. PeerJS Peer PeerJSの本体。 MediaConnection MediaStreamのWrapper。 DataConnection DataChannelのWrapper。
  • 87. SAMPLE ビデオチャット (多者間通信) PeerJS版 with PeerServer Cloud
  • 88. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ; window.URL = window.URL || window.webkitURL ; var PEERJS_API_KEY = '[PEERJS_API_KEY]'; var ws = null; var peer = null; var selfid = null; var localStream = null; function initializePeer(callback) { peer = new Peer({key: PEERJS_API_KEY}); peer.on('open', function(id) { selfid = id; callback(); }); peer.on('call', function(mediaConnection) { mediaConnection.answer(localStream); settingMediaConnection(mediaConnection); }); peer.on('close', function() { peer.destroy(); }); peer.on('error', function(err) { console.error(err); }); } function initializeMedia(callback) { navigator.getUserMedia( {audio: true, video: true}, function(stream) { localStream = stream; var video = document.getElementById('local'); video.src = URL.createObjectURL(stream); video.play(); callback(); }, function(error) { console.error(error); } ); } 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); }); } function settingMediaConnection(mediaConnection) { var remoteid = mediaConnection.peer; var remoteStream = null; var video = null; mediaConnection.on('stream', function(stream) { video = document.createElement('video'); video.src = URL.createObjectURL(stream); video.play(); var parent = document.getElementById('remotes'); parent.appendChild(video); }); mediaConnection.on('close', function() { URL.revokeObjectURL(video.src); video.parentNode.removeChild(video); }); mediaConnection.on('error', function() { console.error(err); }); } function initialize() { initializePeer(function() { initializeMedia(function() { initializeWebSocket(function() { ws.send(selfid); }); }); }); } window.addEventListener('load', initialize); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="styles/style.css" /> <script src="http://cdn.peerjs.com/0.3/peer.js"></script> <script src="scripts/script.js"></script> <title>PeerJS Sample</title> </head> <body> <video id="local"></video> <div id="remotes"></div> </body> </html>
  • 89. SkyWay PeerJSを使ったPaaS。 PeerServer Cloudで できることに加え、 接続しているRemoteの一覧を RestAPIで取得可能。 IDを意識させずに自動接続する場合でも、 RestAPIでIDを取得できるため、 静的ファイルのみで構築可能。
  • 90. SkyWay RestAPI 接続しているPeerIDの一覧を取得 接続しているPeerの数を取得 PeerServerでも、起動時に allowDiscovery オプションを指定すると、 同様のことが可能。
  • 91. SAMPLE ビデオチャット (多者間通信) SkyWay版 (静的ファイルのみで動作可能)
  • 92. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ; window.URL = window.URL || window.webkitURL ; var SKYWAY_API_KEY = '[SKYWAY_API_KEY]'; var REST_API_LIST = 'https://skyway.io/v2/active/list/'; var peer = null; var selfid = null; var localStream = null; function initializePeer(callback) { peer = new Peer({key: SKYWAY_API_KEY}); peer.on('open', function(id) { selfid = id; callback(); }); peer.on('call', function(mediaConnection) { mediaConnection.answer(localStream); settingMediaConnection(mediaConnection); }); peer.on('close', function() { peer.destroy(); }); peer.on('error', function(err) { console.error(err); }); } function initializeMedia(callback) { navigator.getUserMedia( {audio: true, video: true}, function(stream) { localStream = stream; var video = document.getElementById('local'); video.src = URL.createObjectURL(stream); video.play(); callback(); }, function(error) { console.error(error); } ); } 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(); } function settingMediaConnection(mediaConnection) { var remoteid = mediaConnection.peer; var remoteStream = null; var video = null; mediaConnection.on('stream', function(stream) { video = document.createElement('video'); video.src = URL.createObjectURL(stream); video.play(); var parent = document.getElementById('remotes'); parent.appendChild(video); }); mediaConnection.on('close', function() { URL.revokeObjectURL(video.src); video.parentNode.removeChild(video); }); mediaConnection.on('error', function() { console.error(err); }); } function initialize() { initializePeer(function() { initializeMedia(function() { callRemoteAll(); }); }); } window.addEventListener('load', initialize); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="styles/style.css" /> <script src="https://skyway.io/dist/v2/0.3/peer.js"></ script> <script src="scripts/script.js"></script> <title>SkyWay Sample</title> </head> <body> <video id="local"></video> <div id="remotes"></div> </body> </html>
  • 94. 現在の実装状況 Web Audio API Canvas Media Stream Media Stream 音声処理 画像処理 MediaStream Processing APIの中にCanvas Recordingという Canvas要素からstreamを取得する仕様案があったが進展なし?
  • 95. 処理した音声は送信可能 処理した映像は送信不可 Web Audio API Canvas Media Stream Media Stream 音声処理 画像処理 音声処理 API 再生 Web Audio Canvas Media Stream 画像処理 表示 受信側ではどちらも処理可能 画像をバイナリデータとして DataChannelで送信・連続して表示することは可能ですが、 ジッタ処理等のWebRTCのメディア処理の恩恵を受けることができません。 必要であれば、ジッタ処理等を自分で実装することになります。
  • 97. SAMPLE 簡易 ボイスチェンジャー MediaStream <=> Web Audio API 当ボイスチェンジャーで変換した音声は、 音声解析によりほぼ元の音声を復元可能であり、 匿名性を担保するものではありません。
  • 98. navigator.getUserMedia({audio: true}, function(inputStream) { var audioContext = new AudioContext(); // 要ベンダープレフィックス var mediastreamsource = audioContext.createMediaStreamSource(inputStream); var scriptProcessor = audioContext.createScriptProcessor(bufferSize, 1, 1); var mediastreamdestination = audioContext.createMediaStreamDestination(); scriptProcessor.addEventListener('audioprocess', onAudioProcess); mediastreamsource.connect(scriptProcessor); scriptProcessor.connect(mediastreamdestination); var outputStream = mediastreamdestination.stream; peer.addStream(outputStream); }, function(error) {} ); function onAudioProcess(evt) { var input = evt.inputBuffer.getChannelData(0); var output = evt.outputBuffer.getChannelData(0); var bufferData = new Float32Array(bufferSize); for (var i = 0; i < bufferSize; i++) { bufferData[i] = ( (input[(i * 2) % bufferSize] + input[(i * 2 + 1) % bufferSize]) / 2 + input[Math.floor(i / 2) % bufferSize] ) / 2; } output.set(bufferData); }
  • 101. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ; window.URL = window.URL || window.webkitURL ; function initialize() { navigator.getUserMedia( {audio: true, video: true}, function(stream) { var video = document.getElementById('video'); video.src = URL.createObjectURL(stream); video.play(); renderStart(); }, function(error) { console.error(error); } ); } function renderStart() { var video = document.getElementById('video'); var buffer = document.getElementById('buffer_canvas'); var display = document.getElementById('display_canvas'); var bufferContext = buffer.getContext('2d'); var displayContext = display.getContext('2d'); var render = function() { requestAnimationFrame(render); var width = video.videoWidth; var height = video.videoHeight; if (width == 0 || height == 0) {return;} buffer.width = display.width = width; buffer.height = display.height = height; bufferContext.drawImage(video, 0, 0); var imageData = bufferContext.getImageData(0, 0, width, height); var data = imageData.data; for (var i = 0; i < data.length; i += 4) { data[i + 0] = 255 - data[i + 0]; // Red data[i + 1] = 255 - data[i + 1]; // Green data[i + 2] = 255 - data[i + 2]; // Blue } imageData.data = data; displayContext.putImageData(imageData, 0, 0); }; render(); } window.addEventListener('load', initialize); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="styles/style.css" /> <script type="text/javascript" src="scripts/script.js"></script> <title>Reverse with getUserMedia</title> </head> <body> <video id="video"></video> <canvas id="buffer_canvas"></canvas> <canvas id="display_canvas"></canvas> </body> </html>
  • 102. WebRTCを使って 何を作るのか アイディアがあればそれを。 なければ考える。 何も思いつかなければ、 他のAPIとの組み合わせから 考える方法も。 日常の中で、WebRTCを使うと解決する問題や、便利になることはありませんか?
  • 106. HOT! API 総務省 次世代統計利用システム(国勢調査、人口推計、就業構 造、企業統計、物価統計 etc.) NHK番組表(※未公開) 行政・自治体・公共サービス 郵便番号 郵便番号検索API(郵便番号 → 住所) 郵便専門ネット(郵便番号 → 住所、郵便番号の簡易存在チ ェック) ぽすたん(郵便番号 → 住所、住所 → 郵便番号) IW3 PROJECT(郵便番号 → 住所、住所 → 郵便番号) 宇宙 Google+ JAXA PR(※現在一部の学生に限定公開、 Google+にて随時情報を更新) ARTSAT 衛星API(芸術衛星・ARTSATの位置情報、高 度、角速度 etc.) 図書館 国立国会図書館サーチ カーリル(全国各地の図書館の所蔵・貸出状況) テレビ テレビ局 日テレ アプリ テレビ関連 アニメマップ(アニメ番組情報) インフラ Twilio(電話) FullCourt(音声通話、SMS) NTT docomo(電話帳、文字認識、音声認識、知識Q&A) SNS Twitter HootSuite(SNS管理、メッセージ投稿) Google+ LinkedIn Instagram mixi Yammer はてなハイク Klout(影響力解析) Qrust(影響力解析) iddy About.me Pinterest(※Facebookグループにて仕様策定中) Timelog Yahoo!Japan(※新規申し込み停止中) プーペガール youRoom doodle ソーシャルブックマーク はてなブックマーク はてなブックマーク iPhoneアプリケーション はてなスター Delicious 楽天ブックマーク スライド SlideShare 音楽 Last.fm iTunes、App Store、 iBookstore、、Mac App Store Yahoo! Music 動画 動画ホスティング YouTube Vimeo Developer API ニコニコ動画 PANDORA.TV Woopie 動画配信 Ustream ニコニコ実況 ニコ生アニメ動画API Stickam TwitCasting SOBA Web API 写真 Flickr Picasa フォト蔵 はてなフォトライフ Zorg Panoramio fotochan(写真補正) MyPix(画像に文字を入れる) ゲーム Steam ブログ・グループウェア Tumblr はてなダイアリー はてなexist BizPal Retired(ブログ引退マークを付ける) Google サイト プラットフォーム OpenSocial Mobage GREE Facebook mixi OpenSocial OpenSocial Host infoScoop OpenSocial Pages for Google Apps 認証 Yahoo!Japan OpenID 2.0 livedoor はてな はてな Android認証 mixi Jugem 地図・位置情報 地図 Google Maps YOLPYahoo!Japan ジオターゲティング(IP → 住所) どこどこJP(IP → アクセス元地域・組織) HeartRails Geo API Windows Virtual Earth マピオン Geocoding LocoSticker.jp Maxmind 地図関連 住所パワー プロジェクト:位置情報 ジオどす(京都の通り名 → 緯度経度) 逆ジオコーディングAPI(緯度経度 → ランドマーク) 簡易逆ジオコーディング 携帯Art Map インクカートリッジ里帰りAPI(インクカートリッジ回収ボ ックス) 送料の虎Webサービス ‒ 送料の虎(送料計算) 準天頂衛星システム特設サイト QZ-vision(GPS衛星群 の位置、個数、角度、周波数をプロット) 位置情報サービス foursquare ロケタッチ はてなココ 地理 国土地理院 電子国土Webシステム(PDF) http://www.find-job.net/startup/api-2013 より引用 一覧内のサービス名の クリックで、各サービスの ページが開きます。
  • 107. 交通 車・ナビゲーション ドコイク?-リクルート ナビタイムジャパン ガソリン価格情報 鉄道 RailGo HeartRails Express 駅データ.jp バス 鯖江市 つつじバス 高速道路 高速.jp 自転車 自転車大好きマップ 気象・災害 天気 livedoor 天気情報 天気予報API OpenWeatherMap 天気API コンテンツポケット goo天気 コンテンツポケット 指数API(雨傘指数、洗濯指数 etc.) コンテンツポケット 美容天気API 波浪・潮汐 Wave Hunter(波浪予測) 全国潮汐データ 日の出・日の入時刻 おはこん番地は!? 環境 環境省大気汚染物質広域監視システムAPI 災害対策 Yahoo!Japan 震災関連情報 J-SHIS Web API(地震ハザード情報、表層地盤データ) 復旧・復興支援制度データベース NDL東日本大震災アーカイブ 気象庁防災情報 ニュース Yahoo! Japan ニュース 東京証券取引所 アキバ総研 書籍・論文 書籍・雑誌 版元ドットコム(書誌情報、書影) hon.jp(書誌情報、書影) web R25(R25一部のタイトル・本文・画像) 楽天ブックス Fujisan(書誌情報、書影) Making OPAC 2.0(大手4書店、紀伊國屋書店・旭屋書 店・ジュンク堂書店・丸善の書店在庫) The Code4Lib Journal(海外書籍・雑誌) Open Library(海外書籍・雑誌) Springer(海外書籍・雑誌) 出版社 出版社検索API(出版社コード・ISBN → 出版社名や連絡 先 etc.) 論文検索 CiNii(論文) AIRwayプロジェクト(論文) Elsevier Article API Profile(海外大手出版社・エル ゼビア社の論文) アルバム TOLOT+アプリ マネタイズAPI、OEM プリントAPI 辞書 辞書 Wikipedia デ辞蔵 ソシオヘルス(医者からもらった薬がわかる本 etc.) トレンドワード はてなキーワード kizasi.jp 「今日は何の日」API IME ATOKダイレクト API メール・メッセージング メール Outlook.com Gmail Yahoo! Japan メール Lobi(認証なしでチャット可能) メッセージング Skype Windows Messenger はてなメッセージ ChatWork 検索 Bing Live Search Yahoo! Japan カテゴリ検索 検索順位取得API.com API比較・マッチングサービスAPI(API自体の検索) reflexa(連想検索) goo検索 ナレッジベース Qiita Stack Overflow(エンジニア向け英語Q&A) 人力検索はてな Yahoo! Japan 知恵袋 教えて!goo 言語・テキスト解析 テキスト解析 SumibiWebAPI Yahoo! Japan テキスト解析 日本語解析エンジン「なずき」(感性抽出) 有害情報フィルタAPI 個人情報フィルタAPI 5W1H抽出API 大人なツイートAPI(アダルトな表現を含むツイートの抽 出) hotaru / mushikago.org 翻訳 Google Translate Microsoft Translator Gengo(人力翻訳) アカウントアグリゲーション Zaim(家計簿) 決済 クレジットカード Visa MasterCard Web決済 PayPal WebPay ソフトバンク・ペイメント Google Commerce API スマホ決済 Square API Coiney(※公開予定) Eコマース ショッピング Amazon.co.jp Yahoo!ショッピング 楽天市場 DMM gooショッピング NTT-Xストア(PC、家電) apicos(@cosmeのクチコミ、商品情報) coneco.net Yahoo! Japanマーケット(Androidアプリケーショ ン) カラーミーショップ オークション Yahoo!オークション 楽天オークション アフィリエイト バリューコマース 楽天アフィリエイト DWS3.0 チケット チケットぴあ 旅行 楽天トラベルAPI一覧 じゃらんAPI(国内ホテル空室検索、温泉検索、海外ホテル検 索) AB-ROAD yoyaQ.com JTB WEBサービス http://www.find-job.net/startup/api-2013 より引用 一覧内のサービス名の クリックで、各サービスの ページが開きます。
  • 108. 料理 楽天レシピ コンテンツポケット-栄養学 レストラン ぐるなびWebサービス 食べログAPI ホットペッパー ロケタッチグルメ BAR-NAVI(バー検索) ゴルフ 楽天GORAゴルフ(ゴルフ場検索) 中古車検索 カーセンサーラボ.net goo自動車&バイク 不動産 不動産検索 住まい探しノート goo住宅・不動産 住宅・家電 ダイワハウス(住宅内の家電・設備機器のコントロール) ガラポンTV(機器に録画された映像の活用) 占い・心理学 Web ad Fortune(占い) コンテンツポケット-心理学API バラエティ クイズ研(クイズの出題) みんなのはなもげら(はなもげら短歌の生成) 学習 ケイコとマナブ ケイコとマナブ 通信講座 リクナビ進学 求人 フロム・エー ナビ しごとナビ クーポン グルーポン くまポン オールクーポン ポンパレ クーポンサイトjp Shareee イベント ATND connpass お見合い・婚活パーティー日程情報API(婚活・お見合いパー ティー) ファッション ホットペッパーBeauty Art Beat API スケジュール・タスク カレンダー・スケジュール Google Calendar Google Apps Platform IW3 PROJECT CALENDAR サイボウズLive サイボウズ ガルーン 3 Backlog 曜日・祝日計算サービス タスク Google Tasks コンタクトリスト Google Contacts デザイン Dribbble エンジニアリング DeployGate(Android開発、自動ビルドと自動配布をラク に) lleval(JavaScript以外の言語をブラウザーで実行できる) Dozens(Dozenで管理しているドメインのゾーン、レコー ド etc.) バージョン管理システム GitHub Bitbucket Assembla Stash クラウドストレージ Google Drive Google Apps Dropbox Sugarsync SkyDrive Bitcasa(※公開予定) Evernote クラウドサービス IaaS・VPS Amazon Web サービス さくらのクラウド ニフティクラウド クラウド・エヌ Windows Azure Service Management API PaaS Heroku force.com Google App Engine Cloud Foundry OpenShift AWS Elastic Beanstalk dotCloud mitsubachi BaaS Parse appiaries Kiiクラウド(モバイル専用) Appcelerator Cloud Service Dropbox Datastore API 広告 Google Advertise RSS RSSナビ RSET API livedoor Reader アクセス解析 Google Analytics 画像認識 顔検出 顔ラボ(顔検出) PUX(顔検出、顔認識、ペット検出、オブジェクト認識、 手書き文字認識) detectFace();(顔認識) 音声認識 Web Speech API w3voice Laboratory 計算 計算式構文解析サービス ユーティリティ スパムURLチェック FC2ソーシャルスパム対策 URL短縮 bitly Google URL Shortener API p.tl ワイヤフレーム作成 Cacoo グラフ生成 Google Charts(グラフやチャートを画像で取得) はてなグラフ JSChart(円グラフ、棒グラフ、選グラフ、積み上げ棒グ ラフ、百分率棒グラフ) HeartRails Graph(キュートな円グラフ) Webサイトサムネイル生成 thumbalizr SimpleAPI Kikker WebAPIを強化 ‒ Ryoの開発日記 HeartRails Capture(サムネイル画像生成、PDF ファ イル生成) Mozshot PDF生成 HTML2PDF.BIZ はんこ画像生成 はんこAPI http://www.find-job.net/startup/api-2013 より引用 一覧内のサービス名の クリックで、各サービスの ページが開きます。
  • 110. Arduino BeagleBoard BeagleBone Raspberry Pi mbed Chromecast Leap Motion Controller
  • 111. 補足情報 WebRTCはファイルを Webサーバ上に置かないと動作しない。 アドレスが http:// か https:// で 始まる必要がある。 送られてくる映像の表示サイズは、 端末のカメラ性能だけでなく、 帯域の状態によって動的に変わる。 表示サイズをCSSで指定しておくと良い。
  • 113. Node.jsによる簡単な Web Server + WebSocket Server(Signaling Server) server/ ├── app.js ├── node_modules/ ├── package.json └── public/ ├── index.html ├── scripts/ │ └── script.js └── styles/ └── style.css // app.js var WebSocketServer = require('ws').Server , express = require('express') , http = require('http') , path = require('path') , logger = require('morgan'); var app = express(); app.set('port', process.env.PORT || 3000); app.use(logger()); app.use(express.static(path.join(__dirname, 'public'))); var conns = []; var server = http.createServer(app); var wss = new WebSocketServer({server: server}); wss.on('connection', function(ws) { conns.push(ws); ws.on('message', function(data) { conns .filter(function(conn) {return conn != ws;}) .forEach(function(conn) {conn.send(data);}); }); ws.on('close', function() { conns.splice(conns.indexOf(ws), 1); }); }); server.listen(app.get('port'), function() { console.log('Express server listening on port ' + app.get('port')); }); // package.json { "name": "SignalingServer", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "ws": "*", "express": "4.*.*", "morgan": "*" }, "engines": { "node": "0.10.*", "npm": "1.*.*" } }
  • 114. ハイパフォーマンス ブラウザネットワーキング WebRTCの 下回りを理解 したい人にお 勧め。 #HPBNj レビュアーとして参加していますが、宣伝ではありません。念のため。 http://www.oreilly.co.jp/books/9784873116761/
  • 115.
  • 117. 付録
  • 120. getUserMediaの オプション例 音量 映像の縦横 最大 / 最小 フレームレート 最大 / 最小 アスペクト比 利用するカメラ user(前面) environment(背面) left right etc. まだ仕様が固まってない? 動作が不安定。
  • 121. navigator.getUserMedia( constraints, onSuccess, onError ); // HPBNに載っている指定方法 // Chrome : エラー / Firefox : 無視 var constraints = { audio: true, video: { mandatory: { width: { min: 320 }, height: { min: 180 } }, optional: [ { width: { max: 1280 }}, { frameRate: 30 }, { facingMode: "user" } ] } }; // 仕様書に載っている指定方法 // Chrome : エラー / Firefox : 無視 var constraints = { video: { mandatory: { width: { min: 640 }, height: { min: 480 } }, optional: [ { width: 650 }, { width: { min: 650 }}, { frameRate: 60 }, { width: { max: 800 }}, { facingMode: "user" } ] } }; // 一般的な指定方法 var constraints = { audio: true, video: true }; // 動作が確認できた指定方法 // Chrome : 成功 / Firefox : 無視 var constraints = { video: { mandatory: { maxWidth: 320, maxHeight: 320, maxFrameRate: 15 }, optional: [ {facingMode: 'user'} ] }, audio: true }; まだ仕様が固まってない? 動作が不安定。
  • 122. createOfferの オプション例 peer.createOffer(onSuccess, onError, mediaConstraints); // データ通信専用のコネクション作成 var mediaConstraints = {offerToReceiveAudio: false, offerToReceiveVideo: false}; // 音声用のコネクション作成(DataChannelを使わなければ音声専用) var mediaConstraints = {offerToReceiveAudio: true, offerToReceiveVideo: false}; // 映像用のコネクション作成(DataChannelを使わなければ映像専用) var mediaConstraints = {offerToReceiveAudio: false, offerToReceiveVideo: true}; まだ仕様が固まってない様子。 Working DraftとEditor's Draftで指定方法が違う。 指定できるオプションは他にもある。
  • 123. createDataChannelの オプション例 peer.createDataChannel('DataChannel', dataChannelInit); // 順序通り 信頼性有 (like TCP) var dataChannelInit = {}; // 順不同 信頼性無 (like UDP) var dataChannelInit = {ordered: false, maxRetransmits: 0}; // 順不同 信頼性有 var dataChannelInit = {ordered: false}; // 順序通り 部分的信頼性(再送カウンタの上限あり:3回) var dataChannelInit = {ordered: true, maxRetransmits: 3}; // 順不同 部分的信頼性(タイムアウトあり:1000ms) var dataChannelInit = {ordered: false, maxRetransmitTime: 1000}; 指定できるオプションは他にもある。
  • 124. WebRTC http://www.webrtc.org/ Media Capture and Streams Working Draft 情報源 http://www.w3.org/TR/mediacapture-streams/ Editor's Draft http://dev.w3.org/2011/webrtc/editor/getusermedia.html WebRTC 1.0: Real-time Communication Between Browsers Working Draft http://www.w3.org/TR/webrtc/ Editor's Draft http://dev.w3.org/2011/webrtc/editor/webrtc.html High Performance Browser Networking - Chapter 18. WebRTC ハイパフォーマンス ブラウザネットワーキングの原著のオンライン版内 (英語) http://chimera.labs.oreilly.com/books/1230000000545/ch18.html WebRTC | HTML5Experts.jp http://html5experts.jp/tag/webrtc/
  • 125. 情報源 WebRTCのオープンソースソフトウェアまとめ - Qiita http://qiita.com/atskimura/items/97b2cc04e19781f4a4e6 PeerJS PeerJS - Simple peer-to-peer with WebRTC http://peerjs.com/ PeerJS Documentation http://peerjs.com/docs/#api PeerJS ドキュメント(SkyWayのサイト内) http://nttcom.github.io/skyway/docs/ SkyWay SkyWay - WebRTCを簡単&柔軟に使えるプラットフォーム http://nttcom.github.io/skyway/ PeerJS ドキュメント(SkyWayのサイト内) http://nttcom.github.io/skyway/docs/
  • 126. デモ一覧 getUserMedia Pitch Detector with getUserMedia http://webaudiodemos.appspot.com/pitchdetect/index.html PhiloGL - Real time color 3D histogram http://www.senchalabs.org/philogl/PhiloGL/examples/histogram/ An AR Game https://developer.mozilla.org/ja/demos/detail/an-ar-game/launch Facetracking example http://auduno.github.io/clmtrackr/clm_video.html Emotion detection example http://auduno.github.io/clmtrackr/examples/clm_emotiondetection.html Face substitution http://auduno.github.io/clmtrackr/examples/facesubstitution.html Real-time Communication Between Browsers Video Chat with getUserMedia https://apprtc.appspot.com/ VCMap - Video Chat on The Map http://vcmap.net/ Cube Slam https://www.cubeslam.com/