日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

不需要SFU实现WebRTC联播实践

發(fā)布時間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 不需要SFU实现WebRTC联播实践 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


不需要SFU而實現(xiàn)WebRTC聯(lián)播,appear.in的WebRTC工程師Philipp Hancke實現(xiàn)了在Chrome和Firefox之間的聯(lián)播。LiveVideoStack對原文進行了摘譯。


文 / Philipp Hancke

譯 / 元寶

審校 / Ant

原文:

https://webrtchacks.com/a-playground-for-simulcast-without-an-sfu/


同步聯(lián)播是WebRTC用于多方會議的一個很有趣的方面。簡而言之,它意味著可以同時發(fā)送三種不同的分辨率(空間可伸縮性)和不同的幀速率(時間可伸縮性)。


通常,需要一個SFU才能利用聯(lián)播。但是有一個方法可以使在兩個瀏覽器之間或在單個頁面內(nèi)效果可見。這對于做單頁測試或使用聯(lián)播功能是非常有用的,特別是能夠只啟用某些空間層或控制特定流的目標(biāo)比特率。


Playground


Playground有兩種變體,一種用于Chrome,另一種用于Firefox。Chrome版本使用了我們在2014年夏天的谷歌環(huán)聊中首次看到的舊的SDP munging hack 。Firefox 使用‘RTCRtpSender.setParameters’來啟用同步聯(lián)播。兩者都沒有遵守最新的規(guī)范,但這并不會影響任何人對它的使用。


兩種變體都可以顯示視頻圖像,首先是發(fā)送者圖像和總體比特率/幀速率圖,其后是三個不同的空間流,每個空間流具有用于比特率和幀率的對應(yīng)圖。


由于我們不想涉及到服務(wù)器的內(nèi)容,所以我們需要破解一些東西。幸運的是,有一個Chrome的測試驗證了這個想法。Chrome和Firefox都使用一個數(shù)據(jù)包的RTP SSRC將其路由到某一個特定的媒體流。這些SSRC可以在SDP提供中找到:


原始的Chrome SDP

?

1type:?offer,?sdp:?v=0
2o=-?7356021969196541917?2?IN?ImP4?127.0.0.1
3s=-
4t=0?0
5a=group:BUNDLE?video
6a=msid-semantic:?WMS?0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J
7m=video?9?UDP/TLS/RTP/SAVPF?96?97?98?99?100?101?102?124?127?123?125
8c=IN?IP4?0.0.0.0
9a=rtcp:9?IN?IP4?0.0.0.0
10a=ice-ufrag:cTTs
11a=ice-pwd:W9/g2uTwfb6UCRxfIoMkd5nV
12a=ice-options:trickle
13a=fingerprint:sha-256?01:09:17:BA:CD:91:FE:E0:24:24:86:5C:17:71:CC:37:61:CF:BA:D1:31:49:80:F1:BC:B8:B2:6F:8C:D5:39:F2
14a=setup:actpass
15a=mid:video
16a=extmap:2?urn:ietf:params:rtp-hdrext:toffset
17a=extmap:3?http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
18a=extmap:4?urn:3gpp:video-orientation
19a=extmap:5?http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
20a=extmap:6?http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
21a=extmap:7?http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
22a=extmap:8?http://www.webrtc.org/experiments/rtp-hdrext/video-timing
23a=sendrecv
24a=rtcp-mux
25a=rtcp-rsize
26a=rtpmap:96?VP8/90000
27a=rtcp-fb:96?goog-remb
28a=rtcp-fb:96?transport-cc
29a=rtcp-fb:96?ccm?fir
30a=rtcp-fb:96?nack
31a=rtcp-fb:96?nack?pli
32a=rtpmap:97?rtx/90000
33a=fmtp:97?apt=96
34a=rtpmap:98?VP9/90000
35a=rtcp-fb:98?goog-remb
36a=rtcp-fb:98?transport-cc
37a=rtcp-fb:98?ccm?fir
38a=rtcp-fb:98?nack
39a=rtcp-fb:98?nack?pli
40a=rtpmap:99?rtx/90000
41a=fmtp:99?apt=98
42a=rtpmap:100?H264/90000
43a=rtcp-fb:100?goog-remb
44a=rtcp-fb:100?transport-cc
45a=rtcp-fb:100?ccm?fir
46a=rtcp-fb:100?nack
47a=rtcp-fb:100?nack?pli
48a=fmtp:100?level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
49a=rtpmap:101?rtx/90000
50a=fmtp:101?apt=100
51a=rtpmap:102?H264/90000
52a=rtcp-fb:102?goog-remb
53a=rtcp-fb:102?transport-cc
54a=rtcp-fb:102?ccm?fir
55a=rtcp-fb:102?nack
56a=rtcp-fb:102?nack?pli
57a=fmtp:102?level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
58a=rtpmap:124?rtx/90000
59a=fmtp:124?apt=102
60a=rtpmap:127?red/90000
61a=rtpmap:123?rtx/90000
62a=fmtp:123?apt=127
63a=rtpmap:125?ulpfec/90000
64a=ssrc-group:FID?3818935445?664019814
65a=ssrc:3818935445?cname:/9xLVG5y0PJqxacG
66a=ssrc:3818935445?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
67a=ssrc:3818935445?mslabel:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J
68a=ssrc:3818935445?label:d1c9f46b-0328-4ef1-9c31-c1b279ac554a
69a=ssrc:664019814?cname:/9xLVG5y0PJqxacG
70a=ssrc:664019814?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
71a=ssrc:3818935446?cname:/9xLVG5y0PJqxacG
72a=ssrc:3818935446?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
73a=ssrc:3818935447?cname:/9xLVG5y0PJqxacG
74a=ssrc:3818935447?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
75a=ssrc:3818935448?cname:/9xLVG5y0PJqxacG
76a=ssrc:3818935448?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
77a=ssrc:3818935449?cname:/9xLVG5y0PJqxacG
78a=ssrc:3818935449?msid:0AQNo1bnpzlGvB7aE2InJRz85M9lmId7Es9J?d1c9f46b-0328-4ef1-9c31-c1b279ac554a
79a=ssrc-group:FID?3818935446?3818935447
80a=ssrc-group:FID?3818935448?3818935449
81a=ssrc-group:SIM?3818935445?3818935446?3818935448


