SlideShare a Scribd company logo
1 of 22
Download to read offline
WebRTC Multi-Stream
挙動から見たブラウザの現状
2015.07.03
インフォコム株式会社
がねこまさし
@massie_g
JavaScript APIから見た
PeerConnectionとMedia階層
RTCPeerConnection
MediaStream
MediaStream
MediaStream
MediaStreamTrack
MediaStreamTrack
MediaStreamTrack
MediaStreamTrack
videoTracks[] audioTracks[]
DataChannel
N個
N個
DataChannel
N個
複数のMediaを使う手段
• 1 アプリに、複数 PeerConnection
• 1 PeerConnection に、複数 MediaStream
• 1 MediaStream に、複数MediaStreamTrack
複数のMediaを使う手段
• 1 アプリに、複数 PeerConnection
– 複数人のケースと同じ
• 1 PeerConnection に、複数 MediaStream
– 今回検証した範囲
• 1 MediaStream に、複数MediaStreamTrack
– Chromeでは MediaStream.addTrack()は呼び出し可能
• ※特にイベントは発生しない
– 受け側で 特定のTrackを指定して再生することはできないはず
• URL.createObjectURL(stream) で、複数Trackをハンドリングできない
関連する要素
• メソッド
– RTCPeerConnection.addStream(stream)
• ローカルのMediaStreamを追加
– RTCPeerConnection.removeStream(stream)
• ローカルのMediaStreamを除去
• イベント
– RTCPeerConnection.onnegotiationneeded()
• SDPの再送が必要なときに発火
addStream() / removeStream()
• Chrome 43.0.2357.124 (64-bit)
– RTCPeerConnection.addStream()
• 2つのMediaStream(video入り)を追加可能
– RTCPeerConnection.removeStream()も可能
• Firefox 38.0.5
– RTCPeerConnection.addStream()
• 2つのMediaStream(video入り)を追加可能
– RTCPeerConnection.removeStream()は不可
• NotSupportedError:
onnegotiationneeded()
• 発火のタイミング
– ○ RTCPeerConnection.addStream() / .removeStream()
– × RTCPeerConnection.createOffer() / .createAnswer()
– × RTCPeerConnection.setLocalDescription()
– × RTCPeerConnection.setRemoteDescription()
– × RTCPeerConnection.onaddstream() 発火時
• リモートの MediaStream が検出されたときのイベント
• Chorme
– 接続確立前の addStream() でも発火
– 接続確立後の addStream() / removeStream() でも発火
• Firefox
– 接続確立前の addStream() では発火しない (※Nightlyでは発火)
– 接続確立後の addStream() で発火
– 接続確立後の removeStream() は実行できない (※Nightlyでも不可)
参考:vanilla ICE シグナリング
Peer BPeer A
createOffer()
Peer-to-Peer
offer SDP (with ICE candidate)
setLocalDescription()
setLocalDescription()
answer SDP (with ICE candidate)
setRemoteDescription()
createAnswer()
setRemoteDescription()
onicecandidate()
onicecandidate()
onicecandidate()
onicecandidate()
addStream(localStream) addStream(localStream)
onaddstream(remote)
onaddstream(remote)
最初からmultistream : Chrome
• ※ onnegotiationneeded()イベントは無視
• offer:1, answer:1→ 当然OK
• offer:2, answer:2 → OK
• offer:2, answer:1 → OK
• offer:1, answer:2 → OK
最初からmultistream : Firefox
• ※ onnegotiationneeded()イベントは無視
• offer:1, answer:1→ 当然OK
• offer:2, answer:2 → OK
• offer:2, answer:1 → OK
• offer:1, answer:2 → △
– offer側に1つしか表示されない
– ※ answer側でsetOffer後、 onnegotiationneeded()
が発火している
• そのイベントを適切に処理してあげる必要がある??
最初からmultistream
Chrome(offer) → Firefox(answer)
• ※ onnegotiationneeded()イベントは無視
• offer:1, answer:1 → OK
• offer:2, answer:2 → NG
– answer側でエラー
– setRemoteDescription(offer) ERROR: " DOMException
[InvalidSessionDescriptionError: "Found multiple different
webrtc msids in m-section 1
• offer:2, answer:1 → NG
– answer側
– setRemoteDescription(offer) ERROR: " DOMException
[InvalidSessionDescriptionError: "Found multiple different
webrtc msids in m-section 1
• offer:1, answer:2 → △。offer側に1つしか表示されない
最初からmultistream
Firefox(offer) → Chrome(answer)
• ※ onnegotiationneeded()イベントは無視
• offer:1, answer:1 → OK
• offer:2, answer:2 → NG
– answer側でエラー
– Create Answer failed. err: Failed to initialize the answer.
• offer:2, answer:1answer:2 → NG
– answer側でエラー
– Create Answer failed. err: Failed to initialize the answer.
• offer:1, answer:2 → NG
– answer側 OK
– offer側でエラー
– setRemoteDescription(offer) ERROR: " DOMException
[InvalidSessionDescriptionError: "Found multiple different webrtc
msids in m-section 1
後からmultistream : offer側で+1
Peer BPeer A
createOffer()
Peer-to-Peer
offer SDP (with ICE candidate)
setLocalDescription()
setLocalDescription()
answer SDP (with ICE candidate)
setRemoteDescription()
createAnswer()
setRemoteDescription()
addStream(localStream)
onaddstream(remote)
onnegotiationneeded()
後からmultistream : offer側で変化
• onnegotiationneeded()イベントを使う
• offer:1 answer:1後、 offer +1
– offer側
• peer.addStream(stream2)
• peer.onnegotiationneeded()発火
• peer.createOffer()
• peer.setLocalDescription(sdp)
• sendSDP(sdp) ※何らかの手段で送る
– answer側
• receiveSDP(sdp) ※何らかの手段で受けてとる
• peer.setRemoteDescription(sdp)
• peer.onaddstream(stream2) 発火
• ※ peer.onnegotiationneeded()発火しない
• peer.createAnswer()
• peer.setLocalDescription(sdp)
• sendSDP(sdp) ※何らかの手段で送る
– offer側
• receiveSDP(sdp) ※何らかの手段で受けてとる
• peer.setRemoteDescription(sdp)
後からmultistream : answer側で+1
Peer BPeer A
createOffer()
Peer-to-Peer
offer SDP
setLocalDescription()
setLocalDescription()
answer SDP (with ICE candidate)
setRemoteDescription()
createAnswer()
setRemoteDescription()
addStream(localStream)
onnegotiationneeded()
onaddstream(remote)
REQUEST for re-createOffer
後からmultistream : answer側で変化
• onnegotiationneeded()イベントを使う
• offer:1 answer:1後、 answer +1
– answer側
• peer.addStream(stream2)
• peer.onnegotiationneeded()発火
• ※何らかの手段で、offer側にSDP再送を依頼する
– offer側
• peer.createOffer()
• peer.setLocalDescription(sdp)
• sendSDP(sdp) ※何らかの手段で送る
– answer側
• receiveSDP(sdp) ※何らかの手段で受けてとる
• peer.setRemoteDescription(sdp)
• peer.createAnswer()
• peer.setLocalDescription(sdp)
• sendSDP(sdp) ※何らかの手段で送る
– offer側
• receiveSDP(sdp) ※何らかの手段で受けてとる
• peer.setRemoteDescription(sdp)
• peer.onaddstream(stream2) 発火
後からmultistream : Chrome
• onnegotiationneeded()イベントを使う
• offer:1 answer:1後、 offer +1 → OK (※ answer を再生成)
• offer:2 answer:1後、 offer -1→ OK (※ answer を再生成)
• offer:1 answer:2後、 offer +1→ OK (※ answer を再生成)
• offer:2 answer:2後、 offer -1→ OK (※ answer を再生成)
• offer:1 answer:1後、 answer +1 → OK
– answer側のonnegotiationneeded → answer作らずスルー
– offerを強制生成、answer側にoffer再セット(setRemote)
– answer側で、ようやくanswer生成
– offer側に、asnwer再セット(setRemote)
• offer:1 answer:2後、 answer -1 → OK (※同上)
• offer:2 answer:1後、 answer +1 → OK (※同上)
• offer:2 answer:2後、 answer -1 → OK (※同上)
後からmultistream : Firefox
• onnegotiationneeded()イベントを使う
• offer:1 answer:1後、 offer +1 → OK.
– ※+1時には、offer側では onnegotiationneededが呼ばれる。
– ※answerは強制生成
• offer:2 answer:1後、 offer -1→ NG. removeStream() できない
– NotSupportedError: removeStream not yet implemented
• offer:1 answer:2後、 offer +1→ その状況が作れない
• offer:2 answer:2後、 offer -1→ NG. removeStream()できない
• offer:1, answer:1後、 answer +1 → NG. Answer側でエラー
– "Create Answer failed. err:" DOMException [InvalidStateError: "Cannot
create answer in state stable"
• offer:1, answer:2後、 answer -1 → その状況が作れない
• offer:2, answer:1後、 answer +1 → NG?? Javascriptミス?
• offer:2, answer:2後、 answer -1 → NG. removeStream()できない
オマケ1
• RTCPeerConnection.addTrack() …
– onnegotiationneeded()発火しない
• MedaiStreamTrack.enabled = true / false
– メディア送信の on/offできる
オマケ2: 複数のMediaを使う手段
• 1 アプリに、複数 PeerConnection
– 複数人のケースと同じ
• 1 PeerConnection に、複数 MediaStream
– 今回検証した範囲
• 1 MediaStream に、複数MediaStreamTrack
– Chromeでは MediaStream.addTrack()は呼び出し可能
• ※特にイベントは発生しない
– 受け側で 特定のTrackを指定して再生することはできないはず
• URL.createObjectURL(stream) で、複数Trackをハンドリングできない
– ※無理やり再生はできた
• MediaStream 生成 → addTrack() → URL.createObjectURL()
オマケ2: 複数のMediaを使う手段
※複数MediaStreamTrackから無理やり再生手順
var videoTracks = stream1.getVideoTracks();
var stream2 = new webkitMediaStream();
stream2.addTarck(videoTracks[1]);
video.src = URL.createObjectURL(stream2);
Thank you!

More Related Content

What's hot

WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3mganeko
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践Yoshifumi Kawai
 
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話Kazuho Oku
 
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜Yusuke Naka
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例sairoutine
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Akihiro Suda
 
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannelNode.js with WebRTC DataChannel
Node.js with WebRTC DataChannelmganeko
 
kpackによるコンテナイメージのビルド
kpackによるコンテナイメージのビルドkpackによるコンテナイメージのビルド
kpackによるコンテナイメージのビルドMasanori Nara
 
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdf
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdfver.12.9_LAPRAS SCOUTサービスご案内資料.pdf
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdfsaito chinatsu
 
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみるいまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる裕士 常田
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでRyo Nakamaru
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動Takashi Takizawa
 
Cilium - BPF & XDP for containers
 Cilium - BPF & XDP for containers Cilium - BPF & XDP for containers
Cilium - BPF & XDP for containersDocker, Inc.
 
elixirを使ったゲームサーバ
elixirを使ったゲームサーバelixirを使ったゲームサーバ
elixirを使ったゲームサーバHidetaka Kojo
 
Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介Masahito Zembutsu
 
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴mganeko
 
WebRTCの技術解説 第二版 公開版 本編
WebRTCの技術解説 第二版 公開版 本編WebRTCの技術解説 第二版 公開版 本編
WebRTCの技術解説 第二版 公開版 本編Contest Ntt-west
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能Kohei Tokunaga
 
ConfD で Linux にNetconfを喋らせてみた
ConfD で Linux にNetconfを喋らせてみたConfD で Linux にNetconfを喋らせてみた
ConfD で Linux にNetconfを喋らせてみたAkira Iwamoto
 

What's hot (20)

WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
 
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
 
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
実践 WebRTC 〜最新事例と開発ノウハウの紹介〜
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannelNode.js with WebRTC DataChannel
Node.js with WebRTC DataChannel
 
kpackによるコンテナイメージのビルド
kpackによるコンテナイメージのビルドkpackによるコンテナイメージのビルド
kpackによるコンテナイメージのビルド
 
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdf
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdfver.12.9_LAPRAS SCOUTサービスご案内資料.pdf
ver.12.9_LAPRAS SCOUTサービスご案内資料.pdf
 
nginx入門
nginx入門nginx入門
nginx入門
 
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみるいまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
 
Cilium - BPF & XDP for containers
 Cilium - BPF & XDP for containers Cilium - BPF & XDP for containers
Cilium - BPF & XDP for containers
 
elixirを使ったゲームサーバ
elixirを使ったゲームサーバelixirを使ったゲームサーバ
elixirを使ったゲームサーバ
 
Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介
 
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴
 
WebRTCの技術解説 第二版 公開版 本編
WebRTCの技術解説 第二版 公開版 本編WebRTCの技術解説 第二版 公開版 本編
WebRTCの技術解説 第二版 公開版 本編
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能
 
ConfD で Linux にNetconfを喋らせてみた
ConfD で Linux にNetconfを喋らせてみたConfD で Linux にNetconfを喋らせてみた
ConfD で Linux にNetconfを喋らせてみた
 

Viewers also liked

WebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LTWebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LTmganeko
 
2016 February - WebRTC Conference japan - English
2016 February - WebRTC Conference japan - English2016 February - WebRTC Conference japan - English
2016 February - WebRTC Conference japan - EnglishAlexandre Gouaillard
 
WebRTC Reborn Hackference
WebRTC Reborn HackferenceWebRTC Reborn Hackference
WebRTC Reborn HackferenceDan Jenkins
 
SkyWay国内唯一のCPaaS
SkyWay国内唯一のCPaaSSkyWay国内唯一のCPaaS
SkyWay国内唯一のCPaaSKensaku Komatsu
 
Kranky Geek WebRTC 2015 - What's next for WebRTC?
Kranky Geek WebRTC 2015 - What's next for WebRTC?Kranky Geek WebRTC 2015 - What's next for WebRTC?
Kranky Geek WebRTC 2015 - What's next for WebRTC?Kranky Geek
 
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...Mario Heiderich
 
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させる
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させるHTML5 + JavaScriptでDRMつきMPEG-DASHを再生させる
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させるGaprot
 
WebRTC on Mobile Devices: Challenges and Opportunities
WebRTC on Mobile Devices: Challenges and OpportunitiesWebRTC on Mobile Devices: Challenges and Opportunities
WebRTC on Mobile Devices: Challenges and OpportunitiesVladimir Beloborodov
 
Whoscall 的 Realtime Monitoring 經驗分享
Whoscall 的 Realtime Monitoring 經驗分享Whoscall 的 Realtime Monitoring 經驗分享
Whoscall 的 Realtime Monitoring 經驗分享William Yeh
 
Linux Performance Analysis and Tools
Linux Performance Analysis and ToolsLinux Performance Analysis and Tools
Linux Performance Analysis and ToolsBrendan Gregg
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]Kuro Hsu
 
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習台灣資料科學年會
 
姜俊宇/從資料到知識:從零開始的資料探勘
姜俊宇/從資料到知識:從零開始的資料探勘姜俊宇/從資料到知識:從零開始的資料探勘
姜俊宇/從資料到知識:從零開始的資料探勘台灣資料科學年會
 

Viewers also liked (15)

WebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LTWebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
 
2016 February - WebRTC Conference japan - English
2016 February - WebRTC Conference japan - English2016 February - WebRTC Conference japan - English
2016 February - WebRTC Conference japan - English
 
WebRTCとDialogicとの関わり
WebRTCとDialogicとの関わりWebRTCとDialogicとの関わり
WebRTCとDialogicとの関わり
 
WebRTC Reborn Hackference
WebRTC Reborn HackferenceWebRTC Reborn Hackference
WebRTC Reborn Hackference
 
SkyWay国内唯一のCPaaS
SkyWay国内唯一のCPaaSSkyWay国内唯一のCPaaS
SkyWay国内唯一のCPaaS
 
WebRTC on Native App
WebRTC on Native AppWebRTC on Native App
WebRTC on Native App
 
Kranky Geek WebRTC 2015 - What's next for WebRTC?
Kranky Geek WebRTC 2015 - What's next for WebRTC?Kranky Geek WebRTC 2015 - What's next for WebRTC?
Kranky Geek WebRTC 2015 - What's next for WebRTC?
 
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
 
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させる
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させるHTML5 + JavaScriptでDRMつきMPEG-DASHを再生させる
HTML5 + JavaScriptでDRMつきMPEG-DASHを再生させる
 
WebRTC on Mobile Devices: Challenges and Opportunities
WebRTC on Mobile Devices: Challenges and OpportunitiesWebRTC on Mobile Devices: Challenges and Opportunities
WebRTC on Mobile Devices: Challenges and Opportunities
 
Whoscall 的 Realtime Monitoring 經驗分享
Whoscall 的 Realtime Monitoring 經驗分享Whoscall 的 Realtime Monitoring 經驗分享
Whoscall 的 Realtime Monitoring 經驗分享
 
Linux Performance Analysis and Tools
Linux Performance Analysis and ToolsLinux Performance Analysis and Tools
Linux Performance Analysis and Tools
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]
 
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
[DSC 2016] 系列活動:李宏毅 / 一天搞懂深度學習
 
姜俊宇/從資料到知識:從零開始的資料探勘
姜俊宇/從資料到知識:從零開始的資料探勘姜俊宇/從資料到知識:從零開始的資料探勘
姜俊宇/從資料到知識:從零開始的資料探勘
 

More from mganeko

Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)mganeko
 
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたAmazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたmganeko
 
Build Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.jsBuild Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.jsmganeko
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...mganeko
 
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねSkywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねmganeko
 
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updateWebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updatemganeko
 
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたmganeko
 
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sampleWebRTC SFU mediasoup sample
WebRTC SFU mediasoup samplemganeko
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2mganeko
 
WebRTC Build MCU on browser
WebRTC Build MCU on browserWebRTC Build MCU on browser
WebRTC Build MCU on browsermganeko
 
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorderPeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecordermganeko
 
Webrtc bootcamp handson
Webrtc bootcamp handsonWebrtc bootcamp handson
Webrtc bootcamp handsonmganeko
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようmganeko
 
Inside WebM
Inside WebMInside WebM
Inside WebMmganeko
 
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live StreamingMediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streamingmganeko
 
Chromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそうChromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそうmganeko
 
Infocom webrtc conference japan
Infocom webrtc conference japanInfocom webrtc conference japan
Infocom webrtc conference japanmganeko
 
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )mganeko
 
