本文主要记录通过FFmpeg对MP4,FLV,M3U8格式的封装和文件分析以及对这些格式的一些了解。后面还对音视频的抽取做了简单的介绍。
在互联网常见的格式中,跨平台最好的就是MP4,它可以在PC的Flashplayer中播放,又可以在Android和iOS中播放
MP4的官方术语介绍我们就不看了,对于MP4文件要了解如下几个重要的概念:
当一个Box的Data是一些列的子Box时,这个Box也可以称为Container Box
对于各种Box类型的分析我们就不在这里记录,因为太多了。具体参考书籍《FFmpeg从入门到精通》
MP4文件的分析工具除了FFmpeg外,还有很多可视化的工具,例如Elecard StreamEye,mp4box,mp4info,mediainfo等 这些工具我看了在Mac上面感觉都不咋行,于是在Windows上面玩了一下。
ffmpeg -h demuxer=mp4
ffmpeg -h muxer=mp4
上面两个命令可以查看FFmpeg的解封装和封装的参数,下面列举一些参数使用的示例
使用mp4info查看一个mp4文件的Box信息通常如下所示:
ffmpeg -i ~/Movies/i_am_you.mp4 -vcodec libx264 -preset fast -profile baseline -x264opts bitrate=300 -s 320x240 -r 12 -g 12 -f flv ~/Movies/output.flv
下面可以验证我们的faststart参数的效果了
ffmpeg -i output.flv -c copy -f mp4 -movflags faststart output.mp4
转换完成以后通过mp4info来查看MP4文件的Box信息
使用DASH格式的时候,生成的MP4文件的Box信息和之前的不同,它主要包含的容器为sidx,moof和mdat这三个Box
FFmpeg命令生成DASH格式的MP4文件:
ffmpeg -i input.flv -c copy -f mp4 -movflags dash output.mp4
查看生成的MP4文件的Box组成
在网络直播和点播场景中,FLV是一种常见的格式。它的封装格式很简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的。
FLV格式的分析我就不记录了。有点儿复杂
可视化工具可以使用flvparse或者FlvAnalyzer来分析FLV文件格式的信息。我使用FlvAnalyzer工具来查看了一个flv文件的内容如下:
ffprobe -v trace -i ~/Movies/output.flv
输出如下:
主要介绍MP4转换为FLV格式 ,上面我们没有FLV格式的素材的时候转换了一下,并没有了解其中的参数的具体含义。下面我们着重了解一下。
如果封装FLV的时候,内部的音频或者视频不符合标准时,那么它们就无法封装进去。因为FLV的音视频的编码支持如下
支持视频编码:
如果源视频的音视频编码是FLV所支持的,那就可以顺利的封装
上面的封装命令是从网上copy的其实如果我的源视频支持FLV的封装格式只要如下命令:
ffmpeg -i ~/Movies/i_am_you.mp4 -c copy -f flv ~/Movies/output.flv
就可以完成转换
ffmpeg -i ~/Movies/i_am_you.mp4 -vcodec libx264 -preset fast -profile baseline -x264opts bitrate=300 -s 320x240 -r 12 -g 12 -f flv ~/Movies/output.flv
这个命令就是在其中添加了很多封装的参数。到后面详细了解每个参数的含义。
在网络视频点播文件为FLV格式时,人们常用yamdi工具对FLV文件进行一次转换,主要是将FLV文件中的关键帧建立一个索引,并将索引写入Metadata中,使用FFmpeg也可以实现
ffmpeg -i input.mp4 -c copy -f flv -flvflags add_keyframe_index output.flv
M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,即支持直播也支持点播,尤其在Android和IOS最为常用
FFmpeg中自带HLS的封装参数,使用HLS格式即可进行HLS的封装,但是生成HLS的时候有很多参数可以参考具体的参数使用的时候查看文档
转换文件命令:
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8
其中多了一个参数命令 -bsf:v h264_mp4toannexb 这个参数的作用是将MP4中的H.264数据转换为H.264 AnnexB标准的编码,AnnexB标准的编码常用于实时传输流中。如果源文件为FLV,TS等可以作为直播传输流的视频,就不要这个设置。
执行完这个命令之后 看到目录下面有一大片ts切片文件我上面的命令默认的每一个切片的时间是5秒,这个时间可以通过 -hls_time这个参数来设置
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_time 40 output.m3u8
它还有很多参数可以设置 使用的时候查看具体的需求和文档操作
视频文件切片和HLS基本类似,但是HLS切片在标准中只支持TS格式的切片,并且是直播与点播切片。我们可以把一个mp4文件来切成多个mp4文件,可以使用segment 方式来进行切片,也可以使用ss加上t参数进行切片。
这里指定一个切片命令的参数-segment_format
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 test_output-%d.mp4
segment还有很多其余的参数,用的时候了解要使用的参数。
ss进行视频文件的seek定位,ss传递的参数为时间值,t传递的参数也是时间值
ffmpeg -ss 10 -i input.mp4 -c copy output.ts
命令执行后生成的ouput.ts会比input.mp4视频少大概8秒,因为output.ts是从input.mp4的第八秒开始截取的。使用如下命令看duration信息
ffprobe -v quiet -show_format input.mp4 |grep duration;ffmpeg -v quiet -show_format output.ts |grep duration
ffmpeg -i input.mp4 -c copy -t 10 -copyts output.mp4
ffmpeg -i input.mp4 -c copy -t 10 -output_ts_offset 120 output.mp4
ffmpeg -i input.mp4 -vn -acodec copy output.acc
ffmpeg -i input.mp4 -vcodec copy -an output.h.264
ffmpeg -i input.mp4 -vcodec copy -an -bsf hevc_mp4toannexb -f hevc output.hevc