和2014年一樣,重要的是多個‘a(chǎn)=ssrc:’的行以及‘a(chǎn)=ssrc-group:SIM’的行。


原始的Firefox SDP

?

1v=0
2o=mozilla...THIS_IS_SDPARTA-61.0.1?2246157997147315987?0?IN?IP4?0.0.0.0
3s=-
4t=0?0
5a=sendrecv
6a=fingerprint:sha-256?00:3E:DC:02:92:60:97:0D:D8:F7:7F:E9:AD:41:46:CD:B5:FC:33:35:3F:5C:C4:BC:CD:85:17:96:F8:D6:14:57
7a=group:BUNDLE?sdparta_0
8a=ice-options:trickle
9a=msid-semantic:WMS?*
10m=video?40601?UDP/TLS/RTP/SAVPF?120?121?126?97
11c=IN?IP4?192.168.1.230
12a=sendrecv
13a=end-of-candidates
14a=extmap:3?urn:ietf:params:rtp-hdrext:sdes:mid
15a=extmap:4?http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
16a=extmap:5?urn:ietf:params:rtp-hdrext:toffset
17a=extmap:6/sendonly?urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
18a=fmtp:126?profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
19a=fmtp:97?profile-level-id=42e01f;level-asymmetry-allowed=1
20a=fmtp:120?max-fs=12288;max-fr=60
21a=fmtp:121?max-fs=12288;max-fr=60
22a=ice-pwd:f317cfe0aaa529381815e208a6cdec19
23a=ice-ufrag:07366c17
24a=mid:sdparta_0
25a=msid:{8de6968c-0ea9-4a19-aaa6-51355d4a5f4e}?{9bdb3a96-19f3-4730-8459-e56db515b5da}
26a=rid:hi?send
27a=rid:mid?send
28a=rid:lo?send
29a=rtcp-fb:120?nack
30a=rtcp-fb:120?nack?pli
31a=rtcp-fb:120?ccm?fir
32a=rtcp-fb:120?goog-remb
33a=rtcp-fb:121?nack
34a=rtcp-fb:121?nack?pli
35a=rtcp-fb:121?ccm?fir
36a=rtcp-fb:121?goog-remb
37a=rtcp-fb:126?nack
38a=rtcp-fb:126?nack?pli
39a=rtcp-fb:126?ccm?fir
40a=rtcp-fb:126?goog-remb
41a=rtcp-fb:97?nack
42a=rtcp-fb:97?nack?pli
43a=rtcp-fb:97?ccm?fir
44a=rtcp-fb:97?goog-remb
45a=rtcp-mux
46a=rtpmap:120?VP8/90000
47a=rtpmap:121?VP9/90000
48a=rtpmap:126?H264/90000
49a=rtpmap:97?H264/90000
50a=setup:actpass
51a=simulcast:?send?rid=hi;mid;lo
52a=ssrc:252082699?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}
53a=ssrc:2611961929?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}
54a=ssrc:1452646660?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}


