1 背景
直播(bo)延(yan)遲是指(zhi)從推(tui)流端到(dao)播(bo)放端的端到(dao)端延(yan)遲,目前(qian)業界的直播(bo)延(yan)遲普遍在3秒以上,這主(zhu)要有兩方(fang)面(mian)原(yuan)因:
- 提供直播加速的各大云廠商為實現“秒開”功能,普遍在服務端緩存了一個GOP(兩個I幀之間的數據),一個GOP大小普遍在3秒以上,播放器拿到GOP以后如果沒有倍速播放等追趕功能,會保持3秒以上的播放延遲;
- 傳統直播主要使用RTMP或者HTTP協議,都是基于TCP的協議,一旦出現弱網擁塞,將轉變為延遲。
2 目標
本方案(an)的目的是在支持傳統(tong)直播(bo)“秒開”功(gong)能(neng)的前提(ti)下,通過(guo)在拉流端(duan)引(yin)入WebRTC技術,將(jiang)播(bo)放延遲降低(di)(di)到200ms以內。通過(guo)播(bo)放器(qi)客戶(hu)端(duan)內部的“追(zhui)趕”機制來(lai)降低(di)(di)延遲,通過(guo)服(fu)務端(duan)的“丟幀”策略來(lai)降低(di)(di)客戶(hu)端(duan)的追(zhui)趕時間(jian)來(lai)實現用戶(hu)對倍(bei)速播(bo)放的無(wu)感(gan)知,通過(guo)優化擁塞控制算(suan)法(fa)來(lai)提(ti)升弱網下的QOS以達到甚至超過(guo)傳統(tong)RTMP直播(bo)的體驗。
3 技術方案
3.1 RTMP到WebRTC的轉封裝
為(wei)了實現無(wu)侵(qin)入地對接當前的直播(bo)(bo)CDN系統(tong),最大程度地復用當前直播(bo)(bo)系統(tong)上的轉碼、鑒(jian)權(quan)、鑒(jian)黃(huang)等業務(wu),需(xu)要在(zai)直播(bo)(bo)CDN系統(tong)的中心節(jie)(jie)(jie)點或者邊(bian)緣節(jie)(jie)(jie)點部署轉封(feng)裝(zhuang)服務(wu),該(gai)服務(wu)負責從當前節(jie)(jie)(jie)點拉(la)取RTMP流(liu),并通過(guo)FFmpeg將(jiang)RTMP協議轉換(huan)成RTP協議,通過(guo)RTC分發(fa)系統(tong)發(fa)送給(gei)RTC媒(mei)體服務(wu),以對接最終用戶(hu)。也(ye)就是(shi)說推流(liu)端為(wei)RTMP協議,經過(guo)轉封(feng)裝(zhuang)、分發(fa)等服務(wu)后,最終用戶(hu)通過(guo)WebRTC協議拉(la)流(liu)播(bo)(bo)放。
如(ru)圖3.1.1,轉(zhuan)(zhuan)封裝服務(wu)作為(wei)直播CDN系統(tong)到(dao)RTC系統(tong)的網關,負責RTMP協議到(dao)RTP協議的轉(zhuan)(zhuan)換。

