自去年4月Firefox 53删除NPAPI以來,該插件一直無法被正常通路。而就在去年年末,Google Hangouts(環聊)重新支援使用Firefox WebRTC。本文深度剖析了Firefox SDP并比較了Firefox和Chrome Hangouts的WebRTC規範。
作者:Philipp Hancke
翻譯:鴻蒙
Tsahi發現Firefox上的環聊再次開始工作,并迅速呼叫Fippo進行調查。
在2017年的末尾,Google Hangouts(環聊)開始重新支援Firefox。自2017年4月Firefox 53删除NPAPI以來,該插件一直無法正常通路。盡管Firefox WebRTC團隊測試Hangouts的事情已經公開了一段時間,但看到它付諸實際仍然是一件很令人興奮的事情。 Tsahi Levent-Levi是最先注意到的人之一。Hangouts 團隊用實際行動表示他們仍然視網絡為一個開放的平台!
我此前在2014年寫過一篇關于Hangouts的文章(https://webrtchacks.com/hangout-analysis-philipp-hancke/),Hangouts使用了很多非标準技術,如SDES和RTP DataChannel——它們不支援Firefox,而是否支援Firefox往往是一個很重要的産品技術名額(也有傳言說是因為它的NaCl和'hats'特征,正如我在舊部落格中提到的那樣)。
不過,當視訊Hangouts 産品的會議功能作為其不斷現代化的一部分時,事情已經起了變化。例如,Opus早已成為預設的音頻編解碼器。雖然Chrome中的Hangouts 并非100%與WebRTC 1.0規範相容(例如,我已經看到Chrome使用DTLS-SRTP而不是SDES),但Firefox實作似乎有點不同,并且更符合标準:
FireFox Hangouts和Chrome Hangouts WebRTC規範比較
深入剖析SDP
讓我們來深入剖析SDP。不幸的是自從FF57以來,Firefox中的webrtc-externals擴充已被打破,沒有人有時間弄清楚為什麼。 但是我們從about:webrtc中得到的SDP實際上非常有意思:
1v=0
2o=mozilla...THIS_IS_SDPARTA-57.0.1 8208570803153758710 3 IN IP4 0.0.0.0
3s=-
4t=0 0
5a=sendrecv
6a=fingerprint:sha-256 79:67:68:53:C0:3C:4D:60:1B:DD:D5:FE:BA:D0:86:3C:30:44:FE:4B:14:CB:ED:E4:D3:21:22:88:F9:25:F2:F5
7a=group:BUNDLE mid_0 mid_1 mid_2 mid_3 mid_4
8a=ice-options:trickle
9a=msid-semantic:WMS *
10m=audio 37842 UDP/TLS/RTP/SAVPF 109
11c=IN IP4 84.20.98.117
12a=candidate:0 1 UDP 2122252543 192.168.1.230 37842 typ host
13a=candidate:3 1 TCP 2105524479 192.168.1.230 9 typ host tcptype active
14a=candidate:1 1 UDP 1686052863 84.20.98.117 37842 typ srflx raddr 192.168.1.230 rport 37842
15a=sendrecv
16a=end-of-candidates
17a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
18a=fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1
19a=ice-pwd:72af2dc778d255334cb38661e30fc57a
20a=ice-ufrag:80e16c7c
21a=mid:mid_0
22a=msid:{7a66c1a7-b588-4d8d-ab7c-92cb4a248aea} {1dda5d9f-d705-4db7-bfb1-1153833be2a4}
23a=rtcp-mux
24a=rtpmap:109 opus/48000/2
25a=setup:active
26a=ssrc:490004612 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
27m=video 37842 UDP/TLS/RTP/SAVPF 120
28c=IN IP4 84.20.98.117
29a=sendrecv
30a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
31a=extmap:3/sendonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
32a=fmtp:120 max-fs=12288;max-fr=60
33a=ice-pwd:72af2dc778d255334cb38661e30fc57a
34a=ice-ufrag:80e16c7c
35a=mid:mid_1
36a=msid:{444747d4-c2d2-45ce-a761-c572c0648e18} {6030f14c-68c2-4f35-8803-af7011d4bbb8}
37a=rid:f send
38a=rid:h send
39a=rid:q send
40a=rtcp-fb:120 nack
41a=rtcp-fb:120 ccm fir
42a=rtcp-fb:120 goog-remb
43a=rtcp-mux
44a=rtpmap:120 VP8/90000
45a=setup:active
46a=simulcast: send rid=f;h;q
47a=ssrc:944082137 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
48a=ssrc:3093937015 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
49a=ssrc:3682296736 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
50m=application 37842 DTLS/SCTP 5000
51c=IN IP4 84.20.98.117
52a=sendrecv
53a=ice-pwd:72af2dc778d255334cb38661e30fc57a
54a=ice-ufrag:80e16c7c
55a=mid:mid_2
56a=rtcp-mux
57a=sctpmap:5000 webrtc-datachannel 256
58a=setup:active
59a=max-message-size:1073741823
60m=audio 37842 UDP/TLS/RTP/SAVPF 109
61c=IN IP4 84.20.98.117
62a=recvonly
63a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
64a=fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1
65a=ice-pwd:72af2dc778d255334cb38661e30fc57a
66a=ice-ufrag:80e16c7c
67a=mid:mid_3
68a=rtcp-mux
69a=rtpmap:109 opus/48000/2
70a=setup:active
71a=ssrc:2828437981 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
72m=video 37842 UDP/TLS/RTP/SAVPF 120
73c=IN IP4 84.20.98.117
74a=recvonly
75a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
76a=extmap:3/sendonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
77a=fmtp:120 max-fs=12288;max-fr=60
78a=ice-pwd:72af2dc778d255334cb38661e30fc57a
79a=ice-ufrag:80e16c7c
80a=mid:mid_4
81a=rtcp-fb:120 nack
82a=rtcp-fb:120 ccm fir
83a=rtcp-fb:120 goog-remb
84a=rtcp-mux
85a=rtpmap:120 VP8/90000
86a=setup:active
87a=ssrc:3511641524 cname:{90bfee9f-4610-43b0-993f-a064332e442b}
我們可以從中學到很多東西,是以我們來深入研究一下。有關WebRTC SDP的更深入的綜述,請檢視SDP Anatomy指南。
RTP有效負載類型(payload type)
1a=rtpmap:109 opus/48000/2
Firefox主動建立請求,這意味着它為音頻和視訊資料包選擇使用RTP有效負載類型,并且伺服器需要對每個資料包進行重寫。這是相當瑣碎的工作,需要開發人員的努力。
同時聯播(Simulcast)
1a=simulcast: recv rid=f;h;q
2a=rid:f recv
3a=rid:h recv
4a=rid:q recv
5a=extmap:3/recvonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=rid 和 a=simulcast 這幾行表示使用同時聯播, Firefox并沒有在這裡實作最新的IETF草案,但與Chrome不同,它不需要SDP改寫,而依靠RTCRtpSender.setParameters。 如果您對使用情況感興趣,Firefox會進行單元測試,顯示基本使用情況。 這當然比SDP改寫更好(盡管它仍然是我們都害怕的SDP)。在網絡上,Firefox同時聯播使用RID頭擴充來“标記”不同的視訊流。
在FF57之前,Firefox同時聯播并不是非常穩定,這可能因為FF57進一步诠釋了時機。
REMB
1a=rtcp-fb:120 goog-remb
Firefox使用REMB 進行帶寬估算,而不是其尚未支援的更新的transport-cc機制。 在Chrome中使用transport-cc表示它在伺服器中就被終止了。可能要花費很大的努力才能将兩者很好地結合在一起,因為帶寬估計是WebRTC中最難的問題之一。
SCTP資料通道
1m=application 9 DTLS/SCTP 5000
我們看到在 m=application 媒體部分, 使用了SCTP 資料通道。這是相當程度的工程設計工作,但可能是由于RTP資料通道不能與DTLS-SRTP一起工作,才作為Meet早期的全面檢修的一部分。 這也表明通過資料通道發送的控制消息很重要。 不幸的是,它們是原始編碼的,是以比較難以了解。
統一計劃(Unified Plan)
1m=audio 9 UDP/TLS/RTP/SAVPF 109 0
最有趣的是使用有5條m線的 “Unified Plan” SDP (已經融入 JSEP)。 Chrome中缺乏統一計劃顯然不是問題。這并不令人感到意外,如果您想使用單個PeerConnection,您可以将SDP簡單地改寫為浏覽器所需的任何格式。 Jitsi已經在sdp-interop包中做了這麼多年了。檢查這個操作是發生在用戶端的javascript還是伺服器上會很有趣。
SDP中缺少的東西也很有趣。由于Firefox不支援RTX,ulpfec和red,是以伺服器需要打開這些資料包并選擇丢棄它們,或者像RTX那樣,将它們轉換回正常的RTP資料包。根據我的經驗,這遠不是微不足道的。
ice-lite
1a=ice-lite
在伺服器SDP中,我們還發現ice-lite是RFC 5245允許的ICE簡化版本,非常适合具有公共IP位址且易于實作的媒體伺服器。前段時間,Hangouts 從google-ice 轉移到了 ice-lite。可以在about:webrtc檢視完整的細節。
WebRTCon 2018 8折報名
WebRTCon希望與行業專家一同分享、探讨當下技術熱點、行業最佳應用實踐。如果你擁有音視訊領域獨當一面的能力,歡迎申請成為講師,分享你的實踐和洞察,請聯系 [email protected]。更多詳情掃描下圖二維碼。