在直播應用中,RTMP 和 HLS 是兩種較爲成熟且廣泛應用的流媒體協議,基本上可以覆蓋所有客戶端。RTMP 是互聯網 TCP/IP 五層體系結構中應用層的協議,主要優勢就是實時性高,基本可將直播延時控制在3秒以內,因此廣泛應用於低延時直播。
HLS是由 Apple 公司實現的基於 HTTP 的流媒體傳輸協議,擁有性能高、完美支持 iOS等優勢。相比於 RTMP 協議,HLS 無需在移動端安裝 APP,同時兼容HTML5,因此在移動直播的傳播和體驗上都擁有巨大的優勢。不過HLS 的實時性較差,業界的平均直播延時達在10s ~35s。
在讓許多用戶最頭痛的 HLS 延時問題上,又拍雲做了針對性的技術優化,實現了 HLS 的超低延時,將 HLS 延時穩定控制在了 4 秒左右。
HLS 高延時原因分析
HLS 理論上延時=1個切片的時長+ 0-1個td(td是EXT-X-TARGETDURATION,可簡單理解爲播放器取片的間隔時間) + 0-n個啓動切片(蘋果官方建議是請求到3個片之後纔開始播放) + 播放器最開始請求的片的網絡延時(網絡連接耗時)。
從延時組成公式可以看出,HLS 的延時主要是以下四部分組成:
服務器端的編碼器和流分割器生成 TS 文件的時常,HLS 協議應用於直播視頻傳輸時,是將媒體文件切割成了對應於媒體分段的 TS 文件。
播放器取片的間隔時間,在客戶端開始下載之前,必須等待服務器端的編碼器和流分割器至少生成一個TS 文件。
客戶端下載切片的時間及啓動播放所需的切片個數,通常下載完兩個媒體文件後才能保證不同分段音視頻間的無縫連接。
客戶端最開始解碼並開始播放的時間。
HLS的延時優化主要是針對前三個部分,第四個部分是取決於用戶客戶端的性能。
又拍雲 4S 延時 HLS+ 技術詳解
由於客戶端每次請求 TS 或 m3u8 可能都是一個新的連接請求,所以,我們無法有效地標識客戶端,一旦出現問題,基本無法有效地定位問題,因此一般服務器都會對傳統的 HLS 做一些改進。
又拍雲 HLS+ ,又稱爲流式 HLS 技術,將標準的 HLS 進行流式處理,能大幅度降低標準 HLS 延遲,提高HTML5 端直播兼容性,且具有回源量小、系統簡單、排錯容易、防盜鏈、避免 HLS 404 等優勢。
又拍雲 HLS+ 能夠標記每個客戶端的 HLS 請求,併爲每個 HLS 請求建立起連接,再動態的爲每個播放請求生成獨立的 M3U8 列表,並動態快速的生成僅針對這個播放請求的小切片文件。
爲了解決 HLS 請求不友好的問題,又拍雲採用Variant HLS+HTTP 302的方式標識客戶端的行爲。
1、Variant HLS
首先,下載一條又拍雲的 m3u8 文件:
1 | wget http: //uplive.bo.upaiyun.com/live/loading.m3u8 |
然後,打開下載得到的 playlist 文件:
1 2 3 4 5 6 | #EXTM3U #EXT-X-VERSION:3 #EXT-X-ALLOW-CACHE:YES #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:1 #EXTINF:0.998, no desc |
http://183.158.35.12:8080/uplive.b0.upaiyun.com/live/loading-0.ts?shp_uuid=e4989f34fcab282e21ef1fd2980284cb&shp_ts=1490172420851&shp_cid=17906&shp_pid=3370578&shp_sip0=127.0.0.1&shp_sip1=183.158.35.12&domain=uplive.b0.upaiyun.com&shp_seqno=0
可以看出又拍雲的 HLS+ 支持這種 Variant HLS 方式來標識一條 HLS 連接,同時是使用 UUID 來表示一條 HLS 連接。
2、HTTP 302
首先,以 HTTP 302 方式來請求播放地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | curl -v http: //uplive.b0.upaiyun.com/live/loading.m3u8\?shp_identify\=302 -o playlist % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 183.158.35.59... * TCP_NODELAY set * Connected to uplive.b0.upaiyun.com (183.158.35.59) port 80 (#0) > GET /live/loading.m3u8?shp_identify=302 HTTP/1.1 > Host: uplive.b0.upaiyun.com > User-Agent: curl/7.51.0 > Accept: */* > < HTTP/1.1 302 Found < Server: marco/0.26 < Date: Wed, 22 Mar 2017 08:54:11 GMT < Content-Type: text/plain; charset=utf-8 < Content-Length: 259 < Connection: keep-alive < Access-Control-Allow-Methods: GET < Access-Control-Allow-Origin: * < Location: http: //183.158.35.19:8080/uplive.b0.upaiyun.com/live/loading.m3u8?shp_uuid=2862b1b817a74cf719b1cd8f554616cd&shp_ts=1490172851450&shp_cid=59553&shp_pid=1730488&shp_sip0=127.0.0.1&shp_sip1=183.158.35.19&domain=uplive.b0.upaiyun.com&shp_identify=302 < { [259 bytes data] * Curl_http_done: called premature == 0 100 259 100 259 0 0 4813 0 --:--:-- --:--:-- --:--:-- 4886 * Connection #0 to host uplive.b0.upaiyun.com left intact |