Anúncio
Anúncio

Mais conteúdo relacionado

Apresentações para você(20)

Anúncio

Mais de mganeko(20)

Último(20)

Anúncio

WebRTC SFU Mediasoup Sample update

  1. meidasoup アップデート OSSのSFU meidasoup 最新情報 WebRTC Meetup Tokyo #15 インフォコム株式会社 がねこまさし @massie_g 2017.06.13 1
  2. 自己紹介 • がねこまさし / @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
  4. 前回(#13)の復習 4
  5. P2P と SFU:Selective Forwarding Unit ブラウザ A ブラウザ B ブラウザ D ブラウザ C P2Pの場合 • サーバ不要 ◎ • ブラウザ側の • CPU負荷:高 × • ネットワーク負荷:高 × 5 ブラウザ A ブラウザ B ブラウザ D ブラウザ C SFU 映像・音声 を分岐/配信 SFUの場合 • SFUサーバ必要 → CPU負荷:低 ○ • ブラウザ側はCPU負荷:低め ○ • ブラウザ側はネットワーク負荷:中 △ 表示レイアウトの 自由度が高い ◎
  6. MCU と SFU 6 ブラウザ A ブラウザ B ブラウザ D ブラウザ C SFU 映像・音声 を分岐/配信 ブラウザ A ブラウザ B ブラウザ D ブラウザ C MCU 映像・音声 を合成 MCUの場合 • MCUサーバ必要 → CPU負荷:激高 ×× • ブラウザ側はCPU/ネットワーク負荷:低 ◎ SFUの場合 • SFUサーバ必要 → CPU負荷:低 ○ • ブラウザ側はCPU負荷:低め ○ • ブラウザ側はネットワーク負荷:中 △ 表示レイアウトの 自由度が高い ◎
  7. 圧縮と暗号化 7 Browser いらすとや http://www.irasutoya.com/ BrowserP2P 圧縮/エンコード 暗号化 通信 復号化 解凍/デコード TURN Browser TURN Browser SFU MCU Browser SFU Browser Browser MCU Browser
  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
  12. mediasoup のオブジェクト構造(1) 12 Server Room Room Room Peer Peer Peer Transport Transport RtpSender RtpSender RtpSender RtpReceiver RtpReceiver RtpReceiver ・1つのServerに複数のRoom ・1つのRoomに複数のPeer ・1つのPeerに複数のRtpSender ・1つのPeerに複数のRtpReceiver ・1つのPeerに複数のTransport MediaTrackに対応(video/audio) MediaTrackに対応(video/audio) 通信ポートに対応 (UDP/TCP) 1つのTransportを ・複数のRtpSender ・複数のRtpReceiver で利用可能 BUNDLE mux
  13. mediasoup のRoomの構造 13 Room Peer RtpReceiver RtpSender Browser Browser Peer RtpReceiver RtpSender Peer Browser RtpReceiver RtpSender RtpSender RtpSender RtpSender Room内のmediaの 流れは自動に組み 立てられる Transport Transport Transport
  14. mediasoupのプロセス 14 デフォルトは コア数分 1つのRoom 5つのPeerの時 1つのRoomは 同じworkerに割り振られる
  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は自分で明示的には生成しない • 自動に生成され、イベントで渡される ※まだ良く分かっ ていません… ※ここが結構 ややこしい
  16. mediasoup のオブジェクト構造(2) 16 Server Room Room Room Peer Peer Peer RTCPeerConnection ・ 1つのRTCPeerConnectionと、1つのPeerが対応 → Offer/Answerのやり取りで通信を確立できる RTCPeerConnection RTCPeerConnection
  17. 今回 (#15)での、v1.2の更新情報 17
  18. v1.x の大きな変更 • v1.x • 最初のOfferはmediasoup側(SFU側)から • v0.3 – 最初のOfferはブラウザ側(クライアント側)から 18
  19. RTCPeerConenctionを使った流れ(v0.3) 19 Browser A RTCPeerConnection mediasoup RTCPeerConnection A Browser B send offer SDP send offer SDP send answer SDP send answer SDP onnegotiationneeded()発火 onnegotiationneeded()発火 RTCPeerConnection B RTCPeerConnection send answer SDP onaddstream() / ontrack() 発火 send offer SDP send offer SDP send answer SDP onaddstream() / ontrack() 発火 createOffer() createAnswer() createOffer() createAnswer() createOffer() createAnswer() createOffer() createAnswer()
  20. RTCPeerConenctionを使った流れ(v1.2) 20 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
  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を直接制御すれば、対処可能
  29. mediasoup 片方向配信:1人の配信 29 Browser Publisher 1 room Browser Subscriber A Browser Subscriber B Browser Subscriber C PeerConnection PeerConnection PeerConnection PeerConnection
  30. mediasoup 片方向配信:2人目の配信(想定) 30 Browser Publisher 1 room Browser Subscriber A Browser Subscriber B Browser Subscriber C PeerConnection PeerConnection PeerConnection PeerConnection Browser Publisher 2 PeerConnection
  31. mediasoup 片方向配信:2人目の配信(実際) 31 Browser Publisher 1 room Browser Subscriber A Browser Subscriber B Browser Subscriber C PeerConnection PeerConnection PeerConnection PeerConnection Browser Publisher 2 PeerConnection ※ 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
  34. Thank you! 34
Anúncio