m3u8整理3--关于HLS之m3u8小结


***【在线视频教程】***

好文章,来自【福优学苑@音视频+流媒体】

    HLS,Http Live Streaming 是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部分,一是M3U8描述文件,二是TS媒体文件。


1、M3U8文件


   用文本方式对媒体文件进行描述,由一系列标签组成。

#EXTM3U
#EXT-X-TARGETDURATION:5
#EXTINF:5,
./0.ts
#EXTINF:5,
./1.ts

#EXTM3U:每个M3U8文件第一行必须是这个tag。


#EXT-X-TARGETDURATION:指定最大的媒体段时间长度(秒),#EXTINF中指定的时间长度必须小于或等于这个最大值。该值只能出现一次。


#EXTINF:描述单个媒体文件的长度。后面为媒体文件,如./0.ts 



在iOS device和mac上可以用http的方式进行分发,其中playlist标准为由m3u扩展而来的m3u8文件,媒体文件为MPEG2-TS或者AAC文件(audio only)。


m3u8文件有两种应用场景:


多码率适配流,

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000
http://example.com/low.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000
http://example.com/hi.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8

单码率适配流

#EXTM3U
#EXT-X-TARGETDURATION:5220
#EXTINF:5220,
http://media.example.com/entire.ts
#EXT-X-ENDLIST



国际标准组织对此的定义 rfc doc:

http://tools.ietf.org/html/draft-pantos-http-live-streaming-06

m3u8 文件是m3u文件的扩展。在该rfc中定义了扩展的关键字:

其中:

#EXT-X-TARGETDURATION

定义每个TS的最大的duration。

#EXT-X-MEDIA-SEQUENCE

定义当前m3u8文件中第一个文件的序列号,每个ts文件在m3u8文件中都有固定唯一的序列号,该序列号用于在MBR时切换码率进行对齐。

#EXT-X-KEY


定义加密方式和key文件的url,用于取得16bytes的key文件解码ts文件。


属性:

METHOD

URL

#EXT-X-PROGRAM-DATE-TIME

第一个文件的绝对时间


#EXT-X-ALLOW-CACHE


是否允许cache。

#EXT-X-ENDLIST

表明m3u8文件的结束。live m3u8没有该tag。

#EXT-X-STREAM-INF

属性:

BANDWIDTH              指定码率

PROGRAM-ID            唯一ID

CODECS                    指定流的编码类型

#EXT-X-DISCONTINUITY

当遇到该tag的时候说明以下属性发生了变化:

file format 

number and type of tracks

encoding parameters

encoding sequence

timestamp sequence


#EXT-X-VERSION             该属性用不用都可以,可以没有




M3U8分顶级M3U8和二级M3U8, 顶级M3U8主要是做多码率适配的, 二级M3U8才是真正的切片文件,


客户端默认会首先选择码率最高的请求,如果发现码率达不到,会请求郊低码率的流



一个实际使用中的顶级M3U8文件如下 :

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=358400
11.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=972800
22.m3u8



上面顶级M3U8文件中又定义了 11.m3u8 和 22.m3u8 两个二级文件,客户端会选择其中一个获取其内容。


二级M3U8文件内容如下:

#EXTM3U
#EXT-X-VERSION:1
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:3,
1-4.ts
#EXTINF:8,
1-6.ts
#EXTINF:8,
1-8.ts
#EXTINF:8,
1-10.ts
#EXTINF:8,
1-12.ts
#EXTINF:8,
1-14.ts
#EXTINF:8,
1-16.ts
#EXTINF:9,
1-18.ts
#EXTINF:6,
1-20.ts
#EXTINF:8,
1-22.ts
#EXTINF:9,
1-24.ts
#EXTINF:3,
1-26.ts
#EXT-X-ENDLIST



客户端拿到上面的二级M3U8文件后,会继续请求里面的文件,这时就可进行播放了。


上面讲解的是点播的情况,直播的情况,M3U8文件里面会有属性告诉是直播,客户端会定时来请求新的M3U8文件。



//HLS实现点播和直播时,M3U8文件的不同


1.问题描述

最近做一个转码切片播放测试,使用HLS(HTTP Live Streaming)来做直播, 每个TS分片时间为10s,根据TS分片文件生成以下live m3u8文件


