关于HLS之m3u8小结

HLSHttp 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文件列表需要不断更新,更新规则:

  1. 移除一个文件播放列表中靠前的(认为已播放的)文件
  2. 不断更新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 推流过程 ;   视频源 推送流给服务器的时候,用的是http协议的 post方法,post的是ts文件





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值