為什么 4G/5G 的直播延時(shí)依然很高
通信技術(shù)的發(fā)展促進(jìn)了視頻點(diǎn)播和直播業(yè)務(wù)的興起,4G 和 5G 網(wǎng)絡(luò)技術(shù)的進(jìn)步也使得流媒體技術(shù)變得越來越重要,但是網(wǎng)絡(luò)技術(shù)并不能解決流媒體直播的高延遲問題。
本文不會(huì)介紹網(wǎng)絡(luò)對(duì)直播業(yè)務(wù)的影響,而是會(huì)分析直播中常見的現(xiàn)象 — 主播和觀眾之間能夠感覺到的明顯網(wǎng)絡(luò)延遲。除了業(yè)務(wù)上要求的延遲直播之外,有哪些因素會(huì)導(dǎo)致視頻直播的延遲這么高呢?

live-streaming? 圖 1 - 流媒體直播
當(dāng)觀眾通過彈幕與主播進(jìn)行互動(dòng)時(shí),從我們看到彈幕到得到主播的響應(yīng)可能要經(jīng)過 5s 甚至更長(zhǎng)的時(shí)間,雖然主播看到彈幕的時(shí)間與觀眾看到彈幕的時(shí)間不會(huì)有太大的差別,但是直播系統(tǒng)將主播的音視頻數(shù)據(jù)傳輸?shù)娇蛻舳嘶蛘邽g覽器需要較長(zhǎng)的時(shí)間,這個(gè)從主播端到觀眾端傳輸數(shù)據(jù)的時(shí)間一般被稱作端到端的音視頻延遲。
流媒體直播從音視頻的采集和編碼到音視頻的解碼和播放涉及了非常長(zhǎng)的鏈路,需要途徑主播端、流媒體服務(wù)器以及觀眾端,這三方分別提供了不同的功能:
主播端:音視頻采集、音視頻編碼、推流;
流媒體服務(wù)器:直播流收集、音視頻轉(zhuǎn)碼、直播流分發(fā);
觀眾端:拉流、音視頻解碼、音視頻播放;
在這個(gè)冗長(zhǎng)的采集和分發(fā)流程中,不同過程中都會(huì)通過一些技術(shù)保證直播的質(zhì)量,這些為了保證可靠性、降低系統(tǒng)帶寬而使用的手段共同造成了直播高延遲的問題。本文會(huì)從以下三個(gè)方面分析為什么流媒體直播的端到端延遲很高:
音視頻使用的編碼格式?jīng)Q定了客戶端只能從特定幀開始解碼;
音視頻傳輸使用的網(wǎng)絡(luò)協(xié)議切片大小決定了客戶端接收數(shù)據(jù)的間隔;
服務(wù)器和客戶端為了保證用戶體驗(yàn)和直播質(zhì)量預(yù)留緩存;
數(shù)據(jù)編碼
視頻直播一定會(huì)使用音視頻的編碼技術(shù),目前主流的音頻和視頻編碼方式是高級(jí)音頻編碼(Advanced Audio Coding,AAC)[^1] 和高級(jí)視頻編碼(Advanced Video Coding,AVC)[^2],AVC 常被稱作 H.264。
這一節(jié)不討論音頻數(shù)據(jù)的編解碼算法,我們來詳細(xì)分析一下為什么需要 H.264 編碼,它又如何影響直播延遲。假設(shè)我們需要看一部時(shí)長(zhǎng)為 2 小時(shí)的 1080p、60FPS 的電影,如果每個(gè)像素需要 2 字節(jié)的存儲(chǔ),那么整部電影需要占用如下所示的資源:
然而在實(shí)際情況下,每一部電影占用的磁盤空間只有幾百 MB 或者幾 GB,這與我們計(jì)算出來的結(jié)果相差好幾個(gè)數(shù)量級(jí),音視頻編碼就是起到用于壓縮音視頻數(shù)據(jù),減少占用磁盤和網(wǎng)絡(luò)帶寬的關(guān)鍵技術(shù)。
H.264 是用于視頻壓縮的業(yè)界標(biāo)準(zhǔn),因?yàn)橐曨l是由一幀一幀的圖片組成的,而不同的圖片之間有較強(qiáng)的連續(xù)性,H.264 使用關(guān)鍵幀(Intra-coded picture,I 幀)作為視頻的全量數(shù)據(jù),不斷使用向前參考幀(Predicted picture,P 幀)和雙向參考幀(Bidirectional predicted picture,B 幀)對(duì)全量的數(shù)據(jù)進(jìn)行增量式的修改以達(dá)到壓縮的目的。