圖3.1.1
3.2 客戶端倍速播放追趕
客戶端使用WebRTC協議拉取直播流,服務端接收到拉流請求后會立刻發送緩存的1個GOP數據,這些數據在客戶端的接收時間間隔比在以正常碼率傳輸數據時的接收時間間隔要小,基于這個特性可以通過WebRTC的音頻NetEQ模塊和視頻JitterBuffer模塊的配合進行延遲追趕,以快速消費客戶端接收緩沖中的數據。
對音頻來說,NetEQ會通(tong)過(guo)音頻接收時間(jian)間(jian)隔以(yi)直方圖算法和峰值檢測算法估算音頻目標(biao)延(yan)遲,在音視頻同步后的(de)音頻當前延(yan)遲比音頻目標(biao)延(yan)遲大的(de)情況下,通(tong)過(guo)一(yi)定的(de)壓縮(suo)算法壓縮(suo)解碼后的(de)音頻同步緩沖中(zhong)的(de)波形,達到加速播(bo)放的(de)效果。
對(dui)視(shi)頻(pin)來說,JitterBuffer計算出的(de)視(shi)頻(pin)幀(zhen)的(de)視(shi)頻(pin)渲(xuan)(xuan)染時間(jian)的(de)間(jian)隔比正(zheng)常速率(lv)(lv)要小,這(zhe)段時間(jian)的(de)渲(xuan)(xuan)染幀(zhen)率(lv)(lv)要提高(gao),直到(dao)接(jie)收幀(zhen)率(lv)(lv)和推流幀(zhen)率(lv)(lv)持(chi)平后(hou)視(shi)頻(pin)渲(xuan)(xuan)染時間(jian)間(jian)隔會趨(qu)于正(zheng)常。
如圖3.2.1、圖3.2.2、圖3.2.3,首GOP瞬間發送,數據到達(da)間隔小,音頻(pin)NetEQ、視(shi)頻(pin)JitterBuffer模塊分(fen)別根據音、視(shi)頻(pin)到達(da)間隔對音、視(shi)頻(pin)數據做延遲追趕并進行同(tong)步(bu)。

圖3.2.1 首GOP數據間隔

圖(tu)3.2.2 音頻延遲追(zhui)趕

圖3.2.3 視頻延遲追趕
3.3 服務端首GOP內丟幀和時間戳重寫
如上述,客(ke)戶端(duan)追趕算法是實現(xian)低延遲的(de)(de)根本算法,但(dan)是如果推流端(duan)設置(zhi)的(de)(de)GOP過大,或者用(yong)戶側(ce)下載速(su)度不足(zu),會導(dao)致追趕過程持續(xu)較長時間,而(er)追趕過程中可(ke)能會出現(xian)快(kuai)進、跳幀、卡頓等較差的(de)(de)用(yong)戶體驗,為了降低用(yong)戶對這個過程的(de)(de)感(gan)知,需(xu)要通過在(zai)首GOP內丟幀的(de)(de)方式減少第一次發送(song)給客(ke)戶端(duan)的(de)(de)數據(ju)量。
基(ji)于I幀(zhen)(zhen)(zhen)(zhen)、P幀(zhen)(zhen)(zhen)(zhen)之間(jian)的(de)(de)(de)參考關系(xi),首(shou)(shou)(shou)GOP內丟(diu)幀(zhen)(zhen)(zhen)(zhen)的(de)(de)(de)基(ji)本原則是不(bu)能(neng)從(cong)GOP前(qian)面開(kai)始丟(diu)幀(zhen)(zhen)(zhen)(zhen),不(bu)能(neng)從(cong)中間(jian)跳(tiao)躍丟(diu)幀(zhen)(zhen)(zhen)(zhen),只能(neng)丟(diu)GOP末(mo)尾的(de)(de)(de)連(lian)續(xu)幀(zhen)(zhen)(zhen)(zhen)。同(tong)時(shi)(shi)(shi)(shi)還必(bi)須(xu)保證丟(diu)幀(zhen)(zhen)(zhen)(zhen)以后發送(song)(song)的(de)(de)(de)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)時(shi)(shi)(shi)(shi)間(jian)戳(chuo)的(de)(de)(de)連(lian)續(xu),具(ju)體做法(fa)為(wei):設(she)置一個(ge)時(shi)(shi)(shi)(shi)間(jian)窗口(kou)TW(TW<GOP),該時(shi)(shi)(shi)(shi)間(jian)窗口(kou)為(wei)首(shou)(shou)(shou)GOP內需要(yao)發送(song)(song)的(de)(de)(de)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)時(shi)(shi)(shi)(shi)間(jian)總長(chang)度(du),將GOP末(mo)尾TW時(shi)(shi)(shi)(shi)間(jian)長(chang)度(du)內的(de)(de)(de)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)的(de)(de)(de)時(shi)(shi)(shi)(shi)間(jian)戳(chuo)按順序設(she)置為(wei)GOP頭(tou)部(bu)TW時(shi)(shi)(shi)(shi)間(jian)長(chang)度(du)內的(de)(de)(de)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)的(de)(de)(de)時(shi)(shi)(shi)(shi)間(jian)戳(chuo),在發完首(shou)(shou)(shou)GOP內TW時(shi)(shi)(shi)(shi)間(jian)長(chang)度(du)的(de)(de)(de)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)后,立刻開(kai)始發送(song)(song)下一個(ge)GOP,以保證發送(song)(song)視(shi)(shi)(shi)頻幀(zhen)(zhen)(zhen)(zhen)時(shi)(shi)(shi)(shi)間(jian)戳(chuo)的(de)(de)(de)連(lian)續(xu)。而在首(shou)(shou)(shou)GOP還未完整的(de)(de)(de)情況下,則需要(yao)通過收幀(zhen)(zhen)(zhen)(zhen)來(lai)驅動時(shi)(shi)(shi)(shi)間(jian)戳(chuo)的(de)(de)(de)設(she)置。
如圖3.3.1,服務(wu)端(duan)只發送首GOP開(kai)頭TW時間窗口(kou)內的視頻幀,并將GOP末尾TW時間窗口(kou)內的視頻幀的時間戳設置到GOP開(kai)頭TW時間窗口(kou)內的視頻幀,保證發送視頻幀時間戳的連(lian)續。

