FFmpeg命令filter过滤器

Filter的分类

  • 按照处理数据的类型,通常多媒体的Filter过滤器分为:

    1. 音频filter
    2. 视频filter
    3. 字幕filter
  • 另一种按照处于编解码器的位置划分:

    • prefilters:在编码之前使用
    • intrafilters:在编码时使用(因此是视频编解码器的组成部分)
    • postfilters:解码后使用
  • FFmpeg中Filter分为:

    1. source filter(只有输出)
    2. audio filter
    3. video filter
    4. Mulimedia filter
    5. sink filter(只有输入)
    • 除了source filtersink filter,其他filter都至少有一个输入、输出。

视频裁剪

  • 视频过滤器(滤镜):裁剪

描述将输入视频的宽度和高度从x和y值表示的位置裁剪到指定的宽度和高度;xy是输出的左上角坐标,协调系统的中心是输入视频帧的左上角。如果使用了可选的keep_aspect参数,将会改变输出SAR(样本宽比)以补偿新的DAR(显示长宽比)
语法crop = ow[:oh[:x[:y[:keep_aspect]]]]
变量用于owoh参数的表达式中的可用变量
x,yx的计算值(从左上角水平方向的像素个数)和y(垂直像素的数量),对每个帧进行评估,x的默认值为(iw - ow)/ 2,y的默认值为(ih - oh)/ 2
in_w,iw输入的宽度
in_h,ih输入的高度
out_w,ow输出(裁剪)宽度,默认值 = iw
out_h,oh输出(裁剪)高度,默认值 = ih
a纵横比,与 iw / ih 相同
sar输入样本比例
dar输入显示宽比,等于表达式 a * sar
hsub,vsub水平和垂直的色度子样本值,对于像素格式 yuv42p,hsub的值为2,vsub为1
n输入帧的数目,从0开始
pos位置在输入框的文件中,如果不知道 NAN
t时间戳以秒表示,如果输入时间戳未知
  • ow的值可以从oh得到,反之亦然,但不能从xy中得到,因为这些值是在owoh之后进行的。x的值可以从y的值中得到,反之亦然。

    例如:在输入框的左三、中三和右三,可以使用命令:

    ffmpeg -i input -vf crop=iw/3:ih:0:0 output
    ffmpeg -i input -vf crop=iw/3:ih:iw/3:0 output
    ffmpeg -i input -vf crop=iw/3:iw/3*2:0 output
    
    1. 裁剪100x100的区域,起点为(12,34)

      crop=100:100:12:34
      #相同效果:
      crop=w=100:h=100:x=12:y=34
      
    2. 裁剪中心区域,大小为100x100

      crop=100:100
      
    3. 裁剪中心区域,大小为输入视频的2/3

      crop=2/3*in_w:2/3*in_h
      
    4. 裁剪中心区域的正方形,高度为输入视频的高

      crop=out_w=in_h
      crop=in_h
      
    5. 裁剪偏移左上角100像素

      crop=in_w-100:in_h-100:100:100
      
    6. 裁剪掉左右10像素,上下20像素

      crop=in_w-2*10:in_h-2*20
      
    7. 裁剪右下角区域

      crop=in_w/2:in_h/2:in_w/2:in_h/2
      

FFmpeg滤镜Filter内置变量

  • 在使用Filter时,经常会经常会用到根据时间轴进行操作的需求,在使用 FFmpeg 的 Filter 时可以使用 Filter 的时间相关的内置变量,下面先来了解一下这些相关的变量,见下表:

    • FFmpeg滤镜filter基本内置变量

      变量说明
      t以秒表示的时间戳,如果输入的时间是未知的则是 NAN
      n输入帧的顺序编号,从0开始
      pos输入帧的位置,如果未知的则是 NAN
      w输入视频帧的宽度
      h输入视频帧的高度

添加水印