WebRTC Summit 2014 NewYork 参加報告
WebRTC Summit 2014 NewYork 参加報告WebRTC Summit 2014 NewYork 参加報告
WebRTC Summit 2014 NewYork 参加報告mganeko
 

More from mganeko (20)

Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
 
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたAmazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみた
 
Build Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.jsBuild Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.js
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
 
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねSkywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
 
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updateWebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample update
 
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみた
 
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sampleWebRTC SFU mediasoup sample
WebRTC SFU mediasoup sample
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2
 
WebRTC Build MCU on browser
WebRTC Build MCU on browserWebRTC Build MCU on browser
WebRTC Build MCU on browser
 
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorderPeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorder
 
Webrtc bootcamp handson
Webrtc bootcamp handsonWebrtc bootcamp handson
Webrtc bootcamp handson
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
 
Inside WebM
Inside WebMInside WebM
Inside WebM
 
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live StreamingMediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streaming
 
Chromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそうChromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそう
 
Infocom webrtc conference japan
Infocom webrtc conference japanInfocom webrtc conference japan
Infocom webrtc conference japan
 
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
Nodeで操るKurentoメディアサーバー ( Kurento + WebRTC + Node.js )
 
WebRTC Summit 2014 NewYork 参加報告
WebRTC Summit 2014 NewYork 参加報告WebRTC Summit 2014 NewYork 参加報告
WebRTC Summit 2014 NewYork 参加報告
 

