ChromeとFirefoxが2つのビデオストリームを転送することに同意する方法







WebRTC落とし穴の 1つは特別です。 これは、ブラウザがメディアストリームの転送に同意する方法です。 コーデック、ビットレート、ビデオ解像度-これがすべてです。 メディアストリームコードは1つだけです。すべて問題ありません。 しかし、それらが2つある場合(音声付きのビデオ、2つ目のメディアストリーム:1つはビデオ用、もう1つはサウンド用)、状況記述形式に関するブラウザの意見は大きく分かれています。 FirefoxでChromeからビデオ通話を行うのはとても簡単です。 しかし、音声付きのビデオ通話はもうありません。 カットの下では、なぜそれが起こったのか、新しいSafariでそれを見て、Microsoft Edgeが持っている特別な方法について少し話があります。



音声通話とビデオ通話の分野の収穫機



WebRTCはコンバインハーベスターです。 多くのプロトコルと異なる名前のJavaScript APIが1つの名前の下にあり、異なる動作をします。





この話の最も難しい部分は、ピアツーピア接続を確立することです。 これがタブ間のローカル通信ではない場合、デバイスが同じネットワーク上にない場合、またはポートが開いている実際のIPアドレスがない場合、「ネゴシエート」するためにいくつかの中間サーバーが必要です。 通常、これらのサーバーは、WebRTCを使用したい開発者によって作成されます。 STUNを除き、「私のパブリックIPとは何か」という質問に答えるエコーサーバーは、Googleから公開されています。



開発者が送信しようとしているもの(音声、ビデオ、または任意のデータ)に応じて、ピアツーピア接続が確立されます。 WebRTCは、テキストパッケージ「提供」、「回答」、「氷候補」を作成します。開発者は、これらを互いに接続するブラウザー間で(通常は自分のシグナリングサーバーを介して)送信する必要があります。 これらのパッケージでは、両方のブラウザーがその機能と今後の動作を説明し、WebRTCは最適な接続方法を選択しようとしています。



テレフォニーSDPレガシー



WebRTCが開発者の手と交換するパッケージは、SDP形式を使用します。 それは非常に古く、テキストであり、電話から来ました(WebRTCはブラウザから電話ネットワークへ、またはその逆に呼び出すとき、開発者の努力を最小限に抑えようとします)、HTTPに似ています。 SDPパッケージは次のようになります。「このブラウザーは別のブラウザーへのピアツーピア接続を確立しようとしていますが、ネットワークを介して何を送信するかはまだわかりません。」



開発者がデータ、音声、またはビデオの転送を開始/停止したい場合、WebRTCはすぐに彼からの「再ネゴシエーション」を要求します-送信されたデータのネットワークルートの最適性を確認し、コーデックについてネゴシエートするためにピアツーピア接続を再起動します。 これは、WebRTCがビデオの送信を希望することを告げるSDPパッケージの外観です。



非表示のテキスト
type: offer, sdp: v=0
o=- 6268223368571881674 2 IN IP4 127.0.0.1
s=-
t=0 0
m=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Q64h
a=ice-pwd:UPO8gbng2uE2JsOt2pB163Df
a=fingerprint:sha-256 F7:FB:E8:90:A3:DE:F8:2E:02:70:30:D8:2E:19:02:61:A9:E0:FD:8E:E9:D5:EB:D9:65:20:32:B0:CF:35:21:2C
a=setup:actpass
a=mid:video
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=sendrecv
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
a=ssrc-group:FID 1732143492 2116247900
a=ssrc:1732143492 cname:Vsw2XRlFtKOgvIT7
a=ssrc:1732143492 msid:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0 f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:1732143492 mslabel:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
a=ssrc:1732143492 label:f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:2116247900 cname:Vsw2XRlFtKOgvIT7
a=ssrc:2116247900 msid:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0 f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:2116247900 mslabel:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
a=ssrc:2116247900 label:f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
view raw sdp1 hosted with ❤ by GitHub


急速に変化する標準