在Firefox中,重要的聯(lián)播比特數(shù)是‘a(chǎn) = rid’的行和‘a(chǎn) = simulcast’的行(從底部開始的第4行)。注意:這是來自規(guī)范的舊版本,可能會有所變化。


WebRTC hack ??


我們需要讓我們的同行相信,它實際上正在接收三種不同的視頻流——低、中、高的比特率——而不僅僅是其中一種。為實現(xiàn)這一目標(biāo),我們需要創(chuàng)建自己的SDP,其中包含從SSRC到跟蹤的不同映射。這是有點苛刻的,但這個網(wǎng)站被稱為webrtchacks是有原因的!


我們最終將Firefox產(chǎn)品轉(zhuǎn)換為:

?

?1v=0
?2o=mozilla...THIS_IS_SDPARTA-61.0?8324701712193024513?0?IN?IP4?0.0.0.0
?3s=-
?4t=0?0
?5a=sendrecv
?6a=fingerprint:sha-256?00:3E:DC:02:92:60:97:0D:D8:F7:7F:E9:AD:41:46:CD:B5:FC:33:35:3F:5C:C4:BC:CD:85:17:96:F8:D6:14:57
?7a=group:BUNDLE?sdparta_0?sdparta_1?sdparta_2
?8a=msid-semantic:WMS?*
?9m=video?9?UDP/TLS/RTP/SAVPF?120?121?126?97
10c=IN?IP4?0.0.0.0
11a=sendrecv
12a=extmap:3?urn:ietf:params:rtp-hdrext:sdes:mid
13a=extmap:4?http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
14a=extmap:5?urn:ietf:params:rtp-hdrext:toffset
15a=extmap:6/sendonly?urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
16a=fmtp:126?profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
17a=fmtp:97?profile-level-id=42e01f;level-asymmetry-allowed=1
18a=fmtp:120?max-fs=12288;max-fr=60
19a=fmtp:121?max-fs=12288;max-fr=60
20a=ice-pwd:f317cfe0aaa529381815e208a6cdec19
21a=ice-ufrag:07366c17
22a=mid:sdparta_0
23a=msid:low?low
24a=rtcp-fb:120?nack
25a=rtcp-fb:120?nack?pli
26a=rtcp-fb:120?ccm?fir
27a=rtcp-fb:120?goog-remb
28a=rtcp-fb:121?nack
29a=rtcp-fb:121?nack?pli
30a=rtcp-fb:121?ccm?fir
31a=rtcp-fb:121?goog-remb
32a=rtcp-fb:126?nack
33a=rtcp-fb:126?nack?pli
34a=rtcp-fb:126?ccm?fir
35a=rtcp-fb:126?goog-remb
36a=rtcp-fb:97?nack
37a=rtcp-fb:97?nack?pli
38a=rtcp-fb:97?ccm?fir
39a=rtcp-fb:97?goog-remb
40a=rtcp-mux
41a=rtpmap:120?VP8/90000
42a=rtpmap:121?VP9/90000
43a=rtpmap:126?H264/90000
44a=rtpmap:97?H264/90000
45a=setup:actpass
46a=ssrc:252082699?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}
47m=video?9?UDP/TLS/RTP/SAVPF?120?121?126?97
48c=IN?IP4?0.0.0.0
49a=sendrecv
50a=extmap:3?urn:ietf:params:rtp-hdrext:sdes:mid
51a=extmap:4?http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
52a=extmap:5?urn:ietf:params:rtp-hdrext:toffset
53a=extmap:6/sendonly?urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
54a=fmtp:126?profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
55a=fmtp:97?profile-level-id=42e01f;level-asymmetry-allowed=1
56a=fmtp:120?max-fs=12288;max-fr=60
57a=fmtp:121?max-fs=12288;max-fr=60
58a=ice-pwd:f317cfe0aaa529381815e208a6cdec19
59a=ice-ufrag:07366c17
60a=mid:sdparta_1
61a=msid:mid?mid
62a=rtcp-fb:120?nack
63a=rtcp-fb:120?nack?pli
64a=rtcp-fb:120?ccm?fir
65a=rtcp-fb:120?goog-remb
66a=rtcp-fb:121?nack
67a=rtcp-fb:121?nack?pli
68a=rtcp-fb:121?ccm?fir
69a=rtcp-fb:121?goog-remb
70a=rtcp-fb:126?nack
71a=rtcp-fb:126?nack?pli
72a=rtcp-fb:126?ccm?fir
73a=rtcp-fb:126?goog-remb
74a=rtcp-fb:97?nack
75a=rtcp-fb:97?nack?pli
76a=rtcp-fb:97?ccm?fir
77a=rtcp-fb:97?goog-remb
78a=rtcp-mux
79a=rtpmap:120?VP8/90000
80a=rtpmap:121?VP9/90000
81a=rtpmap:126?H264/90000
82a=rtpmap:97?H264/90000
83a=setup:actpass
84a=ssrc:2611961929?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}
85m=video?9?UDP/TLS/RTP/SAVPF?120?121?126?97
86c=IN?IP4?0.0.0.0
87a=sendrecv
88a=extmap:3?urn:ietf:params:rtp-hdrext:sdes:mid
89a=extmap:4?http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
90a=extmap:5?urn:ietf:params:rtp-hdrext:toffset
91a=extmap:6/sendonly?urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
92a=fmtp:126?profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
93a=fmtp:97?profile-level-id=42e01f;level-asymmetry-allowed=1
94a=fmtp:120?max-fs=12288;max-fr=60
95a=fmtp:121?max-fs=12288;max-fr=60
96a=ice-pwd:f317cfe0aaa529381815e208a6cdec19
97a=ice-ufrag:07366c17
98a=mid:sdparta_2
99a=msid:hi?hi
100a=rtcp-fb:120?nack
101a=rtcp-fb:120?nack?pli
102a=rtcp-fb:120?ccm?fir
103a=rtcp-fb:120?goog-remb
104a=rtcp-fb:121?nack
105a=rtcp-fb:121?nack?pli
106a=rtcp-fb:121?ccm?fir
107a=rtcp-fb:121?goog-remb
108a=rtcp-fb:126?nack
109a=rtcp-fb:126?nack?pli
110a=rtcp-fb:126?ccm?fir
111a=rtcp-fb:126?goog-remb
112a=rtcp-fb:97?nack
113a=rtcp-fb:97?nack?pli
114a=rtcp-fb:97?ccm?fir
115a=rtcp-fb:97?goog-remb
116a=rtcp-mux
117a=rtpmap:120?VP8/90000
118a=rtpmap:121?VP9/90000
119a=rtpmap:126?H264/90000
120a=rtpmap:97?H264/90000
121a=setup:actpass
122a=ssrc:1452646660?cname:{004db4a6-943d-496b-9e8d-1689f7be7355}


