Advertisement

流媒体网络协议 -- HLS

阅读量:

HLS

  • HLS介绍

    • 1. 原理
    • 2. HLS多媒体系统
    • 3. HLS的优势和不足:
  • 描述文件用于媒体管理

        1. 核心播放列表(Master Playlist)
        1. 常规媒体列表(Media Playlist)
        1. 播放列表中URL生成规则如下:
        1. 扩展版本或增强版功能
    • 实际应用遇到的问题


HLS介绍

Hls缩略名为Http直播流是一种由苹果公司创建的基于Http的技术,用于实现实时语音与视频数据的传送

1. 原理

服务器将码流分割成一个个小的部分(一般为10秒一档),这些部分可通过HTTP下载作为 media segments(segment);客户端在获取 M3U8 列表后,并遵循标准解析流程确定各 media 片段的具体位置信息;随后依次 download 这些片段至本地设备进行解码和拼接处理,在视觉效果上达到模拟实时接收整个编码流的目的。 其中 HTTP 是网络协议,在 Apple 定义的标准下提供的 M3U8 文件用于管理多媒体内容片段,并且这些多媒体片段以 TS 或 fMP4 格式存储。

2. HLS多媒体系统

该系统结构如下图:

在这里插入图片描述

主要由四个部分组成:

  • 媒体资料输入源
    采集音视频数据

  • 媒体编码封装服务端
    对原始数据流进行编码处理和打包处理,并将其分割成小段以形成一个个简短且连续的小文件。

资源分发服务器,在典型的网络架构中被设计为接收客户端提交的应用请求,并将处理后的结果返回给相应的客户端程序(如M3U8文件及媒体文件)。

  • 客户端
    拉流播放

3. HLS的优势和不足:

  • 劣势:
  1. 采用HTTP协议传输数据以避免其被防火墙阻挡从而实现数据的广泛传播。
  2. 通过自适应码率技术提升播放过程中的连贯性。
  3. 基于无状态设计使得网络负载能够更加均匀地分配。
  4. 在浏览器端拥有良好的兼容性无需额外安装任何插件即可运行。
  • 缺陷:
    实时效果欠佳且响应速度较慢的原因主要包括以下两个方面:
    主要原因在于:
    1>运用分段播放技术(即切片播放),每个分段文件都需要进行时间戳编码以确保正确播放顺序,并因此必然存在一定的延时问题。
    2>采用基于TCP协议的HTTP短连接机制,在数据传输过程中需经历三个通信阶段(建立连接、数据传输、断开连接),导致整个交互过程较为繁琐。

媒体描述文件

M3U8编码方案作为HLS的核心媒体描述文件采用UTF-8编码方式。
具体而言该列表可采用两种主要形式:一种为主列表(Master Playlist) ,另一种为媒体列表(Media Playlist)
如图所示该层次结构展示了列表与媒体文件之间的关系涉及两层嵌套结构。

在这里插入图片描述

1. 主播放列表(Master Playlist)

用来表示多个不同码率码流的媒体播放列表url及相关信息。
如下:

复制代码
    #EXTM3U
    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000,CODECS="avc1.640028,mp4a.40.2"
    http: //example.com/low.m3u8 
    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000,CODECS="avc1.640028,mp4a.40.2"
    http: //example.com/mid.m3u8
    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000,CODECS="avc1.640028,mp4a.40.2"
    http: //example.com/hi.m3u8
TAG以及形式 意义
#EXTM3U 表示该文件一个拓展的M3U8文件,必须放在第一行。

| #EXT-X-STREAM-INF:| 定义一个变体流,并将包含多媒体信息的媒体流URI作为播放列表进行引用
通常用于嵌套M3U8文件中,在这种情况下,默认仅影响后续紧跟在其后面的URI。
attribute-list包含以下几个参数设置:
· BANDWIDTH字段:指定所需的带宽值(此字段必须存在),它是实现码率自适应的关键参数之一。
· PROGRAM_ID字段:十进制整数编码文件范围内的唯一标识符(该标识符具有唯一的特性)。
· CODECS字段:指定了视频和音频编码格式(这些格式是非必需项)。
· RESOLUTION字段:表示分辨率信息(此属性也是非必需项)。

2. 媒体播放列表(Media Playlist)