WebRTCは長年にわたって私たちと一緒にいましたが、まだベータ版の状態です。 最近、JavaScript APIはコールバックからプロミスに完全に書き直され、音声およびビデオストリームの動作が変更され、Microsoftは代替API「oRTC」を作成しました。 多くの興味深いことが起こりました。 また、SDPパッケージのメディアストリームを記述する形式が変更されました。 長年、使用されていた階層構造の「プランB」は廃止され、「統合プラン」に置き換えられました。各ストリームは、SDPパッケージの個別のセクションで定義されていました。 比較してください。



それは:



非表示のテキスト
type: offer, sdp: v=0
o=- 6268223368571881674 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS 986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Q64h
a=ice-pwd:UPO8gbng2uE2JsOt2pB163Df
a=fingerprint:sha-256 F7:FB:E8:90:A3:DE:F8:2E:02:70:30:D8:2E:19:02:61:A9:E0:FD:8E:E9:D5:EB:D9:65:20:32:B0:CF:35:21:2C
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:1333610373 cname:Vsw2XRlFtKOgvIT7
a=ssrc:1333610373 msid:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0 3ff337f5-9edc-494d-a5c1-6da2ce9ed142
a=ssrc:1333610373 mslabel:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
a=ssrc:1333610373 label:3ff337f5-9edc-494d-a5c1-6da2ce9ed142
m=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Q64h
a=ice-pwd:UPO8gbng2uE2JsOt2pB163Df
a=fingerprint:sha-256 F7:FB:E8:90:A3:DE:F8:2E:02:70:30:D8:2E:19:02:61:A9:E0:FD:8E:E9:D5:EB:D9:65:20:32:B0:CF:35:21:2C
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=sendrecv
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
a=ssrc-group:FID 1732143492 2116247900
a=ssrc:1732143492 cname:Vsw2XRlFtKOgvIT7
a=ssrc:1732143492 msid:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0 f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:1732143492 mslabel:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
a=ssrc:1732143492 label:f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:2116247900 cname:Vsw2XRlFtKOgvIT7
a=ssrc:2116247900 msid:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0 f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
a=ssrc:2116247900 mslabel:986f56f0-4d6e-49fa-8b01-1cb6e8bbd6d0
a=ssrc:2116247900 label:f2e5b805-3a98-4ab1-9cc2-df2694fcc9a1
view raw sdp2 hosted with ❤ by GitHub


次のようになりました:



非表示のテキスト
v=0
o=mozilla...THIS_IS_SDPARTA-55.0 5576035894611904766 0 IN IP4 0.0.0.0
s=-
t=0 0
a=sendrecv
a=fingerprint:sha-256 98:7E:DA:2C:ED:DC:F9:CE:ED:CC:43:2F:58:36:AC:BE:17:B4:E2:84:69:60:91:38:11:9D:2B:0C:F8:12:FF:0B
a=group:BUNDLE sdparta_0 sdparta_1
a=ice-options:trickle
a=msid-semantic:WMS *
m=audio 47296 UDP/TLS/RTP/SAVPF 109 9 0 8 101
c=IN IP4 95.213.228.4
a=candidate:0 1 UDP 2122121471 192.168.15.145 1038 typ host
a=candidate:7 1 UDP 2122252543 172.29.0.1 1039 typ host
a=candidate:14 1 UDP 2122187007 192.168.80.1 1040 typ host
a=candidate:21 1 TCP 2105377023 192.168.15.145 58157 typ host tcptype passive
a=candidate:21 1 TCP 2105393407 192.168.15.145 9 typ host tcptype active
a=candidate:26 1 TCP 2105508095 172.29.0.1 57536 typ host tcptype passive
a=candidate:26 1 TCP 2105524479 172.29.0.1 9 typ host tcptype active
a=candidate:31 1 TCP 2105442559 192.168.80.1 57467 typ host tcptype passive
a=candidate:31 1 TCP 2105458943 192.168.80.1 9 typ host tcptype active
a=candidate:0 2 UDP 2122121470 192.168.15.145 1041 typ host
a=candidate:7 2 UDP 2122252542 172.29.0.1 1042 typ host
a=candidate:14 2 UDP 2122187006 192.168.80.1 1043 typ host
a=candidate:21 2 TCP 2105377022 192.168.15.145 53990 typ host tcptype passive
a=candidate:21 2 TCP 2105393406 192.168.15.145 9 typ host tcptype active
a=candidate:26 2 TCP 2105508094 172.29.0.1 59650 typ host tcptype passive
a=candidate:26 2 TCP 2105524478 172.29.0.1 9 typ host tcptype active
a=candidate:31 2 TCP 2105442558 192.168.80.1 54837 typ host tcptype passive
a=candidate:31 2 TCP 2105458942 192.168.80.1 9 typ host tcptype active
a=candidate:1 1 UDP 1685921791 195.91.179.50 1038 typ srflx raddr 192.168.15.145 rport 1038
a=candidate:4 1 UDP 92085759 95.213.228.4 47296 typ relay raddr 95.213.228.4 rport 47296
a=candidate:6 1 UDP 92085247 95.213.228.4 53983 typ relay raddr 95.213.228.4 rport 53983
a=candidate:22 1 TCP 1669160959 195.91.179.50 58157 typ srflx raddr 192.168.15.145 rport 58157 tcptype passive
a=candidate:23 1 UDP 8200191 95.213.228.4 48383 typ relay raddr 95.213.228.4 rport 48383
a=candidate:25 1 UDP 8200191 95.213.228.4 55022 typ relay raddr 95.213.228.4 rport 55022
a=candidate:1 2 UDP 1685921790 195.91.179.50 1041 typ srflx raddr 192.168.15.145 rport 1041
a=candidate:4 2 UDP 92085758 95.213.228.4 33164 typ relay raddr 95.213.228.4 rport 33164
a=candidate:6 2 UDP 92085246 95.213.228.4 55111 typ relay raddr 95.213.228.4 rport 55111
a=candidate:22 2 TCP 1669160958 195.91.179.50 53990 typ srflx raddr 192.168.15.145 rport 53990 tcptype passive
a=candidate:23 2 UDP 8200190 95.213.228.4 47176 typ relay raddr 95.213.228.4 rport 47176
a=candidate:25 2 UDP 8200190 95.213.228.4 45231 typ relay raddr 95.213.228.4 rport 45231
a=sendrecv
a=end-of-candidates
a=extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1
a=fmtp:101 0-15
a=ice-pwd:e01708a35bd9fb67502a714e51a11644
a=ice-ufrag:ac97477f
a=mid:sdparta_0
a=msid:{89226294-ff67-4c59-aa43-6d55e4eeabeb} {09b10fc1-6364-4e6e-b96d-b6a33377a5c8}
a=rtcp:33164 IN IP4 95.213.228.4
a=rtcp-mux
a=rtpmap:109 opus/48000/2
a=rtpmap:9 G722/8000/1
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=setup:actpass
a=ssrc:2414570955 cname:{2d684c3d-4555-45a3-a880-030771197dc8}
m=video 47296 UDP/TLS/RTP/SAVPF 120 121 126 97
c=IN IP4 95.213.228.4
a=candidate:0 1 UDP 2122121471 192.168.15.145 1044 typ host
a=candidate:7 1 UDP 2122252543 172.29.0.1 1046 typ host
a=candidate:14 1 UDP 2122187007 192.168.80.1 1048 typ host
a=candidate:21 1 TCP 2105377023 192.168.15.145 53513 typ host tcptype passive
a=candidate:21 1 TCP 2105393407 192.168.15.145 9 typ host tcptype active
a=candidate:26 1 TCP 2105508095 172.29.0.1 63978 typ host tcptype passive
a=candidate:26 1 TCP 2105524479 172.29.0.1 9 typ host tcptype active
a=candidate:31 1 TCP 2105442559 192.168.80.1 55068 typ host tcptype passive
a=candidate:31 1 TCP 2105458943 192.168.80.1 9 typ host tcptype active
a=candidate:0 2 UDP 2122121470 192.168.15.145 1049 typ host
a=candidate:7 2 UDP 2122252542 172.29.0.1 1050 typ host
a=candidate:14 2 UDP 2122187006 192.168.80.1 1051 typ host
a=candidate:21 2 TCP 2105377022 192.168.15.145 50228 typ host tcptype passive
a=candidate:21 2 TCP 2105393406 192.168.15.145 9 typ host tcptype active
a=candidate:26 2 TCP 2105508094 172.29.0.1 60348 typ host tcptype passive
a=candidate:26 2 TCP 2105524478 172.29.0.1 9 typ host tcptype active
a=candidate:31 2 TCP 2105442558 192.168.80.1 58818 typ host tcptype passive
a=candidate:31 2 TCP 2105458942 192.168.80.1 9 typ host tcptype active
a=sendrecv
a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=fmtp:126 profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
a=fmtp:97 profile-level-id=42e01f;level-asymmetry-allowed=1
a=fmtp:120 max-fs=12288;max-fr=60
a=fmtp:121 max-fs=12288;max-fr=60
a=ice-pwd:e01708a35bd9fb67502a714e51a11644
a=ice-ufrag:ac97477f
a=mid:sdparta_1
a=msid:{89226294-ff67-4c59-aa43-6d55e4eeabeb} {95959808-b921-4070-a3e2-4bbadd7bc9b2}
a=rtcp:1050 IN IP4 172.29.0.1
a=rtcp-fb:120 nack
a=rtcp-fb:120 nack pli
a=rtcp-fb:120 ccm fir
a=rtcp-fb:120 goog-remb
a=rtcp-fb:121 nack
a=rtcp-fb:121 nack pli
a=rtcp-fb:121 ccm fir
a=rtcp-fb:121 goog-remb
a=rtcp-fb:126 nack
a=rtcp-fb:126 nack pli
a=rtcp-fb:126 ccm fir
a=rtcp-fb:126 goog-remb
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 goog-remb
a=rtcp-mux
a=rtpmap:120 VP8/90000
a=rtpmap:121 VP9/90000
a=rtpmap:126 H264/90000
a=rtpmap:97 H264/90000
a=setup:actpass
a=ssrc:3311343959 cname:{2d684c3d-4555-45a3-a880-030771197dc8}
view raw sdp3 hosted with ❤ by GitHub