#EXTM3U
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:10
#EXTINF:10
hls/1.ts
#EXTINF:10
hls/2.ts
#EXTINF:10
hls/3.ts
#EXTINF:10
hls/4.ts
#EXTINF:10
hls/5.ts
#EXTINF:10
hls/6.ts
#EXTINF:10
hls/7.ts
#EXTINF:10
hls/8.ts
#EXTINF:10
hls/9.ts
#EXTINF:10
hls/10.ts

复制代码

 将上述m3u8文件保存为live.m3u8,放到Apache文档目录下,用VLC播放以下网址:


http://localhost/live.m3u8

测试发现,开始播放的第一个文件不是1.ts,多次测试后发现:


只要列表中的文件超过三个,播放的总是列表中的最后三个文件

2.问题解决

很悲惨的是,上网搜索后,没有找到任何有效的信息,有个哥们遇到同样的情况,解决后有没有将经验分享出来。


向一位同事请教后,同事说,这是有可能的,因为live m3u8文件列表是需要实时更新的,我们做测试的话,可以先在最后面加上#EXT-X-ENDLIST,这个方法经测试有效,但这样已经不是live m3u8模式


再次上网搜索后,确认,终于找到一篇live m3u8说明

Live Playlist (Sliding Window)
For live sessions, the index file is updated by removing media URIs from the file as new media files are created and made available.
Important: The EXT-X-ENDLIST tag is not present in the Live playlist, indicating that new media files will be added to the index file as they become available.
See Listing 3 for an example live playlist as it would appear at the beginning of a session.
Listing 3 Live Playlist at the beginning of a session.
复制代码
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10,
fileSequence1.ts
#EXTINF:10,
fileSequence2.ts
#EXTINF:10,
fileSequence3.ts
#EXTINF:10,
fileSequence4.ts
#EXTINF:10,
fileSequence5.ts

复制代码

The EXT-X-MEDIA-SEQUENCE tag value MUST be incremented by 1 for every media URI that is removed from the playlist file. Media URIsmust be removed from the playlist file in the order that they appear in the playlist. The updated index file presents a moving window into a continuous stream. This type of session is suitable for continuous broadcasts.


Here's the same playlist after it has been updated with new media URIs:


Listing 4 Live Playlist after updating the media URIs.

复制代码
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:2
#EXTINF:10,
fileSequence2.ts
#EXTINF:10,
fileSequence3.ts
#EXTINF:10,
fileSequence4.ts
#EXTINF:10,
fileSequence5.ts
#EXTINF:10,
fileSequence6.ts
复制代码

3.live m3u8更新规则

live m3u8文件列表需要不断更新,更新规则:


移除一个文件播放列表中靠前的(认为已播放的)文件

不断更新EXT-X-MEDIA-SEQUENCE标签,以步长为1进行递增

4.实验

写了一个生成live m3u8的小程序,进行测试


Usage:

m3u8_gen.exe start_num list_count duration filename.m3u8 [prefix]

使用示例:


m3u8_gen.exe 1 3 10 live.m3u8 hls/

生成live.m3u8文件为

复制代码
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:10    
#EXTINF:10
hls/1.ts
#EXTINF:10
hls/2.ts
#EXTINF:10
hls/3.ts

复制代码

写一个BAT脚本,每10s循环更新live.m3u8文件


复制代码

@echo off


for /l %%i in (1,1,420) do (

echo m3u8_gen.exe %%i 3 10 live.m3u8 hls/

m3u8_gen.exe %%i 3 10 live.m3u8 hls/

call :SLEEP 10000

)


::延时函数实现

:SLEEP

ping 192.168.11.1 -n 1 -w %1 > nul 

复制代码

经VLC播放测试正常!!



//直播过程中 需要保持实时更新m3u8 文件,也就是一个paylist,服务器如果是8秒一个片,那么每隔5秒就得更新文件,如果之前是

#EXTM3U
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:912
http://10.10.2.167/t00000000000086/test912.ts
http://10.10.2.167/t00000000000086/test913.ts
http://10.10.2.167/t00000000000086/test914.ts

由于是实时视频,因此不需要加  endlist


文件中总是保存最新三个ts文件,以滑动窗口的方式进行更新,序号如下     (3个文件)


1,2,3


2,3,4


4,5,6


#EXT-X-MEDIA-SEQUENCE:1  ,下一次就从 2 开始 依次类推,

客户端也会实时的去请求该  playlist.m3u8,如果有改变 就需要下载该文件,可以查看文件的最后修改日期 


直播过程中,服务器切片ts文件,需要每一个文件的开始是I帧,如何确定


