天天看點

低延時直播應用

低延時直播應用

直播應用中,RTMP和HLS基本上可以覆寫所有用戶端觀看,HLS主要是延時比較大,RTMP主要優勢在于延時低。

應用場景

低延時應用場景包括:

  • 互動式直播:譬如2013年大行其道的美女主播,遊戲直播等等各種主播,流媒體分發給使用者觀看。使用者可以文字聊天和主播互動。
  • 視訊會議:SRS的DEMO就有視訊會議應用,我們要是有同僚出差在外地,就用這個視訊會議開内部會議。其實會議1秒延時無所謂,因為人家講完話後,其他人需要思考,思考的延時也會在1秒左右。當然如果用視訊會議吵架就不行。
  • 其他:監控,直播也有些地方需要對延遲有要求,網際網路上RTMP協定的延遲基本上能夠滿足要求。

RTMP和延時

RTMP的特點如下:

  • Adobe支援得很好:RTMP實際上是現在編碼器輸出的工業标準協定,基本上所有的編碼器(攝像頭之類)都支援RTMP輸出。原因在于PC市場巨大,PC主要是Windows,Windows的浏覽器基本上都支援flash,Flash又支援RTMP支援得灰常好。
  • 适合長時間播放:因為RTMP支援的很完善,是以能做到flash播放RTMP流長時間不斷流,當時測試是100萬秒,即10天多可以連續播放。對于商用流媒體應用,用戶端的穩定性當然也是必須的,否則最終使用者看不了還怎麼玩?我就知道有個教育客戶,最初使用播放器播放http流,需要播放不同的檔案,結果就總出問題,如果換成伺服器端将不同的檔案轉換成RTMP流,用戶端就可以一直播放;該客戶走RTMP方案後,經過CDN分發,沒聽說用戶端出問題了。
  • 延遲較低:比起YY的那種UDP私有協定,RTMP算延遲大的(延遲在1-3秒),比起HTTP流的延時(一般在10秒以上)RTMP算低延時。一般的直播應用,隻要不是電話類對話的那種要求,RTMP延遲是可以接受的。在一般的視訊會議(參考SRS的視訊會議延時)應用中,RTMP延時也能接受,原因是别人在說話的時候我們一般在聽,實際上1秒延時沒有關系,我們也要思考(話說有些人的CPU處理速度還沒有這麼快)。
  • 有累積延遲:技術一定要知道弱點,RTMP有個弱點就是累積誤差,原因是RTMP基于TCP不會丢包。是以當網絡狀态差時,伺服器會将包緩存起來,導緻累積的延遲;待網絡狀況好了,就一起發給用戶端。這個的對策就是,當用戶端的緩沖區很大,就斷開重連。當然SRS也提供配置。

HLS低延時

主要有人老是問這個問題,如何降低HLS延遲。

HLS解決延時,就像是爬到楓樹上去捉魚,奇怪的是還有人喊,看那,有魚。你說是怎麼回事。

我隻能說你在參與謙哥的魔術表演,錯覺罷了。

如果你真的确信有,請用實際測量的圖檔來展示出來,參考下面延遲的測量。

RTMP延遲的測量

如何測量延時,是個很難的問題,不過有個行之有效的方法,就是用手機的秒表,可以比較精确的對比延時。參考:​​RTMP延時測量​​

經過測量發現,在網絡狀況良好時:

  • RTMP延時可以做到0.8秒左右(SRS也可以)。
  • 多級邊緣節點不會影響延遲(和SRS同源的某CDN的邊緣伺服器可以做到)
  • Nginx-Rtmp延遲有點大,估計是緩存的處理,多程序通信導緻?
  • GOP是個硬名額,不過SRS可以關閉GOP的cache來避免這個影響,參考後面的配置方法。
  • 伺服器性能太低,也會導緻延遲變大,伺服器來不及發送資料。
  • 用戶端的緩沖區長度也影響延遲。譬如flash用戶端的NetStream.bufferTime設定為10秒,那麼延遲至少10秒以上。

GOP-Cache

什麼是GOP?就是視訊流中兩個I幀的時間距離。

GOP有什麼影響?Flash(解碼器)隻有拿到GOP才能開始解碼播放。也就是說,伺服器一般先給一個I幀給Flash。可惜問題來了,假設GOP是10秒,也就是每隔10秒才有關鍵幀,如果使用者在第5秒時開始播放,會怎麼樣?

第一種方案:等待下一個I幀,也就是說,再等5秒才開始給用戶端資料。這樣延遲就很低了,總是實時的流。問題是:等待的這5秒,會黑屏,現象就是播放器卡在那裡,什麼也沒有,有些使用者可能以為死掉了,就會重新整理頁面。總之,某些客戶會認為等待關鍵幀是個不可饒恕的錯誤,延時有什麼關系?我就希望能快速啟動和播放視訊,最好打開就能放!

第二種方案:馬上開始放,放什麼呢?你肯定知道了,放前一個I幀。也就是說,伺服器需要總是cache一個gop,這樣用戶端上來就從前一個I幀開始播放,就可以快速啟動了。問題是:延遲自然就大了。

有沒有好的方案?有!至少有兩種:

  • 編碼器調低GOP,譬如0.5秒一個GOP,這樣延遲也很低,也不用等待。壞處是編碼器壓縮率會降低,圖像品質沒有那麼好。
  • 伺服器提供配置,可以選擇前面兩個方案之一:SRS就這麼做,有個gop_cache配置項,on就會馬上播放,off就低延遲。

SRS的配置項:

#
listen              1935;
vhost __defaultVhost__ {
    #
    #
    #
    #
    #
    #
    #
    #
    gop_cache       on;      

備注:參考conf/full.conf的min.delay.com配置。

累積延遲

除了GOP-Cache,還有一個有關系,就是累積延遲。SRS可以配置直播隊列的長度,伺服器會将資料放在直播隊列中,如果超過這個長度就清空到最後一個I幀:

vhost your_vhost {
    #
    #
    #
    #
    queue_length    10;      

當然這個不能配置太小,譬如GOP是1秒,queue_length是1秒,這樣會導緻有1秒資料就清空,會導緻跳躍。

有更好的方法?有的。延遲基本上就等于用戶端的緩沖區長度,因為延遲大多由于網絡帶寬低,伺服器緩存後一起發給用戶端,現象就是用戶端的緩沖區變大了,譬如NetStream.BufferLength=5秒,那麼說明緩沖區中至少有5秒資料。

處理累積延遲的最好方法,是用戶端檢測到緩沖區有很多資料了,如果可以的話,就重連伺服器。當然如果網絡一直不好,那就沒有辦法了。

低延時配置

考慮GOP-Cache和累積延遲,推薦的低延時配置如下(參考min.delay.com):

#
listen              1935;
vhost __defaultVhost__ {
    #
    #
    #
    #
    #
    #
    #
    #
    gop_cache       off;
    #
    #
    #
    #
    queue_length    10;      

當然,伺服器的性能也要考慮,不可以讓一個SRS程序跑太高帶寬,一般CPU在80%以下不會影響延遲。

繼續閱讀