用来表示同一码率码流的一系列切片url及相关信息。

  • 点播的媒体播放列表:
复制代码
    #EXTM3U

    #EXT-X-PLAYLIST-TYPE:VOD  // 播放列表类型
    #EXT-X-VERSION:3         // 版本信息
    #EXT-X-TARGETDURATION:11 // 每个分片的目标时长
    #EXT-X-MEDIA-SEQUENCE:0  // 该文件第一个分片的序号
    #EXTINF:10.922578,       // 分片实际时长
    test000.ts               // 第一个分片文件,序号为0
    #EXTINF:9.929578,        // 第二个分片实际时长
    test001.ts               // 第二个分片文件,序号为1
    ...
    #EXT-X-ENDLIST           // 该列表结束标志

对于加密的码流而言,在信息流中增加了EXT-X-KEY tag这一项配置项。该tag用于标识加密采用的具体方案以及与请求相关联的关键字信息和密钥来源地址(request address)以及密钥偏移量(offset)。特别注意的是,在转换过程中需要确保将该参数转换为十六进制表示(char --> hex),以便后续处理。

复制代码
    #EXTM3U

    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:10
    #EXT-X-MEDIA-SEQUENCE:12616381
    #EXT-X-KEY:METHOD=AES-128,URI="3M_key",IV=0x4F1E7B58678D094361DF3F0FFDEDD333
    #EXTINF:10,
    720p_aes_0.ts
    #EXT-X-KEY:METHOD=AES-128,URI="3M_key",IV=0x4F1E7B58678D094361DF3F0FFDEDD333
    #EXTINF:10,
    720p_aes_1.ts
    #EXT-X-ENDLIST
  • 对于直播流,其媒体播放列表末尾没有ENDLIST tag,是这样的:
复制代码
    EXT-X-PLAYLIST-TYPE为EVENT,而且列表末尾没有EXT-X-ENDLIST tag!

    #EXTM3U
    #EXT-X-PLAYLIST-TYPE:EVENT
    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:11
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10.922578,
    test000.ts
    #EXTINF:9.929578,
    test001.ts               
    ...
  • 下面说明各个TAG的意义:
TAG以及形式 意义
#EXTM3U 一个拓展的M3U8文件,必须放在第一行,以此TAG来说明该文件为M3U8文件
#EXT-X-PLAYLIST-TYPE 播放列表类型。有两个取值:VOD --> 点播;EVENT --> 直播。
#EXT-X-VERSION: 协议的版本号,n为3,HLS v3;n为4,HLS v4
#EXT-X-TARGETDURATION: 该列表中每个切片的最大时长
#EXT-X-MEDIA-SEQUENCE: 该文件第一个切片的序号。如没有,则默认为0
#EXTINF:duration(float),title 一个切片的实际时长和文件名,文件名与url拼接就可以得到切片url。

| #EXT-X-KEY| 解密数据,有三个必要的参数设置:
• METHOD: 设置加密方案,hls协议定义了三种预定义的编码方案:NONE,AES-128(CBC),SAMPLE-AES
• URI: 指定解密密钥的相对路径位置
• IV: 设置解密偏移量 |
|#EXT-X-ENDLIST|M3U8编码结束标志,非直播场景下不需要该标志字段

3. 播放列表中URL生成规则:

播放列表中有以下几种不同的URL生成规则。

直接给出URL
也就是绝对路径,拿到之后直接用来请求既可。如:

复制代码
    #EXTM3U

    #EXT-X-TARGETDURATION:10
    #EXT-X-VERSION:3
    #EXTINF:9.009,
    http ://media.example.com/first.ts
    #EXTINF:9.009,
    http ://media.example.com/second.ts
    #EXTINF:3.003,
    http ://media.example.com/third.ts
    #EXT-X-ENDLIST

那我们直接请求http://media.example.com/first.ts,就可以拿到切片了

单文件名基于路径 仅需提供文件名 说明资源文件与.m3u8文件放置于同一目录中 需进行URL拼接

复制代码
    #EXTM3U

    #EXT-X-TARGETDURATION:10
    #EXT-X-VERSION:3
    #EXTINF:9.009,
    first.ts
    #EXTINF:9.009,
    second.ts
    #EXTINF:3.003,
    third.ts
    #EXT-X-ENDLIST