这样就不能保证时间,m3u8文件list的duration



//=======================================================================


为什么会使用ts 封装,而不是MP4,因为 ts 可以无缝拼接,MP4文件不能,而且编码必须是h264 和aac


hls协议中m3u8文件tag总结

//hls 推流过程 ;   视频源 推送流给服务器的时候,用的是http协议的 post方法,post的是ts文件


1.  引言

    本文档主要描述了“如何传输无边界多媒体数据流的”的协议的规范和实现细节。

    该协议支持加密媒体流和统一流得多版本自适应(多码流自适应)。在该协议下,媒体数据在生成之后会立即进行传输,进而保证其具有接近实时播放的效果。数据的传输建立在HTTP协议的基础之上。


 

2.  总结


    任意多媒体流将由只想某播放列表文件的URI表示,该文件由一个排序的媒体URI列表和信息标签组成。每个媒体URI只想一个连续的流的文件切片。


在播放过程中,客户端首先获取播放列表文件,进而获取播放列表中描述的文件片并播放它。客户端会不断地重新加载播放列表文件。


本文档中部分关键词的描述可参考RFC 2119。


 


3.  播放列表文件


3.1 引言


         播放列表文件是扩展M3U播放列表。本文档通过定义额外的标签扩展了M3U文件格式。

   


         一个M3U播放列表文件包含多个独立的行。每一行由一个LF标记结尾或由一个CR+LF标记结尾。每行的内容可以是一个URI,空行或者是以”#”开头的注释。空白行将被忽略。空格符将不会被展示出来,除非某元素明确的制定它。


 

         一个URI行指定了一个媒体文件或者另外一个播放列表。(参阅3.3.8节)



         URIs地址可以使相对地址。该相对路径的定位地址必须与播放列表文件所在目录一致。


         由”#”开头的行可以是注释或者标签。一般标签以”#EXT”开头,其余的行均被视为注释。


          播放列表的总时长应该是其所包含媒体文件的时长之和。


          M3U文件中,以.m3u8结尾,或其http头中”Content-Type”字段为” application/vnd.apple.mpegurl”会以UTF-8编码,而以”m3u” 或其http对应字段为” "audio/mpegurl”会以US-ASCII编码。播放列表文件必须以上面某一匹配对对应。


          扩展的M3U文件格式定义了两个标签:EXTM3U和EXTINF。扩展的M3U文件通过在第一行中加入” #EXTM3U” 与基本的M3U文件进行区分。


         


3.2 属性列表


         某些扩展的M3U标签的值是一个由逗号作为分隔符的属性列表,属性列表中不应出现空格。其语法如:


         AttributeName=AttributeValue


        


         其中属性名不需要被引号包含,它是一个有字符[A –Z ] 和‘-‘组成的字符串。而属性值得取值范围如下:


l  十进制整型数:由[ 0 –9 ]组合成的10进制整数。


l  十六进制整数:[ 0 –9 ] 和 [A –F],以0x或0X开头


l  十进制浮点数:[ 0 –9 ] 和‘ . ‘


l  字符串:引号包含,不可使用linefeed(0xA,换行) carriage-return(0xD, 回车) 和双引号(0x22)。需要使用这些特殊符号时,需要转义。


l  枚举字符串:由属性定义的一个取值集合,表现形式为一个无引号字符串,其值不能包括双引号、逗号和空格。


l  十进制表示的分辨率: 宽度X高度,单位为像素



属性值得类型由给定的属性定义。在一个属性列表中,属性名应该仅出现一次。客户端在实现的过程中,需要忽略无法识别的属性名/属性值对。尤其对于枚举类型,若其属性名可识别,但其属性值不可识别,则也需要忽略。


 


        


3.3 标准标签


3.3.1 EXTM3U


扩展的M3U文件与基本的M3U的区别在第一行,其值必须为标签 #EXTM3U。这个标签在媒体播放列表和主播放列表中均应该被包含。形式如下:


 


#EXTM3U


 


3.3.2 EXTINF


该标签指定媒体文件片的时长。其作用范围仅限于它后面的媒体文件片,其后必须为一个媒体文件片的资源地址(URI)。每个文件片均需前置一个EXTINF。形式如下:


#EXTINF:<duration>,<title>


 


Duration的取值可以是:十进制整型或十进制浮点数,采用近似取整。若协议版本低于3,则该值必须为整数。协议版本不小于3时,其值使用浮点数表示。


