一、M3U8 格式标准介绍

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

下面我们来分别说明一下相关的几个字段:

  • EXTM3U:这个是M3U8文件必须包含的标签,并且必须在文件的第一行,所有的M3U8文件中必须包含这个标签。
  • EXT-X-VERSION:M3U8文件的版本,常见的是3(目前最高版本应该是7)。
  • EXT-X-TARGETDURATION:该标签指定了媒体文件持续时间的最大值,播放文件列表中的媒体文件在EXTINF标签中定义的持续时间必须小于或者等于该标签指定的持续时间。该标签在播放列表文件中必须出现一次。
  • EXT-X-MEDIA-SEQUENCE:M3U8直播是的直播切换序列,当播放打开M3U8时,以这个标签的值作为参考,播放对应的序列号的切片。
  • EXTINF:EXTINF为M3U8列表中每一个分片的duration,如上面例子输出信息中的第一片的duration为10秒。在EXTINF标签中,除了duration值,还可以包含可选的描述信息,主要为标注切片信息,使用逗号分隔开。

关于客户端播放M3U8的标准还有更多的讲究,下面我们来介绍一些:

  1. 分片必须是动态改变的,序列不能相同,并且序列必须是增序的。
  2. 当M3U8没有出现EXT-X-ENDLIST标签时,无论这个M3U8列表中有多少分片,播放分片都是从倒数第三片开始播放,如果不满三片则不应该播放。当然如果有些播放器做了特别定制了,则可以不遵照这个原则。
  3. 以播放当前分片的duration时间刷新M3U8列表,然后做对应的加载动作。
  4. 前一片分片和后一片分片有不连续的时候,播放可能会出错,那么需要X-DISCONTINUTY标签来解决这个错误。
  5. 如果播放列表在刷新之后与之前的列表相同,那么在播放当前分片duration一半的时间内在刷新一次。

在上面,我们提到了,一些上面例子没有出现的一些标签字段,下面我们针对一些额外的标签做一些补充说明:

  • EXT-X-ENDLIST:若出现EXT-X-ENDLIST标签,则表明M3U8文件不会再产生更多的切片,可以理解为该M3U8已停止更新,并且播放分片到这个标签后结束。M3U8不仅仅是可以作为直播,也可以作为点播存在,在M3U8文件中保存所有切片信息最后使用EXT-X-ENDLIST结尾,这个M3U8即为点播M3U8。EXT-X-ENDLIST标签可能会出现在播放列表文件的任何地方,但是不能出现两次或以上。
  • EXT-X-STREAM-INF:EXT-X-STREAM-INF标签出现在M3U8时,主要是出现在多级M3U8文件中时,例如M3U8中包含子M3U8列表,或者主M3U8中包含多码率M3U8时;该标签后需要跟一些属性,下面就来逐一说明一下这些属性:
    1. BANDWIDTH:BANDWIDTH的值为最高码率值,当播放EXT-X-STREAM-INF下对应的M3U8时占用的最大码率(必要参数)。
    2. AVERAGE-BANDWIDTH:AVERAGE-BANDWIDTH的值为平均码率值,当播放EXT-X-STREAM-INF下对应的M3U8时占用的平均码率。(可选参数)。
    3. CODECS:CODECS的值用于声明EXT-X-STREAM-INF下面对应M3U8里面的音视频编码、视频编码的信息(可选参数)。
    4. RESOLUTION:M3U8中视频的宽高信息描述(可选参数)。
    5. FRAME-RATE:子M3U8中的视频帧率(可选参数)。

二、HLS 与 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,对代理服务器的要求小很多。所有代理服务器都支持小文件的高效缓存。

CSDN站内私信我,或文末扫马免费领取最新最全C++音视频学习提升资料,内容包括(C/C++,Linux 服务器开发,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)等等。

三、FFmpeg转HLS文件(M3U8)实战

1. FFmpeg转MP4为HLS(M3U8)文件

将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时还可以配置的其他参数。

四、FFmpeg 转 HLS (M3U8) 文件命令参数

1. start_number 参数

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参数已生效。

2. hls_time 参数

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_flags的子参数split_by_time来保证生成的切片能够与hls_time设置的切片时长差不多。

( 注意:split_by_time参数必须与hls_time配合使用,并且使用split_by_time参数有可能会影响首画面体验,例如花屏或者首画面显示慢的问题,因为视频的第一帧不一定是关键帧。)

3. hls_list_size 参数

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设置生效了。

4. hls_base_url参数

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生效了。