WebRTC multistream

  • 3. 複数のMediaを使う手段 • 1 アプリに、複数 PeerConnection • 1 PeerConnection に、複数 MediaStream • 1 MediaStream に、複数MediaStreamTrack
  • 4. 複数のMediaを使う手段 • 1 アプリに、複数 PeerConnection – 複数人のケースと同じ • 1 PeerConnection に、複数 MediaStream – 今回検証した範囲 • 1 MediaStream に、複数MediaStreamTrack – Chromeでは MediaStream.addTrack()は呼び出し可能 • ※特にイベントは発生しない – 受け側で 特定のTrackを指定して再生することはできないはず • URL.createObjectURL(stream) で、複数Trackをハンドリングできない
  • 5. 関連する要素 • メソッド – RTCPeerConnection.addStream(stream) • ローカルのMediaStreamを追加 – RTCPeerConnection.removeStream(stream) • ローカルのMediaStreamを除去 • イベント – RTCPeerConnection.onnegotiationneeded() • SDPの再送が必要なときに発火
  • 6. addStream() / removeStream() • Chrome 43.0.2357.124 (64-bit) – RTCPeerConnection.addStream() • 2つのMediaStream(video入り)を追加可能 – RTCPeerConnection.removeStream()も可能 • Firefox 38.0.5 – RTCPeerConnection.addStream() • 2つのMediaStream(video入り)を追加可能 – RTCPeerConnection.removeStream()は不可 • NotSupportedError:
  • 7. onnegotiationneeded() • 発火のタイミング – ○ RTCPeerConnection.addStream() / .removeStream() – × RTCPeerConnection.createOffer() / .createAnswer() – × RTCPeerConnection.setLocalDescription() – × RTCPeerConnection.setRemoteDescription() – × RTCPeerConnection.onaddstream() 発火時 • リモートの MediaStream が検出されたときのイベント • Chorme – 接続確立前の addStream() でも発火 – 接続確立後の addStream() / removeStream() でも発火 • Firefox – 接続確立前の addStream() では発火しない (※Nightlyでは発火) – 接続確立後の addStream() で発火 – 接続確立後の removeStream() は実行できない (※Nightlyでも不可)
  • 8. 参考:vanilla ICE シグナリング Peer BPeer A createOffer() Peer-to-Peer offer SDP (with ICE candidate) setLocalDescription() setLocalDescription() answer SDP (with ICE candidate) setRemoteDescription() createAnswer() setRemoteDescription() onicecandidate() onicecandidate() onicecandidate() onicecandidate() addStream(localStream) addStream(localStream) onaddstream(remote) onaddstream(remote)
  • 9. 最初からmultistream : Chrome • ※ onnegotiationneeded()イベントは無視 • offer:1, answer:1→ 当然OK • offer:2, answer:2 → OK • offer:2, answer:1 → OK • offer:1, answer:2 → OK
  • 10. 最初からmultistream : Firefox • ※ onnegotiationneeded()イベントは無視 • offer:1, answer:1→ 当然OK • offer:2, answer:2 → OK • offer:2, answer:1 → OK • offer:1, answer:2 → △ – offer側に1つしか表示されない – ※ answer側でsetOffer後、 onnegotiationneeded() が発火している • そのイベントを適切に処理してあげる必要がある??
  • 11. 最初からmultistream Chrome(offer) → Firefox(answer) • ※ onnegotiationneeded()イベントは無視 • offer:1, answer:1 → OK • offer:2, answer:2 → NG – answer側でエラー – setRemoteDescription(offer) ERROR: " DOMException [InvalidSessionDescriptionError: "Found multiple different webrtc msids in m-section 1 • offer:2, answer:1 → NG – answer側 – setRemoteDescription(offer) ERROR: " DOMException [InvalidSessionDescriptionError: "Found multiple different webrtc msids in m-section 1 • offer:1, answer:2 → △。offer側に1つしか表示されない
  • 12. 最初からmultistream Firefox(offer) → Chrome(answer) • ※ onnegotiationneeded()イベントは無視 • offer:1, answer:1 → OK • offer:2, answer:2 → NG – answer側でエラー – Create Answer failed. err: Failed to initialize the answer. • offer:2, answer:1answer:2 → NG – answer側でエラー – Create Answer failed. err: Failed to initialize the answer. • offer:1, answer:2 → NG – answer側 OK – offer側でエラー – setRemoteDescription(offer) ERROR: " DOMException [InvalidSessionDescriptionError: "Found multiple different webrtc msids in m-section 1
  • 13. 後からmultistream : offer側で+1 Peer BPeer A createOffer() Peer-to-Peer offer SDP (with ICE candidate) setLocalDescription() setLocalDescription() answer SDP (with ICE candidate) setRemoteDescription() createAnswer() setRemoteDescription() addStream(localStream) onaddstream(remote) onnegotiationneeded()
  • 14. 後からmultistream : offer側で変化 • onnegotiationneeded()イベントを使う • offer:1 answer:1後、 offer +1 – offer側 • peer.addStream(stream2) • peer.onnegotiationneeded()発火 • peer.createOffer() • peer.setLocalDescription(sdp) • sendSDP(sdp) ※何らかの手段で送る – answer側 • receiveSDP(sdp) ※何らかの手段で受けてとる • peer.setRemoteDescription(sdp) • peer.onaddstream(stream2) 発火 • ※ peer.onnegotiationneeded()発火しない • peer.createAnswer() • peer.setLocalDescription(sdp) • sendSDP(sdp) ※何らかの手段で送る – offer側 • receiveSDP(sdp) ※何らかの手段で受けてとる • peer.setRemoteDescription(sdp)
  • 15. 後からmultistream : answer側で+1 Peer BPeer A createOffer() Peer-to-Peer offer SDP setLocalDescription() setLocalDescription() answer SDP (with ICE candidate) setRemoteDescription() createAnswer() setRemoteDescription() addStream(localStream) onnegotiationneeded() onaddstream(remote) REQUEST for re-createOffer
  • 16. 後からmultistream : answer側で変化 • onnegotiationneeded()イベントを使う • offer:1 answer:1後、 answer +1 – answer側 • peer.addStream(stream2) • peer.onnegotiationneeded()発火 • ※何らかの手段で、offer側にSDP再送を依頼する – offer側 • peer.createOffer() • peer.setLocalDescription(sdp) • sendSDP(sdp) ※何らかの手段で送る – answer側 • receiveSDP(sdp) ※何らかの手段で受けてとる • peer.setRemoteDescription(sdp) • peer.createAnswer() • peer.setLocalDescription(sdp) • sendSDP(sdp) ※何らかの手段で送る – offer側 • receiveSDP(sdp) ※何らかの手段で受けてとる • peer.setRemoteDescription(sdp) • peer.onaddstream(stream2) 発火
  • 17. 後からmultistream : Chrome • onnegotiationneeded()イベントを使う • offer:1 answer:1後、 offer +1 → OK (※ answer を再生成) • offer:2 answer:1後、 offer -1→ OK (※ answer を再生成) • offer:1 answer:2後、 offer +1→ OK (※ answer を再生成) • offer:2 answer:2後、 offer -1→ OK (※ answer を再生成) • offer:1 answer:1後、 answer +1 → OK – answer側のonnegotiationneeded → answer作らずスルー – offerを強制生成、answer側にoffer再セット(setRemote) – answer側で、ようやくanswer生成 – offer側に、asnwer再セット(setRemote) • offer:1 answer:2後、 answer -1 → OK (※同上) • offer:2 answer:1後、 answer +1 → OK (※同上) • offer:2 answer:2後、 answer -1 → OK (※同上)
  • 18. 後からmultistream : Firefox • onnegotiationneeded()イベントを使う • offer:1 answer:1後、 offer +1 → OK. – ※+1時には、offer側では onnegotiationneededが呼ばれる。 – ※answerは強制生成 • offer:2 answer:1後、 offer -1→ NG. removeStream() できない – NotSupportedError: removeStream not yet implemented • offer:1 answer:2後、 offer +1→ その状況が作れない • offer:2 answer:2後、 offer -1→ NG. removeStream()できない • offer:1, answer:1後、 answer +1 → NG. Answer側でエラー – "Create Answer failed. err:" DOMException [InvalidStateError: "Cannot create answer in state stable" • offer:1, answer:2後、 answer -1 → その状況が作れない • offer:2, answer:1後、 answer +1 → NG?? Javascriptミス? • offer:2, answer:2後、 answer -1 → NG. removeStream()できない
  • 19. オマケ1 • RTCPeerConnection.addTrack() … – onnegotiationneeded()発火しない • MedaiStreamTrack.enabled = true / false – メディア送信の on/offできる
  • 20. オマケ2: 複数のMediaを使う手段 • 1 アプリに、複数 PeerConnection – 複数人のケースと同じ • 1 PeerConnection に、複数 MediaStream – 今回検証した範囲 • 1 MediaStream に、複数MediaStreamTrack – Chromeでは MediaStream.addTrack()は呼び出し可能 • ※特にイベントは発生しない – 受け側で 特定のTrackを指定して再生することはできないはず • URL.createObjectURL(stream) で、複数Trackをハンドリングできない – ※無理やり再生はできた • MediaStream 生成 → addTrack() → URL.createObjectURL()
  • 21. オマケ2: 複数のMediaを使う手段 ※複数MediaStreamTrackから無理やり再生手順 var videoTracks = stream1.getVideoTracks(); var stream2 = new webkitMediaStream(); stream2.addTarck(videoTracks[1]); video.src = URL.createObjectURL(stream2);