探索LowLatency的HLS低延迟直播协议

HLS全称为HTTP Live Streaming,其中m3u8作为描述协议,指向一系列切片文件。支持多码流与自适应码率,支持广告无缝播放,支持CMAF协议的低延时直播,也支持CDN动态选择。

我们先看下HLS整体架构,由三部分构成:服务端、CDN分发、客户端,切片文件可以是ts或者mp4。如下图所示:

一、自适应码率

服务端提供多个不同码率的码流,客户端根据估计的码率来选择最合适的码流,实现自适应码率的流畅播放。码流描述使用EXT-X-STREAM-INF表示,BANDWIDTH表示带宽,RESOLUTION表示分辨率,如下所示:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/lo_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=440000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/hi_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=640000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/high/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5"
http://example.com/audio/index.m3u8

二、广告无缝播放

视频和广告的编码器参数往往不同,所以在插播广告时,需要重新创建解码器,有一定耗时。m3u8为了解决这个问题,引入EXT-X-DISCONTINUITY来标识前后切片参数不同,让客户端可以提前初始化解码器。m3u8描述如下:

#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
ad0.ts
#EXTINF:8.0,
ad1.ts
#EXT-X-DISCONTINUITY
#EXTINF:10.0,
movieA.ts
#EXTINF:10.0,
movieB.ts

使用AVQueuePlayer进行无缝播放,示例代码如下:

let player = AVQueuePlayer()
let item1  = AVPlayerItem(url: url1)
let item2  = AVPlayerItem(url: url2)

player.insert(item1, after: nil)
player.insert(item2, after: item1)

player.play()

三、低延迟直播

HLS的低延迟直播基于CMAF协议(Common Media Application Format)。CMAF由四部分组成:

  • CMAF Track:包含video、audio、subtitle轨道;
  • CMAF Header:轨道头部信息,比如视频的宽高、分辨率,音频采样率、声道数;
  • CMAF Segment:轨道的一系列片段;
  • CMAF Chunk:Segment的分片,若干个Chunk组成一个Segment;

关于CMAF的结构示意图如下:

在认识CMAF协议后,我们看下Low-Latency HLS的关键点:生成segment分片(chunk)、Playlist增量更新、使用预加载提示、切换码率过渡上报。

1、生成segment分片

在CMAF协议中,segment还可以划分更小单元——chunk。每个chunk块有更短的时长,易于打包、发布、传输。例如,一个时长为6s的segment划分30个chunk,那么每个chunk时长仅有200ms。使用EXT-X-PART标签来表示chunk分块。

2、Playlist增量更新

使用EXT-X-SKIP标签实现增量更新,降低传输成本。

3、阻止列表重新加载

低延迟协议支持阻止播放列表重新加载,避免浪费带宽。当客户端发起HTTP请求更新列表时,指定需要更新的segment。服务端收到请求后,先保持住请求,等待segment准备就绪,然后push推送给客户端。

4、预加载提示

为了消除不必要的RTT等待,服务端使用EXT-X-PRELOAD-HINT标签,来通知客户端预加载下一个segment。

5、切换码率过渡上报

低延迟播放,客户端支持以最少的RTT数来切换码率,实现码率自适应。使用EXT-X-RENDITION-REPORT标签来携带媒体序列号、分块等信息。

四、CDN动态选择

CDN架构包括:origin源站和edge边缘节点。客户端会就近访问边缘节点,如果命中缓存,那么直接使用缓存;如果不命中缓存,回溯到源站去请求,简称为回源。架构如下图所示:

提供PATHWAY-ID来选择CDN,使用EXT-X-CONTENT-STEERING来指定选中的CDN,描述如下:

#EXTM3U 
#EXT-X-CONTENT-STEERING:SERVER-URI="/steering?video=00012",PATHWAY-ID="CDN-A" 
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=“A”,NAME="English",DEFAULT=YES, 
LANGUAGE="en",URI="audio.m3u8" 
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=“B”,NAME=“ENGLISH”,DEFAULT=YES, 
LANGUAGE="en",URI="https://backup.example.com/content/videos/video12/
audio.m3u8" #EXT-X-STREAM-INF:BANDWIDTH=1280000,AUDIO="A",PATHWAY-ID="CDN-A" 
low/video.m3u8 
#EXT-X-STREAM-INF:BANDWIDTH=7680000,AUDIO="A",PATHWAY-ID="CDN-A" 
hi/video.m3u8 
#EXT-X-STREAM-INF:BANDWIDTH=1280000,AUDIO="B",PATHWAY-ID="CDN-B" 
https://backup.example.com/content/videos/video12/low/video.m3u8 
#EXT-X-STREAM-INF:BANDWIDTH=7680000,AUDIO="B",PATHWAY-ID="CDN-B" 
https://backup.example.com/content/videos/video12/hi/video.m3u8

提供PATHWAY-PRIORITY来表示各个CDN路径的优先级,排在前面的优先级最高。另外用TTL标识客户端等待时间,默认为300s。使用json格式描述,如下所示:

{ 
    "VERSION": 1, 
    "TTL": 300, 
    "RELOAD-URI": "https://example.com/steering?video=00012&session=123", 
    "PATHWAY-PRIORITY": [ 
        "CDN-A", 
        "CDN-B" 
    ] 
}

猜你喜欢

转载自blog.csdn.net/u011686167/article/details/131155501
今日推荐