Chrome vs Firefox vs Edge vs Safari



Webテクノロジーのベータ版に関しては、ブラウザーでの実装が大きく異なる場合があり、標準の現在のバージョンに何年も遅れることがあります。 そのため、WebRTCで起こりました。 何年も前、Google Chromeは「Plan B」形式のいくつかのメディアトラックをサポートしていましたが、実装を「Unified Plan」に変更していません。 対応するチケットは数年前開かれ、開発者はこれがどれほど重要かを議論し、チケットを相互に再割り当てしていますが、まだそこにあります。 典型的なFirefoxでは、統合プランのみが実装されているため、問題なく音声または音声なしの1つのメディアトラックのみを通信できます。 もっと必要ですか? アダプターとポリフィルの世界へようこそ!



最初に独自のoRTC APIの実装のみをサポートするMicrosoft Edgeは、最近のバージョンでWebRTC APIと統合プランのサポートを追加しました。 Safariは、次のバージョンのWebRTCのみをサポートます。ベータ版はすでに開発者が利用できます 。 そして、悲しいことに、プランB。これはChromiumに基づいて作成されたためです。



ブラウザー間の呼び出しを行う方法



ご覧のとおり、最も人気のあるブラウザであるChromeには、古い「Plan B」形式が残っています。 Safariがあり、そのモバイル版はiPhoneにあります。 Firefoxおよび新しい統合プランを備えた新しいMicrosoft Edge。



音声なしで音声またはビデオを転送する場合、これは何の役割も果たしませんが、複数のメディアトラックの場合は、SDPを手動で変更するか、 アダプターを使用する必要があります。 遅かれ早かれ、すべてのブラウザが統合プランに切り替わることを本当に望んでいます。 しかし、現時点では、ほとんどのデスクトップおよびモバイルブラウザーの大部分がプランBをサポートしているという厳しい現実があり、FirefoxおよびEdgeとの互換性のためにコードを追加する必要があります。 そして、多くのデバッグが必要です。



katの前の写真はここから撮影されました。



All Articles