首页 编程 正文
604

ffmpeg的一些使用示例

ffmpeg命令格式:
ffmpeg [全局选项][输入文件选项] -i [输入文件]...[输出文件选项][输出文件]

主要选项 :
-f 指定输入或者输出文件格式,不指定的话会根据文件扩展名进行推测。
-i 输入文件
-y 默认覆盖同名文件
-n 不覆盖同名文件,如果输出文件存在立即退出
-codec 指定编码格式,也可以仅指定音频或视频,如-codec:v指定视频编码格式,-codec:a指定音频编码格式
-t 限制输入或者输出时间, 一般配合-ss使用,用来截取时间段的音视频。
-to 指定结束时间点,一般配合-ss使用,用来截取某时间段的内容。
-ss 设置开始时间,单位是秒
-fiiter_complex 复合滤镜
-vf 单一滤镜
视频:
-r 设置帧数
-s 设置输出尺寸(只能是偶数)
-vn 禁止输出视频
-va 禁止输出音频
-codec:v 设置视频编码格式,等同-c:v
-codec:a 设置音频编码格式,等同-c:a
音频:
-ar 设置采样频率
-ac 设置音频通道数
-an 禁止输出音频
-sn 禁止输出字幕
-ab 设置比特率

//将管道里的图片制作成视频
ffmpeg -f image2pipe -framerate 24 -i pipe:.png -s 1600x900 -y -vcodec libopenh264 out.mp4
//从视频里提取音频
ffmpeg -i input.mp4 -vn -ar 44100 -ab 128k -ac 2 out.ts
ffmpeg -i input.mp4 -acodec copy -vn -y out.m4a
//制作空音频
ffmpeg -f lavfi -i aevalsrc=0 -t 15 -q:a 9 -ar 44100 -ab 128k -ac 2 out.ts
//连接视频或者音频
ffmpeg -i "concat:0.ts|1.ts" -c copy out.ts 
//混合音频
ffmpeg -i 1.ts  -i 2.ts -filter_complex"amix=inputs=2:duration=longest:dropout_transition=1" out.ts 

//降低音频音量,比如降低50%
ffmpeg.exe -i a.mp3 -filter:a "volume=0.5" b.mp3

//固定时间点截取一张图片
ffmpeg -i input.mp4  -ss 4.500 -vframes 1 output.png

//固定时间开始连续截图多张图片
ffmpeg  -i input.mp4  -ss 4.500 -vframes 10 output%d.png

//视频每秒截一张图片,保存为png图片
ffmpeg  -i input.mp4 -vf fps=1  output%d.png

//视频每10秒截一张图片,保存为jpeg图片
ffmpeg  -i input.mp4 -vf fps=0.1  output%d.jpg

//视频每秒截十张图片,保存为bmp图片
ffmpeg  -i input.mp4 -vf fps=10  output%d.bmp

//内嵌srt字幕
ffmpeg -i input.mp4 -i input.srt -c copy -c:s mov_text output.mp4

