WebRTC multitrack / multistream

23
WebRTC multi-track / multi-stream 挙挙挙挙挙挙挙挙挙挙挙挙挙 2015.09.29 挙挙挙挙挙挙 挙挙挙挙挙挙 挙挙挙挙挙挙 () @massie_g

Transcript of WebRTC multitrack / multistream

Page 1: WebRTC multitrack / multistream

WebRTC multi-track / multi-stream挙動から見たブラウザの現状

2015.09.29インフォコムがねこまさし(我如古正志)@massie_g

Page 2: WebRTC multitrack / multistream

いきなり余談

Page 3: WebRTC multitrack / multistream

懺悔 (1) setRemoteDescription() 問題• peer.setRemoteDescript() は非同期実行

– 直後に createAnswer() するとエラーになることがある– Chrome では経験したことはないが、 Firefox では時々発生

// NGpeer.setRemoteDescription(offer);peer.createAnswer( ... );

//OKpeer.setRemoteDescription(offer, function (evt) { peer.createAnswer( ... ); }, function (err) { … });

※ 私の HTML5Experts.jp の記事はコールバックになってません ※ こっちは修正済です• https://lab.infocom.co.jp/demo/webrtc-hand-signaling-easy.html

Page 4: WebRTC multitrack / multistream

懺悔 (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

Page 5: WebRTC multitrack / multistream

懺悔 (3) revokeObjectURL() 未使用• URL 取得– video.src = window.URL.createObjectURL(stream);

• URL 解放– window.URL.rekoveObjectURL(video.src);※ おそらく、 Single Page Application なら明示的に開放した方が良い

Page 6: WebRTC multitrack / multistream

本題• multi-track について• Firefox の multi-stream について• Chrome 45.0.2454.85• Firefox 40.0.3

Page 7: WebRTC multitrack / multistream

JavaScript API から見たPeerConnection と Media 階層

RTCPeerConnection

MediaStream

MediaStream

MediaStream

MediaStreamTrack

MediaStreamTrack

MediaStreamTrack

MediaStreamTrack

videoTracks[] audioTracks[]

DataChannel

N 個

N 個DataChannel

N 個

Page 8: WebRTC multitrack / multistream

複数の Media を使う手段• 1 アプリに、複数 PeerConnection– 複数人のケースと同じ

• 1 PeerConnection に、複数 MediaStream– 前回検証した範囲

• 1 MediaStream に、複数 MediaStreamTrack– 今回の中心

Page 9: WebRTC multitrack / multistream

WebRTC 周辺 API の微妙なところChrome Firefox

Media Capture and Streamshttp://www.w3.org/TR/mediacapture-streams/ ○ △WebRTC 1.0: Real-time Communication Between Browsershttp://w3c.github.io/webrtc-pc/ △ ○

MediaDevices× ○

MediaStream Recordinghttp://www.w3.org/TR/mediastream-recording/ × ○

Page 10: WebRTC multitrack / multistream

Chrome addTrack / removeTrack

• メソッド– MediaStream.addTrack(track)

• video/audio トラックを追加– MediaStream.removeTrack(track)

• video/audio トラックを除去– MediaStream.getVideoTracks() / getAudioTracks()– MediaStream.getTracks()

• イベント– MediaStream.onaddtrack() / onremovetrack ()

• SDP 再交換後、 remoteStream で発火

Page 11: WebRTC multitrack / multistream

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() は発火しない

Page 12: WebRTC multitrack / multistream

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)

Page 13: WebRTC multitrack / multistream

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

Page 14: WebRTC multitrack / multistream

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 と関係してます??

Page 15: WebRTC multitrack / multistream

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 受け取り

Page 16: WebRTC multitrack / multistream

Answer 側 addTrack()Peer BPeer A

createOffer()

Peer-to-Peer

offer SDPsetLocalDescription()

setLocalDescription()answer SDP

setRemoteDescription()

createAnswer()setRemoteDescription()

onnetosiationneeded () 発火

localStream1localStream2remoteStream2remoteStream1

addTrack(track, localStream2)

onaddstream () 発火 remoteStream2 受け取り

request offer

Page 17: WebRTC multitrack / multistream

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: 0nsresult: 0x0]

– ※Firefox Nightly 43.0a1 では OK– ※Firefox 41.0 では OK 。ただし繰り返していると no ice-uflag エラー発生

Page 18: WebRTC multitrack / multistream

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

FirefoxWebRTC 1.0

RTCPeerConnection

MediaStream

addStream() removeStream()

onaddstream()onremovestream()

RTCPeerConnection

MediaStream

Peer-to-PeerChrome multi-track

Page 19: WebRTC multitrack / multistream

拡大: Chrome の場合 (stream)RTCPeerConnection

MediaStream

addStream()removeStream()

onaddstream()onremovestream()

RTCPeerConnection

MediaStream

Peer-to-Peer

Page 20: WebRTC multitrack / multistream

拡大: Chrome の場合 (track)RTCPeerConnection

MediaStream

MediaStreamTrackMediaStreamTrack

addTrack()removeTrack() onaddtrack()

onremovetrack()

RTCPeerConnection

MediaStream

Peer-to-Peer

Page 21: WebRTC multitrack / multistream

拡大: Firefox の場合RTCPeerConnection

MediaStreamTrack MediaStreamTrack

addTrack()removeTrack()

onaddstream()onremovestream()

RTCPeerConnection

MediaStream

Peer-to-Peer

Page 22: WebRTC multitrack / multistream

おまけ: Firefox replaceTrackvar sender1 = mozRTCPeerConnection.addTrack(track1, stream1);sender1.replaceTrack(track2).then(function() { console.log('replaced'); }); // track2※ は、 PeerConnection に未接続でなければならない

Page 23: WebRTC multitrack / multistream

Thank you!