标签:在线 相对 average ffmpeg mamicode 解决 生成 保留 android
M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,既支持直播又支持点播,尤其在Android、iOS等平台最为常用。
下面是CCTV6直播播放地址:http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8的M3U8的文件列表:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:35232 #EXT-X-TARGETDURATION:10 #EXTINF:10.000, cctv6hd-1549272376000.ts #EXTINF:10.000, cctv6hd-1549272386000.ts #EXTINF:10.000, cctv6hd-1549272396000.ts #EXTINF:10.000, cctv6hd-1549272406000.ts #EXTINF:10.000, cctv6hd-1549272416000.ts #EXTINF:10.000, cctv6hd-1549272426000.ts
下面我们来分别说明一下相关的几个字段:
关于客户端播放M3U8的标准还有更多的讲究,下面我们来介绍一些:
在上面,我们提到了,一些上面例子没有出现的一些标签字段,下面我们针对一些额外的标签做一些补充说明:
HLS(全称:Http Live Streaming)是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部分,一是M3U8描述文件,二是TS媒体文件。
HLS的优势为:自适应码率流播(adaptive streaming)。效果就是客户端会根据网络状况自动选择不同码率的视频流,条件允许的情况下使用高码率,网络繁忙的时候使用低码率,并且能够自动在二者之间随意切换。这对移动设备网络状况不稳定的情况下保障流畅播放非常有帮助。实现方法是服务器端提供多码率视频流,并且在列表文件中注明,播放器根据播放进度和下载速度进行自动调整。
为什么要用 TS 而不是 MP4?这是因为两个 TS 片段可以无缝拼接,播放器能连续播放,而 MP4 文件由于编码方式的原因,两段 MP4 不能无缝拼接,播放器连续播放两个 MP4 文件会出现破音和画面间断,影响用户体验。而且如果要在一段长达一小时的视频中跳转,如果使用单个 MP4 格式的视频文件,并且也是用 HTTP 协议,那么需要代理服务器支持 HTTP range request 获取大文件中的一部分。这样的话,对于代理服务器的性能来说要求较高。而 HTTP Live Streaming 则只需要根据列表文件中的时间轴找出对应的 TS 片段下载即可,不需要 range request,对代理服务器的要求小很多。所有代理服务器都支持小文件的高效缓存。
将MP4文件转换成HLS(M3U8)命令行:
ffmpeg -re -i 好汉歌.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8
可以看到生成的M3U8及相应的ts文件:
查看一下生成的M3U8文件:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:19 #EXTINF:10.000000, output19.ts #EXTINF:10.000000, output20.ts #EXTINF:9.280000, output21.ts #EXTINF:4.120000, output22.ts #EXTINF:2.440000, output23.ts #EXT-X-ENDLIST
细心的人可能发现一个问题,就是生成的m3u8文件里只有最后的五个片段的信息。这是因为ffmpeg 默认的list size 为5,所以只获得最后的5个片段。为了解决这个问题,需要指定参数-hls_list_size 0,这样就能包含所有的片段。
下面是优化后的命令行:
ffmpeg -re -i 好汉歌.mp4 -c copy -f hls -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
这时,我们可以看到从output0.ts到output23.ts的文件列表了。
可能有人会发现,无论是优化之前的命令行,还是优化后的命令行都有一个参数-bsf:v h264_mp4toannexb,这个参数的作用是将MP4中的H.264数据转换成为H.264 AnnexB标准的编码,AnnexB标准的编码常见于实时传输流中。如果源文件为FLV、TS等可以作为直播传输流的视频,则不需要这个参数。
下面我们逐一介绍下使用FFmpeg生成HLS时还可以配置的其他参数。
start_number 参数用于设置M3U8列表中的第一片的序列数。
下面的例子中,我们使用start_number参数设置M3U8中的第一片序列书为100,命令行如下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -start_number 100 -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
输出的M3U8内容如下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:100 #EXTINF:3.000000, output100.ts #EXTINF:3.000000, output101.ts #EXTINF:3.000000, output102.ts #EXTINF:3.000000, output103.ts #EXTINF:3.000000, output104.ts #EXTINF:3.000000, output105.ts #EXTINF:3.000000, output106.ts #EXTINF:1.000000, output107.ts #EXT-X-ENDLIST
从输出可以看出,切片的第一片编号是100,上面的命令行参数的-start_number参数已生效。
hls_time参数用于设置M3U8列表中切片的duration。
下面的例子中,我们使用hls_time参数设置M3U8的TS文件的每一片时长为9秒左右。命令行如下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_time 9 -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
然后查看输出的M3U8内容如下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:9 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:9.000000, output0.ts #EXTINF:9.000000, output1.ts #EXTINF:4.000000, output2.ts #EXT-X-ENDLIST
可以看到TS的文件每一片的时常都是9秒左右,hls_time参数生效。
( 注意:hls_time设置后效果不一定准确,会受到关键帧大小及其他因素影响。)
hls_list_size参数用于为M3U8列表中的TS切片的个数。其中设置为0的时候,将包含所有。
这个命令,我们在第3节优化MP4转HLS文件的命令行时使用到了。
下面的例子中,我们使用hls_list_size参数设置只保留2片TS切片。命令行如下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_list_size 2 -bsf:v h264_mp4toannexb output.m3u8
查看输出的M3U8内容如下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:6 #EXTINF:3.000000, output6.ts #EXTINF:1.000000, output7.ts #EXT-X-ENDLIST
从输出的M3U8内容可以看出,在M3U8文件中只保留了2片TS的文件信息,可以看出hls_list_size设置生效了。
hls_base_url 参数用于为M3U8列表的文件路径设置前置基本路径参数,因为在FFmpeg中生成M3U8时写入的TS切片路径默认为M3U8生成的路径相同,但是实际上TS所存储的路径既可以为本地绝对路径,也可以为相对路径,还可以为网络路径,因此使用hls_base_url参数可以达到该效果,命令行如下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_base_url /Users/renhui/Desktop/test/ -bsf:v h264_mp4toannexb output.m3u8
查看输出的M3U8内容如下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:3 #EXTINF:3.000000, /Users/renhui/Desktop/test/output3.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output4.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output5.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output6.ts #EXTINF:1.000000, /Users/renhui/Desktop/test/output7.ts #EXT-X-ENDLIST
可以看到,TS的路径变为绝对路径了,使用ffplay output.m3u8播放,看到播放是能够正常播放的。这样就可以说明hls_base_url生效了。
标签:在线 相对 average ffmpeg mamicode 解决 生成 保留 android
原文地址:https://www.cnblogs.com/renhui/p/10351870.html