下一代低延时直播CDN:HLS、RTMP 与UDP +WebRTC
在上月落幕帷幕的多媒體領(lǐng)域技術(shù)盛會(huì)——LiveVideoStackCon2018音視頻技術(shù)大會(huì)上,阿里云的高級(jí)技術(shù)專家李剛進(jìn)行了《下一代低延時(shí)的直播CDN》技術(shù)分享。本文由云棲社區(qū)整理,并授權(quán)LiveVideoStack發(fā)布。
文 / 李剛
整理 / 云棲社區(qū)
一、直播場(chǎng)景回顧
下圖列舉了當(dāng)下存在的一些常見的直播場(chǎng)景。
秀場(chǎng)直播是國(guó)內(nèi)最早出現(xiàn)的直播形式,在各個(gè)直播平臺(tái)上是比較常見的。
游戲直播,像斗魚、虎牙、戰(zhàn)旗等直播平臺(tái)都是比較典型的游戲直播平臺(tái),游戲直播對(duì)碼率要求比較高,觀看人數(shù)也多,所以它也是流量貢獻(xiàn)最大的直播形式。
移動(dòng)直播是最近一兩年比較火的直播形式,比較明顯的特點(diǎn)就是推流和播放比較容易, 通過(guò)手機(jī)APP就可以進(jìn)行直播,所以手機(jī)直播一般也是推流數(shù)最多的直播形式。
活動(dòng)賽事直播,像今年夏天的世界杯,這類直播一般對(duì)交互要求不高,所以一般都是HLS播放形式,延遲相對(duì)其他都會(huì)多一些。
答題直播是今年年初左右出現(xiàn)的新型直播形式,每場(chǎng)直播的時(shí)間不長(zhǎng),突發(fā)流量比較高。
這些直播場(chǎng)景,在國(guó)內(nèi)主要用HTTP-FLV和RTMP這種傳輸形式,這兩種傳播形式一般延時(shí)在3-5秒,當(dāng)然這也會(huì)受視頻本身GOP影響, 移動(dòng)直播一般是1-2秒時(shí)間間隔,所以控制在3-5秒是比較容易的。但是游戲直播關(guān)鍵幀延時(shí)一般在8-10秒,所以游戲直播的延時(shí)更大一些。而活動(dòng)賽事直播一般不會(huì)強(qiáng)調(diào)互動(dòng)性,對(duì)流暢度比較高,所以會(huì)一般選用HLS,延時(shí)在10秒以上。
二、低延時(shí)直播需求
3~5秒延時(shí)對(duì)于多數(shù)常見的直播形式一般問(wèn)題不大, 但是對(duì)于某些場(chǎng)景效果會(huì)很差。
對(duì)于連麥場(chǎng)景影響是最明顯的, 連麥超過(guò)1秒,對(duì)話可能就沒(méi)辦法維持下去了。現(xiàn)在一般直播平臺(tái)的連麥直播需求都會(huì)借助第三方的連麥服務(wù),然后再推給直播CDN廠商。
在答題直播場(chǎng)景下, 一般都要求在一段時(shí)間內(nèi)用戶提交答案,如果有各別用戶延遲比較大,這樣對(duì)用戶是不公平的。雖然直播平臺(tái)仍然使用FLV的傳輸形式完成答題直播,但是基本都會(huì)采用SEI插幀等方法來(lái)解決時(shí)間同步問(wèn)題, 需要平臺(tái)的端和直播CDN做一些配合來(lái)完成。
除了連麥、答題場(chǎng)景之外,像在線課堂、在線拍賣等場(chǎng)景因?yàn)樯婕暗綄?shí)時(shí)性的互動(dòng),對(duì)延時(shí)的要求也比較高。
從對(duì)業(yè)務(wù)的支持層面來(lái)看, 僅僅有RTMP、FLV這種3~5秒延時(shí)以上的直播形式已經(jīng)不夠了, 需要對(duì)更低延遲的直播業(yè)務(wù)進(jìn)行支持。從技術(shù)的角度來(lái)看,國(guó)內(nèi)常用的FLV、RTMP這種直播手段,本身是Adobe自己的標(biāo)準(zhǔn), 而且很快會(huì)停止對(duì)Flash的維護(hù), 另一方面WebRTC技術(shù)的興起,Chrome、Safari等瀏覽器也都進(jìn)行了支持,因此也需要對(duì)新的技術(shù)有一些調(diào)研和準(zhǔn)備。
基于對(duì)于這些問(wèn)題的思考, 阿里云CDN也開展了對(duì)低延時(shí)直播技術(shù)的研發(fā)。
三、短延時(shí)直播VS實(shí)時(shí)音視頻通信
簡(jiǎn)單介紹下實(shí)時(shí)音視頻通信和短延時(shí)直播的區(qū)別:
使用WebRTC主要用于解決實(shí)時(shí)音視頻通話的需求,必然對(duì)延遲要求非常嚴(yán)格, 一個(gè)會(huì)議室中參與的多方可以進(jìn)行視頻通話, 每個(gè)參與者可以看到其他參與者,也能聽到其他參與者說(shuō)話。每個(gè)參與者既有推流,又有播放,數(shù)據(jù)是雙向的。所以參與人數(shù)不會(huì)太多,一般不能超過(guò)20個(gè)。
短延時(shí)直播仍然是直播業(yè)務(wù)類型, 只是延時(shí)比較低, 短延時(shí)直播的業(yè)務(wù)模型相對(duì)簡(jiǎn)單, 數(shù)據(jù)單向傳輸,一個(gè)主播推流,參與的播放者人數(shù)沒(méi)有限制,上百萬(wàn)都可以。
四、技術(shù)選型的思考
在做短延時(shí)直播項(xiàng)目的時(shí)候,我們?cè)诩夹g(shù)選型上做了一些思考。
首先,是必須要兼容已有直播業(yè)務(wù)和技術(shù)棧,因?yàn)榘⒗镌浦辈DN系統(tǒng)已經(jīng)有了很多客戶,短延時(shí)直播需要從現(xiàn)有直播的業(yè)務(wù)上慢慢衍生, 可以讓客戶在短延時(shí)和常規(guī)直播手段進(jìn)行切換, 這也是處于業(yè)務(wù)穩(wěn)定性的考慮。
第二,對(duì)于直播來(lái)講, 秒開是一個(gè)很重要的指標(biāo),我們后面詳細(xì)展開。當(dāng)然卡頓也是重要的指標(biāo),因?yàn)閃ebRTC在移動(dòng)端擁塞控制和重傳方面有一些處理,所以卡頓率方面不會(huì)比TCP差。
第三,對(duì)齊到WebRTC會(huì)是最終的結(jié)果, 畢竟用戶能夠使用H5就可以直接推流或者觀看直播, 更方便客戶的接入和使用。但由于完整的支持WebRTC要解決加解密、打洞、音頻格式等問(wèn)題, 所以前期考慮只使用WebRTC中的一部分技術(shù),完整支持WebRTC會(huì)是二期的工作。
五、TCP的可能性
已有的業(yè)務(wù),無(wú)論是圖片、大小文件、點(diǎn)播、直播,這些都是在TCP通信基礎(chǔ)上實(shí)現(xiàn)的,所以短延時(shí)直播在開展的時(shí)候我們就思考了TCP的可能性。
我們對(duì)于短延時(shí)的目標(biāo)定義為從端到端800毫秒以內(nèi),一場(chǎng)直播的延遲來(lái)自于推流端延遲、CDN產(chǎn)生的延遲、播放端延遲這三個(gè)方面,很多客戶會(huì)關(guān)注CDN產(chǎn)生的延遲,我們也對(duì)數(shù)據(jù)進(jìn)行過(guò)統(tǒng)計(jì),CDN從入到出所產(chǎn)生的總延時(shí),全網(wǎng)平均不到100毫秒,晚高峰平均也不超過(guò)200毫秒。而從經(jīng)驗(yàn)角度來(lái)看,播放端的延遲會(huì)比較嚴(yán)重,主要是兩方面,一方面是開播時(shí)候卡前一個(gè)關(guān)鍵幀所帶來(lái)的延遲,另一方面如果CDN服務(wù)器到播放端有抖動(dòng),累積的延遲會(huì)越來(lái)越多。
之前有一個(gè)彩票直播業(yè)務(wù)的客戶, 因?yàn)榭蛻魮?dān)心用戶懷疑刮獎(jiǎng)的時(shí)效性, 所以對(duì)延時(shí)要求就非??量? 客戶的端進(jìn)行延遲優(yōu)化, 延遲也可以做到1秒內(nèi)。
所以,一開始我們有了這樣一個(gè)結(jié)論,網(wǎng)絡(luò)正常的情況下,使用現(xiàn)有的RTMP、FLV進(jìn)行分發(fā),延遲也可以做到1秒以內(nèi)。
但是現(xiàn)實(shí)情況是網(wǎng)絡(luò)是不可能出現(xiàn)不丟包的情況。當(dāng)網(wǎng)絡(luò)抖動(dòng)出現(xiàn)丟包的時(shí)候,TCP是ACK確認(rèn)機(jī)制的,也就是發(fā)送方發(fā)送一包之后,一定要等過(guò)對(duì)方回應(yīng),才會(huì)繼續(xù)發(fā)。如果說(shuō)網(wǎng)絡(luò)一旦出現(xiàn)丟包,就會(huì)在一個(gè)RTO之后重傳,RTO的值和RTT有關(guān),并且RTO的最小值是200ms。如果想保證流暢性,你的播放端一定要至少能容忍200ms以上的抖動(dòng),但播放端的jitbuffer太多又無(wú)法滿足低延時(shí)的要求。
這里對(duì)一下比WebRTC中RTP傳輸使用的NACK機(jī)制,NACK的丟包反饋更加及時(shí),如果網(wǎng)絡(luò)是偶然性抖動(dòng)居多的時(shí)候, NACK機(jī)制效果更加好。這里我們也做了一個(gè)統(tǒng)計(jì),全網(wǎng)平均RTT小于15ms,如果CDN節(jié)點(diǎn)覆蓋足夠好的情況下,延遲理論上會(huì)很低。以1.5Mbps碼率的音視頻流舉例,每秒鐘100個(gè)包,包和包之間就是10ms的間隔。如果當(dāng)?shù)诙€(gè)丟包出現(xiàn)的時(shí)候,第三個(gè)包對(duì)方接收到了,就可以馬上知道第二個(gè)包是丟掉了,就可以立刻返回一個(gè)NACK,進(jìn)行重傳。在這種極限情況下,重傳間隔就是25ms,相比之前TCP的200ms是一個(gè)質(zhì)的提升,想滿足絕大部分播放延遲在800ms以內(nèi)才有可能。
另外,使用TCP的話,無(wú)效傳輸沒(méi)法避免,。TCP是采用socket buffer進(jìn)行通信,數(shù)據(jù)也是從應(yīng)用層先進(jìn)入socket buffer再分發(fā)。對(duì)于RTMP或FLV的分發(fā)來(lái)說(shuō),假如某一幀的數(shù)據(jù)的一部分已經(jīng)進(jìn)入了socket緩沖區(qū), 那么也必須將這一幀剩余的數(shù)據(jù)發(fā)送出去, 如果剩余的數(shù)據(jù)不發(fā)出去的話, 播放端會(huì)出現(xiàn)解析錯(cuò)誤, 斷開連接, 這個(gè)體驗(yàn)會(huì)很差。
而在網(wǎng)絡(luò)在出現(xiàn)波動(dòng)的時(shí)候, 有可能這socket buffer里面的數(shù)據(jù)很久之后才能傳送到對(duì)方, 而在短延時(shí)直播的場(chǎng)景下, 這些socket buffer里面和應(yīng)用層太久的數(shù)據(jù)再發(fā)送給播放端已經(jīng)沒(méi)有意義,也就是說(shuō)會(huì)產(chǎn)生很多無(wú)效的傳輸。
六、自研短延時(shí)直播方案
基于這些考慮,我們最終采用了以下的方案。WebRTC是當(dāng)下短延時(shí)流媒體的傳輸比較熱門的技術(shù), 所以在實(shí)現(xiàn)短延時(shí)直播的同時(shí)會(huì)考慮使用WebRTC相關(guān)的一些技術(shù)。原有的RTMP, FLV, HLS這些使用TCP,新增阿里自研私有ARTP短延時(shí)方案,最終會(huì)支持WebRTC,ARTP和WebRTC使用UDP傳輸。
在研發(fā)之前,我們會(huì)對(duì)各項(xiàng)部署做一些思考。
1. 端口問(wèn)題
WebRTC的默認(rèn)工作方式SFU服務(wù)器會(huì)為每個(gè)參與者需要為其他每個(gè)參與者分配一個(gè)端口, 一定程度上來(lái)說(shuō)是通過(guò)不同的端口來(lái)區(qū)分參與者。而CDN從安全的角度來(lái)考慮, 不會(huì)采取這種方式, 所以從一開始就認(rèn)定在短延時(shí)直播這個(gè)場(chǎng)景下,我們會(huì)使用固定端口的方式來(lái)提供服務(wù)。下圖是最終的方案,流媒體服務(wù)器會(huì)開幾個(gè)端口分別支持不同播放形式的訪問(wèn),允許用戶的端進(jìn)行的靈活控制。
2. 秒開問(wèn)題
這里講一下播放秒開的問(wèn)題, 如果采用標(biāo)準(zhǔn)的WebRTC方式,那么需要經(jīng)過(guò)下圖這樣幾個(gè)環(huán)節(jié)。
這樣下來(lái)對(duì)于直播秒開的體驗(yàn)來(lái)說(shuō)就會(huì)很差,所以在實(shí)現(xiàn)低延時(shí)直播方案時(shí)針對(duì)這個(gè)問(wèn)題需要進(jìn)行優(yōu)化處理, 去掉一些不必要的環(huán)節(jié)。
CDN服務(wù)器本身是有公網(wǎng)IP和端口的, 播放端沒(méi)有獨(dú)立的公網(wǎng)IP和端口,如果是像WebRTC這么實(shí)現(xiàn)的話, 服務(wù)器把數(shù)據(jù)直接傳給播放端,那么必然涉及到打洞探測(cè)的問(wèn)題,所以如果想要達(dá)到秒開效果的話,就不能使用WebRTC的這種方式, 需要讓播放端先給服務(wù)器發(fā)送請(qǐng)求, 讓自己所在的NAT網(wǎng)關(guān)建立起映射之后,服務(wù)器再把數(shù)據(jù)吐給客戶端時(shí)就OK了。
上圖就是最終的時(shí)序圖,使用的是比較簡(jiǎn)單的應(yīng)答模式。沒(méi)有了TCP的三次握手環(huán)節(jié),所以秒開效果一定比FLV、RTMP更好。同時(shí),客戶端直接發(fā)起播放請(qǐng)求,請(qǐng)求包長(zhǎng)度盡量控制在一個(gè)UDP包內(nèi),不要出現(xiàn)一個(gè)請(qǐng)求兩個(gè)包的情況。
國(guó)內(nèi)直播平臺(tái)大部分還是使用H.264和AAC,所以我們也是首先支持這兩種格式,其他音視頻格式像HEVC等也是我們后續(xù)要支持的格式。
3. RTP報(bào)文
PT字段是載荷類型,sequence number是包序列號(hào),發(fā)送端切片的時(shí)候,寫好序列號(hào),接收端依據(jù)這個(gè)序列號(hào)進(jìn)行數(shù)據(jù)的還原。而且在重傳發(fā)生的時(shí)候,還依靠這個(gè)序列號(hào)進(jìn)行NACK的反饋。時(shí)間戳對(duì)流媒體傳輸非常重要,播放器依賴它進(jìn)行解碼和同步。SSRC用來(lái)識(shí)別不同的身份,同一個(gè)IP和端口被NAT重新分配的時(shí)候, SSRC識(shí)別出這是一個(gè)不同的連接。
前面講過(guò)使用TCP傳輸?shù)臅r(shí)候,網(wǎng)絡(luò)抖動(dòng)出現(xiàn)堆積時(shí),需要丟幀,但是一定是丟完整的幀,不能丟片段。那為什么RTP場(chǎng)景下為什么沒(méi)有這個(gè)問(wèn)題?以H.264為例,RTP在封裝的時(shí)候,如果NAL單元小于MTU,那么我們認(rèn)為一個(gè)RTP包可以完整封裝一個(gè)NAL單元的,如果出現(xiàn)丟幀,那么我們認(rèn)為缺少的是一個(gè)完整的NAL單元,對(duì)后面NAL單元解析是沒(méi)有問(wèn)題的,不會(huì)出現(xiàn)數(shù)據(jù)錯(cuò)亂。
如果一個(gè)NAL單元大于一個(gè)MTU的時(shí)候,假設(shè)一個(gè)NAL單元需要三個(gè)RTP包封裝,不管丟到哪一個(gè)還是全部丟掉,接收端都可以標(biāo)識(shí)出這個(gè)NAL單元,不會(huì)影響其他NAL單元的解析。
4. 平滑發(fā)送機(jī)制
現(xiàn)在采用的混合擁塞算法,基于丟包率和基于延遲進(jìn)行碼率控制。標(biāo)準(zhǔn)的做法是,當(dāng)播放卡頓時(shí),會(huì)讓發(fā)送端降碼率。
從兩個(gè)方面來(lái)看,當(dāng)推流端上行出現(xiàn)抖動(dòng)的時(shí)候,服務(wù)器會(huì)反饋數(shù)據(jù)包,把碼率自動(dòng)降下來(lái)。當(dāng)播放端出現(xiàn)下行抖動(dòng)的時(shí)候,一種是輸出轉(zhuǎn)碼流,另一種是讓主播推兩路流上來(lái),讓播放卡頓的用戶換到低碼率。
5. 播放端上的優(yōu)化
第一階段是開播階段,獲得GOP數(shù)據(jù)的時(shí)候,如果端不做處理的話,一定會(huì)有一個(gè)延遲。所以在這個(gè)階段,播放端一定進(jìn)行快進(jìn)的操作,縮短延遲。第二階段是當(dāng)網(wǎng)絡(luò)出現(xiàn)抖動(dòng)的時(shí)候,會(huì)慢慢放大buffer的長(zhǎng)度,來(lái)一定程度上適應(yīng)抖動(dòng),提高流暢度。第三階段,當(dāng)網(wǎng)絡(luò)恢復(fù)的時(shí)候,我們可以適當(dāng)快進(jìn),減小buffer,把進(jìn)度趕回來(lái)。也就是說(shuō)這個(gè)buffer大小是動(dòng)態(tài)變化的。
6. RTC內(nèi)部打包機(jī)制
H.264和AAC數(shù)據(jù)會(huì)在內(nèi)部先進(jìn)行切片,放到平滑發(fā)送隊(duì)列再發(fā)送給對(duì)端,同時(shí)重傳包也會(huì)進(jìn)入平滑發(fā)送隊(duì)列, 并且會(huì)放到平滑發(fā)送隊(duì)列的隊(duì)首位置。
7. FEC冗余傳輸
FEC是靠冗余傳輸,來(lái)提高容錯(cuò)率。關(guān)鍵幀10%冗余率, 非關(guān)鍵幀5%,根據(jù)丟包判斷出網(wǎng)絡(luò)狀況,動(dòng)態(tài)調(diào)整冗余度。
8. UDP傳輸注意事項(xiàng)
UDP無(wú)連接,也就沒(méi)有TCP的連接斷開時(shí)的揮手確認(rèn)連接關(guān)閉的機(jī)制。那么對(duì)于主播來(lái)說(shuō),如果出現(xiàn)斷開,然后短時(shí)間再重推的話就會(huì)遇到問(wèn)題,因?yàn)镃DN會(huì)認(rèn)為前一個(gè)推流連接還在,新的推流連接推的是同名流,會(huì)拒絕掉新的連接,主播也會(huì)反饋無(wú)法推流。對(duì)于播放來(lái)說(shuō),雖然沒(méi)有同名流問(wèn)題,但是如果播放端不再觀看,CDN服務(wù)器會(huì)仍然將數(shù)據(jù)發(fā)送給指定的IP和端口,這就產(chǎn)生了很多無(wú)效的傳輸。最終會(huì)反映到流量和計(jì)費(fèi)日志上。所以采用RTCP報(bào)文的方式,對(duì)于播放和推流連接的斷開進(jìn)行通知,節(jié)省資源消耗, 流搶占等問(wèn)題。
9. 探活策略
除了對(duì)于正常關(guān)閉進(jìn)行主動(dòng)通知之外, 還需要對(duì)超時(shí)情況進(jìn)行處理。即便是TCP傳輸?shù)臅r(shí)候也有類似的問(wèn)題,推流端發(fā)送了FIN結(jié)束報(bào)文,但是服務(wù)器未必收到,所以一定要有超時(shí)的機(jī)制來(lái)進(jìn)行管理。我們采用數(shù)據(jù)及時(shí)反饋的機(jī)制,在下行播放端要求周期性的返回心跳,上行要求推流端在8或10秒內(nèi)一定要有一些真實(shí)數(shù)據(jù)傳輸,否則我們就會(huì)斷開。
這幅時(shí)序圖更細(xì)致的展開了一下實(shí)現(xiàn)的邏輯,播放端和服務(wù)器。
Tengine是阿里開源的服務(wù)器軟件, 阿里云CDN的文件、點(diǎn)播、直播功能都是在其基礎(chǔ)上進(jìn)行開發(fā),而在短延時(shí)直播功能的實(shí)現(xiàn)我們也是把開源的WebRTC的庫(kù)進(jìn)行了一些改造。選擇Tengine來(lái)做主要原因也是因?yàn)閷?duì)其非常的熟悉,而且在其基礎(chǔ)上也積累了很多配套的技術(shù),包括配置下發(fā)管理、日志收集、業(yè)務(wù)處理等。
最后,我們來(lái)看下實(shí)際的數(shù)據(jù)情況。
目前短延時(shí)直播功能是在一些地區(qū)進(jìn)行了部署和驗(yàn)證,還沒(méi)到全網(wǎng)鋪開的階段。
秒開數(shù)據(jù)比原來(lái)FLV訪問(wèn)提升很大, UDP交互省去了三次握手環(huán)節(jié)。錯(cuò)誤率和延遲都有了較大的提升。這里目前只對(duì)比了下行,從已經(jīng)灰度的一些節(jié)點(diǎn)來(lái)看,上行卡頓數(shù)據(jù)要優(yōu)于原有RTMP的推流。
七、后續(xù)展望
完整的支持WebRTC一定是目標(biāo), 畢竟直接通過(guò)瀏覽器就可以完成推流和播放對(duì)于用戶的接入來(lái)說(shuō)實(shí)在太方便, 對(duì)于CDN來(lái)講控制接入一定是一個(gè)必須做的事情。
對(duì)于CDN要做的另一個(gè)事情就是優(yōu)化傳輸,其實(shí)無(wú)論對(duì)于文件加速還是流媒體加速,傳輸永遠(yuǎn)都是最重要的,CDN這個(gè)分發(fā)網(wǎng)絡(luò)本身就是為了優(yōu)化傳輸而存在。
從實(shí)踐來(lái)看,UDP傳輸比原來(lái)的TCP傳輸對(duì)資源消耗要多,而且重傳、封包、FEC冗余計(jì)算等都會(huì)額外增加計(jì)算量,在多進(jìn)程模式下可能還會(huì)遇到內(nèi)存資源的過(guò)多消耗。
總結(jié)
以上是生活随笔為你收集整理的下一代低延时直播CDN:HLS、RTMP 与UDP +WebRTC的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 音视频技术开发周刊 72期
- 下一篇: 2018年是VR的新机会吗?