//媒体叠加
ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output
input1为背景输入源,input2为前景输入源。
overlay为叠加滤镜:
  描述:前景窗口(第二输入)覆盖在背景窗口(第一输入)的指定位置。
  语法:overlay[=x:y[[:rgb={0, 1}]]
    参数 x 和 y 是可选的,默认为 0。
    参数 rgb 参数也是可选的,其值为 0 或 1,默认为 0。
  参数说明:
    x                   从左上角的水平坐标,默认值为 0
    y                   从左上角的垂直坐标,默认值为 0
    rgb                 值为 0 表示输入颜色空间不改变,默认为 0;值为 1 表示将输入的颜色空间设置为 RGB
  变量说明:如下变量可用在 x 和 y 的表达式中
    main_w 或 W          主输入(背景窗口)宽度
    main_h 或 H          主输入(背景窗口)高度
    overlay_w 或 w       overlay 输入(前景窗口)宽度
    overlay_h 或 h       overlay 输入(前景窗口)高度
//overlay应用示例:从左向右移动的入场动画
ffmpeg -i moving.jpg -vf color=c=green:s=720x1280[vbg];[vbg][0:v]overlay=x='if(lte(t,5),-w+(W+w)/2/5*t,(W-w)/2)':y=(H-h)/2 -t 5 -y move.mp4

//运用delog滤镜去除logo,如果有多个delog用逗号分隔。 用delogo来做马赛克很不错。
ffmpeg -t 10 -i input.mp4 -filter_complex "delogo=x=300:y=300:w=100:h=100" -c:v libx264 -crf 28 -preset veryfast -c:a copy -movflags +faststart output.mp4 -y
delog参数:
delogo=x:y:w:h[:t[:show]] 
x:y 离左上角的坐标 
w:h logo的宽和高 
band 或者 t: 矩形边缘的厚度,默认值4 
show:若设置为1有一个绿色的矩形,默认值0。

//合并视频
ffmpeg -f concat -safe 0 -i videoslist.txt -c copy output.mp4
-safe 0 为了避免Operation not permitted.
videoslist.txt内容类似:
file '/path/to/file1'
file '/path/to/file2'

//截取视频
//从时间为00:00:15开始,截取5秒钟的视频。 
ffmpeg -i input.mp4 -ss 00:00:15.0 -t 00:00:05.0  -vcodec copy -acodec copy output.mp4 
-ss表示开始切割的时间,-t表示要切多少。上面就是从15秒开始,切5秒钟出来。
或者
ffmpeg -i input.mp4 -ss 00:00:15.0 -c:v copy -c:a copy -to 00:00:20.0 output.mp4
-to 表示截止到某个时间点为止
-c:v copy 表示复制视频源的编码
-c:a copy 表示复制音频源的编码

//降低视频码率,从而压缩视频体积
ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k output.mp4
什么是码率?很简单: 
bitrate = file size / duration 
比如一个文件20.8M,时长1分钟,那么,码率就是: 
biterate = 20.8M bit/60s = 20.8*1024*1024*8 bit/60s= 2841Kbps 
一般音频的码率只有固定几种,比如是128Kbps, 
那么,video的就是 
video biterate = 2841Kbps -128Kbps = 2713Kbps。
那么ffmpeg如何控制码率。 
ffmpg控制码率有3种选择,-minrate -b:v -maxrate 
-b:v主要是控制平均码率。 
比如一个视频源的码率太高了,有10Mbps,文件太大,想把文件弄小一点,但是又不破坏分辨率。 
ffmpeg -i input.mp4 -b:v 2000k output.mp4 
上面把码率从原码率转成2Mbps码率,这样其实也间接让文件变小了。目测接近一半。 
不过,ffmpeg官方wiki比较建议,设置b:v时,同时加上 -bufsize 
-bufsize 用于设置码率控制缓冲器的大小,设置的好处是,让整体的码率更趋近于希望的值,减少波动。(简单来说,比如1 2的平均值是1.5, 1.49 1.51 也是1.5, 当然是第二种比较好) 
ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k output.mp4
-minrate -maxrate就简单了,在线视频有时候,希望码率波动,不要超过一个阈值,可以设置maxrate。 
ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k -maxrate 2500k output.mp4
ffmpeg.exe -i input.mkv -b:v 2000k -bufsize 2000k output.mkv
//指定某几个时间段进行delogo
ffmpeg.exe -i input.mp4 -filter_complex "[0:v]crop=x=0:y=16:w=1080:h=38,delogo=x=0:y=0:w=1080:h=40[fg];[0:v][fg]overlay=0:16:enable='between(t,210,374) + between(t,1080,1244) + between(t, 2160, 2324)':eof_action=pass[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy -y  "output.mp4"
注意overlay的enable参数,通过between选择符合需求的时间段,通过+(加号)进行“逻辑或”组合。

//根据不同时间调整delogo的位置
ffmpeg.exe -i "input.mp4" -filter_complex "[0:v]crop=x=0:y='if(between(t,2700,2721), 7, 16 )':w=1080:h=38,delogo=x=0:y=0:w=1080:h=40[fg];[0:v][fg]overlay=x=0:y='if(between(t,2700,2721), 7, 16 )':enable='between(t,210,386) + between(t,900,1076) + between(t, 1980, 2156) + between(t, 2700, 2721)':eof_action=pass[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy -y  "output.mp4"

内置函数:
abs(x) 返回x的绝对值
acos(x)  计算x的反余弦
atan(x)  计算x的反正切
lte(x, y)  小于等于比较
lt(x, y)   小于比较
gte(x, y)  大于等于
gt(x, y)  大于比较
eq(x, y) 判断是否相等
floor(expr) 向下取整
ceil(expr)向下取整
between(x, min, max)  判断min<x<max是否成立 成立返回1不成立返回0(*可以用来在视频的特定时间插入音频)
if(x, y) 判断x如果非0返回y否则返回0
if(x, y, z) 判断x如果非0返回y否则返回z
ifnot(x, y)
ifnot(x, y, z)
isinf(x)      x是正无穷或者负无穷(+/-INFINITY),返回1
isnan(x)     x是NAN,返回1
max(x,y)  返回x,y的最大值
min(x,y)  返回x,y的最小值
random(x)  返回0-1的随机数
mod(x, y) 取余
not(expr) expr 是零返回1
pow(x, y)  x^y
round(expr) 四舍五入
*  星号相当于AND
+  加号相当于OR
更多内置函数参考:https://ffmpeg.org/ffmpeg-utils.html#Expression-Evaluation

ffmpeg滤镜的一些知识:
FFmpeg filter可以认为是一些预定义的范式,可以实现类似积木的多种功能的自由组合。
每个filter都有固定数目的输入和输出,而且实际使用中不允许有空悬的输入输出端。
使用文本描述时我们可以通过标识符指定输入和输出端口,将不同filter串联起来,构成更复杂的filter。这就形成了嵌套的filter。
当然每个filter可以通过ffmpeg/ffplay命令行实现,但通常filter更方便。
ffmpeg.exe、ffplay.exe能够通过filter处理原始的音视频数据。
ffmpeg将filtergraph分为simple filtergraph和complex filtergraph。
通常simple filtergraph只有一个输入和输出,ffmpeg命令行中使用-vf、-af识别,
complex filtergraph,通常是具有多个输入输出文件,并有多条执行路径;
ffmpeg命令行中使用-lavfi、-filter_complex,
在libavfilter, 一个filter可以包含多个输入、多个输出。
filterChain:
filterchain的语法:filter1,filter2,...
它是多个filter的组合,以逗号分隔;并且每个filter是输入是前一个filter的输出;
例如:
ffmpeg -i audio.aac -filter_complex "aresample=async=16000,adelay=316397,volume=1.0" -acodec libfdk_aac -y output.mp4
这里用到了三个filter,分别的aresample, adelay, volume, 组成一个filterchain.
filterGraph:
filtergraph的语法:filterchain1;filterchain2;...

它是多个filterchain的组合,以分号";"分隔,

例如:

ffmpeg -i INPUT -filter_complex "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT

这里用到了三个filterchain, 分别是:

split [main][tmp]; // 它只有一个filter,即 split; 它有一个默认的输入,即INPUT解码后的frame;有两个输出, 以 [main], [tmp] 标识;

[tmp] crop=iw:ih/2:0:0, vflip [flip] // 它由两个filter组成,即crop和vflip;一个输入 [tmp], 一个输出[flip];

[main][flip] overlay=0:H/2 // 它由一个filter组成,即overlay, 有两输入,分别是[main][flip], 一个默认的输出。
参考:https://blog.csdn.net/fireroll/article/details/85316881

正在加载评论...