圖3.3.1 首GOP丟(diu)幀(zhen)和(he)時間戳重寫
3.4 WebRTC NetEQ對AAC的兼容
如(ru)上述(shu),客(ke)戶端(duan)(duan)(duan)的(de)NetEQ模(mo)塊(kuai)(kuai)需要(yao)解(jie)(jie)碼(ma)音(yin)(yin)頻(pin)數(shu)據并壓縮波形(xing)以(yi)實現對音(yin)(yin)頻(pin)的(de)快進(jin)播放,傳統直播的(de)音(yin)(yin)頻(pin)編碼(ma)一般(ban)為(wei)AAC,而WebRTC系(xi)統的(de)音(yin)(yin)頻(pin)編碼(ma)一般(ban)為(wei)OPUS,不支(zhi)持(chi)AAC,并且NetEQ支(zhi)持(chi)的(de)音(yin)(yin)頻(pin)采(cai)樣(yang)率必須為(wei)8K的(de)倍(bei)數(shu),不支(zhi)持(chi)AAC的(de)44.1K采(cai)樣(yang)率。針(zhen)對這些兼容性問題有(you)兩(liang)個解(jie)(jie)決方案,一是(shi)(shi)服(fu)務(wu)端(duan)(duan)(duan)將AAC轉(zhuan)碼(ma)成OPUS,并重(zhong)采(cai)樣(yang)成48K,但是(shi)(shi)會增大服(fu)務(wu)端(duan)(duan)(duan)的(de)壓力;二是(shi)(shi)本方案采(cai)取的(de)辦法,修改客(ke)戶端(duan)(duan)(duan)NetEQ模(mo)塊(kuai)(kuai)以(yi)支(zhi)持(chi)AAC的(de)解(jie)(jie)碼(ma)并重(zhong)采(cai)樣(yang)到8K的(de)倍(bei)數(shu),優點(dian)為(wei)服(fu)務(wu)端(duan)(duan)(duan)只需要(yao)轉(zhuan)發不影響性能,但是(shi)(shi)提(ti)高了(le)客(ke)戶端(duan)(duan)(duan)復雜(za)度(du)。
如圖3.4.1,RTP包進入NetEQ之前(qian)需要經過44.1K采(cai)樣(yang)率(lv)到(dao)48K采(cai)樣(yang)率(lv)的時間(jian)戳映射,然(ran)后經過AAC解碼、重(zhong)采(cai)樣(yang),得到(dao)48K的PCM數據由(you)NetEQ進行處理。

