Google Hangouts支持使用Firefox WebRTC

2021-09-02 11:18:01 浏览数 (1)

自去年4月Firefox 53删除NPAPI以来,该插件一直无法被正常访问。而就在去年年末,Google Hangouts(环聊)重新支持使用Firefox WebRTC。本文深度剖析了Firefox SDP并比较了Firefox和Chrome Hangouts的WebRTC规范。

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实际上非常有意思:

代码语言:javascript复制
 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)

代码语言:javascript复制
1a=rtpmap:109 opus/48000/2

Firefox主动创建请求,这意味着它为音频和视频数据包选择使用RTP有效负载类型,并且服务器需要对每个数据包进行重写。这是相当琐碎的工作,需要开发人员的努力。

同时联播(Simulcast)

代码语言:javascript复制
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

代码语言:javascript复制
1a=rtcp-fb:120 goog-remb

Firefox使用REMB 进行带宽估算,而不是其尚未支持的更新的transport-cc机制。 在Chrome中使用transport-cc表示它在服务器中就被终止了。可能要花费很大的努力才能将两者很好地结合在一起,因为带宽估计是WebRTC中最难的问题之一。

SCTP数据通道

代码语言:javascript复制
1m=application 9 DTLS/SCTP 5000

我们看到在 m=application 媒体部分, 使用了SCTP 数据通道。这是相当程度的工程设计工作,但可能是由于RTP数据通道不能与DTLS-SRTP一起工作,才作为Meet早期的全面检修的一部分。 这也表明通过数据通道发送的控制消息很重要。 不幸的是,它们是原始编码的,所以比较难以理解。

统一计划(Unified Plan)

代码语言:javascript复制
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

代码语言:javascript复制
1a=ice-lite

在服务器SDP中,我们还发现ice-lite是RFC 5245允许的ICE简化版本,非常适合具有公共IP地址且易于实现的媒体服务器。前段时间,Hangouts 从google-ice 转移到了 ice-lite。可以在about:webrtc查看完整的细节。

0 人点赞