HLS(HTTP Live Streaming) 协议
HLS 流媒体传输协议相关笔记
HLS(HTTP Live Streaming) 是由苹果公司提出的流媒体传输协议,HLS 基于 HTTP 协议实现,传输内容包括两部分:一是 M3U8 列表文件,二是 TS 媒体文件。
HLS 是新一代流媒体传输协议,其基本实现原理为将一个大的媒体文件进行分片,将该分片文件资源路径记录于 m3u8 文件(即 playlist)内,其中附带一些额外描述(比如该资源的多带宽信息等)用于提供给客户端。客户端依据该 m3u8 文件即可获取对应的媒体资源,进行播放。
RFC8216(HLS)
RFC8216 - HTTP Live Streaming
https://datatracker.ietf.org/doc/rfc8216/
HLS 优势
HLS 最初用于 MacOS 和 IOS 的音视频传输,由于简单高效,应用越来越广泛。
HLS 具有以下优势:
- 动态码率自适应
- 基于 HTTP 协议,兼容性更好
- 跨 PC, Android, IOS 平台,IOS 平台原生支持。
- 对 CDN 更友好,如果使用 RTMP 传输视频还需要基于 nginx-rtmp 模块做开发,使用 HLS 则只要支持 HTTP 协议即可。
M3U8文件
m3u8 文件格式详解
https://www.jianshu.com/p/e97f6555a070
M3U8 就是 UTF-8 编码格式的 M3U 文件。M3U 和 M3U8 都是苹果的 HLS 协议的基础。
M3U 文件是记录了一个索引的纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
m3u8 文件实质是一个播放列表(playlist),其可能是一个 媒体播放列表(Media Playlist), 或者是一个 主播放列表(Master Playlist), 但无论是哪种播放列表,其内部文字使用的都是 utf-8 编码。
主播放列表M3U8/一级索引(多码率适配)
当 m3u8 作为主播放列表(Master Playlist)时,其内部提供的是同一份媒体资源的多份流列表资源(Variant Stream)。其格式如下所示:
#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/二级索引
当 m3u8 文件作为媒体播放列表(Meida Playlist)时,其内部信息记录的是一系列媒体片段资源,顺序播放该片段资源,即可完整展示多媒体资源。其格式如下所示:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:20
#EXTINF:19.799999237060547,
http://127.0.0.1:8080/file/video/video1.ts
#EXTINF:19.959999084472656,
http://127.0.0.1:8080/file/video/video2.ts
#EXTINF:19.959999084472656,
http://127.0.0.1:8080/file/video/video3.ts
#EXT-X-ENDLIST
多码率适配播放流程
在多码率适配的场景下的播放流程:
1、先请求主播放列表 m3u8 文件,可以当做是一级 m3u8 文件,或者说一级索引文件。
2、然后再根据带宽情况请求具体码率的 媒体播放列表 m3u8 文件,即二级 m3u8 文件,或者说二级索引文件。
3、然后根据具体码率的 m3u8 媒体播放列表文件中的 ts 地址顺序请求播放媒体。
请求m3u8文件
有两种请求 m3u8 播放列表的方法:
一是通过 m3u8 的 URI 进行请求,则该文件必须以 .m3u8 或 .m3u 结尾;
二是通过 HTTP 进行请求,则请求头 Content-Type
必须设置为 application/vnd.apple.mpegurl
或者 audio/mpegurl
直播点播实现
对于点播来说,客户端只需按顺序下载二级 m3u8 文件中的片段资源,依次进行播放即可。
对于直播来说,客户端需要定时重新请求二级 m3u8 文件,看是否有新的片段数据需要进行下载并播放。
一、点播
客户端在播放 VOD 模式的视频时其实只需要下载一次一级 index 文件(主播放列表M3U8)和二级 index 文件(媒体播放列表M3U8)就可以得到所有 ts 文件的下载地址,除非客户端进行比特率切换,否则无需再下载任何 index 文件,只需顺序下载 ts 文件并播放就可以了。
二、直播
Live 模式下略有不同,因为播放的同时,新 ts 文件也在被生成中,所以客户端实际上是下载一次二级 index 文件,然后下载 ts 文件,再下载二级 index 文件(这个时候这个二级 index 文件已经被重写,记录了新生成的 ts 文件的下载地址),再下载新 ts 文件,如此反复进行播放。
M3U8文件格式
播放列表(Playlist,也即 m3u8 文件) 内容需严格满足规范定义所提要求。
一些主要规范:
m3u8 文件必须以 utf-8 进行编码,不能使用 Byte Order Mark(BOM)字节序, 不能包含 utf-8 控制字符(U+0000 ~ U_001F 和 U+007F ~ u+009F)。
m3u8 文件的每一行要么是一个 URI,要么是空行,要么就是以 #
开头的字符串。不能出现空白字符,除了显示声明的元素。
m3u8 文件中以 #
开头的字符串要么是注释,要么就是标签。标签以 #EXT
开头,大小写敏感。
属性
某些特定的标签的值为属性列表。标签后面的属性列表以逗号 ,
作为分隔符,分离出多组不带空格的 k=v
对。k=v
对的语法格式为:AttributeName=AttributeValue
其中:
属性名 AttributeName 是由 [A..Z],[0..9]
和 -
组成的不带引号的字符串。因此,属性 AttributeName 只能使用大写字母,不能使用小写字母,并且 AttributeName 和 = 中间不能有空格,同理,= 和 AttributeValue 之间也不能有空格。
属性值 AttributeValue 只能取以下类型:
- 十进制整型(decimal-interger):由
[0..9]
之间组成的十进制不带引号的字符串,范围为0 ~ 2^64
(18446744073709551615),字符长度为 1 ~ 20 之间。 - 十六进制序列:由
[0..9]
和[A..F]
且前缀为0x
或0X
组合成的不带引号的字符串。其序列的最大长度取决于他的属性名AttributeNames。 - 带符号十进制浮点型(signed-decimal-floating-point):由
[0..9]
,-
和.
组合成的不带引号的字符串。 - 字符串(quoted-string):由双引号包裹表示的字符串。其中,0xA,0xD 和 双引号”不能出现在该字符串中。该字符串区分大小写。
- 可枚举字符串(enumerated-string):由 AttributeName 显示定义的一系列不带引号的字符串。该字符串不能包含双引号”,逗号,和空白字符。
- decimal-resolution:由字符
x
进行隔离的两个十进制整型数。第一个整型表示水平宽度大小,第二个整型数表示垂直方向高度大小(单位:像素)。
标签
标签用于指定 m3u8 文件的全局参数或在其后面的切片文件/媒体播放列表的一些信息。
标签的类型可分为五种类型:基础标签(Basic Tags),媒体片段标签(Media Segment Tags),媒体播放列表标签,主播放列表类型标签 和 媒体或主播放列表标签。
m3u8媒体切片
m3u8 文件媒体片段的表示方法:
m3u8 文件中,媒体片段可以采用全路径表示:
#EXTINF:10.0,
http://example.com/movie1/fileSequenceA.ts
这样,获取资源片段的路径就是 m3u8 文件内指定的路径,即:http://example.com/movie1/fileSequenceA.ts
m3u8 文件中,媒体片段还可以使用相对路径表示:
#EXTINF:10.0,
fileSequenceA.ts
这表示片段文件的路径是相对于 m3u8 文件路径的,即假设当前 m3u8 的路径为:https://127.0.0.1/hls/m3u8 那么,片段文件 fileSequenceA.ts 的路径即为:https://127.0.0.1/hls/fileSequenceA.ts
尽管可以在 m3u8 文件中使用绝对路径指定媒体片段资源路径,但是更好的选择是使用相对路径。相对路径相较于绝对路径更轻便,同时是相对于 m3u8 文件的 URL。相比之下,绝对路径增加了 m3u8 文件内容(更多字符),增大了文件内容,同时也增大了网络传输量。
每个切片的码率(bit rate) 就是切片的大小除以它对应的时长(EXTINF 指定的时长)。
M3U8标签
基础标签
基础标签(Basic Tags):可同时适用于媒体播放列表(Media Playlist)和主播放列表(Master Playlist)。
#EXTM3U
#EXTM3U
表明该文件是一个 m3u8 文件。每个 M3U 文件必须将该标签放置在第一行。
#EXT-X-VERSION
HLS版本
#EXT-X-VERSION
表示 HLS 的协议版本号,该标签与流媒体的兼容性相关。该标签为全局作用域,用于整个 m3u8 文件;每个 m3u8 文件内最多只能出现一个该标签定义。如果 m3u8 文件不包含该标签,则默认为协议的第一个版本。
媒体切片标签
媒体片段类型标签(Media Segment Tags):每个切片 URI 前面都有一系列媒体片段标签对其进行描述。有些片段标签只对其后切片资源有效;有些片段标签对其后所有切片都有效,直到后续遇到另一个该标签描述。媒体片段类型标签不能出现在主播放列表(Master Playlist)中。
#EXTINF
分片时长
#EXTINF
表示其后 URL 指定的媒体片段时长(单位为秒)。每个 URL 媒体片段之前必须指定该标签。该标签的使用格式为:
#EXTINF:<duration>,[<title>]
其中:duration
可以为十进制的整型或者浮点型,其值必须小于或等于 #EXT-X-TARGETDURATION
指定的值。
注:建议始终使用浮点型指定时长,这可以让客户端在定位流时,减少四舍五入错误。但是如果兼容版本号 EXT-X-VERSION 小于 3,那么必须使用整型。
媒体播放列表标签
媒体播放列表类型标签:媒体播放列表标签为 m3u8 文件的全局参数信息。
这些标签只能在 m3u8 文件中至多出现一次。
媒体播放列表(Media Playlist)标签不能出现在主播放列表(Master Playlist)中。
#EXT-X-TARGETDURATION
分片最大时长
#EXT-X-TARGETDURATION
表示每个视频分段最大的时长(单位秒)。
该标签为必选标签。
其格式为:
#EXT-X-TARGETDURATION:<s>
其中:参数 s 表示目标时长(单位:秒)。#EXTINF
中指定的时间长度必须小于或等于这个最大值。该值只能出现一次。
#EXT-X-MEDIA-SEQUENCE
分片序号
#EXT-X-MEDIA-SEQUENCE
表示播放列表第一个 URL 片段文件的序列号。
每个媒体片段 URL 都拥有一个唯一的整型序列号。
每个媒体片段序列号按出现顺序依次加 1。
如果该标签未指定,则默认序列号从 0 开始。
媒体片段序列号与片段文件名无关。
其格式为:
#EXT-X-MEDIA-SEQUENCE:<number>
其中:参数 number 即为切片序列号。
#EXT-X-PLAYLIST-TYPE
直播/点播
#EXT-X-PLAYLIST-TYPE
表明流媒体类型。全局生效。
该标签为可选标签。
其格式为:
#EXT-X-PLAYLIST-TYPE:<type-enum>
其中:type-enum 可选值如下:
VOD
即 Video on Demand,表示该视屏流为点播源,因此服务器不能更改该 m3u8 文件;EVENT
表示该视频流为直播源,因此服务器不能更改或删除该文件任意部分内容(但是可以在文件末尾添加新内容)。
注:VOD 文件通常带有 EXT-X-ENDLIST 标签,因为其为点播源,不会改变;而 EVEVT 文件初始化时一般不会有 EXT-X-ENDLIST 标签,暗示有新的文件会添加到播放列表末尾,因此也需要客户端定时获取该 m3u8 文件,以获取新的媒体片段资源,直到访问到 EXT-X-ENDLIST 标签才停止)。
#EXT-X-ENDLIST
结束标识
#EXT-X-ENDLIST
表明 m3u8 文件的结束。
该标签可出现在 m3u8 文件任意位置,一般是结尾。
其格式为:
#EXT-X-ENDLIST
主播放列表标签
主播放列表(Master Playlist)定义了备份流,多语言翻译流和其他全局参数。
主播放列表标签绝不能出现在媒体播放列表(Media Playlist)中。
#EXT-X-STREAM-INF
#EXT-X-STREAM-INF
该属性指定了一个备份源。该属性值提供了该备份源的相关信息。
其格式为:
#EXT-X-STREAM-INF:<attribute-list>
<URI>
其中:URI
指定的 m3u8 媒体播放列表携带了该标签指定的翻译备份源。URI 为必选参数。
EXT-X-STREAM-INF
标签的参数属性列表有如下选项:
BANDWIDTH
该属性为每秒传输的比特数,也即带宽。代表该备份流的巅峰速率。
该属性为必选参数。CODECS
双引号包裹的包含由逗号分隔的格式列表组成的字符串。
每个 EXT-X-STREAM-INF 标签都应当携带 CODECS 属性。RESOLUTION
该属性描述备份流视屏源的最佳像素方案。
该属性为可选参数,但对于包含视屏源的备份流建议增加该属性设置。
媒体或主播放列表标签
这些标签可同时设置于主播放列表(Master Playlist)和媒体播放列表(Media Playlist)中。
但是对于在主播放列表中设置了的标签,不应当再次设置在主播放列表指向的媒体播放列表中。
同时出现在两者播放列表的相同标签必须具备相同的值。这些标签在播放列表中不能出现多次(只能使用一次)。
上一篇 RTMP
下一篇 群晖NAS使用笔记
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: