1 ffmpeg常用命令
ffmpeg在做音视频编解码时非常方便,所以在很多场景下转码使用的是ffmpeg,通过 ffmpeg --help可以看到 ffmpeg 常见的命令大概分为6个部分,具体如下。
- ffmpeg信息查询部分
- 公共操作参数部分
- 文件主要操作参数部分
- 视频操作参数部分
- 音频操作参数部分
- 字幕操作参数部分
ffmpeg信息查询部分的主要参数具体如下:
ffmpeg [options] [[infile options]-i infile]... {[outfile options] outfile}..
通过ffmpeg --help查看到的help信息是ffmpeg命令的基础信息,如果想获得高级参数部分,那么可以通过使用ffmpeg --help long参数来查看,如果希望获得全部的帮助信息,那么可以通过使用ffmpeg --help full参数来获得。
ffmpeg --help
ffmpeg --help long
ffmpeg --help full
通过-L参数,可以看到ffmpeg目前所支持的license协议;通过-version可以查看 ffmpeg的版本,包括子模块的详细版本信息,如libavformat、libavcodec、libavutillibavfilter、libswscale、libswresample 的版本:
使用ffmpeg转码,有时候可能会遇到无法解析的视频文件或者无法生成视频文件,报错提示不支持生成对应的视频文件,这时候就需要查看当前使用的fmpeg是否支持对应的视频文件格式,需要使用ffmpeg -formats参数来查看:
ffmpeg -formats
根据上面输出的信息可以看到,输出的内容分为3个部分,具体如下
- 第一列是多媒体文件封装格式的Demuxing支持与Muxing 支持
- 第二列是多媒体文件格式
- 第三列是文件格式的详细说明
使用ffmpeg命令时,可能会出现fmpeg不支持某种编码格式或者某种解码格式的错误提示信息,这种错误常见于并未将该编码器或者解码器集成到ffmpeg中,若想查看ffmpeg是否支持H.264编码或者解码,可以通过ffmpeg -codecs 查看全部信息,也可以通过 ffmpeg -encoders査看 ffmpeg是否支持H.264编码器,或者通过 ffmpeg -decoders查看ffmpeg是否支持H.264解码器。
ffmpeg -decoders 命令行执行后,输出如下:
输出信息中包含了三部分内容,具体如下。
- 第一列包含6个字段,第一个字段用来表示此编码器为音频、视频还是字幕,第二个字段表示帧级别的多线程支持,第三个字段表示分片级别的多线程,第四个字段表示该编码为试验版本,第五个字段表示 draw horiz band 模式支持,第六个字段表示直接渲染模式支持
- 第二列是编码格式
- 第三列是编码格式的详细说明
ffmpeg -encoders 命令执行后,输出如下
输出信息中同样包含了三部分内容,具体如下
- 第一列包含6个字段,第一个字段用来表示此编码器为音频、视频还是字幕,第二个字段表示帧级别的多线程支持,第三个字段表示分片级别的多线程,第四个字段表示该编码为试验版本,第五个字段表示 draw horiz band 模式支持,第六个字段表示直接渲染模式支持
- 第二列是编码格式
- 第三列是编码格式的详细说明
除了查看ffmpeg支持的封装(Muxer)格式与解封装(Demuxer)格式、编码(Encoder)类型与解码(Decoder)类型,还可以通过ffmpeg -flters查看 ffmpeg 支持哪些滤镜:
输出信息的内容分为四列,具体如下
- 第一列总共有3个字段,第一个字段是时间轴支持,第二个字段是分片线程处理支持,第三个字段是命令支持
- 第二列是滤镜名
- 第三列是转换方式,如音频转音频,视频转视频,创建音频,创建视频等操作
- 第四列是滤镜作用说明
通过 ffmpeg --help full命令,可以査看ffmpeg 支持的所有封装(demuxer、muxer)格式,编解码器(encoders、decoders)和滤镜处理器(filters)。如果要了解 ffmpeg 支持的具体某一种 demuxer、muxer类型,可以通过 ffmpeg -h查看该类型的详细参数,包括encoder、decoder 所支持的操作参数,fiter所支持的参数,下面就列举几个对应的例子。
1)查看FLV封装器的参数支持(ffmpeg -h muxer=flv):
ffmpeg -h muxer=flv
从输出的帮助信息中可以看到,FLV的muxer的信息包含两大部分,具体如下
- 第一部分为FLV封装的默认配置描述,如扩展名、MIME类型、默认的视频编码格式、默认的音频编码格式
- 第二部分为FLV 封装时可以支持的配置参数及相关说明
2)查看 flv解封装器的参数支持(ffmpeg -h demuxer=flv):
ffmpeg -h demuxer=flv
从帮助信息中可以看到,FLV的demuxer的信息包含两大部分,具体如下
- 第一部分为 FLV 解封装默认的扩展文件名
- 第二部分为FLV 解封装设置的参数及相关说明
3)查看H.264(AVC)的编码参数支持(ffmpeg -h encoder=h264):
ffmpeg -h encoder=h264
从帮助信息可以看到,H.264(AVC)的编码参数包含两大部分,具体如下。
- 第一部分为H.264所支持的基本编码方式、支持的多线程编码方式(例如帧级别多线程编码或 Slice 级别多线程编码)、编码器所支持的像素的色彩格式
- 第二部分为编码的具体配置参数及相关说明
4)查看H.264(AVC)的解码参数支持(ffmpeg -h decoder=h264):
ffmpeg -h decoder=h264
从帮助信息可以看到,H.264(AVC)的解码参数查看包含两大部分,具体如下
- 第一部分为解码H.264时可以采用的常规支持、多线程方式支持(帧级别多线程解码或Slice级别多线程解码)
- 第二部分为解码 H.264时可以采用的解码参数及相关说明
5)查看 colorkey 滤镜的参数支持(ffmpeg -h filter=colorkey),输出内容如下
ffmpeg -h filter=colorkey
从帮助信息中可以看到,colorkey滤镜参数查看信息包含两大部分,具体如下
- colorkey所支持的色彩格式信息,colorkey所支持的多线程处理方式,输入或输出支持
- colorkey所支持的参数及说明
1.1 ffmpeg 的封装转换
ffmpeg的封装转换(转封装)功能包含在AVFormat模块中,通过libavformat库进行Mux和Demux操作;多媒体文件的格式有很多种,这些格式中的很多参数在Mux与Demux的操作参数中是公用的,下面就来详细介绍一下这些公用的参数。
参数 | 类型 | 说明 |
---|---|---|
avioflags | 标记 | format 的缓冲设置,默认为 0,就是有缓冲 |
direct | 标记 | 无缓冲状态 |
probesize | 整数 | 在进行媒体数据处理前获得文件内容的大小,可用在预读取文件头时提高速度,也可以设置足够大的值来读取到足够多的音视频数据信息 |
fflags | 标记 | |
flush_packets | 标记 | 立即将 packets 数据刷新写入文件中 |
genpts | 标记 | 输出时按照正常规则产生 pts |
nofillin | 标记 | 不填写可以精确计算缺失的值 |
igndts | 标记 | 忽略 dts |
discardcorrupt | 标记 | 丢弃损坏的帧 |
sortdts | 标记 | 尝试以 dts 的顺序为准输出 |
keepside | 标记 | 不合并数据 |
fastseek | 标记 | 快速 seek(定位)操作,但是不够精确 |
latm | 标记 | 设置 RTP MP4_LATM 生效 |
nobuffer | 标记 | 直接读取或写出,不存入 buffer,用于在直播采集时降低延迟 |
bitexact | 标记 | 不写入随机或者不稳定的数据 |
seek2any | 整数 | 支持随意位置 seek,这个 seek 不以 keyframe 为参考 |
analyzeduration | 整数 | 指定解析媒体所需要花费的时间,这里设置的值越高,解析越准确,如果在直播中为了降低延迟,这个值可以设置得低一些 |
codec_whitelist | 列表 | 设置可以解析的 codec 的白名单 |
format_whitelist | 列表 | 设置可以解析的 format 的白名单 |
output_ts_offset | 整数 | 设置输出文件的起始时间 |
1.2 ffmpeg 的转码参数
ffmpeg编解码部分的功能主要是通过模块AVCodec来完成的,通过libavcodec库进行Encode与 Decode 操作。多媒体编码格式的种类有很多,但是还是有很多通用的基本操作参数设置,下面就来详细介绍一下这些公用的参数。
参数 | 类型 | 说明 |
---|---|---|
b | 整数 | 设置音频与视频码率,可以认为是音视频加起来的码率,默认为 200kbit/s。使用这个参数可以根据 b:v 设置视频码率,b:a 设置音频码率 |
ab | 整数 | 设置音频的码率,默认是 128kbit/s |
g | 整数 | 设置视频 GOP(可以理解为关键帧间隔)大小,默认是 12 帧一个 GOP |
ar | 整数 | 设置音频采样率,默认为 0 |
ac | 整数 | 设置音频通道数,默认为 0 |
bf | 整数 | 设置连续编码为 B 帧的个数,默认为 0 |
maxrate | 整数 | 最大码率设置,与 bufsize 一同使用即可,默认为 0 |
minrate | 整数 | 最小码率设置,配合 maxrate 与 bufsize 可以设置为 CBR 模式,平时很少使用,默认为 0 |
bufsize | 整数 | 设置控制码率的 buffer 的大小,默认为 0 |
keyint_min | 整数 | 设置关键帧最小间隔,默认为 25 |
sc_threshold | 整数 | 设置场景切换支持,默认为 0 |
me_threshold | 整数 | 设置运动估计阈值,默认为 0 |
mb_threshold | 整数 | 设置宏块阈值,默认为 0 |
profile | 整数 | 设置音视频的 profile,默认为 -99 |
level | 整数 | 设置音视频的 level,默认为 -99 |
timecode_frame_start | 整数 | 设置 GOP 帧的开始时间,需要在 non-drop-frame 默认情况下使用 |
channel_layout | 整数 | 设置音频通道的布局格式 |
threads | 整数 | 设置编解码工作的线程数 |
1.3 ffmpeg 的基本转码原理
ffmpeg 工具的主要用途为编码、解码、转码以及媒体格式转换,ffmpeg 常用于进行转码操作。
通过前两节介绍的参数,可以设置转码的相关参数,如果转码操作涉及封装的改变,则可以通过设置AVCodec与AVFormat的操作参数进行封装与编码的改变。
ffmpeg -i input.mp4 -vcodec mpeg4 -b:v 200k -r 15 -an output.avi
从输出信息中可以看到,以上输出的参数中使用了前面介绍过的参数,具体如下。
- 转封装格式从MP4格式转换为AVI格式
- 视频编码从 MPEG4转换为 MPEG4 格式
- 视频码率从原来的1027kbit/s转换为200kbit/s
- 视频帧率从原来的23.98fps转换为15fps
- 转码后的文件中不包括音频(-an 参数)
2 ffprobe 常用命令
ffprobe的参数较多
ffprobe --help
超级多
使用 ffprobe -show_packets input.mp4 查看多媒体数据包信息:
ffprobe -show_packets input.mp4
通过 show_packets查看的多媒体数据包信息使用PACKET标签括起来,其中包含的信息主要如表所示。
字段 | 说明 |
---|---|
codec_type | 多媒体类型,如视频包、音频包等 |
stream_index | 多媒体的 stream 索引 |
pts | 多媒体的显示时间值 |
pts_time | 根据不同格式计算过后的多媒体的显示时间 |
dts | 多媒体解码时间值 |
dts_time | 根据不同格式计算过后的多媒体解码时间 |
duration | 多媒体包占用的时间值 |
duration_time | 根据不同格式计算过后的多媒体包所占用的时间值 |
size | 多媒体包的大小 |
pos | 多媒体包所在的文件偏移位置 |
flags | 多媒体包标记,如关键包与非关键包的标记 |
组合参数来查看包中的具体数据:除了以上字段和信息之外,还可以通过ffprobe -show_data -show _packets input.flv
ffprobe -show_data -show_packets input.mp4
通过 ffprobe 读取 packets来进行对应的数据分析,使用show_packets与 show_data 配合可以进行更加精确的分析。
除了packets与data之外,ffprobe还可以分析多媒体的封装格式,通过ffprobe -show_format output.mp4命令可以查看多媒体的封装格式,其使用 FORMAT 标签括起来显示:
ffprobe -show_format output.avi
下面对输出信息关键字段进行说明
字段 | 说明 |
---|---|
filename | 文件名 |
nb_streams | 媒体中包含的流的个数 |
nb_programs | 节目数(相关概念在 2.3 节中有详细介绍) |
format_name | 使用的封装模块的名称 |
format_long_name | 封装的完整名称 |
start_time | 媒体文件的起始时间 |
duration | 媒体文件的总时间长度 |
size | 媒体文件的大小 |
bit_rate | 媒体文件的码率 |
通过 ffprobe -show_frames input.flv命令可以查看视频文件中的帧信息,输出的帧信息将使用FRAME 标签括起来:
ffprobe -show_frames input.mp4
通过 -show frames参数可以查看每一帧的信息,下面就来介绍一下其中重要的信息具体见表
属性 | 说明 | 值 |
---|---|---|
media_type | 帧的类型(视频、音频、字幕等) | video |
stream_index | 帧所在的索引区域 | 0 |
key_frame | 是否为关键帧 | 1 |
pkt_pts | Frame 包的 pts | 0 |
pkt_pts_time | Frame 包的 pts 的时间显示 | 0.080000 |
pkt_dts | Frame 包的 dts | 80 |
pkt_dts_time | Frame 包的 dts 的时间显示 | 0.080000 |
pkt_duration | Frame 包的时长 | N/A |
pkt_duration_time | Frame 包的时长时间显示 | N/A |
pkt_pos | Frame 包所在文件的偏移位置 | 344 |
width | 帧显示的宽度 | 1280 |
height | 帧显示的高度 | 714 |
pix_fmt | 帧的图像色彩格式 | yuv420p |
pict_type | 帧类型 | I |
通过-show_streams参数可以查看到多媒体文件中的流信息,流的信息将使用STREAM 标签括起来:
如以上输出内容所示,从中可以看到流的信息
属性 | 说明 | 值 |
---|---|---|
index | 流所在的索引区域 | 0 |
codec_name | 编码名 | h264 |
codec_long_name | 编码全名 | MPEG-4 part 10 |
profile | 编码的 profile | High |
level | 编码的 level | 31 |
has_b_frames | 包含 B 帧信息 | 2 |
codec_type | 编码类型 | video |
codec_time_base | 编码的时间戳计算基础单位 | 1/50 |
pix_fmt | 图像显示的色彩格式 | yuv420p |
coded_width | 图像的宽度 | 1280 |
coded_height | 图像的高度 | 714 |
codec_tag_string | 编码的标签数据 | [0][0][0][0] |
# 得到的XML输出格式
ffprobe -of xml -show_streams input.mp4
# 得到的INI输出格式
ffprobe -of ini -show_streams input.mp4
# 得到的FLAT输出格式
ffprobe -of flat -show_streams input.mp4
# 得到的JOSN输出格式
ffprobe -of json -show_packets input.mp4
# 得到的CSV输出格式,可以用excel打开
ffprobe -of csv -show_packets input.mp4
使用select streams可以只查看音频(a)、视频(v)、字幕(s)的信息,例如配合show_frames查看视频的frames信息:
ffprobe -show_frames -select_streams v -of xml input.mp4
3 ffplay 常用命令
在FFmpeg中通常使用ffplay作为播放器,其实ffplay同样也可以作为很多音视频数据的图形化分析工具,通过fplay可以看到视频图像的运动估计方向、音频数据的波形等,本节将会介绍更多的参数并举例说明。
3.1 ffplay 常用参数
ffplay不仅仅是播放器,同时也是测试ffmpeg的codec引擎、format引擎,以及 filter引擎的工具,并且还可以进行可视化的媒体参数分析,其可以通过ffplay --help进行查看:
介绍一些参数
参数 | 类型 | 说明 |
---|---|---|
x | 整数 | 强制设置视频显示窗口的宽度 |
y | 整数 | 强制设置视频显示窗口的高度 |
s | 整数 | 设置视频显示的宽高 |
fs | 整数 | 强制全屏显示 |
an | 整数 | 屏蔽音频 |
vn | 整数 | 屏蔽视频 |
sn | 整数 | 屏蔽字幕 |
ss | 整数 | 根据设置的秒进行定位拖动 |
t | 整数 | 设置播放视频 / 音频的长度 |
bytes | 整数 | 设置定位拖动的策略,0 为不可拖动,1 为可拖动,-1 为自动 |
nodisp | 整数 | 关闭图形化显示窗口 |
f | 整数 | 强制使用设置的格式进行解析 |
window_title | 整数 | 设置显示窗口的标题 |
af | 整数 | 设置音频的滤镜 |
codec | 整数 | 强制使用设置的 codec 进行解码 |
autorotate | 整数 | 自动旋转视频 |
常见命令
# 从30s开始,播放10s视频
ffplay -ss 30 -t 10 input.mp4
# 自定义窗口标题
ffplay -window_title "studywinter" output.avi
# 测试播放流
ffplay -window_title "播放测试" rtmp://202.69.69.180:443/webcast/bshdlive-mobile
3.2 ffplay 高级参数
参数 | 类型 | 说明 |
---|---|---|
ast | 整数 | 设置将要播放的音频流 |
vst | 整数 | 设置将要播放的视频流 |
sst | 整数 | 设置将要播放的字幕流 |
stats | 整数 | 输出多媒体播放状态 |
fast | 整数 | 非标准化规范的多媒体兼容优化 |
sync | 整数 | 音视频同步设置可根据音频时间、视频时间或者外部扩展时间进行参考 |
autoexit | 整数 | 多媒体播放完毕之后自动退出 ffplay,ffplay 默认播放完毕之后不退出播放器 |
exitonkeydown | 整数 | 当有按键按下事件产生时退出 ffplay |
exitonmousedown | 整数 | 当有鼠标按键事件产生时退出 ffplay |
loop | 整数 | 设置多媒体文件循环播放的次数 |
framedrop | 整数 | 当 CPU 资源占用过高时,自动丢帧 |
infbuf | 整数 | 设置无极限的播放器 buffer,这个选项常见于实时流媒体播放场景 |
vf | 整数 | 视频滤镜设置 |
acodec | 整数 | 强制使用设置的音频解码器 |
vcodec | 整数 | 强制使用设置的视频解码器 |
scodec | 整数 | 强制使用设置的字幕解码器 |
例如从 20秒播放一个视频,播放时长为10秒钟,播放完成后自动退出fplay,播放器的窗口标题为“Hello World”,为了确认播放时长正确,可以通过系统命令 time 查看命令运行时长:
time ffplay -window_title "Hello World" -ss 20 -t 10 -autoexit output.avi
从输出的内容分析来看,实际消耗时间为12.241秒,用户空间消耗4.147秒
强制使用H.264解码器解码 MPEG4的视频,将会报错
ffplay -vcodec h264 input.mp4
当视频流中出现多个Program时,播放Program与常规的播放方式有所不同,需要指定对应的流,可以通过 vst、ast、sst参数来指定,例如希望播放Program13中的音视频流视频流编号为4,音频流编号为5,则可以通过如下命令行进行指定:
ffplay -vst 4 -ast 5 ~/Movies/movie/ChinaTv-11.ts
首先编辑SRT字幕文件,内容如下
1
00:00:01.000 --> 00:00:30.000
Test Subtitle by StudyWinter
2
00:00:30.001 --> 00:00:60.000
Hello Test Subtitle
3
00:01:01.000-->00:01:10.000
Test Subtitle by StudyWinter
4
00:01:11.000-->00:01:30.000
Test Subtitle by StudyWinter
ffplay -window_title "Test Movie" -vf "subtitles=input.srt" input.mp4
3.3 ffplay 的数据可视化分析应用
使用ffplay除了可以播放视频流媒体文件之外,还可以作为可视化的视频流媒体分析工具,例如播放音频文件时,如果不确定文件的声音是否正常,则可以直接使用ffplay播放音频文件,播放的时候其将会把解码后的音频数据以音频波形的形式显示出来,命令行执行后的效果如图所示,命令如下:
ffplay -showmode 1 input.mp3
例如,当播放视频时想要体验解码器是如何解码每个宏块的,可以使用如下命令:
ffplay -debug vis_mb_type -window_title "show vis_mb_type" -ss 20 -t 10 -autoexit input.mp4
具体地
例如通过ffplay查看B帧预测与P帧预测信息,希望将信息在窗口中显示出来,可使用如下命令:
ffplay -vismv pf input.mp4
笔者无这个命令,这个命令应该被舍弃了
ffplay -flags2 +export_mvs -ss 40 input.mp4 -vf codecview=mv=pf+bf+bb
参数 | 说明 |
---|---|
pf | P 帧向前运动估计显示 |
bf | B 帧向前运动估计显示 |
bb | B 帧向后运动估计显示 |