拼接方式:在请求该m3u8文件的URL时,请先去除对应的m3u8文件标识,在获取到切片文件部分后进行拼接,则可得到最终完整URL地址。

复制代码
    如该m3u8的url为:http://media.example.com/index.m3u8

    那么每个切片url前缀就是:http://media.example.com/
    所以第一个切片url就是:http://media.example.com/first.ts

明确资源文件的路径位置,并指出资源文件与m3u8文件位于不同的目录结构中,必须执行URL拼接操作。

复制代码
    #EXTM3U

    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
    1000k/hls/index.m3u8
    或者:
    #EXTM3U
    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
    /1000k/hls/index.m3u8

拼接规则同2)。

复制代码
    如该m3u8的url为:http://media.example.com/index.m3u8

    那么每个媒体播放列表url前缀就是:http://media.example.com/
    所以该媒体播放列表的url就是:http://media.example.com/1000k/hls/index.m3u8

还有一种:

复制代码
    #EXTM3U

    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
    /15467_73a719b2/1000k/hls/index.m3u8

而请求该m3u8的url是:

http://media.example.com/123/15467_73a719b2/index.m3u8

可以看到文件路径和请求url存在重复项的情况。根据第2条的拼接规范,则是:

http://media.example.com/123/15467_73a719b2/15467_73a719b2/1000k/hls/index.m3u8

显然不对,需要去重,所以应该是:

http://media.example.com/123/15467_73a719b2/1000k/hls/index.m3u8

双斜杆相对位置:
双斜杆后面一般直接就是域名,如:

复制代码
    #EXTM3U

    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
    //douban.donghongzuida.com/20210109/15467_73a719b2/1000k/hls/index.m3u8

拼接规则 :直接添加请求该m3u8列表的协议。

复制代码
    如该m3u8为http://media.example.com/index.m3u8,

    那么就是:http://douban.donghongzuida.com/20210109/15467_73a719b2/1000k/hls/index.m3u8
    如该m3u8为https://media.example.com/index.m3u8,
    那么就是:https://douban.donghongzuida.com/20210109/15467_73a719b2/1000k/hls/index.m3u8

4. 扩展

在HLS高版本中引入了ISO profile的支持, 并在此基础上实现了fragment MP4的技术功能. 为此,HLS增加了EXT-X-MAP这一元数据字段以辅助标识相关媒体内容.

复制代码
    #EXTM3U

    #EXT-X-TARGETDURATION:15
    #EXT-X-ALLOW-CACHE:YES
    #EXT-X-PLAYLIST-TYPE:VOD
    #EXT-X-VERSION:6
    #EXT-X-MEDIA-SEQUENCE:1
    #EXT-X-MAP:URI="init-v1-a1.mp4"
    #EXTINF:13.000,
    seg-1-v1-a1.m4s
    #EXTINF:12.000,
    seg-2-v1-a1.m4s
    #EXT-X-ENDLIST

mp4文件中的moov和mdat通常是分开编码以实现不同功能需求的,在HLS编码方案中,
用于传输moov数据的部分称为init片段(init segments),而相应的dat数据部分则称为媒体片段(media segments)。
为了明确区分这两部分的数据流,
引入了EXT-X-MAP扩展标记来标识这些片段类型。
其中每个ts头对应于一个特定类型的包格式(如PAT或PMT),用于标识相关的媒体数据块。
同样支持通过EXT-X-MAP扩展标记来指定相关的传输参数,
其中每个ts头对应于一个特定类型的包格式(如PAT或PMT),用于标识相关的媒体数据块。

低延迟HLS的实现方式
【该方案由第三方公司提出

apple官方提出的low-latency HLS方案取得最显著的进步,在这一改进中发现并实施了一种创新的方法:将最新的那个切分过程优化为将数据进行更细粒度的切分。这种优化使得每个请求的数据颗粒度进一步减小,在生成可访问切分的时间上也实现了缩短目标。基于此需求,在原有的技术架构中特别增加了#EXT-X-PART这个元数据字段进行参数配置支持

