M3U8是什么?
M3U8是苹果公司推出的视频播放标准,准确来说是一种索引文件,使用M3U8文件实际上是通过它来解析对应的放在服务器上的视频网络地址,从而实现在线播放。M3U8文件使用UTF-8字符编码。M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,既支持直播又支持点播,尤其在Android、iOS等平台最为常用。使用M3U8格式文件主要因为可以实现多码率视频的适配,视频网站可以根据用户的网络带宽情况,自动为客户端匹配一个合适的码率文件进行播放,从而保证视频的流畅度。
m3u8文件内容格式
M3U8文件的内容格式主要包含三方面内容:
- 文件播放列表格式定义:播放列表(Playlist,也即M3U8文件)内容需严格满足以下条件:
- M3U8文件必须以UTF-8进行编码,不能使用Byte Order Mark(BOM)字节序,不能包含UTF-8控制字符(U+0000 ~ U+001F和U+007F ~ U+009F)。
- M3U8文件的每一行要么是一个URI,要么是空行,要么就是以#开头的字符串。不能出现空白字符,除了显示声明的元素。M3U8文件中以#开头的字符串要么是注释,要么就是标签。标签以#EXT开头,大小写敏感。
- 属性列表(Attribute Lists):某些特定的标签的值是属性列表。标签后面的属性列表以逗号作为分隔符,分离出多组不带空格的属性/值对。
以下是文件格式的例子
#EXTM3U
#EXTINF:10,Name of the Playlist
http://example.com/path/to/file1.ts
#EXTINF:20,Name of the Playlist
http://example.com/path/to/file2.ts
#EXTINF:30,Name of the Playlist
http://example.com/path/to/file3.ts
在这个示例中,M3U8文件包含三个URL,每个URL对应一个视频文件。每个文件的名称和长度(以秒为单位)也被列出。播放器会根据文件的索引找到对应的音视频文件的网络地址进行在线播放。
tag说明
下面我们说明一下比较常用和关键的几个字段:
• EXTM3U:这个是M3U8文件必须包含的标签,并且必须在文件的第一行,所有的M3U8文件中必须包含这个标签。
• EXT-X-VERSION:M3U8文件的版本,常见的是3(目前最高版本应该是7)。
•EXT-X-TARGETDURATION:该标签指定了单个媒体文件持续时间的最大值,播放文件列表中的媒体文件在EXTINF标签中定义的持续时间必须小于或者等于该标签指定的持续时间。该标签在播放列表文件中必须出现一次。
•EXT-X-MEDIA-SEQUENCE:M3U8直播是的直播切换序列,当播放打开M3U8时,以这个标签的值作为参考,播放对应的序列号的切片。
•EXTINF:EXTINF为M3U8列表中每一个分片的duration,如上面例子输出信息中的第一片的duration为2.969秒。在EXTINF标签中,除了duration值,还可以包含可选的描述信息,主要为标注切片信息,使用逗号分隔开。
•EXT-X-DISCONTINUITY:需要特别说明的就是这个tag了,表示前一片分片和后一片分片有不连续。
•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时;该标签后需要跟一些属性,下面就来逐一说明一下这些属性:
BANDWIDTH:BANDWIDTH的值为最高码率值,当播放EXT-X-STREAM-INF下对应的M3U8时占用的最大码率(必要参数)。
AVERAGE-BANDWIDTH:AVERAGE-BANDWIDTH的值为平均码率值,当播放EXT-X-STREAM-INF下对应的M3U8时占用的平均码率。(可选参数)。
CODECS:CODECS的值用于声明EXT-X-STREAM-INF下面对应M3U8里面的音视频编码、视频编码的信息(可选参数)。
RESOLUTION:M3U8中视频的宽高信息描述(可选参数)。
FRAME-RATE:子M3U8中的视频帧率(可选参数)。
•#EXT-X-KEY:表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media URI,格式如下:
#EXT-X-KEY:<attribute-list>:NONE 或者 AES-128。如果是NONE,则URI以及IV属性必须不存在,如果是AES-128(Advanced EncryptionStandard),则URI必须存在,IV可以不存在。
对于AES-128的情况,keytag和URI属性共同表示了一个key文件,通过URI可以获得这个key,如果没有 IV(Initialization Vector),则使用序列号作为IV进行编解码,将序列号的高位赋到16个字节的buffer中,左边补0;如果 有IV,则将改值当成16个字节的16进制数。
•#EXT-X-PROGRAM-DATE-TIME:将一个绝对时间或是日期和一个媒体段中的第一个sample相关联,只对下一个meida URI有效,格式如下:
#EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ>
For example:
#EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
•#EXT-X-ALLOW-CACHE:是否允许做cache,这个可以在PlayList文件中任意地方出现,并且最多出现一次,作用效果是所有的媒体段。格式如下:
#EXT-X-ALLOW-CACHE:<YES|NO>
•#EXT-X-PLAYLIST-TYPE: 提供关于PlayList的可变性的信息, 这个对整个PlayList文件有效,是可选的,格式如下:
#EXT-X-PLAYLIST-TYPE:<EVENT|VOD> :如果是VOD,则服务器不能改变PlayList 文件;如果是EVENT,则
服务器不能改变或是删除PlayList文件中的任何部分,但是可以向该文件中增加新的一行内容。
在nodeJS 里解析
在Node.js中解析M3U8文件,可以使用一些第三方库,例如 m3u8-stream
或者 node-m3u8
。
以下是一个使用 m3u8stream
库的示例:
const m3u8stream = require('m3u8stream');
const fs = require('fs');
const stream = m3u8stream('http://example.com/path/to/playlist.m3u8');
stream.on('data', (file) => {
const fileStream = fs.createReadStream(file.path);
console.log(`Playing: ${file.path}`);
fileStream.pipe(process.stdout); // replace process.stdout with your output destination (e.g., http response)
});
直接下载M3U8的软件
市面上有一些可以下载m3u8软件,您可以百度查找下。本人自己根据上面的知识开发了一个解析软件。为了验证上面的功能。以下是软件的下载地址: https://www.feiaci.com/xhl/m3u8Video 。供大家学习参考。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。