Title部分用于对其后文件片添加一些可读的描述信息。


 


3.4 新标签


本节中我们将展示本文档中新定义的标签。


 


3.4.1 EXT-X-BYTERANGE


         本标签标明文件片为URI对应文件资源的一个子集。其仅作用于其后的下一个媒体文件URI 。形式如下:


         #EXT-X-BYTERANGE:<n>[@<o>]


         其中n为整数,表示子集的字节数。o为可选项,标明子集的起始位置,相当于从资源开始出计算的偏移量。若o未定义,则其开始位置为上一个子集的结束位置下一个字节。


 


         当o未定义的时候,其上一个文件资源必须是同一文件的子集,且其不能为文件列表中的第一个文件片。


         本标签出现在4以上版本,且不应出现在主播放列表中。


 


3.4.2 EXT-X-TARGETDURATION


         本标签的值应大于等于文件列表中最大文件片的时长,其只在媒体播放列表中出现一次,作用域为整个媒体文件列表,它不可出现在主播放列表中,形式如下:


         #EXT-X-TARGETDURATION:<max-duration>


 


3.4.3 EXT-X-MEDIA-SEQUENCE


         播放列表中的每个文件片均由唯一的一个整型序列号,其值顺序加1递增。本标签的值为当前播放列表中第一个文件片的序列号。形式如下:


         #EXT-X-MEDIA-SEQUENCE:<number>


 


         本标签需出现在第一个文件片之前,且不能出现在主播放列表中。当媒体播放列表不包含改标签时,其首个文件片的序列号被视为0 。


         文件资源定位符中可不出现序列号。


 


3.4.4 EXT-X-KEY


         媒体文件片可能被加密,而本标签表明如何对其进行解密。它作用于其后所有的文件片,直到下一个同名标签(with the same KEYFORMAT)的出现。两个以上的EXT-X-KEY可能会将不同的KEYFORMAT属性作用于同一文件片,它们必须被解析为相同的key。


 


#EXT-X-KEY:<attribute-list>


 


以下是一些属性:


METHOD : 枚举值,标明加密方法,必须。


u  NONE ,未加密,当METHOD取值为NONE时,以下属性不得出现 URI、IV、KEYFORMAT、KEYFORMATVERSION


u  AES-128,使用128位密钥和PKCS7补齐的AES算法。该取值下,URI属性必须出现,IV属性可选。


u  SAMPLE-AES ,标明文件片中包含使用AES-128加密的媒体取样,如audio或video,这些取样的加密和封装方式与媒体文件的编码和文件片类型有关。


客户端遇到无法识别的METHOD,放弃解密。


 


URI : 引号包含的字符串,其URI指明获取密钥的地址,出METHOD取值为NONE时,该属性为必须。


 


Iv:   十六进制整数,指明密钥使用的初始向量。


 


KEYFORMAT: 引号包含的字符串,指明密钥在URI中的表现形式。该属性可选,当该属性不出现时,其具有一个默认值”identity”。


 


KEYFORMATVERSION:引号包含的字符串,其内容为斜杠分隔的整数,如”1/3”,当有多个KEYFORMAT时,指明实例的版本,不出现表示值为1 。


 


3.4.5 EXT-X-PROGRAM-DATE-TIME


         标明其后一个文件片第一个取样的日期和事件,形式如下:


         #EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ>


         示例:#EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00


 


3.4.6 EXT-X-ALLOW-CACHE


         作用于全局文件片,表明客户端是否缓存文件资源。


         #EXT-X-ALLOW-CACHE:<YES|NO>


 


3.4.7 EXT-X-PLAYLIST-TYPE


         标明播放列表的类型信息,作用于整个播放列表文件,可选的。


         #EXT-X-PLAYLIST-TYPE:<EVENT|VOD>


 


3.4.8 EXT-X-ENDLIST


         标明其后再没有文件片,可以出现在播放列表文件的任意位置,但只能出现一次。


 


3.4.9 EXT-X-MEDIA


         用于对统一内容会有不同翻译的媒体播放列表。属性有点多,而且感觉不是很重要,不翻了,自己看吧。


http://tools.ietf.org/html/draft-pantos-http-live-streaming-13


 


3.4.10 EXT-X-STREAM-INF


         用于指定一个变化的流(多码流)。其属性提供了该可变留的一些信息。其标明它后面的URI是该可变流的一个可选项。


         该标签不应出现在媒体文件播放列表中。


         #EXT-X-STREAM-INF:<attribute-list>