文字水印

  • 在视频中增加文字水印需要准备的条件比较多,需要有文字字库处理的相关文件,在编译 FFmpeg 时需要支持 FreeType、FontConfig、iconv,系统中需要有相关的字库,在 FFmpeg 中增加纯字母水印可以使用 drawtext滤镜进行支持,下面就来看一下 drawtext 的滤镜参数,具体见下表:

    • FFmpeg文字滤镜参数

      参数类型说明
      text字符串文字
      textfile字符串文字文件
      box布尔文字区域背景框(缺省 false)
      boxcolor色彩展示字体区域快的颜色
      font字符串字体名称(默认为 Sans 字体)
      fontsize整数显示字体的大小
      x字符串缺省为 0
      y字符串缺省为 0
      aplha浮点数透明度(默认为 1),值从 0 ~ 1
    • 举例:

      1. 将文字的水印加载视频的左上角:

        ffplay -i test_video.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':x=200:y=20"
        
        #将字体的颜色设置为绿色:
        ffplay -i test_vide0.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':fontcolor=green"
        
        #如果想调整文字水印的显示位置,调整x与y参数的数值即可
        ffplay -i test_video.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello Wolrd':fontcolor=green:x=400:y=200"
        
        #修改透明度
        ffplay -i test_video.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':fontcolor=green:x=400:y=200:alpha=0.5"
        
      2. 文字水印还可以增加边框,然后给边框加上背景颜色:

        ffplay -i test_video.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':fontcolor=green:box=1:boxcolor:yellow"
        
      3. 有些时候文字水印希望以本地时间作为水印内容,可以在drawtext滤镜中配合一些特殊用法来完成,在text中显示本地当前时间,格式为年月日时分秒的方式

        ffplay -i test_video.mp4 "drawtext=fontsize=60:fontfile=FreeSerif.ttf:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':fontcolor=green:box=1:boxcolor=yellow"
        

        在使用FFmpeg转码存储至文件时需要加上-re,否则时间不对

        ffmpeg -re -i test_video.mp4 -vf "drawtext=fontsize=60:fontfile=FreeSerif.ttf:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':fontcolor=green:box=1:boxcolor=yellow" ouput_test_video.mp4
        
      4. 在个别在个别场景中,需要定时显示水印,定时不显示水印,这种方式同样可以配合drawtext滤镜进行处理,使用drawtextenable配合即可,例如每 3 秒钟显示一次文字水印:

        ffplay -i test_video.mp4 -vf "drawtext=fontsize=60:fontfile=FreeSerif.ttf:text='Hello World':fontcolor=green:box=1:boxcolor=yellow:enable=lt(mod(t\,3)\,1)"
        

        在使用FFmpeg转码存储至文件时需要加上-re,否则时间不对

        表达式参考:FFmpeg Utilities Documentation

        • lt(x, y) 	#如果x小于y返回1,否则返回0
          mod(x, y) 	#计算x除以y的余数
          
      5. 跑马灯效果:

        ffplay -i test_video.mp4 "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':x=mod(100*t\,w):y=abs(sin(t))*h*0.7"
        

        修改字体透明度,修改字体颜色

        ffplay -i test_video.mp4 "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='Hello World':x=mod(50*t\,w):y=abs(sin(t))*h*0.7:alpha=0.5:fontcolor=white:enable=lt(mod(t\3)\,1)"
        

图片水印

  • FFmpeg 除了可以向视频添加文字水印之外,还可以向视频添加图片水印、视频跑马灯等,为视频添加图片水印可以使用 movie 滤镜,下面就来熟悉一下 movie 滤镜的参数,如表所示。

    • FFmpeg movie滤镜的参数

      参数类型说明
      filename字符串输入的文件名,可以是文件、协议、设备
      format_name,f字符串输入的封装格式
      stream_index,si整数输入的流索引编号
      seek_point,sp浮点数Seek输入流的时间位置
      streams,s字符串输入的多个流的流信息
      loop整数循环次数
      discontinuity时间差值支持跳动的时间戳差值
      ffmpeg -i test_video.mp4 -vf "movie=log.png[watermark];[in][watermark]overlay=x=10:y=10[out]" output_test_video.mp4
      
      • 原始视频文件路径:test_video.mp4

      • 水印图片路径:logo.png

      • 水印位置:(x,y)=(10,10)<=(left,top)距离左侧、顶部各10像素

      • 输出文件路径:output_test_video.mp4

        参数说明
        main_w视频单帧图像宽度
        main_h视频单帧图像高度
        overlay_w水印图片的宽度
        overlay_h水印图片的高度

        对应地可以将overlay参数设置成如下值来改变图片的位置:

        水印图片位置overlay位置
        左上角10:10
        右上角main_w-overlay_w-10:10
        左下角10:main_h-overlay_h-10
        右下角main_w-overlay_w-10:main_h-overlay_h-10

  1. 图片logo.png将会打入到test_video.mp4视频中,显示在x坐标50、y坐标20的位置

    ffplay -i test_video.mp4 -vf "movie=logo.png[logo];[in][logo]overlay=50:10[out]"
    

    由于logo.png图片的背景色是白色,所以显示起来比较生硬,如果水印图片是透明背景效果会更好,找一张透明背景色的图片尝试:

    ffplay -i test_video.mp4 -vf "movie=logo.png[watermark];[in][watermark]overlay=50:10[out]"
    
  2. 显示位置

    ffplay -i test_video.mp4 -vf "movie=logo.png[watermark];[in][watermark]overlay=10:10[out]"
    ffplay -i test_video.mp4 -vf "movie=logo.png[watermark];[in][watermark]overlay=main_w-overlay_w-10:10[out]"
    ffplay -i test_video.mp4 -vf "movie=logo.png[watermark];[in][watermark]overlay=10:main_h-overlay_h-10[out]"
    ffplay -i test_video.mp4 -vf "movie=logo.png[watermark];[in][watermark]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out]"
    
  3. 跑马灯效果

    ffplay -i test_video.mp4 "movie=logo.png[watermark];[in][watermark]overlay=x=mod(50*t\,main_w):y=abs(sin(t))*h*0.7[out]"
    

