1、首先要了解HLS延時的機制,也就是為什么會延時,延時主要發生在什么地方。
HTTP Live Streaming 並不是一個真正實時的流媒體系統,這是因為對應於媒體分段的大小和持續時間有一定潛在的時間延時。在客戶端,至少在一個分段媒體文件被完全下載后才能夠開始播放,而通常要求下載完兩個媒體文件之后才開始播放以保證不同分段音視頻之間的無縫連接。此外,在客戶端開始下載之前,必須等待服務器端的編碼器和流分割器至少生成一個TS文件,這也會帶來潛在的時延。服務器軟件將接收到的流每緩存一定時間后包裝為一個新的TS文件,然后更新m3u8文件。m3u8文件中只保留最新的幾個片段的索引,以保證觀眾任何時候連接進來都會看到較新的內容,實現近似直播的效果。這種方式的理論最小延時為一個ts文件的時長,一般為2-3個ts文件的時長。
所以,hls的延時主要由以下三個部分組成:
(1)服務器端的編碼器和流分割器生成TS文件的時間
(2)客戶端下載TS文件的時間,而通常要求下載完兩個TS媒體文件
(3)客戶端解碼並播放時間
這三個方面里面,前兩個方面我們是可以控制調節的,對於第三個方面只能取決於客戶端的性能。
2、具體優化方法
由於服務器端生成TS流段需要時間,那么我們可以調節每段TS文件的大小,讓其小些,那么服務器生成它的速度就加快,時間縮短。這樣一來,客戶端下載第一段或者前兩段的時間就會減少,延時就會降低。根據上述的方式可以更改HLS的分段大小,方法是修改nginx配置文件nginx.conf,默認情況下nginx.conf文件的hls配置部分如下:
rtmp { server { listen 1935; chunk_size 4096; application live { live on; } hls on; hls_path /tmp/hls; } }
文件並沒有設置HLS 分段長度,添加設置:
hls_fragment 1s;
將每段的長度限定為1s,HLS官方推薦的是10s,但是在我這里10s延時太大。但是段的時長越短,服務器的負載越大,延時越少。對於這句話我不是十分理解,至少我並沒有發現服務器負載增加。當每段的長度固定之后,播放列表的長度也會影響延時時間,而且會對再次播放時的開始時間產生影響,非首次播放時,客戶端會在播放列表的開頭開始播放,所以總的延時時間等於播放列表長度加上上述的延時時間。所以將播放列表長度不要設置太大:
hls_playlist_length 3s;
這樣設置完之后的配置文件RTMP模塊配置部分為:
rtmp { server { listen 1935; chunk_size 4096; application live { live on; } hls on; hls_path /tmp/hls; hls_fragment 1s; hls_playlist_length 3s; } }
配置完成后重新啟動nginx,重新使用ffmpeg推流,結果延時時間降到7~8s。
優化前測試結果:26S
優化后VLC播放測試結果:11s