Contenu connexe Similaire à WebRTC SFU Mediasoup Sample update (20) WebRTC SFU Mediasoup Sample update2. 自己紹介
• がねこまさし / @massie_g
• インフォコム株式会社で、技術調査チームに所属
• WebRTC Meetup Tokyo スタッフ
• WebRTC Begginers Tokyo 講師
• WebRTC入門2016を HTML5Experts.jpに執筆
– https://html5experts.jp/series/webrtc2016/
2
3. 今日のお題
• 前回(#13)の復習
– SFU : Selective forwarding Unit
– mediasoup : オープンソースのSFU モジュール
• 今回(#15)の新しい話題
– v0.3 (2017.01.27時点) → v1.2 (2017.05.26現在) に進化
– 使い方が変わったので、新しいサンプルソース
• https://github.com/mganeko/mediasoup_sample
3
5. P2P と SFU:Selective Forwarding Unit
ブラウザ
A
ブラウザ
B
ブラウザ
D
ブラウザ
C
P2Pの場合
• サーバ不要 ◎
• ブラウザ側の
• CPU負荷:高 ×
• ネットワーク負荷:高 ×
5
ブラウザ
A
ブラウザ
B
ブラウザ
D
ブラウザ
C
SFU
映像・音声
を分岐/配信
SFUの場合
• SFUサーバ必要 → CPU負荷:低 ○
• ブラウザ側はCPU負荷:低め ○
• ブラウザ側はネットワーク負荷:中 △
表示レイアウトの
自由度が高い ◎
8. mediasoupとは?
• オープンソースのSFU
– サイト https://mediasoup.org/
– GitHub https://github.com/ibc/mediasoup/ → https://github.com/versatica/mediasoup
• 独立したサーバーではなく、部品
– Instead of creating yet another opinionated server, mediasoup is a Node.js module
which can be integrated into a larger application or made standalone with just a few
lines of JavaScript.
– 「他のアプリに組み込める」
• Node.js用モジュールとして提供
– Webサーバーやシグナリングの仕組みは、自分で用意する必要あり
8
9. mediasoupとは? (2)
• ミニマム … メディアのみ、かつSFUなのでコーデックは処理しない
• パワフル … 実体は C++ で記述、libuv 利用
– Node.js から起動された子プロセスで通信を担当
– Node.js とはプロセス間通信でやりとり
• JavaScript API を提供
– WebRTC 1.0 … RTCPeerConnection, promise利用
– ORTC … Transport, RtpSender, RtpReceiver
9
10. mediasoup サンプル Demo
10
• 複数人の双方向通信
– 映像/音声
– 見た目P2Pと変わらないけど…
• SFUサーバーを止めると、映像も停止
• ソースコード
– https://github.com/mganeko/mediasoup_sample
• 複数人双方向に加えて、片方向配信、SSL対応版も
11. mediasoup のインストール
• 前提環境
– Node.js v4.8.0 以上
– Linux / Mac OS X ※Windowsは未サポート
– Python 2.x
• pyenv / virtualenv利用時は要注意。明示的なローカルPythonのバージョン指定が必要
• $ pyenv local 2.7.12
– make
– gcc & g++ または clang, with C++11
• インストール
– $ npm install mediasoup
• C++のコンパイルあり、数分から数十分でビルド→インストール完了
11
15. 利用のイメージ
let server = mediasoup.Server();
let peer1;
let receiver1;
return server.createRoom(roomOptions)
.then( (room) => {
peer1 = room.Peer('alice');
return peer.setCapabilities(peerCapabilities);
})
.then(() => {
return peer.createTransport({ tcp: false });
})
.then((transport) => {
rtpReceiver1 = peer1.RtpReceiver('audio', transport);
})
15
• 順番に自分でオブジェクトを組み立てる
• Promiseベース
• RtpSenderは自分で明示的には生成しない
• 自動に生成され、イベントで渡される
※まだ良く分かっ
ていません…
※ここが結構
ややこしい
21. “Peer Capabilities” の送り方
• Peer Capabilities
– どんなコーデックが使えるか
– どんなRTCPの制御が使えるか
• ブラウザの能力を取得する方法
– ORTC, WebRTC 1.0 仕様なら取得可能、現在の実装では取得できない
• RTCRtpSender.getCapabilities(kind),
• RTCRtpReceiver.getCapabilities(kind)
– だがしかし、SDPに書いてある
• ブラウザ側
– createOffer({ offerToReceiveAudio: false, offerToReceiveVideo: false}) でSDPを取得
– setLocalDescription() しない … P2Pの試行は始まらない
– Capabilities 情報として、SDPをサーバー(MediaSoup)に送る
21
22. SDPに含まれる情報
22
m=video 50083 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125
a=mid:video
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtpmap:100 H264/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:102 red/90000
a=rtpmap:127 ulpfec/90000
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:125 rtx/90000
a=fmtp:125 apt=102
23. Peer Capabilities のやりとり (v1.2)
23
Browser A
RTCPeerConnection
mediasoup
RTCPeerConnection A
send “Peer Capabilities” SDP
send offer SDP
createOffer()
createAnswer()
setLocalDescription()
setCapabilities()
createOffer()
setRemoteDescription()
setLocalDescription()
setLocalDescription()
send answer SDP
setRemoteDescription()
24. RTCPeerConnectionの制約(v0.3)
• 最初のOfferをリモートから(ブラウザから)受け取る必要がある
– Currently, the mediasoup implementation of RTCPeerConnection requires that the initial offer
comes from the remote endpoint,
• その後、onnegotiationneeded()発火後に Offerを生成させる
• 通信確立後、リモート側でのOffer再生成には対応していない
– リモート側での stream / track 追加、削除には対応していない
• Chromeの採用しているPlan Bには暫定的な対応 … ※私のサンプルが悪いだけかも
24
あくまで RTCPeerConnectionの制限(mediasoupの実力の10%??)
Transport, RtpReceiver, SDP を自分で組み立てれば、できる(はず)
25. RTCPeerConnectionの変更 (v1.2)
• 最初にブラウザの能力(Capabilities)を受けとる
• Offerは常に mediasoup 側から … mediasoupはAnswerのみ受け取り
• 通信確立後にブラウザ側でstream / track 追加、削除の場合
– 何らかの方法で、mediasoupにリクエスト
– mediasoupで Offerを 再生成して送る
– ブラウザ側からstream/trackが変更されたAnswerを返す
• Plan B対応(Chrome対応)
– PeerConnection生成時に、明示的に指定することで対応可能
– Chrome / Firefox 混在で利用可能 … 元からかも(私のサンプルが悪かった)
25
26. Vanilla ICEの注意点
• サンプルではVanilla ICEを利用
– ブラウザ側で、createAnswer()直後にはSDPを送らない
– ICE Candidateが揃ってから、まとめてAnswer SDPを送信
• ブラウザ側で、2度目のcreateAnswer()の時
– Chrome では、 onicecandidate()は発火しない
• もう ICE Candidateはそろっている
• 待たずに、ただちに Answer SDPを送る
– Firefox では、onicecandidate()が発火(candidateは空)
• 待っても待たなくても良い
26
27. Vanilla ICEの注意点
27
Browser A
RTCPeerConnection
mediasoup
RTCPeerConnection A
Browser B
send “Peer Capabilities”
send offer SDP
send answer SDP
send offer SDP
onnegotiationneeded()発火
RTCPeerConnection B RTCPeerConnection
send answer SDP
onaddstream() / ontrack() 発火
onaddstream() / ontrack() 発火
createOffer()
createOffer()
createAnswer()
createOffer()
createAnswer()
createAnswer()
send “Peer Capabilities”
send answer SDP
send offer SDP
ここは、ICE candidateが
出揃うのを待つ
ここは待たずに送る
28. 片方向配信の場合
• 1:nの片方向配信の場合
– mediasoup側で、受信側用のOffer 生成時にオプションを指定
• pc.createOffer({ offerToReceiveAudio:0, offerToReceiveVideo:0})
• 厳密に 1:n 配信したい場合
– 2人目の配信者は弾くように、アプリで制御する必要あり
– ※ そのまま2人目の配信者を加えた場合、2:n 配信になる
• さらに配信者間は双方向になる
• つまり、ontrack()/onaddstream() イベントが発生する
28※ RtpSenderを直接制御すれば、対処可能
32. mediasoup その他の制約
• mediasoupは NAT/Firewallの外に置く必要あり
– mediasoupはSTUN/TURNを必要としない環境に置く
• ブラウザが NAT/Firewallの中にあるケースはOK
– ブラウザが(STUN)/TURNを利用するのはOK
32
mediasoup
Browser
STUN
Browser TURN
NAT
Firewall
33. まとめ
• WebRTCの主戦場は P2P → MCU → SFU/MCUの使い分け
• mediasoup も、v1.2でかなり安定利用できるようになった
– SFUを組み込んだアプリケーションを自分でも作れる
• もちろん、高機能、高安定性は商用製品が有力: Sora, tokbox, twillio
• 本日のプレゼン資料は SlideShareに
– https://www.slideshare.net/mganeko/webrtc-sfu-mediasoup-sample-update
– English: https://speakerdeck.com/mganeko/playing-with-oss-webrtc-sfu-meidasoup-update-for-v1-dot-2
• ソースコードは GitHubに
– https://github.com/mganeko/mediasoup_sample
33