Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

WebRTC multitrack / multistream

3,671 views

Published on

WebRTCでChromeとFirefoxで異なる、multi-track / multi-stream の挙動について調べてみました

Published in: Technology
  • Be the first to comment

WebRTC multitrack / multistream

  1. 1. WebRTC multi-track / multi-stream 挙動から見たブラウザの現状 2015.09.29 インフォコム がねこまさし(我如古正志) @massie_g
  2. 2. いきなり余談
  3. 3. 懺悔 (1) setRemoteDescription()問題 • peer.setRemoteDescript()は非同期実行 – 直後にcreateAnswer()するとエラーになることがある – Chromeでは経験したことはないが、Firefoxでは時々発生 // NG peer.setRemoteDescription(offer); peer.createAnswer( ... ); //OK peer.setRemoteDescription(offer, function (evt) { peer.createAnswer( ... ); }, function (err) { … } ); ※私のHTML5Experts.jpの記事はコールバックになってません ※こっちは修正済です • https://lab.infocom.co.jp/demo/webrtc-hand-signaling-easy.html
  4. 4. 懺悔 (2) onnegotiationneeded()問題 • 前回「onnegotiationneeded()は無視してます」と言ったら怒られた • その後、発火タイミングが FirefoxもChromeと同じになった – 接続確立前も peer.addStream(localStream) で発火 • createDataChannel()でも?? • ケース1: 接続確立前 – peer.localDescription の有無で判断 – 確立前(localDescription無し)なら、何もしない • 自分がOffer側になるか、Answer側になるか決まっていないので • ケース2: 接続確立後 – Offer側か、Answer側かを判断 • peer.localDescription.type – Offer側なら • peer.createOffer()  send Offer – Answer側なら • request Offer • Offer側で peer.createOffer()  send Offer • Answer側で peer.createAnswer() → send Answer
  5. 5. 懺悔 (3) revokeObjectURL()未使用 • URL取得 – video.src = window.URL.createObjectURL(stream); • URL解放 – window.URL.rekoveObjectURL(video.src); ※おそらく、Single Page Application なら明示的 に開放した方が良い
  6. 6. 本題 • multi-track について • Firefox のmulti-stream について • Chrome 45.0.2454.85 • Firefox 40.0.3
  7. 7. JavaScript APIから見た PeerConnectionとMedia階層 RTCPeerConnection MediaStream MediaStream MediaStream MediaStreamTrack MediaStreamTrack MediaStreamTrack MediaStreamTrack videoTracks[] audioTracks[] DataChannel N個 N個 DataChannel N個
  8. 8. 複数のMediaを使う手段 • 1 アプリに、複数 PeerConnection – 複数人のケースと同じ • 1 PeerConnection に、複数 MediaStream – 前回検証した範囲 • 1 MediaStream に、複数MediaStreamTrack – 今回の中心
  9. 9. WebRTC周辺APIの微妙なところ Chrome Firefox Media Capture and Streams http://www.w3.org/TR/mediacapture-streams/ ○ △ WebRTC 1.0: Real-time Communication Between Browsers http://w3c.github.io/webrtc-pc/ △ ○ MediaDevices × ○ MediaStream Recording http://www.w3.org/TR/mediastream-recording/ × ○
  10. 10. Chrome addTrack / removeTrack • メソッド – MediaStream.addTrack(track) • video/audio トラックを追加 – MediaStream.removeTrack(track) • video/audio トラックを除去 – MediaStream.getVideoTracks() / getAudioTracks() – MediaStream.getTracks() • イベント – MediaStream.onaddtrack() / onremovetrack () • SDP再交換後、remoteStreamで発火
  11. 11. Offer側 addTrack() / removeTrack() Peer BPeer A createOffer() Peer-to-Peer offer SDPsetLocalDescription() setLocalDescription()answer SDP setRemoteDescription() createAnswer() setRemoteDescription() onaddtrack() 発火 localStream remoteStream remoteStream localStream addTrack(track) ※onnegotiationneeded()は発火しない ※localStream.onaddtrack()は発火しない
  12. 12. onaddtrack()後、trackの再生まで • onaddtrack(event) – var track = event.track; • URL.createObjectURL(stream)は、最初のトラックしか対 応していない – × URL.createObjectURL(stream, trackId); – × URL.createObjectURL(stream, trackIndex); – × URL.createObjectURL(track); • 臨時のMedaiSteramを生成して利用 – var tempStream = new MediaStream(); – tempStream.addTrack(track); – video.src = window.URL.createObjectURL(tempStream)
  13. 13. Answer側 addTrack() / removeTrack() Peer BPeer A createOffer() Peer-to-Peer offer SDPsetLocalDescription() setLocalDescription()answer SDP setRemoteDescription() createAnswer() setRemoteDescription() onaddtrack() 発火 localStream remoteStream remoteStream localStream addTrack(track) ※onnegotiationneeded()は発火しない ※localStream.onaddtrack()は発火しない request offer
  14. 14. Firefox addTrack / removeTrack • メソッド – MediaStream.addTrack() / removeTrack()は無い – mozRTCPeerConnection.addTrack()/removeTrack()がある! • WebRTC 1.0 の仕様 – var sender = peerConnection.addTrack(track, stream); • sender: RTCRtpSender – peerConnection.removeTrack(sender); • イベント:addTrack()側 – mozRTCPeerConnection.onnegotiationneeded()発火 • イベント:相手側 – SDP再交換後 → mozRTCPeerConnection.onaddstream() 発火 • 相手には、新たなmediastreamとして見える → multi-stream • ※これって、Unified Plan と関係してます??
  15. 15. Offer側 addTrack() Peer BPeer A createOffer() Peer-to-Peer offer SDPsetLocalDescription() setLocalDescription()answer SDP setRemoteDescription() createAnswer() setRemoteDescription() onnetosiationneeded () 発火 localStream1 localStream2 remoteStream2 remoteStream1 addTrack(track, localStream2) onaddstream () 発火 remoteStream2受け取り
  16. 16. Answer側 addTrack() Peer BPeer A createOffer() Peer-to-Peer offer SDP setLocalDescription() setLocalDescription()answer SDP setRemoteDescription() createAnswer() setRemoteDescription() onnetosiationneeded () 発火 localStream1localStream2remoteStream2remoteStream1 addTrack(track, localStream2) onaddstream () 発火 remoteStream2受け取り request offer
  17. 17. Firefox addTrack / removeTrack • 嬉しいところ – 別のmediastreamになるので、そのまま URL.createObjectURL() 使える – ※逆に、テンポラリーの MediaStream が作れない • var temp = new MediaStream() // コンストラクター呼べない(protected) • 気になるところ – Answer側から removeTrack()でSDP交換 – Offer側で serRemoteDescription(answer)後、エラー発生 setRemoteDescription(answer) ERROR: DOMException [InvalidSessionDescriptionError: "Invalid description, no ice-ufrag attribute" code: 0 nsresult: 0x0] – ※Firefox Nightly 43.0a1 ではOK – ※Firefox 41.0 ではOK。ただし繰り返していると no ice-uflag エラー発生
  18. 18. RTCPeerConnection MediaStream MediaStreamTrack MediaStreamTrack addTrack() removeTrack() onaddtrack() onremovetrack() RTCPeerConnection MediaStream Peer-to-Peer RTCPeerConnection MediaStreamTrack MediaStreamTrack addTrack() removeTrack() onaddstream() onremovestream() RTCPeerConnection MediaStream Peer-to-Peer Chrome multi-stream Firefox WebRTC 1.0 RTCPeerConnection MediaStream addStream() removeStream() onaddstream() onremovestream() RTCPeerConnection MediaStream Peer-to-Peer Chrome multi-track
  19. 19. 拡大:Chromeの場合(stream) RTCPeerConnection MediaStream addStream() removeStream() onaddstream() onremovestream() RTCPeerConnection MediaStream Peer-to-Peer
  20. 20. 拡大: Chromeの場合(track) RTCPeerConnection MediaStream MediaStreamTrack MediaStreamTrack addTrack() removeTrack() onaddtrack() onremovetrack() RTCPeerConnection MediaStream Peer-to-Peer
  21. 21. 拡大: Firefoxの場合 RTCPeerConnection MediaStreamTrack MediaStreamTrack addTrack() removeTrack() onaddstream() onremovestream() RTCPeerConnection MediaStream Peer-to-Peer
  22. 22. おまけ:Firefox replaceTrack var sender1 = mozRTCPeerConnection.addTrack(track1, stream1); sender1.replaceTrack(track2).then(function() { console.log('replaced'); }); // ※track2は、PeerConnectionに未接続でなければならない
  23. 23. Thank you!

×