假设原始视频尺寸是 1080p(即 1920×1080 px,16:9),使用下面命令可以缩小到 480p:
ffmpeg -i a.mov -vf scale=-1:480 -acodec aac -vcodec h264 out.mp4
ffmpeg -i a.mov -vf scale=-1:480 out.mp4
-i a.mov
指定待处理视频的文件名
-vf scale=853:480
vf 参数用于指定视频滤镜,其中 scale 表示缩放,后面的数字表示缩放至 853×480 px,其中的 853px 是计算而得,因为原始视频的宽高比为 16:9,所以为了让目标视频的高度为 480px,则宽度 = 480 x 9 / 16 = 853
-acodec aac
指定音频使用 aac 编码。注:因为 ffmpeg 的内置 aac 编码目前(写这篇文章时)还是试验阶段,故会提示添加参数 “-strict -2” 才能继续,尽管添加即可。又或者使用外部的 libfaac(需要重新编译 ffmpeg)。
-vcodec h264
指定视频使用 h264 编码。注:目前手机一般视频拍摄的格式(封装格式、文件格式)为 mov 或者 mp4,这两者的音频编码都是 aac,视频都是 h264。
上面的参数 scale=853:480 当中的宽度和高度实际应用场景中通常只需指定一个,比如指定高度为 480 或者 720,至于宽度则可以传入 “-1” 表示由原始视频的宽高比自动计算而得。即参数可以写为:
scale=-1:480
,当然也可以 scale=480:-1
有时可能只需要视频的正中一块,而两头的内容不需要,这时可以对视频进行裁剪(crop),比如有一个
竖向
的视频 1080 x 1920,如果指向保留中间 1080×1080 部分,可以使用下面的命令:
ffmpeg -i a.mov -strict -2 -vf crop=1080:1080:0:420 out.mp4
其中的 crop=1080:1080:0:420 是裁剪参数,含义是 crop=width:height: x:y,其中:
width 和 height 表示裁剪后的尺寸,
x:y 表示裁剪区域的左上角坐标。
比如当前这个示例,我们只需要保留竖向视频的中间部分,所以 x 不用偏移,故传入0,而 y 则需要向下偏移:(1920 – 1080) / 2 = 420
视频缩放和裁剪是可以同时进行的,如下命令则为将视频缩小至 853×480,然后裁剪保留横向中间部分:
ffmpeg -i input.mov -strict -2 -vf scale=853:480,crop=480:480:186:0 out.mp4
如果有一段很长的视频只需保留其中的一段,可以使用下面命令对视频进行剪辑。
ffmpeg -i input.mov -ss 00:00:21 -t 00:00:10 -acodec aac -vcodec h264 -strict -2 out.mov
-ss 00:00:21
表示开始剪辑的位置(时间点),
-t 00:00:10
表示剪辑的长度,即 10 秒钟。
当然一段视频是可以在一个命令里同时进行剪辑、缩放、裁剪的,只需把相关的参数合在一起即可。
调整图像大小
指定长宽:
ffmpeg -i input.jpg -vf scale=320:240 output_320x240.png
指定长,高度按比例缩放:
ffmpeg -i input.jpg -vf scale=320:-1 output_320x240.png
缩放为之前的两倍:
ffmpeg -i input.jpg -vf scale=iw*2:ih input_double_width.png
缩放为之前的二分之一:
ffmpeg -i input.jpg -vf “scale=iw*.5:ih*.5” input_half_size.png
ffmpeg -i input.jpg -vf “scale=iw/2:ih/2” input_half_size.png
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
ffmpeg
可以从任意数量的输入文件中读取数据,输出到任意数量的文件中,这里的文件包括通常意义的文件,管道,网络流,输入设备等,输入文件可以通过
-i
选项指定,输出文件通过一个纯文本的字符串指定。在命令行上发现的所有的非选项内容都被认为是输出文件名。
原则上,所有的输入或输出文件都可以包含任意数量的不同类型的流,包括视频流,音频流,字幕流,附件流和数据流。数量和类型受容器的限制。输入文件中的某一个流保存到输出文件中的哪一个流,这件事情可以由
ffmpeg
自动完成或由
-map
选项来指定 (见流选择章节)。
如果某个选项是针对哪一个输入文件的,需要使用从0开始的索引号指定,第一个文件的索引号为0,第二个文件的索引号为1,以此类推。同样的,文件中的流也是用索引号来表示的。例如
2:3
代表第3个文件中的第4个流,详见流选择章节。
通用规则是,所有选项作用于其后边的第一个文件。因此,顺序是非常重要的,你可以在命令行中重复指定相同的选项,只是指定的文件不同。那些全局的选项需要在命令行中优先指定。
千万不要输入文件和输出文件交叉出现在命令行中,先统一指定所有的输入文件,然后再指定所有的输入文件。同时也不要把指定给不同文件的选项弄混了。
设置输出文件的视频码率为64kbit/s:
ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
指定输出文件的帧率为24:
ffmpeg -i input.avi -r 24 output.avi
强制指定输入文件的帧率为1,输出文件的帧率为24
ffmpeg -r 1 -i input.m2v -r 24 output.avi
ffmpeg
中的转码流程可以用下图来描述:
ffmpeg
调用 libavformat 库(包含demuxer) 读取输入文件,从中提取出编码的数据包。如果有多个输入文件,
ffmpeg
会根据最低的时间戳信息保持文件间的输入流同步。
编码的数据包会交给解码器,除非使用了流拷贝,详情查看后边章节。解码器输出无压缩的数据帧,然后再交给滤波器做处理(见下一节)。经过滤波器后,这些数据帧会再传给编码器,输出压缩的数据包,最后把这些数据交给muxer, 把这些数据保存成文件。
在编码之前,
ffmpeg
会在libavfilter库中使用滤波器处理解码后的原始音视频数据。各种不同的滤波器组成一个滤波器组。
ffmpeg
可以区分简单和复杂两种滤波器组。
简单滤波器组
简单滤波器组由单输入单输出滤波器构成,并且滤波器都是同种类型。他们可以用下图表达。
简单滤波器组可以通过
-per-stream
-filter
选项进行配置,视频滤波器选项简化为
-vf
, 音频滤波器选项简化为
-af
. 一个简单的视频滤波器组可以表达成以下形式:
注意,有些滤波器会改变帧的属性,但是并不会改变其内容。例如,上边例子中的
fps
滤波器改变了帧率 ,但是每一帧的内容是没有被改变的。再者,
setpts
滤波器,只是改变了时间戳信息,而帧内容没有改变。
复杂滤波器组
复杂滤波器组是那些不能简单的用线性处理描述的滤波器。举个例子,当这个滤波器组由多个输入和输出,或者输出的流类型跟输入不同。这样的滤波器组可以用下图描述:
复杂滤波器组通过
-filter_complex
选项进行配置。注意,这个选项是全局的,也就是说不能单独为单个流添加复杂滤波器组。
-lavfi
选项跟
-filter_complex
选项等效。
常见的复杂滤波器组是
overlay
, 有两个视频输入一个视频输出,其中一个视频会改在另一个视频的上边。与其对应的是
amix
滤波器。
流拷贝是通过给
-codec
选项添加
copy
参数的一种模式。可以让 ffmpeg 省掉了先解码再编码的步骤,只有demuxer和muxer. 经常应用于改变视频文件类型,或修改容器的元数据。可以用下图描述:
因为没有编解码,流拷贝运行的非常快并且可以做到无损。但是,有些时候是不能用流拷贝的,例如你想应用滤波器组。
默认情况下,ffmpeg 只从输入文件中选择一个视频流,一个音频流,一个字幕流,然后把这些流保存到输出文件中。ffmpeg通过下边的标准选择最优的视频,音频和字幕:
视频,选择最高分辨率的流
音频,选择有最多升到的流
字幕,选择第一个字幕流
如果多个同类型的流具有相同的参数,那么选取第一个。
我们可以通过
-vn/-an/-sn/-dn
选项禁用这些默认标准。如果你想全部手动选择,可以通过
-map
选项进行配置。
除非特别标明,所有的数字选项都采用字符串表示,数字后边可能需要加国际单位制的前缀,像”K”, “M”或”G”等。
如果”i”被追加到国际单位制前缀后的话,组成的前缀表示二进制倍数,基于1024的幂而不是1000的幂。如果追加的是”B”的话,表示这个数值的8倍。因此,允许我们使用像”KB”, “MiB”, “G”和”B”作为后缀。
不带参数的选项表示是布尔选项,并且设置该选项为真。如果要设置此选项为假,那么只需要在该选项前边加上前缀”no”。举例来说,”nofoo”会设置”foo”选项为假。
有些选项要被应用到每一个流上,例如bitrate和codec。流指示符被用来精确的表明某个选项参数应用于哪一个流。
流指示符是一个字符串,通常被追加在选项后边,并用冒号分割。例如
-codec:a:1 ac3
包含了流指示符
a:1
,这表示编码器
ac3
被用于第二个音频流。
流指示符也可以用于多个流,这样选项参数就可以应用于这些流。例如
-b:a 128k
被应用于所有的音频流。
如果没有流指示符,代表该选项参数被应用于所有的流,例如
codec copy
,
-codec: copy
表示直接拷贝流而不进行重新编码。
常用的流指示符有:
stream_index
匹配该选项指定的流。例如
-threads:1 4
, 表示设置第一个流的线程号为4.
stream_type[:stream_index]
stream_type
有以下几种类型,
‘v’ 表示所有的视频流 ‘V’ 表示不带缩略图的视频流 ‘a’ 表示音频 ‘s’ 表示字幕 ‘d’ 表示数据 ‘t’ 表示附件
如果给出
stream_index
那么表示
stream_index
代表的流是这种类型,否则,代表所有的流都是这种类型。
p:program_id[:stream_index]
如果给出
stream_index
, 则其代表的流在
program_id
表达的进程中操作,否则,所有的流都在此进程中。
#stream_id或i:stream_id
匹配
stream_id
表示的流(例如 MPEG-TS 容器中的PID)
m:key[:value]
匹配元数据标签
key
的值为指定值得流。如果没有给出
value
, 匹配所有具有该元数据标签的流。
匹配具有可用配置的流,codec必须指定必要的参数,像视频的长宽,音频的采样频率等。
注意,在
FFmpeg
中,用元数据匹配只作用于指定的输入文件。
以下选项在所有的
ff*
工具中通用,
显示许可证
-h, -?, -help, –help [arg]
显示帮助。可选参数可以只打印指定项的帮助信息。如果没有指定可选参数,只显示基本的工具选项。
可选参数
arg
,请参考如下详细描述
显示识别的颜色名称
sources device[, opt1=val1[,opts=val2]...]
显示自动检测到的输入设备。有些输入设备的名称可能以来操作系统,这样就没法自动检测到。返回列表可能是不完整的。
ffmpeg -sources pulse,server=192.168.0.4
-sinks device[,opt1=val1[,opt2=val2]...]
显示自动侦测到的输出设备。有些输出设备的名称可能依赖操作系统,这样就没法自动检测到。返回列表可能是不完整的。
ffmpeg -sinks pulse,server=192.168.0.4
-loglevel [repeat+]loglevel | -v [repeat+]loglevel
设置库的日志等级。添加
repeat+
表明重复的日志输出不会覆盖第一行,并且后边的重复日志会被忽略。
repeat
也可以单独使用。如果
repeat
被单独使用,也没有指定日志优先级,那么将使用默认的日志等级。如果指定了多个日志等级参数,使用
repeat
将不会改变日志等级。
loglevel
是一个字符串或一个数字,可以是一下的形式,
默认情况下,程序的logs会不给输出到
stderr
. 如果中断支持颜色,警告和错误会用颜色高亮显示出来。可以使用
AV_LOG_FORCE_NOCOLOR
或
NO_COLOR
关掉颜色,也可以使用
AV_LOG_FORCE_COLOR
打开颜色。
NO_COLOR
已经过时。
-report
把所有的命令行和终端打印信息输出到当前目录的文件
program-YYYYMMDD-HHMMSS.log
. 这个文件有助于分析bug, 默认使用
-loglevel-verbose
.
设置任意值到环境变量
FFREPORT
也可以达到同样的效果。也可以追加level, 举例如下
FFREPORT=file=ffreport.log:level=32 ffmpeg -i input output
hide_banner
禁止打印横幅。
所有的FFmpeg工具通常都会显示版权信息,编译选项和库版本号。增加这个选项可以让程序不打印这些信息。
-cpuflags flags (global)
允许设置和清空CPU标志,这个选项只是用于测试。如果你不了解这些标志位的意义,建议你不要使用。
ffmpeg -cpuflags -sse+mmx ...
ffmpeg -cpuflags mmx ...
ffmpeg -cpuflags 0 ...
可用的标志位如下:
mmx
,
mmxext
,
sse
,
sse2
,
sse2slow
,
sse3
,
sse3slow
,
ssse3
,
atom
,
sse4.1
,
sse4.2
,
avx
,
avx2
,
xop
,
fma3
,
fma4
,
3dnow
,
3dnowext
,
bmi1
,
bmi2
,
cmov
armv5te
,
armv6
,
armv6t2
,
vfp
,
vfpv3
,
neon
,
setend
AArch64
armv8
,
vfp
,
neon
PowerPC
altivec
Specific Processors
pentium2
,
pentium3
,
pentium4
,
k6
,
k62
,
athlon
,
athlonxp
,
k8
-opencl_bench
这个选项用于对支持
OpenCL
的设备进行基准测试并且打印出结果。使用此选项前请确保你的FFmpeg编译的时候添加了选项
-enable-opencl
.
如果FFmpeg配置了
-enable-opencl
,
OpenCL
的全局上下文选项可以通过
-opencl_options
进行配置。请参考
ffmpeg-utils
手册中的
OpenCL Options
部分。还可以指定平台和设备来运行OpenCL代码。默认情况下,FFmpeg会运行在第一个平台的第一个设备上。而OpenCL 的全局上下文选项允许用户选择OpenCL设备,大多数用户会选择系统中最快的OpenCL设备。
这个选项有助于选择系统中最快的OpenCL设备。内置的基准程序会在所有的OpenCL设备上运行并且对设备的性能做出评价。运行结束后会输出一个按照性能高低的顺序排列的列表,性能越高,排名越靠前。然后用户可以用性能最好的设备运行FFmpeg, 以获取最高的硬件加速性能。
通常用下面的步骤来应用最快的OpenCL设备,
ffmpeg -opencl_bench
记录下平台ID(pidx)和设备ID(didx),然后执行下边的指令,
ffmpeg -opencl_options platform_idx=pidx:device_idx=didx ...
-opencl_options options (global)
设置OpenCL环境变量,只有FFmpeg编译时添加了
--enable-opencl
才能使用该选项。
选项必须是一个符合
key=value
的序列,中间用”:” 分割开。详见
ffmpeg-utils
手册中的
OpenCL Options
部分。
AVOptions
这些选项由
libavformat
,
libavdevice
,
libavcodec
库提供。可以使用
-help
选项来查看AVOptions支持列表。其可以分为两类,
这些选项可以用用于所有的容器,编解码器或设备。
AVFormatContext
中定义了关于容器和设备的通用选项,
AVCodecContext
中定义了关于编解码器的通用选项。
这些选项是针对特定容器,设备或编解码器的。他们被定义在相应的容器/设备/编解码器中。
例如,要将一个MP3文件的文件头由默认的ID3V2.4改成ID3V2.3, 可以使用
id3v2_version
这个MP3 容器的私有选项:
ffmpeg -i input.flac -id3v2_version 3 out.mp3
所有的编解码器AVOptions 都是针对特定流的,因此需要使用流指示符来指定这个选项应用于哪一个流。
注意
, AVOptions不能使用布尔选项,即没有
nooption
这样的语法,应该使用
-option 0/ -option 1
.
-f fmt (input/output)
指定输入文件和输出文件的格式。通常情况下输入文件的格式是自动检测出的,输出文件的格式是通过文件后缀猜出来的。所以,在大多数情况下,不需要使用这个选项。
-i url (input)
输入文件的路径。
-y (global)
不提示,直接覆盖输出文件。
-n (global)
不要覆盖输出文件,如果输出文件已存在直接退出。
-stream_loop number (input)
设置输入文件的循环次数。0 表示不循环,-1代表无限循环。
-c[:stream_specifier] codec (input/output,per-stream)
-codec[:stream_specifier] codec (input/output,per-stream)
给输出流选择编码器,给输入流选择解码器。codec 是编码器或解码器的名字,或者是 copy,表示不会对输入流进行重新编码。
ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
表示对所有的视频流使用libx264编码,拷贝所有的音频流。
对每个流,总是应用最后的
-c
选项,例如,
ffmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
除了第2个视频流使用libx264编码和第138个音频流使用libvorbis编码之外,拷贝所有剩余流。
-t duration (input/output)
作为输入文件的参数时,表示从输入文件中读取 duration指定时间的数据。
作为输出文件的参数是,表示当时间超过duration指定的时间时,停止写文件。
duration 必须符合时间持续标准,详见
(ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual
.
-t
和
-to
互相排斥,不过
-t
具有更高的优先级。
-to position (output)
在某个位置时停止写文件。位置必须符号时间持续标准 ,详见
(ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual
.
-t
和
-to
互相排斥,不过
-t
具有更高的优先级
-fs limit_size (output)
限制文件大小,以字节计。一旦达到了限定大小,停止写入数据。
-ss position (input/output)
作为输入文件参数时,跳转到输入文件的position位置,注意在大多数的文件格式中,是很难精确的跳转的,ffmpeg只会跳转到指定位置的附近。在转码时,默认开启
-accurate_seek
参数。在跳转点和position之间的数据,会在解码后丢弃。当流拷贝或使用
-noaccurate_seek
时,会保留这些数据。
当作为输出文件参数时,解码后丢弃输入,直到时间戳跟position匹配为止。
position 必须符号时间持续标准,详见
(ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual
.
sseof position (input/output)
跟
-ss
选项很像,只是会跳转到从文件结尾处开始计数的某一个为止,这个数是个负数,0表示文件尾。
-itsoffset offset (input)
设置输入文件的时间偏移量。
偏移量必须符合时间持续标准,详见
(ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual
.
这个偏移量会被加到输入文件的时间戳中。如果offset是正数,代表相应的流会延时offset的时间。
-timestamp date (output)
设置容器中的录制时间戳。
date必须符合日期标准,详见
(ffmpeg-utils)the Date section in the ffmpeg-utils(1) manual
.
-metadata[:metadata_specifier] key=value (output,per-metadata)
设置元数据。
可以给流,章节和节目设置专门的元数据 metadata_specifier. 详见
-map_metadata
.
这个选项可以覆盖
-map_metadata
设置的元数据。可以是设置一个空值来删除元数据。
例如,设置输出文件的标题:
ffmpeg -i in.avi -metadata title="my title" out.flv
设置第一个音频流的语言:
ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
-disposition[:stream_specifier] value (output,per-stream)
设置流的属性。
这个选项会覆盖从输入文件中拷贝的流属性。也可以通过设置0值来删除某个属性。
可以使用如下的属性,
default` `dub` `original` `comment` `lyrics` `karaoke` `forced` `hearing_imparied` `visual_imparied` `clean_effects` `captions` `descriptions` `metadata
例如, 设置第二个音频流为默认流:
ffmpeg -i in.mkv -disposition:a:1 default out.mkv
设置第二个字幕流为默认流,并且删除第一个字幕流的默认属性:
ffmpeg -i INPUT -disposition:s:0 0 -disposition:s:1 default OUTPUT
-program [title=title:][program_num=program_num:]st=stream[:st=stream...] (output)
使用指定的标题和节目号创建节目。并且给节目添加指定的流。
target type (output)
指定目标文件类型,如
vcd
,
svcd
,
dvd
,
dv
,
dv50
. 文件类型通常添加像
pal-
,
ntsc-
或
film-
的前缀以满足相应的标准。然后所有的像码率,编解码器,内存大小等参数会被自动设置。例如
ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
尽管如此,只要不跟相应的标准冲突,你也可以指定其他的选项,例如:
ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
未完待续。。。 ```