【网络通信 -- 直播】音视频常见封装格式 -- HLS
发布日期:2021-05-07 20:53:05 浏览次数:17 分类:原创文章

本文共 4803 字,大约阅读时间需要 16 分钟。

【网络通信 -- 直播】音视频常见封装格式 -- HLS

【0】简介

HTTP 直播流技术(HLS,HTTP Live Streaming),Apple 的动态码率自适应技术,主要用于 PC 和 Apple 终端的音视频服务;包括一个 m3u(8) 的索引文件,TS 媒体分片文件和 key 加密串文件;

【1】HLS 直播架构

  1. 客户端采集媒体数据后,通过 RTMP 协议将音视频流推送给 CDN 网络的源节点(接入节点);源节点收到音视频流后,再通过 Convert 服务器将 RTMP 流切割为 HLS 切片文件,即 .ts 文件;同时生成与之对应的 m3u8 文件,即 HLS 播放列表文件;
  2. 切割后的 HLS 分片文件(.ts 文件)和 HLS 列表文件(.m3u8 文件)经 CDN 网络转发后,客户端就可以从离自己最近的 CDN 边缘节点拉取 HLS 媒体流;
  3. 在拉取 HLS 媒体流时,客户端首先通过 HLS 协议将 m3u8 索引文件下载下来,然后按索引文件中的顺序,将 .ts 文件一片一片下载下来,然后一边播放一边缓冲;从而可以在 PC、手机、平板等设备上观看直播节目;

服务器

  • 负责将输入的音视频媒体内容转换成为适合于内容分发组件进行递送的格式;
  • 对于视频直播,编码器首先将摄像机实时采集的音视频数据压缩编码为符合特定标准的音视频基本流,然后再复用和封装成为符合 MPEG-2 系统层标准的传输流(TS)格式进行输出;

流分割器 (Stream Segmenter)

  • 负责将编码器输出的 MPEG-2 TS 流分割为一系列连续的、长度均等的小 TS 文件(后缀名为.ts),并依次发送至内容分发组件中的 Web 服务器进行存储;
  • 创建一个含有指向这些小 TS 文件指针的索引文件,并放置于 Web 服务器之中,以跟踪播放过程中媒体文件的可用性和当前位置;
  • 对生成的每个小 TS 文件进行加密,并生成相应的密钥文件;

索引文件可以看作是一个连续媒体流中的播放列表滑动窗口,每当流分割器生成一个新的 TS 文件时,这个索引文件的内容也被更新,新的文件 URI (统一资源定位符) 加入到滑动窗口的末尾,老的文件 URI 则被移去,这样索引文件中将始终包含最新的固定数量的 x 个分段;

采用 MPEG-2 TS 格式来对编码后的媒体流进行统一封装,原因是该格式能够将音视频媒体流严格按时序进行交织复用,任意截取和分段后,每一个分段都可能不依赖于之前的分段而独立进行解码和播放;

HLS 协议的优势

  • HLS 相对于 RTMP 使用了标准的 HTTP 协议传输数据,可以避免在一些特殊的网络环境下被屏蔽;
  • HLS 相比 RTMP 便于在服务器端做负载均衡,因为 HLS 是基于无状态协议 HTTP 实现的,客户端只需要按照顺序使用下载存储在服务器的普通 ts 文件进行播放即可;而 RTMP 是一种有状态协议,很难对视频服务器进行平滑扩展,因为需要为每一个播放视频流的客户端维护状态;
  • HLS 协议本身实现了码率自适应,在不同带宽情况下,设备可以自动播放最适合自己码率的视频;

HLS 协议的缺点

  • HLS 延迟高,通常 10 秒以上;

【2】HLS 的 M3U8

m3u8 文件是用文件方式对媒体文件进行描述,由一些列标签组成;m3u8 文件每一行可以是一个 URI、空白行或是一个 以 "#" 号开头的字符串,并且空格只能存在于一行中不同元素间的分隔;

  • 以 # 字母开头的行是注释和 TAG,其中 TAG 必须是 #EXT 开头;
  • 一个 URI 表示一个媒体段或是 "variant Playlist file"(最多支持一层嵌套,即一个 m3u8 文件中嵌套另一个 m3u8);