FFmpeg 生成画中画

  • 在使用 FFmpeg 处理流媒体文件时,有时需要使用画中画的效果。在 FFmpeg 中,可以通过 overlay 将多个视频流、多个多媒体采集设备、多个视频文件合并到一个界面中,生成画中画的效果。在前面的滤镜使用中,以至于以后的滤镜使用中,与视频操作相关的处理,大多数都会与 overlay 滤镜配合使用,尤其是用在图层处理与合并场景中,下面就来了解一下 overlay 的参数,具体如下表:

    • FFmpeg滤镜overlay基本参数

      参数类型说明
      x字符串X坐标
      y字符串Y坐标
      eof_action整数遇到eof表示时的处理方式,默认为重复。repeat(值为0):重复前一帧 endcall(值为1):停止所有流 pass(值为2):保留主图层
      shortest布尔终止最短的视频时全部终止(默认为false)
      format整数设置output的像素格式,默认为yuv420。yuv420(值为0) yuv422(值为1) yuv444(值为2) rgb(值为3)

      从参数列表中可以看到,主要参数并不多,但实际上在 overlay 滤镜使用中,还有很多组合的参数可以使用,可以使用一些内部变量,例如 overlay 图层的宽、高、坐标等。

  1. 显示画中画效果

    ffplay -i main.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20[out]"
    ffplay -i main.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20:eof_action=1[out]"
    ffplay -i main.mp4 -vf "movie=sub_320x240.mp4[sub];[in][sub]overlay=x=20:y=20:shortest=1[out]"
    
    #缩放子画面尺寸:
    ffplay -i main.mp4 -vf "movie=sub_320x240.mp4,scale=640x480[sub];[in][sub]overlay=x=20:y=20[out]"
    
  2. 跑马灯

    ffplay -i main.mp4 -vf "movie=sub_320x240.mp4[test];[in][test]overlay=x=mod(50*t\,main_w):y=abs(sin(t))*main_h*0.7[out]"
    

FFmpeg视频多宫格处理

  • 视频除了画中画显示,还有一种场景为以多宫格的方式呈现出来,除了可以输入视频文件,还可以输入视频流、采集设备等。从前文中可以看出进行视频图像处理时,overlay 滤镜为关键画布,可以通过 FFmpeg建立一个画布,也可以使用默认的画布。如果想以多宫格的方式展现,则可以自己建立一个足够大的画布,下面就来看一下多宫格展示的例子:

    ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v] setpts=PTS-STARTPTS,scale=320x240[upperleft];[1:v]setpts=PTS-STARTPTS,scale=320x240[upperright];[2:v]setpts=PTS-STARTPTS,scale=320x240[lowerleft];[3:v]setpts=PTS-STARTPTS,scale=320x240[lowerright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320[tmp2];[tmp2][lowerleft]overlay=shortest=1:y=240[tmp3];[tmp3][lowerright]overlay=shortest=1:x=320:y=240" output_video.mp4
    
    • 1 2 3 4.mp4为文件路径,output.mp4为输出文件路径,通过nullsrc创建overlay画布,画布大小640x480,使用[0:v][1:v][2:v][3:v]将输入的 4 个视频流去除,分别进行缩放处理,然后基于nullsrc生成的画布进行视频平铺,命令中自定义 upperleft,upperright,lowerleft,lowerright 进行不同位置平铺。

    • 只叠加左上右上的命令

      ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v]setpts=PTS-STARTPTS,scale=320x240[upperleft];[1:v]setpts=PTS-STARTPTS,scale=320x240[upperright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320" output_video.mp4
      
  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值