多媒体文件格式(三):M3U8 格式相关推荐

  1. 多媒体文件格式:TS 格式

    一.TS 格式标准介绍 TS是一种音视频封装格式,全称为MPEG2-TS.其中TS即"Transport Stream"的缩写. 先简要介绍一下什么是MPEG2-TS: DVD的音 ...

  2. 网页在线视频下载教程(m3u8格式介绍及下载教程)

    简介: m3u8文件是苹果公司使用的HTTP Live Streaming(HLS)协议格式的基础.HLS是新一代流媒体传输协议,其基本实现原理为将一个大的媒体文件进行分片,将该分片文件资源路径记录与 ...

  3. 如何优雅的批量下载m3u8 格式视频

    我们去很多网站上 去下载视频,解析出的地址 是m3u8格式视频, 使用 普通的下载方式下载就是一个m3u8文件.里面装的是一段一段的视频.一方面,不做特殊处理播放器可能播放不了,另一方面该格式可能是加 ...

  4. 如何下载优酷 m3u8 格式的视频文件?

    mp4 平常最熟悉的视频文件格式就是mp4了,比如这个微博视频就是mp4格式https://weibo.com/tv/v/I6NlI3XNO?fid=1034:4416174394388093 通过一 ...

  5. 【音视频基础】多媒体文件格式

    转载自原文地址:https://www.cnblogs.com/batsing/p/5135508.html 视频: mp4/m4v/3gp/mpg.flv/f4v/swf.avi.gif.wmv.r ...

  6. 音视频 HLS协议和m3u8格式分析

    什么是HLS HLS协议草案历史:https://datatracker.ietf.org/doc/rfc8216/ 可直接看:https://www.rfc-editor.org/rfc/rfc82 ...

  7. 【iOS】控件截图、MP4格式视频流和m3u8格式视频流截取某一帧功能的实现

    最近开发遇到一个点击按钮实现直播视频流截屏的功能,去网上查了一下资料,总结了一下iOS中截屏相关的知识,然后自己做了个demo. demo主要实现了3种截屏方法,分别对应三种不同的应用场景. 1.im ...

  8. m3u8解析_浅谈m3u8格式视频文件采集

    在对某在线视频网站抓包分析时,发现该站点采用m3u8格式进行视频文件传输. 通过m3u8的response可以看到,m3u8格式文件由很多段ts文件组成.那么什么是m3u8,什么是ts呢? M3U8是 ...

  9. m3u8手机批量转码_手机怎么把m3u8格式转换成mp4格式?

    展开全部 转换步骤如下: 一.手机上面找62616964757a686964616fe4b893e5b19e31333431373834到m3u8格式文件的存储位置,在打开方式里边选择"HT ...

最新文章

  1. 在关联枚举中使用Codable
  2. [Hihocoder 1289] 403 Forbidden (微软2016校园招聘4月在线笔试)
  3. python恶搞程序-愚人节恶搞程序源码【两种语言】
  4. Activity 中的Toast在Activity销毁后报错,解决方法,把context改成应用的
  5. 反射调用 java bean的set和get方法
  6. .Net Core 自定义配置源从配置中心读取配置
  7. 【mysql】显式加锁
  8. 短板决定高度 | 人工智能的数学基础
  9. 在有的公司,高手遍地走,天才不如狗
  10. 郑州大学linux安装锐捷客户端
  11. 更改google桌面搜索的索引文件位置
  12. 高防服务器的机房硬件防火墙类型和主要功能
  13. Efficient Protocols for Set Membership and Range Proof 学习笔记
  14. mac与windows的区别
  15. 墨者学院01 SQL手工注入漏洞测试(MySQL数据库)
  16. 在PS里要怎么样才能把一个图片的数字改成另一个数字,还要看不出来?
  17. c语言long long是什么意思,long是什么意思_long在线翻译_英语_读音_用法_例句_海词词典...
  18. Hadoop web端打开hdfs上的文件问题
  19. Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/
  20. android studio 扰码,Visual Studio 调试技巧 (三) -- 调试第三方组件代码

热门文章

  1. Spring项目在虚拟机的部署
  2. 白盒测试:语句/条件/判定/判定条件/条件组合/路径覆盖
  3. 入侵分析钻石模型与基于网络的威胁复制(二)
  4. [monkey]monkey只跑白名单页面方法
  5. 美的微晶冰箱智慧升级,满足消费者对高端智能冰箱的新诉求
  6. 使用CFStringTransform将汉字转换为拼音
  7. 零基础学室内设计要多久才能学好?
  8. LeetCode经典300题【C++版】
  9. ARM学习之Cortex-A
  10. QFramework Pro 开发日志(一)随便写点啥,3 月开始整活了。