ffmpeg 滤镜

FFmpeg通过libavfilter库实现滤镜功能,滤镜(filter)处理的是未压缩的原始音视频数据(RGB/YUV视频帧,PCM音频帧等)。比较常用的滤镜有:scale、trim、overlay、rotate。scale滤镜用于缩放,trim滤镜用于帧级剪切,overlay滤镜用于视频叠加,rotate滤镜实现旋转。

滤镜语法

滤镜链是由逗号分隔的滤镜(filter)序列组成:

ffmpeg -i input.mpg -vf filter1,fiter2,filter3,...  output.mp4

滤镜图通常是由分号分隔的滤镜链组成。滤镜图分为简单滤镜图和复杂滤镜图。

一个滤镜由一个字符串表单表示:

[in_link_1]...[in_link_N]filter_name=arguments[out_link_1]...[out_link_M]

filter_name是滤镜类名字,用于指定滤镜实例(它注册于程序中)。其后的=arguments用于指定滤镜选项。arguments是用于初始化滤镜的参数,它可能有下面两类表单中的一个:

  • 一个“:”分隔的key=value列表
  • 一个“:”分隔的列表value值,在这种情况下,键(key)假定为选项名声明顺序,如fade滤镜按顺序声明了3个选项type、start_frame和nb_frames,则参数 in:0:30 意味着type为in,start_frame为0,nb_frames为30。
  • 前面二者的混合。这种情况下,键值对必须在前,然后接遵循相同约束的若干值。

如果选项的值本身就是一个列表(例如format滤镜有一个像素格式列表选项),则这种列表通常用“|”分隔。

列表参数可以被’(单引号)包含起来。字符\作为转义字符用于引号包含的文本。否则参数字符串在遇到特殊字符(例如’[]=;,’)处被看作终止。

标签in_link_1 … in_link_N作为滤镜的输入端,out_link_1 … out_link_M作为滤镜的输出端。

当中一个滤镜链图中找到相同名字的连接标签时,一个在相应输入端和输出端之间的连接被创建。

如果一个输出端没有命名标签,它默认连接到滤镜链上后面滤镜中第一个没有命名标签的输入端。例如:

nullsrc, split[L1], [L2]overlay, nullsink

这里split有两路输出,overlay有两路输入,split的第一路输出被命名为标签”L1”,overlay的第一路输入被命名为标签”L2”。则split的第二路输出链接到overlay的第二路输入(它们都没有用标签命名)。

在一个滤镜描述中,如果第一个滤镜的输入没有指定,则假定为”in”,如果最后一个滤镜输出没有指定,则假定为”out”。

如果滤镜没有输入端,则被称作“源”,如果滤镜没有输出端则被称作“槽”(这样的滤镜用于描述/测试等场景,而不用于实际处理)。

在一个完整的滤镜链上,所有滤镜的输入和输出都被连接则被认为是有效的。

滤镜链图成分需要包含多层的转义:

  • 第一层的转义效果在每个滤镜选项值
  • 第二层的转义在整个滤镜描述
  • 第三层的转义在shell命令行上描述滤镜链图时

例如下面的字符需要嵌入drawtext滤镜描述的text值

this is a 'string': may contain one, or more, special characters

这个字符串包含’字符需要被转义,还有:这里也需要被转义,方法是:

text=this is a \'string\'\: may contain one, or more, special characters

当嵌入滤镜描述时发生第二层的转义,为了转义所有的滤镜链图特殊字符,需要按下例处理:

drawtext=text=this is a \\\'string\\\'\\: may contain one\, or more\, special characters

最终当在shell命令行中写这个滤镜链图时再次转义。例如需要对每个特殊字符和转义处理的\等进行转义,最终为:

-vf "drawtext=text=this is a \\\\\\'string\\\\\\'\\\\: may contain one\\, or more\\, special characters"

简单滤镜图

简单滤镜图只能处理单路输入流和单路输出流,而且要求输入和输出具有相同的流类型。
简单滤镜图由-filter选项指定,-filter:v选项(同-vf)表示使用视频滤镜, -filter:a选项(同-af)表示使用音频滤镜。

简单滤镜图示意图如下:

 _______        _____________________        ________
|       |      |                     |      |        |
| input | ---> | simple filter graph | ---> | output |
|_______|      |_____________________|      |________|

举例如下:

               [main]
input --> split ---------------------> overlay --> output
        |                             ^
        |[tmp]                  [flip]|
        +-----> crop --> vflip -------+

在这个滤镜链图中,利用split滤镜把输入流分离成了两路流,其中一路通过crop滤镜和vfilp滤镜的同一路级联应用,再同另外一路一起通过overlay滤镜处理的流合成进行输出。则可以采用如下的命令行实现:

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

同一路的滤镜间用逗号(‘,’)进行分割,不同路的滤镜间用分号(‘;’)进行分割。在这个例子里面crop和vflip是在同一路中的滤镜,split和overlay则不是同一路的。可以通过在方括号(’[]’)中的标签名来命名处理的链路。这个例子里,split滤镜生成了两路就通过[main]和[tmp]进行了标签命名以方便后续处理。

复杂滤镜图

复杂滤镜图用于简单滤镜图处理不了的场合。比如,多路输入流和(或)多路输出流,或者输出流与输入流类型不同。
有些特殊的滤镜(filter)本身就属于复杂滤镜图,用-filter_complex选项或-lavfi选项指定,如overlay滤镜就是复杂滤镜图:

 ffmpeg -i cuc_short.flv  -i clock.avi -filter_complex overlay=0:0 compare.mp4
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值