迅達(dá)云SpeedyCloud工程副總裁,2010年始涉足云計(jì)算行業(yè),至今積累了大量架構(gòu)、研發(fā)、運(yùn)維、運(yùn)營(yíng)、管理等經(jīng)驗(yàn),曾就職于Joyent、藍(lán)汛、Yottaa等公司。2013年加入SpeedyCloud迅達(dá)云,現(xiàn)在負(fù)責(zé)技術(shù)的總體把控、技術(shù)可行性調(diào)研等工作。
在視頻領(lǐng)域,電影、電視、數(shù)字視頻等可視為隨時(shí)間連續(xù)變換的許多張畫(huà)面,而幀則指這些畫(huà)面當(dāng)中的每一張。不過(guò)如果按照如此的方式存儲(chǔ)視頻的話,文件勢(shì)必會(huì)變得很大,所以需要專(zhuān)門(mén)的算法對(duì)視頻文件進(jìn)行編碼。一旦視頻進(jìn)行編碼之后,得到的文件可以看做是連續(xù)的一組幀的集合,而這一組幀中的每一個(gè)都是有自己的類(lèi)型的。幀的類(lèi)型分為以下3種:
*Inter Frame(I幀)
*P-Frame(P幀)
*B-Frame(B幀)
對(duì)于B幀和P幀來(lái)說(shuō)需找到對(duì)應(yīng)的一個(gè)或者多個(gè)參考幀才能解碼出來(lái)(如圖1)。
對(duì)于非I幀來(lái)說(shuō)想要進(jìn)行解碼就需要多個(gè)參考幀進(jìn)行計(jì)算,由此引出了Groupof Picture(以下簡(jiǎn)稱(chēng)GoP)的概念。
對(duì)于P幀和B幀來(lái)說(shuō),他們所包含的內(nèi)容可以理解為針對(duì)其參考幀的一個(gè)patch,也就是一個(gè)變化量。
GoP顧名思義就是有一組幀組成的一個(gè)序列。Wikipedia上給出的一個(gè)圖簡(jiǎn)單的解釋了GoP是怎么回事(如圖 2)。
GoP由I幀開(kāi)始,后面跟隨者一組B幀和P幀,直到下一個(gè)I幀之前的幀為一個(gè)GoP。了解了GoP之后,就會(huì)發(fā)現(xiàn)播放器只有在拿到某個(gè)GoP中的I幀之后才能播放視頻。
圖1 B幀和P幀對(duì)應(yīng)多個(gè)參考幀
GoP到底應(yīng)該設(shè)置多大?那么GoP的大小到底有什么影響呢?
GoP設(shè)置較大時(shí):
好處:由于B幀和P幀的字節(jié)大小會(huì)比I幀小很多,所以GoP越長(zhǎng),所包含的B幀和P幀越多,相應(yīng)的壓縮比也會(huì)更高,在同樣的碼率下,視頻會(huì)更清晰一些。
壞處:對(duì)于視頻直播來(lái)說(shuō),播放器連接到服務(wù)器的時(shí)間是不固定的,當(dāng)播放器在GoP中間連接服務(wù)器,并獲取了中間的B幀和P幀,這時(shí)播放器是無(wú)法對(duì)這些幀進(jìn)行解碼的,需要進(jìn)行丟棄。所以會(huì)導(dǎo)致客戶端的首屏播放時(shí)間變長(zhǎng)。
GoP設(shè)置較小時(shí):
好處:由于GoP設(shè)置小可以降低I幀間隔時(shí)間,對(duì)于直播來(lái)說(shuō)可以實(shí)現(xiàn)秒開(kāi)的功能。
壞處:由于GoP時(shí)間比較短,會(huì)導(dǎo)致I幀的比例增高,壓縮比降低。同樣碼率情況下視頻的質(zhì)量會(huì)有所下降。
HLS格式的視頻分為兩個(gè)部分。首先,HLS會(huì)根據(jù)指定的切片時(shí)間和實(shí)際的GoP大小對(duì)視頻進(jìn)行切割,并生成.ts文件。其次,HLS會(huì)生成一個(gè).m3u8文件來(lái)保存這些ts文件的索引。
對(duì)于.ts文件的切割來(lái)講,并不是告訴直播服務(wù)器指定1秒切一個(gè).ts文件他就能保證1秒切一個(gè).ts文件的。.ts文件的切割還是要根據(jù)直播視頻的實(shí)際GoP大小來(lái)進(jìn)行切割的。之前已經(jīng)講過(guò),任何一個(gè)視頻流在播放端需要能獲取到完整的GoP才能播放,所以一個(gè).ts文件所實(shí)際包含的時(shí)間是GoP的整數(shù)倍。
例如:當(dāng)視頻的GoP設(shè)置為1秒,.ts切片時(shí)間為2秒時(shí),實(shí)際的.ts文件切片所包含的視頻為2秒。當(dāng)視頻的GoP設(shè)置為5秒,.ts切片時(shí)間為2妙時(shí),實(shí)際的.ts文件切片所包含的視頻為5秒。
圖 2 GoP示意圖
如果視頻流的GoP大小設(shè)置不合適的話,那么HLS的切片時(shí)間就會(huì)變長(zhǎng),同時(shí)也會(huì)增加HLS的延遲。這個(gè)特性對(duì)于HLS直播來(lái)講簡(jiǎn)直就是延遲殺手。
如果是HLS點(diǎn)播的話,流的GoP設(shè)置過(guò)大也會(huì)影響點(diǎn)播視頻的加載時(shí)間。一般的一個(gè)720P的視頻,如果切片時(shí)間為2秒的話,單個(gè).ts文件也就是在百K字節(jié)上下。但如果源視頻的GoP很大,會(huì)導(dǎo)致第一個(gè).ts文件所包含的視頻時(shí)常變長(zhǎng)(比如10秒),同時(shí)導(dǎo)致.ts文件的大小膨脹到接近1M字節(jié)上下。
RTMP協(xié)議本身也會(huì)抽象出一個(gè)Packet的概念來(lái)封裝H264編碼中的幀,也就是一個(gè)Packet會(huì)包含1到多個(gè)幀,播放器以Packet為單位來(lái)進(jìn)行解碼。那么RTMP的問(wèn)題在于客戶端連接的時(shí)間點(diǎn)是否合適。
例如一個(gè)RTMP直播流的GoP設(shè)置為2秒,如果客戶端接入時(shí)間剛好是第4秒,那么客戶端會(huì)獲取一個(gè)包含I幀的Packet,由于I幀是自描述的,所以客戶端可以直接解碼出該幀的畫(huà)面并顯示出來(lái)。但是當(dāng)客戶端的接入之間為第5秒,那么他會(huì)獲得一個(gè)包含B幀或者P幀的Packet,由于客戶端拿到的數(shù)據(jù)是一個(gè)不完整的GoP,所以客戶端只好拋棄當(dāng)前獲取的Packet中視頻的數(shù)據(jù),而且只有當(dāng)獲取到包含下一個(gè)GoP的I幀的Packet時(shí)才能解碼出圖像。因此客戶端會(huì)等待1秒才能播放出畫(huà)面。
由此我們可以得出一個(gè)結(jié)論:GoP的大小會(huì)影響RTMP播放端的首幀加載時(shí)間。
為了優(yōu)化首幀加載時(shí)間,我們可以在流媒體服務(wù)器端增加一個(gè)緩存,把上一個(gè)GoP緩存在內(nèi)存中。如果客戶端接入的話,我們首先放出來(lái)的是上一個(gè)GoP。這樣客戶端接到的數(shù)據(jù)永遠(yuǎn)是一I幀開(kāi)頭的數(shù)據(jù)。
在視頻直播和點(diǎn)播盛行的年代,對(duì)于GoP大小的取舍還是需要看具體應(yīng)用場(chǎng)景。對(duì)于直播來(lái)講,對(duì)延遲要求敏感的應(yīng)用來(lái)說(shuō),1~2秒的GoP大小還是比較合適的,至于GoP緩存來(lái)講,還是不用為好。如果是對(duì)延遲要求不敏感,對(duì)首屏播放時(shí)間很敏感的應(yīng)用,GoP還是1~2秒最為合適,GoP緩存應(yīng)該是必備的。另外直播使用HLS的話,延遲是絕對(duì)PK不過(guò)RTMP的。
對(duì)于點(diǎn)播的應(yīng)用來(lái)說(shuō),視頻加載速度是個(gè)硬指標(biāo),如果不是HLS格式的話,GoP大小適當(dāng)選大一點(diǎn)可以降低視頻文件大小,提高視頻打開(kāi)速度。
HLS格式的話,還是推薦在2秒左右,否則很影響視頻打開(kāi)速度的。
其實(shí)視頻直播技術(shù)的挑戰(zhàn)很多,這次分享的只是其中一小部分,也是迅達(dá)云SpeedyCloud研發(fā)團(tuán)隊(duì)的經(jīng)驗(yàn)總結(jié),希望能夠和大家多交流,一起為技術(shù)社區(qū)發(fā)展做些有益的事情。