1. 程式人生 > >直播中的關鍵幀技術探祕

直播中的關鍵幀技術探祕

轉自:http://chuansong.me/n/357427751042

現在視訊直播技術很火,ArchSummit微信大講堂有幸邀請到迅達雲SpeedyCloud工程副總裁李雨來,分享下其團隊在雲平臺上做視訊直播業務其中的一個技術方面——關鍵幀,本文整理自微信ArchSummit交流體驗群裡的分享內容(文章底部有加群方式喲!)希望能夠對大家有所幫助。

一.關鍵幀的痛點

在視訊領域,電影、電視、數字視訊等可視為隨時間連續變換的許多張畫面,而幀則指這些畫面當中的每一張。如果把這些幀轉換成圖片檔案,並原封不動的根據一個指定的格式連續擺放的話,就得到了一個視訊檔案。當然,這個檔案有點類似電影的膠片。

不過如果按照如此的方式儲存視訊的話,檔案勢必會變得很大,而且其間有很多重複的資料。所以需要專門的演算法對視訊檔案進行編碼。對於視訊的編碼格式來講,常見的就是H264。

一旦視訊進行編碼之後,得到的檔案可以看做是連續的一組幀的集合,而這一組幀中的每一個都是有自己的型別的。幀的型別分為以下3種:

* Inter Frame(I幀)

* P-Frame(P幀)

* B-Frame(B幀)

其中只有I幀中的資料是可以自描述的,也就是說當我們獲得I幀的資料之後,就可以直接解碼出當前幀的影象,對於B幀和P幀來說需要找到對應的一個或者多個參考幀才能解碼出來,見圖一所示;


圖一

因此對於非I幀來說想要進行解碼就需要多個參考幀進行計算,並得出最終的結果。由此引出了Group of Picture的概念。

對於P幀和B幀來說,他們所包含的內容可以理解為針對其參考幀的一個patch,也就是一個變化量,所以他們不用包含整個影象的資訊,只要描述好與參考幀之間的變化關係即可。所以在位元組大小方面,P幀和B幀要遠遠小於I幀的。這也是視訊壓縮能節省空間的一個原因所在。

二.GoP效能調優分析

Group of Picture(以下簡稱GoP)顧名思義就是有一組幀組成的一個序列。Wikipedia上給出的一個圖簡單的解釋了GoP是怎麼回事(見圖二):

圖二

GoP由I幀開始,後面跟隨者一組B幀和P幀,直到下一個I幀之前的幀為一個GoP。瞭解了GoP之後,就會發現播放器只有在拿到某個GoP中的I幀之後才能播放視訊。對於GoP來說,編碼器都是可以進行設定的,像OBS,ffmpeg等程式可以通過對應的設定和引數對視訊的GoP進行設定。

那麼引出了一個問題:GoP到底應該設定多大?那麼GoP的大小到底有什麼影響呢?

  1. GoP設定比較大時:

好處:由於B幀和P幀的位元組大小會比I幀小很多,所以GoP越長,所包含的B幀和P幀越多,響應的壓縮比也會更高,或者說同樣的位元速率下,視訊會更清晰一些。

壞處:對於視訊直播來說,播放器連線到伺服器的時間是不固定的,當播放器在GoP中間連線伺服器,並獲取了中間的B幀和P幀,這時播放器是無法對這些幀進行解碼的,需要進行丟棄。所以會導致客戶端的首屏播放時間變長(客戶端需要等待一段時間才能看到影象)。

  2.  如果 GoP設定比較小時:

好處:由於GoP設定小可以降低I幀間隔時間,對於直播來說可以實現秒開的功能。

壞處:由於GoP時間比較短,會導致I幀的比例增高,壓縮比降低。同樣位元速率情況下視訊的質量會有所下降。

三 .為什麼我的HLS視訊載入會慢?

