天天看点

Google Hangouts支持使用Firefox WebRTC

自去年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]。更多详情扫描下图二维码。

继续阅读