【2.1】TAG 说明

  • #EXTM3U:每个 m3u8 文件第一行必须是这个 tag;
  • #EXTINF:指定每个媒体段(ts)的持续时间,仅对其后面的 URI 有效,每两个媒体段 URI 间被该 tag 分隔开;
    • 格式为:#EXTINF:<duration>,<title>
      • duration:表示持续的时间(秒),若 Playlist 的版本小于 3 则 duration 必须为整数,否则可以是浮点数;
  • #EXT-X-BYTERANGE:表示媒体段是一个媒体 URI 资源中的一段,只对其后的 media URI 有效
    • 格式为:#EXT-X-BYTERANGE:<n>[@o]
      • n:表示这个区间的大小
      • o:表示在 URI 中的 offset
    • 该 TAG 在 4 版本中出现
  • #EXT-X-TARGETDURATION:指定当前视频流中的单个切片(即 ts)文件的最大时长(秒);#EXTINF 中指定的时间长度必须小于或是等于这个最大值;这个 tag 在整个 Playlist 文件中只能出现一次(在嵌套的情况下,一般有真正 ts url 的 m3u8 才会出现该 tag);
    • 格式为:#EXT-X-TARGETDURATION:<s>
      • s:表示最大的秒数
  • #EXT-X-MEDIA-SEQUENCE:每一个 media URI 在 Playlist 中只有唯一的序号,相邻之间序号 +1;
    • 格式为:#EXT-X-MEDIA-SEQUENCE:<number>
  • #EXT-X-KEY:表示对 media segments 进行解码的方式;其作用范围是下次该 tag 出现前的所有 media URI;
    • 格式为:#EXT-X-KEY:<attribute-list>
      • NONE 或者 AES-128;如果是 NONE,则 URI 以及 IV 属性必须不存在,如果是 AES-128(Advanced Encryption Standard),则 URI 必须存在,IV 可以不存在。
      • 对于 AES-128 的情况,keytag 和 URI 属性共同表示了一个 key 文件,通过 URI 可以获得这个 key,如果没有 IV(Initialization Vector),则使用序列号作为 IV 进行编解码,将序列号的高位赋到 16 个字节的 buffer 中,左边补 0;如果有 IV,则将该值当成 16 个字节的 16 进制数;
  • #EXT-X-PROGRAM-DATE-TIME:将一个绝对时间或是日期和一个媒体段中的第一个 sample 相关联,只对下一个 media URI 有效
    • 格式为:#EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ>
  • #EXT-X-ALLOW-CACHE:表示是否允许做 cache,可以在 Playlist 文件中任意地方出现,并且最多只出现一次,作用效果是所有的媒体段;
    • 格式为:#EXT-X-ALLOW-CACHE:<YES|NO>
  • #EXT-X-PLAYLIST-TYPE:提供关于 Playlist 的可变性的信息,对整个 Playlist 文件有效,是可选的;
    • 格式为:#EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
      • VOD,即为点播视频,服务器不能改变 Playlist 文件
      • EVENT,实时生成 m3u8 和 ts 文件,服务器不能改变或是删除 Playlist 文件中的任何部分,但是可以向该文件中增加新的一行内容;其索引文件一直处于动态变化中,播放的时候需要不断下载二级 index 文件;
  • #EXT-X-ENDLIST:表示 m3u8 文件的结束,live m3u8 没有该 tag;可以在 Playlist 中任意位置出现,但是只能出现一个;
    • 格式为:#EXT-X-ENDLIST
  • #EXT-X-MEDIA:用来在 Playlist 中表示相同内容的不同语种/译文的版本,比如可以通过使用 3 个这种 tag 表示 3 种不同语音的音频,或者用 2 个这个 tag 表示不同角度的 video;在 Playlist 中,该标签是独立存在的;
    • 格式为:#EXT-X-MEDIA:<attribute-list>
      • 该属性列表中包含,URI、TYPE、GROUP-ID、LANGUAGE、NAME、DEFAULT、AUTOSELECT;
      • URI:如果没有,则表示这个 tag 描述的可选择版本在主 PlayList 的 EXT-X-STREAM-INF 中存在
      • TYPE:AUDIO and VIDEO
      • GROUP-ID:具有相同 ID 的 MEDIAtag,组成一组样式
      • LANGUAGE:译文的主要语言
      • NAME:译文的描述,若 LANGUAGE 属性存在则使用 LANGUAGE 指定的语言描述;
      • DEFAULT:YES 或是 NO,默认是 No,如果是 YES,则客户端会以这种选项来播放,除非用户自己进行选择
      • AUTOSELECT:YES 或是 NO,默认是 No,如果是 YES,则客户端会根据当前播放环境来进行选择(用户没有根据自己偏好进行选择的前提下);
    • 在版本 4 中出现;
  • #EXT-X-STREAM-INF:指定一个包含多媒体信息的 media URI 作为 Playlist,一般做 m3u8 的嵌套使用,只对紧跟后面的 URI 有效;
    • 格式为:#EXT-X-STREAM-INF:<attribute-list>
      • 常用属性如下
      • BANDWIDTH:带宽,必须有
      • PROGRAM-ID:该值是一个十进制整数,唯一地标识一个在 Playlist 文件范围内的特定的描述;一个 Playlist 文件中可能包含多个有相同 ID 的此 tag
      • CODECS:指定流的编码类型,不是必须的
      • RESOLUTION:分辨率
      • AUDIO:该值必须和 AUDIO 类别的 "EXT-X-MEDIA" 标签中 "GROUP-ID" 属性值相匹配
      • VIDEO:该值必须和 VIDEO 类别的 "EXT-X-MEDIA" 标签中 "GROUP-ID" 属性值相匹配
  • #EXT-X-DISCONTINUITY:当遇到该 tag 的时候说明以下属性发生了变化;
    • file format
    • number and type of tracks
    • encoding parameters
    • encoding sequence
    • timestamp sequence
  • #ZEN-TOTAL-DURATION:表示这个 m3u8 所含 ts 的总时间长度

【2.2】示例文件

单码率适配流

多码率适配流

包含多种比特率的 Master Playlist,该文件是一个实际使用中的顶级 m3u8 文件,该文件中定义了 http://example.com/low.m3u8、 http://example.com/mid.m3u8 等多个二级文件;顶级 m3u8 文件主要是做码率适配的,二级 m3u8 才是真正的切片文件,客户端会默认选择码率最高的请求,如果发现码率达不到,会请求降低码率的流,客户端拿到二级 m3u8 文件后,会继续请求其中的文件,从而进行播放;

【3】HLS 的 TS

参见,

参考资料

draft-pantos-http-live-streaming-18,链接:https://pan.baidu.com/s/1JQIds3oJmafnd85HeZ2HeQ 提取码:lar7 

draft-pantos-hls-rfc8216bis-04,链接:https://pan.baidu.com/s/1ODXUCRzY4R5XE1MghqVV4g 提取码:69zj 

参考致谢

本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。

【1】

【2】

【3】

上一篇:【网络通信 -- 直播】音视频流编码 -- AAC 基础
下一篇:【网络通信 -- 直播】音视频常见封装格式 -- MP4

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2025年03月21日 03时16分01秒