HLS (HTTP Live Streaming),Apple的動態位元速率自適應技術。主要用於PC和Apple終端的音視訊服務。HLS格式的視訊分為兩個部分的。首先,HLS會根據指定的切片時間和實際的GoP大小對視訊進行切割,並生成.ts檔案。其次,HLS會生成一個.m3u8檔案來儲存這些ts檔案的索引。

HLS協議可以用來做點播,也可以用來做直播。HLS直播是對直播流實時進行格式轉換,並切片出.ts檔案,同時更新.m3u8檔案。客戶端通過間歇獲取新的.m3u8檔案來獲取新的.ts檔案的索引。HLS點播是通過預先轉碼好的視訊進行切片,並生成一個完整的.m3u8檔案,客戶端通過獲取.m3u8檔案來得到視訊的時長和各個.ts切片檔案的索引。

對於HLS格式的直播來說,.m3u8檔案會在生成完一個.ts檔案之後才生成。所以對於HLS直播來說,剛開始推流時,到第一個.ts檔案生成完畢之前是無法開啟的。同理,HLS的延遲也是跟.ts檔案切片時間相關的。也就是說HLS的ts檔案切片時間為1秒的話,HLS直播的延遲最小為1秒。

當然對於播放端來講,下載.m3u8檔案,然後下載第一個.ts檔案也是需要花費一點時間的,那麼這個時間也會加在延遲中。

對於.ts檔案的切割來講,並不是告訴直播伺服器指定1秒切一個.ts檔案他就能保證1秒切一個.ts檔案的。.ts檔案的切割還是要根據直播視訊的實際GoP大小來進行切割的。之前已經講過,任何一個視訊流在播放端需要能獲取到完整的GoP才能播放,所以一個.ts檔案所實際包含的時間是GoP的整數倍。

例如:當視訊的GoP設定為1秒,.ts切片時間為2秒時,實際的.ts檔案切片所包含的視訊為2秒。當視訊的GoP設定為5秒,.ts切片時間為2妙時,實際的.ts檔案切片所包含的視訊為5秒。

從上面兩個例子不難發現,視訊流的實際GoP對HLS切片的時間影響非常大。如果視訊流的GoP大小設定不合適的話,那麼HLS的切片時間就會變長,同時也會增加HLS的延遲。這個特性對於HLS直播來講簡直就是延遲殺手。如果推流上來的GoP為10秒的話,不要說切出來一個.ts檔案就要10秒,同時下載一個.ts檔案所花費的時間也會大大增加。

另外如果是HLS點播的話,流的GoP設定過大也會影響點播視訊的載入時間。一般的一個720P的視訊,如果切片時間為2秒的話,單個.ts檔案也就是在百K位元組上下。對於現有的網速來講,下載這麼一個.ts檔案很快。但如果源視訊的GoP很大,會導致第一個.ts檔案所包含的視訊時常變長(比如10秒),同時導致.ts檔案的大小膨脹到接近1M位元組上下。想想看,如果第一個.ts檔案是1M位元組的話,播放器下載這個.ts檔案的時間會是多久。

四.為什麼我的RTMP直播首屏渲染速度很慢?

RTMP是Real Time Messaging Protocol(實時訊息傳輸協議)的首字母縮寫。該協議基於TCP,是一個協議族,包括RTMP基本協議及RTMPT/RTMPS/RTMPE等多種變種。RTMP是一種設計用來進行實時資料通訊的網路協議,主要用來在Flash/AIR平臺和支援RTMP協議的流媒體/互動伺服器之間進行音視訊和資料通訊。

對於RTMP協議的直播視訊來說,它並不像HLS協議需要切.ts檔案,它只是把視訊流實時地進行轉發即可。RTMP協議本身也會抽象出一個Packet的概念來封裝H264編碼中的幀,也就是一個Packet會包含1到多個幀,播放器以Packet為單位來進行解碼。那麼RTMP的問題在於客戶端連線的時間點是否合適。