<URI>


 


其属性定义如下:


BANDWIDTH : 指定码率的整数。应该为URI中文件片码流的上限,必须。


 


CODECS: 引号包含的字符串,内容为逗号分割的格式列表,每个格式标明一个媒体播放列表中的文件片的媒体取样类型。该属性属于推荐属性(should,但是不加好像也没事)。


 


RESOLUTION: 十进制坐标,标明资源的分辨率。


 


PROGRAM-ID: 实际使用中用到过,但是不知道其作用,文档中也没写。


 


还有一些其他的属性,去看英文吧。


 


3.4.11 EXT-X-DISCONTINUITY


         标明前后两个文件片编码方式不连续,比如:


         文件类型,track的类型和数量,编码参数,编码序号,时间戳序号等


         #EXT-X-DISCONTINUITY


         其不应出现在主播放列表中。实际中还没发现它的用处。


 


3.4.12 EXT-X-DISCONTINUITY-SEQUENCE


         该标签允许多码流不同码流之间同步,并能够使多个流在它们的媒体播放列表文件中加入EXT-X-DISCONTINUITY标签。


         #EXT-X-DISCONTINUITY-SEQUENCE:<number>


         其中number是一个十进制证书。不连续的文件片序列号必须是递增的。


         一个媒体播放列表不能包含多于一个EXT-X-DISCONTINUITY-SEQUENCE标签。如果列表文件中不包含该标签,则文件列表中第一个文件片的不连续序列号标记为0。


         本标签必须出现在第一个文件片之前,且必须出现在EXT-X-DISCONTINUITY标签前,且只能出现在媒体播放文件列表中 。


         如果媒体列表文件中EXT-X-PLAYLIST-TYPE的值为VOD或者EVENT,则不可使用本标签。


 


3.4.13 EXT-X-I-FRAMES-ONLY


本选项标明播放列表文件中文件片都描述了一个I关键帧。本标签作用于整个播放列表文件。


#EXT-X-I-FRAMES-ONLY


在拥有 该标签的播放列表文件中,文件片的时长是从某一个I帧开始到另外一个I帧的出现或者文件列表末尾。


包含关键帧资源的媒体文件必须以传输流PAT/PMT开始,或者与EXT-X-MAP标签一起出现。


包含有EXT-X-BYTERANGE标签的I帧分片的字节范围不能包含PAT/PMT。本标签只应该出现在媒体文件列表中。


 


3.4.14 EXT-X-MAP


         本标签用于说明如何获取用于解析媒体文件片的头部信息,比如传输流 PAT/PMT 或者WebVTT头。


         它作用于其后出现的所有文件片,直到文件末尾或EXT-X-DISCONTINUITY出现。


         #EXT-X-MAP:<attribute-list>


 


         选项情况如下:


         URI:”string” ,指明包含头部信息的资源的URI,必须的。


        


        


         BYTERANGE:”string”,指明URI资源的一定字节范围,可选的。不填写该属性时,指代URI所指的全部资源。


 


         这个标签的使用情景:当播放列表文件中的第一个文件片在资源的开头部分没有和PAT/PMT紧随,且文件片带有EXT-X-I-FRAMES-ONLY标签。该标签不应出现在主列表文件中。


 


3.4.15 EXT-X-I-FRAME-STREAM-INF


         本标签标明媒体播放列表文件包含多媒体内容的I-frame。本标签单独使用,不依赖于任何资源的URI。


         #EXT-X-I-FRAME-STREAM-INF:<attribute-list>


本标签支持所有EXT-X-I-FRAME-STREAM-INF支持的属性,并额外支持一个URI属性。


 


3.4.16 EXT-X-INDEPENDENT-SEGMENTS


         本标签标明,一个分片可以独立解码而不需要其他分片的信息。本选项作用于列表文件中的所有项目。


         #EXT-X-INDEPENDENT-SEGMENTS


         本选项可选,但只能使用一次,当其放置在主列表文件中时,其作用于所有播放列表文件中的每一个文件片。貌似很有用啊。


 


3.4.17 EXT-X-INDEPENDENT-SEGMENTS


         没太看懂他的作用,有时间测试了之后再翻译这段。


 


3.4.18 EXT-X-VERSION


         本标签标明播放列表文件兼容版本。


         #EXT-X-VERSION:<n>

好文章,来自【福优学苑@音视频+流媒体】
***【在线视频教程】***