h264-frames??圖 2 - H.264 壓縮視頻數(shù)據(jù)
H.264 會(huì)使用 I 幀、P 幀和 B 幀將視頻數(shù)據(jù)壓縮成如上圖所示的圖片序列,這三種不同的視頻幀分別起到不同的作用[^3]:
| 視頻幀 | 作用 |
I 幀 | 類似 JPG 或者 BMP 格式的完整的圖片 |
P 幀 | 可以使用前一個(gè)視頻幀的數(shù)據(jù)壓縮數(shù)據(jù) |
B 幀 | 可以使用前一個(gè)和后一個(gè)視頻幀壓縮數(shù)據(jù) |
壓縮后的視頻數(shù)據(jù)是一系列連續(xù)的視頻幀,客戶端在解碼視頻數(shù)據(jù)時(shí)會(huì)先找到視頻數(shù)據(jù)的第一個(gè)關(guān)鍵幀,然后增量對(duì)關(guān)鍵幀進(jìn)行修改。如果客戶端接收到的第一個(gè)視頻幀就是關(guān)鍵幀,那么客戶端就可以直接播放視頻,但是如果客戶端錯(cuò)過了關(guān)鍵幀,那么就需要等待下一個(gè)關(guān)鍵幀才可以播放視頻。

group-of-pictures??圖 3 - 視頻編碼 GOP
圖像組(Group of pictures,GOP)指定了視頻幀的組織方式,編碼的視頻流就由連續(xù)的 GOP 組成,因?yàn)槊總€(gè) GOP 都會(huì)以關(guān)鍵幀開頭,所以 GOP 的大小會(huì)影響播放端的延遲。
視頻占用的網(wǎng)絡(luò)帶寬也與 GOP 息息相關(guān),在通常情況下,移動(dòng)端直播的 GOP 都會(huì)被設(shè)置成 1 ~ 4 秒,當(dāng)然我們也可以使用更長(zhǎng)的 GOP 降低占用的帶寬[^4]。
視頻編碼中的 GOP 決定了關(guān)鍵幀的間隔,也決定了客戶端在找到第一個(gè)可以播放的關(guān)鍵幀的時(shí)間,進(jìn)而影響流媒體直播的延遲,這種秒級(jí)別的延遲對(duì)于視頻直播業(yè)務(wù)來說影響還是比較明顯的,GOP 的設(shè)置是對(duì)視頻質(zhì)量、帶寬和延遲權(quán)衡的結(jié)果。
數(shù)據(jù)傳輸
音視頻數(shù)據(jù)傳輸可以選擇使用不同的應(yīng)用層協(xié)議,最常見的兩種網(wǎng)絡(luò)協(xié)議是實(shí)時(shí)消息傳輸協(xié)議(Real Time Messaging Protocol,RTMP)和 HTTP 實(shí)時(shí)流式傳輸協(xié)議(HTTP Live Streaming,HLS),這兩種網(wǎng)絡(luò)協(xié)議分別使用不同的方式傳輸音視頻流,我們可以認(rèn)為 RTMP 協(xié)議基于音視頻流分發(fā)數(shù)據(jù),而 HLS 協(xié)議基于文件分發(fā)音視頻數(shù)據(jù)。

live-streaming-protoco?圖 4 - 流媒體數(shù)據(jù)傳輸協(xié)議
RTMP 協(xié)議是基于 TCP 的應(yīng)用層協(xié)議,它將音視頻流切分成片段進(jìn)行傳輸,在默認(rèn)情況下音頻數(shù)據(jù)段的大小為 64 字節(jié),視頻數(shù)據(jù)段的大小是 128 字節(jié)[^5]。使用 RTMP 協(xié)議時(shí),所有的數(shù)據(jù)都會(huì)塊(Chunk)的形式傳輸:

rtmp-payload?圖 5 - RTMP 協(xié)議數(shù)據(jù)塊
每個(gè) RTMP 的數(shù)據(jù)塊都包含 1 ~ 18 字節(jié)的協(xié)議頭,協(xié)議頭由基本協(xié)議頭(Basic Header)、消息頭(Message Header)和擴(kuò)展時(shí)間戳(Extended Timestamp)三個(gè)部分組成,除了包含塊 ID 和類型的基本協(xié)議頭之外,其他的兩個(gè)部分都是可以省略的,進(jìn)入傳輸階段的 RTMP 協(xié)議只需要 1 字節(jié)的協(xié)議頭,這也意味著極低的額外開銷[^6]。
HLS 協(xié)議是蘋果在 2009 年發(fā)布的基于 HTTP 協(xié)議的碼率自適應(yīng)的流媒體網(wǎng)絡(luò)傳輸協(xié)議[^7]。當(dāng)播放器獲得使用 HLS 協(xié)議的拉流地址時(shí),播放器會(huì)從拉流地址中獲得如下所示的 m3u8 文件:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:9.009,
http://media.example.com/first.ts
#EXTINF:9.009,
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
m3u8 是一種播放多媒體列表的文件格式[^8],該文件中包含了一系列的視頻流切片,播放器可以根據(jù)文件中的描述依次播放各個(gè)視頻流。
HLS 協(xié)議將直播流拆分成一個(gè)個(gè)小的文件并使用 m3u8 組織這些直播片段,當(dāng)播放器播放直播流時(shí)會(huì)根據(jù) m3u8 的描述依次播放拆分后的 ts 文件。