圖3.4.1 NetEQ支持AAC
3.5 優化擁塞控制算法
WebRTC協議(yi)使用基(ji)于(yu)UDP的RTP協議(yi)傳輸(shu)媒(mei)體數據,在(zai)弱網下需(xu)要對(dui)擁(yong)塞控制算(suan)法做一(yi)定的優化以(yi)達(da)到甚至超(chao)過RTMP的指標。這里主要分成兩部分,一(yi)個是NACK、FEC等冗(rong)余數據的發(fa)送(song),在(zai)低延遲丟(diu)包(bao)場景下基(ji)于(yu)評(ping)估(gu)的RTT和丟(diu)包(bao)率按照(zhao)一(yi)定比(bi)例增大(da)NACK的發(fa)送(song)量,在(zai)高延遲丟(diu)包(bao)場景下按照(zhao)一(yi)定比(bi)例提高FEC的發(fa)送(song)量;二是在(zai)帶寬受限(xian)等擁(yong)塞場景下,對(dui)碼(ma)(ma)率進(jin)行波形(xing)的整形(xing),對(dui)以(yi)GOP為周期的I幀位置的碼(ma)(ma)率峰值進(jin)行削(xue)峰,平滑發(fa)送(song)碼(ma)(ma)率,以(yi)達(da)到擁(yong)塞避(bi)免的目(mu)標。
如圖3.5.1,通(tong)過NACK、FEC發送(song)冗余數據對(dui)抗丟包,通(tong)過Pacer Sender平滑發送(song)對(dui)抗擁塞。

圖3.5.1 擁(yong)塞控(kong)制
4 架構
如下圖4所(suo)示,轉封裝(zhuang)服務采用SRS,提供回源(yuan)拉流、轉封裝(zhuang)、GOP緩存等(deng)功(gong)能(neng),RTC媒體服務采用基于Janus的SFU,實現WebRTC接入(ru)(ru),提供NACK、FEC、Pacer Sender等(deng)擁(yong)塞控(kong)制能(neng)力,低延遲直播客戶端的功(gong)能(neng)封裝(zhuang)在libctrts.so動態庫中,以(yi)播放(fang)器插件的形式接入(ru)(ru)播放(fang)器,可以(yi)達到業務的無侵(qin)入(ru)(ru)對接。

圖4
5 技術要點
- 客戶端通過WebRTC的音頻NetEQ、視頻JitterBuffer對直播流進行倍速播放以實現播放延遲追趕;
- 服務端通過首GOP丟幀、重寫時間戳以壓縮客戶端追趕過程;
- 客戶端WebRTC NetEQ對傳統直播AAC編碼以及1K采樣率的兼容;
- 在擁塞控制優化中使用NACK、FEC等算法,在參數調整、閾值設置,以及平滑碼率發送中采用一系列自動控制算法;
- 實現服務端回源拉流、客戶端通過播放器插件無侵入對接現有直播系統。
6 優勢
通過(guo)使用本方案(an),在傳統(tong)直播業務系統(tong)的基礎(chu)上疊加了穩定可靠(kao)的超(chao)低延遲直播的能力:
- 超低播放延遲
可(ke)以達(da)到(dao)200ms的播放延(yan)遲,極限環境可(ke)以達(da)到(dao)120ms,基本做到(dao)實時。
- 用戶無感知
通過首GOP丟幀壓縮了快進追趕的(de)時(shi)間,基本做到了用戶無感知。
- 無侵入接入
服(fu)務端通(tong)過拉流轉封裝服(fu)務接(jie)入(ru)(ru)現有直播系統,客戶端通(tong)過播放器插件化的SDK接(jie)入(ru)(ru),可以做(zuo)到無侵(qin)入(ru)(ru)的業務對接(jie)。
- 不降低QOS性能
通過優化(hua)的擁(yong)塞控制(zhi)算法(fa),QOS性能可以達到(dao)甚至超(chao)過傳統RTMP直播的性能指(zhi)標。