例如一個RTMP直播流的GoP設定為2秒,如果客戶端接入時間剛好是第4秒,那麼客戶端會獲取一個包含I幀的Packet,由於I幀是自描述的,所以客戶端可以直接解碼出該幀的畫面並顯示出來。但是當客戶端的接入之間為第5秒,那麼他會獲得一個包含B幀或者P幀的Packet,由於客戶端拿到的資料是一個不完整的GoP,所以客戶端只好拋棄當前獲取的Packet中視訊的資料,而且只有當獲取到包含下一個GoP的I幀的Packet時才能解碼出影象。因此客戶端會等待1秒才能播放出畫面。

由此我們可以得出一個結論:GoP的大小會影響RTMP播放端的首幀載入時間。也就是說首幀載入時間最久為一個GoP的時間。當然,如何客戶端運氣夠好的話,可以瞬間播放。

為了優化首幀載入時間,我們可以在流媒體伺服器端增加一個快取,把上一個GoP快取在記憶體中。如果客戶端接入的話,我們首先放出來的是上一個GoP。這樣客戶端接到的資料永遠是一I幀開頭的資料。

不過這種方案對於延遲要求比較高的場景下就不適合。畢竟GoP的快取會增加一個延遲,具體延遲的時間也是跟GoP大小相關的。如果要實時性,那麼GoP快取並不能很好的解決問題,只能通過減少關鍵幀間隔的方式來進行調優了。

五.結論

在視訊直播和點播盛行的年代,對於GoP大小的取捨還是需要看具體應用場景。對於直播來講,對延遲要求敏感的應用來說,1~2秒的GoP大小還是比較合適的,至於GoP快取來講,還是不用為好。如果是對延遲要求不敏感,對首屏播放時間很敏感的應用,GoP還是1~2秒最為合適,GoP快取應該是必備的。另外直播使用HLS的話,延遲是絕對PK不過RTMP的。

對於點播的應用來說,視訊載入速度是個硬指標,如果不是HLS格式的話,GoP大小適當選大一點可以降低視訊檔案大小,提高視訊開啟速度。HLS格式的話,還是推薦在2秒左右,否則很影響視訊開啟速度的。

其實視訊直播技術的挑戰很多,這次分享的只是其中一小部分,也是迅達雲SpeedyCloud研發團隊的經驗總結,希望能夠和大家多交流,一起為技術社群發展做些有益的事情。

六.Q&A;

問題1:求推薦視訊直播的知識資源,關於rmtp、h264編碼的更多知識。大量視訊檔案儲存伺服器技術方案有哪些?

這方面的內容,可以通過翻閱wikipedia,Google來獲取想要的知識。另外看一些開源專案的文件也會有所幫助。比如Nginx-RTMP-Module,Simple-rtmp-server,ffmpeg

問題2:視訊直播這塊有沒有開源專案可以來練手的?  

上面說到了Nginx-rtmp,SRS,FFMPEG

問題3:nginx 的rtmp模組,可以配置gop快取時間嗎?

nginx-rtmp是沒有GoP Cache的。Simple-RTMP-Server是有的。

問題4:求現在創業公司如何快速搭建自己的直播平臺,是自研還是使用第三方平臺,有哪些第三方平臺可以推薦?

搭建直播平臺的話,涉及的東西會很多,一般都是自研一部分,外包一部分。

問題5:老師說到B偵和P偵需要參考偵才能解碼,但在GoP的那張圖中沒有看到參考偵呀?

最前面和最後的兩個橘黃色的是I幀。另外參考不一定是I幀,前後的B幀和P幀都可以做參考

問題6:ffmepg裡,哪個選項是配置 x264的 gop的?

-g引數可以設定gop長度,單位是幀。

問題7:就rtmpserver來說,哪些server 使用者更多些?

這個看應用場景了,如果是自己用,Nginx-rtmp比較容易一些,如果是做CDN的話,simple-rtmp-server是個比較好的選擇。

 講師介紹