m3u8-ts??圖 6 - m3u8 和 ts 文件
HLS 協(xié)議切分的 ts 文件大小會(huì)影響端到端的直播延遲,蘋果官方文檔推薦使用 6 秒的 ts 切片,這也就意味著從主播到觀眾的延遲至少會(huì)增加 6 秒,使用更短的切分方式并不是不可行,只是會(huì)帶來巨大的額外開銷和存儲(chǔ)壓力。
雖然所有應(yīng)用層協(xié)議受限于物理設(shè)備的 MTU[^9] 都只能分段傳輸音視頻數(shù)據(jù),但是不同應(yīng)用層協(xié)議對(duì)音視頻數(shù)據(jù)的切分粒度決定了端到端的網(wǎng)絡(luò)延遲。
RTMP 以及 HTTP-FLV 等基于流分發(fā)的協(xié)議切片粒度很小,延遲在 3s 以下,可以看做實(shí)時(shí)的傳輸協(xié)議;而 HLS 協(xié)議是基于文件分發(fā)的協(xié)議,它的切片粒度很大,在實(shí)際使用中可能會(huì)帶來 20 ~ 30s 的延遲。
需要注意的是基于文件分發(fā)不等價(jià)于高延遲,分片的大小才是決定延遲的關(guān)鍵因素,在保證分片小的同時(shí)降低額外開銷是實(shí)時(shí)流媒體傳輸協(xié)議需要考慮的問題。
多端緩存
視頻直播架構(gòu)的鏈路往往都很長(zhǎng),我們不能保證整條鏈路的穩(wěn)定性,想要提供流暢的數(shù)據(jù)傳輸和用戶體驗(yàn),服務(wù)端和和客戶端都會(huì)增加緩存以應(yīng)對(duì)直播的音視頻卡頓。
服務(wù)器一般會(huì)先緩存一部分直播數(shù)據(jù),然后將數(shù)據(jù)傳輸至客戶端,在網(wǎng)絡(luò)突然抖動(dòng)時(shí),服務(wù)端可以使用緩存中的數(shù)據(jù)保證直播流的流暢。
當(dāng)網(wǎng)絡(luò)狀況恢復(fù)時(shí),又會(huì)重新緩存數(shù)據(jù);客戶端也會(huì)使用預(yù)讀緩沖區(qū)來提高直播的質(zhì)量。我們可以調(diào)小緩沖區(qū)增加實(shí)時(shí)性,但是在網(wǎng)絡(luò)狀況抖動(dòng)較多時(shí)會(huì)嚴(yán)重影響客戶端的用戶體驗(yàn)[^10]。
總結(jié)
流媒體直播的高延遲是一個(gè)系統(tǒng)性的工程問題,與微信視頻等 1 對(duì) 1 的實(shí)時(shí)通信相比,視頻流的生產(chǎn)方和消費(fèi)方之間的鏈路極長(zhǎng),很多因素都會(huì)影響主播和觀眾的感受,因?yàn)閹挼某杀?、歷史的慣性以及網(wǎng)絡(luò)的不確定,我們只能通過不同的技術(shù)解決遇到的問題,而不得不犧牲的就是用戶的體驗(yàn):
全量的音視頻數(shù)據(jù)過多 — 使用音視頻編碼會(huì)使用關(guān)鍵幀以及增量修改的方式壓縮數(shù)據(jù),關(guān)鍵幀的間隔 GOP 決定了客戶端在播放第一個(gè)畫面時(shí)需要等待的最長(zhǎng)時(shí)間;
瀏覽器對(duì)實(shí)時(shí)流的協(xié)議支持不夠 — 使用 HLS 協(xié)議基于 HTTP 對(duì)直播的切片進(jìn)行分發(fā),這會(huì)為主播和觀眾帶來 20 ~ 30s 的直播延遲;
鏈路過長(zhǎng)帶來的不確定性 — 服務(wù)器和客戶端使用緩存減少網(wǎng)絡(luò)抖動(dòng)對(duì)直播質(zhì)量造成的顯著影響;
上述的這些因素都會(huì)影響直播系統(tǒng)的端到端延遲,在一個(gè)正常的直播系統(tǒng)中使用 RTMP 和 HTTP-FLV 可以達(dá)到 3s 以下的延遲,不過 GOP 以及多端緩存都會(huì)影響這一指標(biāo),延遲在 10s 以內(nèi)都是很正常的。到最后,我們還是來看一些比較開放的相關(guān)問題,有興趣的讀者可以仔細(xì)思考一下下面的問題:
基于文件的流媒體傳輸協(xié)議最大會(huì)帶來多少的額外開銷?
不同的視頻編碼格式的壓縮率是怎么樣的?
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號(hào)
好文章,我在看??
