1.1,m3u8描述文件
M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
M3U8是一种常见的流媒体格式,紧张以文件列表的形式存在,既支持直播又支持点播,尤其在Android、iOS等平台最为常用。

#EXTM3U#EXT-X-VERSION:3#EXT-X-MEDIA-SEQUENCE:0#EXT-X-ALLOW-CACHE:YES#EXT-X-TARGETDURATION:3#EXTINF:1.969test0.ts#EXTINF:1.972test1.ts#EXTINF:1.109test2.ts#EXT-X-DISCONTINUITY#EXTINF:2.969test3.ts#EXT-X-ENDLIST
最常见的参数有:
#EXTM3U#EXT-X-VERSION:3#EXT-X-TARGETDURATION:17#EXT-X-MEDIA-SEQUENCE:0#EXTINF:16.683333,参数解释:
#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时;该标签后须要跟一些属性,下面就来逐一解释一下这些属性: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中的视频帧率(可选参数)。
#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文件中的任何部分,但是可以向该文件中增加新的一行内容。
1.2,ts媒体文件
HLS的上风为:自适应码率流播(adaptive streaming)。效果便是客户端会根据网络状况自动选择不同码率的视频流,条件许可的情形下利用高码率,网络繁忙的时候利用低码率,并且能够自动在二者之间随意切换。这对移动设备网络状况不稳定的情形下保障流畅播放非常有帮助。实现方法是做事器端供应多码率视频流,并且在列表文件中注明,播放器根据播放进度和下载速率进行自动调度。
为什么要用 TS 而不是 MP4?这是由于两个 TS 片段可以无缝拼接独立解码,播放器能连续播放,而 MP4 文件由于编码办法的缘故原由,两段 MP4 不能无缝拼接,播放器连续播放两个 MP4 文件会涌现破音和画面间断,影响用户体验。
2,ffmpeg简介官方网站:https://ffmpeg.org/
FFMPEG堪称自由软件中最完备的一套多媒体支持库,它险些实现了所有当下常见的数据封装格式、多媒体传输协议以及音视频编解码器,堪称多媒体业界的瑞士军刀。因此,对付从事多媒体技能开拓的工程师来说,深入研究FFMPEG成为一门必不可少的事情。
2.1,FFMPEG命令
这里指FFMPEG供应的命令行(CLI)工具ffmpeg,其利用方法如下(方括号表示可选项,花括号表示必选项目):
ffmpeg [global options] {[infile options]['-i' 'infile'] ...} {[outfile options] 'outfile' ...}
参数选项由三部分组成:可选的一组全局参数、一组或多组输入文件参数、一组或多组输出文件参数,个中,每组输入文件参数以‘-i’为结束标记;每组输出文件参数以输出文件名为结束标记。
2.2,基本参数
能力集列表
-formats:列出支持的文件格式。-codecs:列出支持的编解码器。-decoders:列出支持的解码器。-encoders:列出支持的编码器。-protocols:列出支持的协议。-bsfs:列出支持的比特流过滤器。-filters:列出支持的滤镜。-pix_fmts:列出支持的图像采样格式。-sample_fmts:列出支持的声音采样格式。常用输入选项
-i filename:指定输入文件名。-f fmt:逼迫设定文件格式,需利用能力集列表中的名称(缺省是根据扩展名选择的)。-ss hh:mm:ss[.xxx]:设定输入文件的起始韶光点,启动后将跳转到此韶光点然后开始读取数据。对付输入,以下选项常日是自动识别的,但也可以逼迫设定。
-c codec:指定解码器,需利用能力集列表中的名称。-acodec codec:指定声音的解码器,需利用能力集列表中的名称。-vcodec codec:指定视频的解码器,需利用能力集列表中的名称。-b:v bitrate:设定视频流的比特率,整数,单位bps。-r fps:设定视频流的帧率,整数,单位fps。-s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。-pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。-ar sample rate:设定音频流的采样率,整数,单位Hz。-ab bitrate:设定音频流的比特率,整数,单位bps。-ac channels:设置音频流的声道数目。常用输出选项
-f fmt:逼迫设定文件格式,需利用能力集列表中的名称(缺省是根据扩展名选择的)。-c codec:指定编码器,需利用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。-acodec codec:指定声音的编码器,需利用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。-vcodec codec:指定视频的编码器,需利用能力集列表中的名称(编解码器设定为”copy“表示不进行编解码)。-r fps:设定视频编码器的帧率,整数,单位fps。-pix_fmt format:设置视频编码器利用的图像格式(如RGB还是YUV)。-ar sample rate:设定音频编码器的采样率,整数,单位Hz。-b bitrate:设定音视频编码器输出的比特率,整数,单位bps。-ab bitrate:设定音频编码器输出的比特率,整数,单位bps。-ac channels:设置音频编码器的声道数目。-an 忽略任何音频流。-vn 忽略任何视频流。-t hh:mm:ss[.xxx]:设定输出文件的韶光长度。-to hh:mm:ss[.xxx]:如果没有设定输出文件的韶光长度的画可以设定终止韶光点。3,利用ffmpeg进行mp4与m3u8之间转换变切片切片会将MP4切成一个m3u8文件和无数个ts文件。
3.1,安装ffmpeg
首先是给做事器安装ffmpeg,我这里是ubuntu,ubuntu上安装非常大略,实行如下代码就行:
sudo apt install ffmpegffmpeg -version
第一行是安装ffmpeg,第二行是查看ffmpeg版本,来确认是否安装好了;
3.2,转码切片m3u8
然后MP4转码并切片,基本命令:
ffmpeg -i movie.mp4 -profile:v baseline -level 3.0 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls movie.m3u8
这个命令,大概15分钟旁边一部电影。个中movie.mp4和movie.m3u8便是原文件和须要转换成的m3u8文件;
-profile:v baseline 大概意思是档次转成基本画质,有四种画质级别,分别是baseline, extended, main, high,从低到高-level 3.0 大概也是视频画质级别吧,基本上是从1到5-start_number 0 表示从0开始-hls_time 10 标识每10秒切一个转码速率有点慢,但是可以多线程跑,加上参数,-threads 10和 -preset ultrafast
-threads 线程,根据自己cpu核数自己调度。-preset 的参数紧张调节编码速率和质量的平衡,有ultrafast(转码速率最快,视频每每也最模糊)、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo这10个选项,从快到慢。ffmpeg -i movie.mp4 -threads 10 -preset ultrafast -profile:v baseline -level 3.0 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls movie.m3u8
以上速率虽然提升了,但是画质可能会降落,有时候会模糊。命令大概5分钟一部电影。
有没有速率快,而且画质不影响的命令?
有的,这也是我最常用的,最大略的命令。
主要参数
-codec: copy 复制原来的码率和编码,由于不进行转码,以是速率很快,基本10秒一部片,而且基本无损画质。以是终极的命令为:(正常电影10秒一部片)
ffmpeg -i movie.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls movie.m3u8
3.3,hls_time不生效的问题
这个命令,虽然速率快,但是碰着一个问题。我改切片韶光hls_time不生效,如我改成4秒。
ffmpeg -i movie.mp4 -codec: copy -start_number 0 -hls_time 4 -hls_list_size 0 -f hls movie.m3u8
但在 m3u8 文件中始终是#EXTINF:8.341667。hls_time不管改成多少,都是这个数。在GitHub问大神,得到答案。大神原话参考:
-c copy is fast and (oftentimes) lossless because you aren't remuxing. That's pretty much the entire point. To quote
The video streams can be encoded in the MPEG-1, MPEG-2, MPEG-4 and H. 264/AVC standards. The audio streams can be (HE)-AAC, MPEG-1 Audio Layer 1-2-3, CELP, TwinVQ, Vorbis or Apple Lossless.
Note: it's missing H.265/HEVC. On first glance. Some codecs actually are segmented already. Hence you'd have to remux if you want to change the segmentation time.
大概意思, -codec: copy所支持的视频流MPEG-1, MPEG-2, MPEG-4 and H. 264/AVC 标准流,和音频流(HE)-AAC, MPEG-1 Audio Layer 1-2-3, CELP, TwinVQ, Vorbis,Apple Lossless。
注:H.265/HEVC是不支持的。有些转码器已经内置切片时长,如果须要改切片时长,须要重新编码。
以是我电影是通过格式工厂默认编码,查询得知,格式工厂默认内置为8秒或者10秒。以是hls_time自定义切片韶光不生效。
办理方法,格式工厂重新编码即可。格式工厂编码输出设置,改两个选项。
1:二次编码,是
2:关键帧间,选择2或者更小。2代表可以切2秒的倍数,如可切2秒,4秒,6秒。默认该当为8,以是只能切8秒。
重新编码的影片,可以重新切片2秒或者4秒。
4,编写脚本批量自动检测切片做事器影片目录为TV,子目录分别由m3u8,mp4,upload三个文件夹。
ubuntu@ubuntu:/TV$ tree.├── m3u8├── mp4└── upload
脚本逻辑,电影上传至upload,脚本检测到后,将影片移动至mp4文件夹作为原片保存,然后切片文件保存在m3u8文件夹。upload可自行创建文件夹,脚本自动在mp4和m3u8自动天生对应文件夹。
切片完成,保存干系不雅观看链接至指定txt文档,作为日志保存。
脚本内容:
#! /bin/bash#調試模式#set -x#上传目录path_tv=/TV/uploadcut_m3u8(){mv $path_upload/$filemp4 $path_mp4 &&ffmpeg -i $path_mp4/$filemp4 -codec: copy -start_number 0 -hls_time 4 -hls_list_size 0 -f hls $path_m3u8/$filem3u8 &&echo "$name.m3u8 切片完成,韶光:`date +%F_%R`" >> /var/www/tv_link/link.txt && echo "$name网站链接为:https://ywbj.cc/$path/$name.m3u8" >> /var/www/tv_link/link.txt &&echo >> /var/www/tv_link/link.txt}#循环在upload查找所有的MP4格式文件for file in `find $path_tv $1 | grep 'mp4'`do #截取影片名称name1=${file%.mp4}name=${name1##/}#合并MP4文件名,和m3u8文件名。filem3u8=`eval echo $name.m3u8`filemp4=`eval echo $name.mp4`#截取upload下影片文件夹名称path1=${file%/}path=${path1##/}path_upload=/TV/upload/$pathpath_mp4=/TV/mp4/$pathpath_m3u8=/TV/m3u8/$path#检测是否由对应文件夹,没有则创建if [ ! -d $path_mp4 ]; then# echo "创建文件夹" mkdir -p $path_mp4fiif [ ! -d $path_m3u8 ]; then# echo "创建文件夹" mkdir -p $path_m3u8fiif [ -f $path_m3u8/$filem3u8 ]; thenecho "$filem3u8已存在,删除旧文件,重新切片..." >> /var/www/tv_link/link.txt &&rm -f $path_m3u8/$name &&cut_m3u8elsecut_m3u8fidone
5,定时任务,自动运行脚本定时任务,脚本每5分钟,检测一次upload文件夹,是否有mp4文件。
crontab -e
添加定时任务,脚本保存在/shell/m3u8_auto.sh路径。
#切片脚本,5分钟检讨一次/5 bash /shell/m3u8_auto.sh