复制代码
    #EXTINF:6.003,

    LLHLS_Video1_67750710.mp4
    #EXT-X-PROGRAM-DATE-TIME:2021-03-18T09:20:29.482Z
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.0.mp4",INDEPENDENT=YES
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.1.mp4",INDEPENDENT=YES
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.2.mp4",INDEPENDENT=YES
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.3.mp4",INDEPENDENT=YES
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.4.mp4",INDEPENDENT=YES
    #EXT-X-PART:DURATION=1.000,URI="LLHLS_Video1_67750711.5.mp4",INDEPENDENT=YES

可以看到LLHLS_Video1_67750710.mp4这个视频片段被分割成更小的部分,在这种情况下就不必等到该视频片段完全生成后再进行再次访问了。

搭建HLS服务器。
使用nginx或Apache2搭建Http server即可…

如何在HLS流媒体中实现插播广告?

复制代码
    #EXTM3U

    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:11
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10.922578,
    test000.ts
    #EXTINF:9.929578,
    test001.ts
    ...

如果想在原视频开头前插入广告:

复制代码
    #EXTM3U

    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:11
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10.0,
    ad0.ts
    #EXTINF:8.0,
    ad1.ts
    #EXT-X-DISCONTINUITY
    #EXTINF:10.922578,
    test000.ts
    #EXTINF:9.929578,
    test001.ts
    ...

如果想在原视频中间插入广告:

复制代码
    #EXTM3U

    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:11
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10.922578,
    test000.ts
    #EXT-X-DISCONTINUITY
    #EXTINF:10.0,
    ad0.ts
    #EXTINF:8.0,
    ad1.ts
    #EXT-X-DISCONTINUITY
    #EXTINF:9.929578,
    test001.ts
    ...

码率切换策略:
综合考虑网络带宽和buffer水位。
当前带宽小于当前播放码率且buffer中的数据也不充足(不足够一个切片)的时候,降到对应的码率。
当前带宽大于当前播放码率且buffer中的数据充足(大于一个切片)时,升到对应的码率。
怎么计算当前buffer中的切片数量?
通过buffer中数据量和上一个已下载的切片平均比特率来计算当前buffer中是否足够一个切片的时长(targetduration)


实际应用遇到的问题

在直播过程中,请问playlist请求的时间间隔是多少?通常情况下,在每次播放列表更新前会等待一个切片的时间长度。

在直播过程中,请问playlist请求的时间间隔是多少?通常情况下,在每次播放列表更新前会等待一个切片的时间长度。

在直播过程中,在选择第一个播放片段时应当注意什么?答:根据HLS协议的要求,在直播过程中客户端应优先选择距离播放列表末尾至少两个目标时长之前的片段作为初始片段进行播放。在HLS流式传输中,默认情况下客户端会选择距离最后一个片段至少三个时间段之前的片段作为初始段序列

如何判断播放源是直播还是点播?
答:有两种方法进行判断
1>检查媒体播放列表中是否存在#EXT-X-ENDLIST标签:若存在,则判定为点播;若不存在,则判定为直播。
2> 方法2>查看#EXT-X-PLAYLIST-TYPE字段的值:若值为"live"则判定为直播;若值为"stream"则判定为点播

#EXT-X-PLAYLIST-TYPE: VOD // 点播源
#EXT-X-PLAYLIST-TYPE: EVENT // 直播源

如何确定一个M3U8文件属于主播放列表还是媒体播放列表?通过检查该文件所在目录中的EXT-X-STREAM-INF标志项是否存在:若存在,则该文件属于主m3u8文件;若不存在,则属于媒体m3u8文件。

在直播过程中,请问如何鉴别当前收到的M3U8文件相较于上一次所获取的M3U8文件中是否新增了Segment URL?答:一种高效的方法是通过计算并比较上一次请求与当前请求所获取的M3U8文件各自的MD5值来判断是否存在新增内容。如果两者MD5值一致,则无需解析;如果存在差异,则表示存在更新内容。

当m3u8列表无法获取时,默认策略将执行重试操作两次

为何HLS在实时性方面存在不足?
1>由于采用了分段式的媒体形式,并且每个分段(切片)都需要经过编码处理才能被请求,因此每个分段都不可避免地会产生延迟.
2>基于HTTP短连接的数据传输机制导致每次数据请求都需要等待服务器的响应,并且每次通信需经历一个RTT时间间隔.

全部评论 (0)

还没有任何评论哟~