這顯示了三個不同的媒體部分(按照統(tǒng)一計劃的規(guī)定),它將在接收器處觸發(fā)“跟蹤”事件三次,為我們提供三個不同的 MediaStream對象以附加到視頻元素,并且還允許使用getStats API來為各個比特率制作圖表。


請參閱SDP的源代碼,了解如何創(chuàng)建它。


調(diào)整各個層的比特率


Chrome長期以來一直使用硬編碼表來表示各個空間層的同步比特率。

?

1//?These?tables?describe?from?which?resolution?we?can?use?how?many
2//?simulcast?layers?at?what?bitrates?(maximum,?target,?and?minimum).
3//?Important!!?Keep?this?table?from?high?resolution?to?low?resolution.
4//?clang-format?off
5const?SimulcastFormat?kSimulcastFormats[]?=?{
6??{1920,?1080,?3,?5000,?4000,?800},
7??{1280,?720,?3,??2500,?2500,?600},
8??{960,?540,?3,?900,?900,?450},
9??{640,?360,?2,?700,?500,?150},
10??{480,?270,?2,?450,?350,?150},
11??{320,?180,?1,?200,?150,?30},
12??{0,?0,?1,?200,?150,?30}
13};


該表顯示了分辨率(例如1920×1080),空間層數(shù)(3)以及最大,最佳和最小比特率。


感謝‘setParameters’讓我們現(xiàn)在可以偏離這個表中定義的比特率并獲得一些創(chuàng)意。如果你運行該示例而不進行任何修改,你可以看到聯(lián)播以大約3.2mbps的比特率在發(fā)送。它分為三個不同的空間流,大約是150kbps,500kbps和2500kbps,與表中的設(shè)置相匹配。


讓我們通過將這個JavaScript粘貼到控制臺來修改它:

?

1var?p?=?pc1.getSenders()[0].getParameters();
2p.encodings[1].maxBitrate?=?300*1000;
3p.encodings[2].maxBitrate?=?400*1000;
4pc1.getSenders()[0].setParameters(p)
5??.catch(e?=>?console.error(e))


這將中分辨率(640×360)空間層的目標(biāo)比特率設(shè)置為300kbps,將720p流的目標(biāo)比特率設(shè)置為400kbps。編碼器可以很好地匹配這些比特率,它們的質(zhì)量非常好,即使將720p流的比特率設(shè)置為400kbps也是如此。


如果我們將720p的目標(biāo)比特率降低到200 kbps,那么我們可以看到由于幀率下降而導(dǎo)致的視覺退化,因為只有基本的時間層被發(fā)送。對于720p的流,你可以用像200kbps一樣低的比特率來使用...



此圖表(以及下面的圖表)中均是左側(cè)為比特率,右側(cè)為幀率。


這對于在SFU中成功實現(xiàn)同步聯(lián)播的任何人來說都不是新聞,但是在沒有任何服務(wù)器的情況下,在單個頁面中展示這個效果還是很驚人的。


到處都是Bug


最初構(gòu)建頁面的主要動機之一是探索Firefox中對聯(lián)播的支持。它沒有預(yù)期的那么好,最大的問題是因為Firefox以及我在SFU實現(xiàn)中的錯誤。在playground的頁面上,我可以證明它不在SFU中,但在Firefox中出現(xiàn)了問題。


?


中分辨率圖層的比特率僅以300kbps,而不是Chrome發(fā)送的500kbps。盡管請求超過2000kbps,我們只能為高分辨率層獲得500kbps的速率。部分原因是SDP munging中的一個非常巧妙的錯誤,它影響了低分辨率層的設(shè)置。這很容易在JavaScript中修復(fù)。


接下來,有一個問題是高分辨率層的配置被修改了,這將很快在Firefox中登陸,并將被提升到Beta和ESR。有了修復(fù),比特率就會高得多:


?


中等分辨率層的目標(biāo)比特率也根據(jù)我的要求更改為500kbps。把我當(dāng)成一個非常滿意的客戶!


Jitsi的Brian Baldino發(fā)現(xiàn)了另外一個有趣的問題。當(dāng)禁用高中空間層時,Chrome將以每秒超過一兆比特的比特率繼續(xù)發(fā)送。這是為了保持比特率估計值高而填充數(shù)據(jù)。



這實際上是對舊版Chrome問題非常好的再現(xiàn),希望在一個更具體的用例中出現(xiàn)的不良行為,以及在單個頁面測試中進行復(fù)制,使這更容易修復(fù)。


最后但并非最不重要的是,您可能已經(jīng)注意到Chrome中本地視頻的高幀率,接近90幀。Chrome似乎將所有發(fā)送流的比特率和幀率都加了起來。這(可能)不太正確,所以這里有另一個bug報告。


同步聯(lián)播對于構(gòu)建高級WebRTC應(yīng)用程序非常重要。希望這個playground讓W(xué)eb開發(fā)人員更容易訪問它。特別感謝Florent Castelli在Chrome中實現(xiàn)‘setParameters’,并允許更多的修補以及Byron Campen在Firefox問題上的快速支持。


總結(jié)

以上是生活随笔為你收集整理的不需要SFU实现WebRTC联播实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。