强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

FFmpeg 多媒体处理教程 / 滤镜系统

滤镜系统

概述

FFmpeg 的滤镜系统(Filter System)是其最强大的功能之一,允许对音视频进行各种处理和转换。滤镜通过滤镜图(Filtergraph)连接,支持复杂的处理流程。

滤镜基础

滤镜语法

[input]filter1=param1:param2,filter2=param1,filter3[output]

基本概念

概念说明
滤镜(Filter)处理单元,对音视频进行转换
滤镜图(Filtergraph)滤镜的连接图
滤镜链(Filterchain)用逗号分隔的滤镜序列
滤镜图链接(Filtergraph link)用分号分隔的滤镜链
输入(Input)滤镜的输入流
输出(Output)滤镜的输出流

滤镜选项

# 使用 -vf 指定视频滤镜
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4

# 使用 -af 指定音频滤镜
ffmpeg -i input.mp4 -af "volume=2.0" output.mp4

# 使用 -filter_complex 指定复杂滤镜图
ffmpeg -i input.mp4 -filter_complex "[0:v]scale=1280:720[v]" -map "[v]" output.mp4

视频滤镜

几何变换滤镜

scale(缩放)

# 基本缩放
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4

# 保持宽高比
ffmpeg -i input.mp4 -vf "scale=1280:-1" output.mp4

# 使用表达式
ffmpeg -i input.mp4 -vf "scale=iw/2:ih/2" output.mp4

# 指定算法
ffmpeg -i input.mp4 -vf "scale=1280:720:flags=lanczos" output.mp4

crop(裁剪)

# 基本裁剪
ffmpeg -i input.mp4 -vf "crop=640:480:0:0" output.mp4

# 裁剪中心区域
ffmpeg -i input.mp4 -vf "crop=in_w-100:in_h-100" output.mp4

# 保持宽高比裁剪
ffmpeg -i input.mp4 -vf "crop=in_w:in_w*9/16" output.mp4

rotate(旋转)

# 旋转 45 度
ffmpeg -i input.mp4 -vf "rotate=PI/4" output.mp4

# 旋转 90 度
ffmpeg -i input.mp4 -vf "rotate=PI/2" output.mp4

# 填充黑色背景
ffmpeg -i input.mp4 -vf "rotate=PI/4:fillcolor=black" output.mp4

transpose(转置)

# 顺时针旋转 90 度
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4

# 逆时针旋转 90 度
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4

# 旋转 180 度
ffmpeg -i input.mp4 -vf "transpose=1,transpose=1" output.mp4

hflip/vflip(翻转)

# 水平翻转
ffmpeg -i input.mp4 -vf "hflip" output.mp4

# 垂直翻转
ffmpeg -i input.mp4 -vf "vflip" output.mp4

pad(填充)

# 添加黑边
ffmpeg -i input.mp4 -vf "pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4

# 指定填充颜色
ffmpeg -i input.mp4 -vf "pad=1920:1080:(ow-iw)/2:(oh-ih)/2:color=blue" output.mp4

颜色调整滤镜

eq(均衡器)

# 调整亮度
ffmpeg -i input.mp4 -vf "eq=brightness=0.1" output.mp4

# 调整对比度
ffmpeg -i input.mp4 -vf "eq=contrast=1.2" output.mp4

# 调整饱和度
ffmpeg -i input.mp4 -vf "eq=saturation=1.5" output.mp4

# 调整伽马
ffmpeg -i input.mp4 -vf "eq=gamma=1.2" output.mp4

# 组合调整
ffmpeg -i input.mp4 -vf "eq=brightness=0.05:contrast=1.1:saturation=1.2:gamma=1.1" output.mp4

hue(色调)

# 调整色调
ffmpeg -i input.mp4 -vf "hue=h=30" output.mp4

# 调整饱和度
ffmpeg -i input.mp4 -vf "hue=s=0.5" output.mp4

# 调整亮度
ffmpeg -i input.mp4 -vf "hue=b=0.1" output.mp4

colorbalance(色彩平衡)

# 调整阴影色调
ffmpeg -i input.mp4 -vf "colorbalance=rs=0.1:gs=-0.1:bs=-0.1" output.mp4

# 调整中间色调
ffmpeg -i input.mp4 -vf "colorbalance=rm=0.1:gm=-0.1:bm=-0.1" output.mp4

# 调整高光色调
ffmpeg -i input.mp4 -vf "colorbalance=rh=0.1:gh=-0.1:bh=-0.1" output.mp4

curves(曲线)

# 轻度提亮
ffmpeg -i input.mp4 -vf "curves=lighter" output.mp4

# 轻度变暗
ffmpeg -i input.mp4 -vf "curves=darker" output.mp4

# 增强对比度
ffmpeg -i input.mp4 -vf "curves=stronger" output.mp4

# 自定义曲线
ffmpeg -i input.mp4 -vf "curves=r='0/0 0.5/0.6 1/1'" output.mp4

colorchannelmixer(颜色通道混合)

# 转换为灰度图
ffmpeg -i input.mp4 -vf "colorchannelmixer=rr=0.3:gg=0.4:bb=0.3" output.mp4

# 增强红色
ffmpeg -i input.mp4 -vf "colorchannelmixer=rr=1.5" output.mp4

# 色调偏移
ffmpeg -i input.mp4 -vf "colorchannelmixer=rr=0.5:rg=0.5:rb=0:gr=0:gg=1:gb=0:br=0:bg=0:bb=1" output.mp4

模糊和锐化滤镜

boxblur(盒式模糊)

# 基本模糊
ffmpeg -i input.mp4 -vf "boxblur=5:5" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "boxblur=luma_radius=5:luma_power=2:chroma_radius=3:chroma_power=1" output.mp4

gblur(高斯模糊)

# 基本高斯模糊
ffmpeg -i input.mp4 -vf "gblur=sigma=5" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "gblur=sigma=5:steps=3" output.mp4

unsharp(锐化)

# 基本锐化
ffmpeg -i input.mp4 -vf "unsharp=5:5:1.0:5:5:0.0" output.mp4

# 轻度锐化
ffmpeg -i input.mp4 -vf "unsharp=3:3:0.5" output.mp4

# 强锐化
ffmpeg -i input.mp4 -vf "unsharp=5:5:2.0" output.mp4

去噪滤镜

hqdn3d

# 基本去噪
ffmpeg -i input.mp4 -vf "hqdn3d" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "hqdn3d=4:3:6:4.5" output.mp4

nlmeans

# 基本去噪
ffmpeg -i input.mp4 -vf "nlmeans=s=7" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "nlmeans=s=10:p=7:r=15" output.mp4

文字和绘制滤镜

drawtext(文字绘制)

# 基本文字
ffmpeg -i input.mp4 -vf "drawtext=text='Hello World':x=10:y=10:fontsize=24:fontcolor=white" output.mp4

# 带背景的文字
ffmpeg -i input.mp4 -vf "drawtext=text='Hello':x=10:y=10:fontsize=24:fontcolor=white:box=1:boxcolor=black@0.5" output.mp4

# 时间戳文字
ffmpeg -i input.mp4 -vf "drawtext=text='%{localtime\:%Y-%m-%d %H\\\:%M\\\:%S}':x=10:y=10:fontsize=24:fontcolor=white" output.mp4

# 帧计数
ffmpeg -i input.mp4 -vf "drawtext=text='%{frame_num}':x=10:y=10:fontsize=24:fontcolor=white" output.mp4

# 动态位置
ffmpeg -i input.mp4 -vf "drawtext=text='Scroll':x='mod(n, width)':y=10:fontsize=24:fontcolor=white" output.mp4

drawbox(绘制矩形)

# 基本矩形
ffmpeg -i input.mp4 -vf "drawbox=x=10:y=10:w=200:h=100:color=red@0.5:t=fill" output.mp4

# 边框矩形
ffmpeg -i input.mp4 -vf "drawbox=x=10:y=10:w=200:h=100:color=red:t=3" output.mp4

drawgrid(绘制网格)

# 基本网格
ffmpeg -i input.mp4 -vf "drawgrid=w=100:h=100:t=1:c=white@0.5" output.mp4

特效滤镜

fade(淡入淡出)

# 淡入
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=2" output.mp4

# 淡出
ffmpeg -i input.mp4 -vf "fade=t=out:st=58:d=2" output.mp4

# 组合
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=2,fade=t=out:st=58:d=2" output.mp4

overlay(叠加)

# 右下角叠加
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[1:v]scale=320:240[pip];[0:v][pip]overlay=W-w-10:H-h-10" output.mp4

# 居中叠加
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[0:v][1:v]overlay=(W-w)/2:(H-h)/2" output.mp4

# 动态位置
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[0:v][1:v]overlay='mod(n, W)':10" output.mp4

concat(拼接)

# 视频拼接
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0" output.mp4

# 带音频拼接
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" output.mp4

稳定滤镜

vidstab(视频稳定)

# 第一遍:分析
ffmpeg -i input.mp4 -vf "vidstabdetect=shakiness=5:accuracy=15:result=transforms.trf" -f null -

# 第二遍:应用
ffmpeg -i input.mp4 -vf "vidstabtransform=input=transforms.trf:smoothing=30:zoom=5" output.mp4

deshake

# 基本稳定
ffmpeg -i input.mp4 -vf "deshake" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "deshake=x=-1:y=-1:w=-1:h=-1:rx=16:ry=16" output.mp4

音频滤镜

音量控制滤镜

volume

# 音量加倍
ffmpeg -i input.mp4 -af "volume=2.0" output.mp4

# 使用分贝
ffmpeg -i input.mp4 -af "volume=10dB" output.mp4

# 动态音量
ffmpeg -i input.mp4 -af "volume='if(lt(t,10),1,0.5)'" output.mp4

loudnorm

# 响度归一化
ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" output.mp4

淡入淡出滤镜

afade

# 淡入
ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=3" output.mp4

# 淡出
ffmpeg -i input.mp4 -af "afade=t=out:st=57:d=3" output.mp4

# 使用曲线
ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=3:curve=exp" output.mp4

均衡器滤镜

equalizer

# 调整特定频率
ffmpeg -i input.mp4 -af "equalizer=f=1000:t=q:w=2:g=5" output.mp4

# 多频段均衡
ffmpeg -i input.mp4 -af "equalizer=f=100:t=q:w=1:g=3,equalizer=f=1000:t=q:w=1:g=2,equalizer=f=10000:t=q:w=1:g=1" output.mp4

bass/treble

# 低音增强
ffmpeg -i input.mp4 -af "bass=g=10" output.mp4

# 高音增强
ffmpeg -i input.mp4 -af "treble=g=10" output.mp4

滤波器滤镜

highpass/lowpass

# 高通滤波
ffmpeg -i input.mp4 -af "highpass=f=80" output.mp4

# 低通滤波
ffmpeg -i input.mp4 -af "lowpass=f=8000" output.mp4

# 带通滤波
ffmpeg -i input.mp4 -af "highpass=f=200,lowpass=f=3000" output.mp4

bandpass/bandreject

# 带通滤波
ffmpeg -i input.mp4 -af "bandpass=f=1000:w=500" output.mp4

# 带阻滤波
ffmpeg -i input.mp4 -af "bandreject=f=1000:w=100" output.mp4

降噪滤镜

afftdn

# 基本降噪
ffmpeg -i input.mp4 -af "afftdn=nf=-25" output.mp4

# 自适应降噪
ffmpeg -i input.mp4 -af "afftdn=nf=-25:nt=w" output.mp4

anlmdn

# 基本降噪
ffmpeg -i input.mp4 -af "anlmdn=s=7" output.mp4

混音滤镜

amix

# 混合两个音频
ffmpeg -i audio1.mp3 -i audio2.mp3 -filter_complex "[0:a][1:a]amix=inputs=2:duration=longest" output.mp3

# 设置权重
ffmpeg -i audio1.mp3 -i audio2.mp3 -filter_complex "[0:a][1:a]amix=inputs=2:weights=1 0.5" output.mp3

速度调整滤镜

atempo

# 加速
ffmpeg -i input.mp4 -af "atempo=2.0" output.mp4

# 减速
ffmpeg -i input.mp4 -af "atempo=0.5" output.mp4

# 多级调整
ffmpeg -i input.mp4 -af "atempo=2.0,atempo=2.0" output.mp4  # 4倍速

特效滤镜

aecho(回声)

# 基本回声
ffmpeg -i input.mp4 -af "aecho=0.8:0.88:60:0.4" output.mp4

# 多重回声
ffmpeg -i input.mp4 -af "aecho=0.8:0.9:1000|1500|2000:0.3|0.2|0.1" output.mp4

chorus(合唱)

# 基本合唱
ffmpeg -i input.mp4 -af "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3" output.mp4

vibrato(颤音)

# 基本颤音
ffmpeg -i input.mp4 -af "vibrato=f=5:d=0.2" output.mp4

复合滤镜

滤镜图语法

# 基本滤镜图
ffmpeg -i input.mp4 -filter_complex "[0:v]scale=1280:720[v]" -map "[v]" output.mp4

# 多输入滤镜图
ffmpeg -i video.mp4 -i watermark.png -filter_complex "[0:v][1:v]overlay=10:10[v]" -map "[v]" output.mp4

# 多输出滤镜图
ffmpeg -i input.mp4 -filter_complex "[0:v]split=2[v1][v2]" -map "[v1]" output1.mp4 -map "[v2]" output2.mp4

滤镜链

# 使用逗号连接多个滤镜
ffmpeg -i input.mp4 -vf "scale=1280:720,hflip,volume=2.0" output.mp4

# 使用分号连接多个滤镜链
ffmpeg -i input.mp4 -filter_complex "[0:v]scale=1280:720[v];[0:a]volume=2.0[a]" -map "[v]" -map "[a]" output.mp4

常用复合操作

画中画

# 基本画中画
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex \
    "[1:v]scale=320:240[pip]; \
     [0:v][pip]overlay=W-w-10:H-h-10[outv]" \
    -map "[outv]" -map 0:a output.mp4

# 带边框的画中画
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex \
    "[1:v]scale=320:240,pad=324:244:2:2:black[pip]; \
     [0:v][pip]overlay=W-w-10:H-h-10[outv]" \
    -map "[outv]" -map 0:a output.mp4

画中画动画

# 移动的画中画
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex \
    "[1:v]scale=320:240[pip]; \
     [0:v][pip]overlay='mod(n*2, W)':10[outv]" \
    -map "[outv]" -map 0:a output.mp4

视频拼接

# 水平拼接
ffmpeg -i left.mp4 -i right.mp4 -filter_complex \
    "[0:v][1:v]hstack[outv]" \
    -map "[outv]" output.mp4

# 垂直拼接
ffmpeg -i top.mp4 -i bottom.mp4 -filter_complex \
    "[0:v][1:v]vstack[outv]" \
    -map "[outv]" output.mp4

# 2x2 网格
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -filter_complex \
    "[0:v][1:v]hstack[top]; \
     [2:v][3:v]hstack[bottom]; \
     [top][bottom]vstack[outv]" \
    -map "[outv]" output.mp4

视频混合

# 叠加混合
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
    "[0:v][1:v]blend=all_mode=overlay:all_opacity=0.5[outv]" \
    -map "[outv]" output.mp4

# 变暗混合
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
    "[0:v][1:v]blend=all_mode=darken[outv]" \
    -map "[outv]" output.mp4

音频混合

# 基本混合
ffmpeg -i audio1.mp3 -i audio2.mp3 -filter_complex \
    "[0:a][1:a]amix=inputs=2:duration=longest[outa]" \
    -map "[outa]" output.mp3

# 带音量调整的混合
ffmpeg -i music.mp3 -i voice.mp3 -filter_complex \
    "[0:a]volume=0.3[music]; \
     [music][1:a]amix=inputs=2:duration=longest[outa]" \
    -map "[outa]" output.mp3

滤镜图高级用法

条件滤镜

# 根据时间应用滤镜
ffmpeg -i input.mp4 -vf "drawtext=text='Intro':x=10:y=10:fontsize=24:fontcolor=white:enable='lt(t,5)'" output.mp4

# 根据帧号应用滤镜
ffmpeg -i input.mp4 -vf "drawtext=text='%{frame_num}':x=10:y=10:fontsize=24:fontcolor=white:enable='lt(n,100)'" output.mp4

帧选择

# 选择特定帧
ffmpeg -i input.mp4 -vf "select='eq(n,0)+eq(n,10)+eq(n,20)'" -vsync vfr output.mp4

# 选择关键帧
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -vsync vfr output.mp4

# 每 10 帧选择 1 帧
ffmpeg -i input.mp4 -vf "select='not(mod(n,10))'" -vsync vfr output.mp4

帧率处理

# 改变帧率
ffmpeg -i input.mp4 -vf "fps=30" output.mp4

# 去除重复帧
ffmpeg -i input.mp4 -vf "fps=fps=source_fps:round=near" output.mp4

# 插帧
ffmpeg -i input.mp4 -vf "minterpolate=fps=60:mi_mode=mci" output.mp4

自定义滤镜

使用滤镜脚本

# 创建滤镜脚本文件
cat > filter_script.txt << 'EOF'
[0:v]scale=1280:720,hflip[v];
[0:a]volume=2.0[a]
EOF

# 使用滤镜脚本
ffmpeg -i input.mp4 -filter_complex_script filter_script.txt -map "[v]" -map "[a]" output.mp4

滤镜图复用

# 定义常用滤镜图
FILTER_GRAPH="[0:v]scale=1280:720:flags=lanczos,eq=brightness=0.05:contrast=1.1[v]"

# 使用
ffmpeg -i input.mp4 -filter_complex "$FILTER_GRAPH" -map "[v]" output.mp4

滤镜性能优化

滤镜线程

# 设置滤镜线程数
ffmpeg -i input.mp4 -filter_complex_threads 4 -vf "scale=1280:720" output.mp4

滤镜格式

# 指定中间格式(提高性能)
ffmpeg -i input.mp4 -vf "format=yuv420p,scale=1280:720" output.mp4

滤镜链优化

# 将缩放放在前面(减少后续处理数据量)
ffmpeg -i input.mp4 -vf "scale=640:360,hqdn3d,eq=brightness=0.05" output.mp4

# 避免不必要的格式转换
ffmpeg -i input.mp4 -vf "scale=1280:720:flags=lanczos" -c:v libx264 output.mp4

常用滤镜组合

视频增强组合

# 轻度增强
ffmpeg -i input.mp4 -vf "unsharp=3:3:0.5,eq=brightness=0.03:contrast=1.05:saturation=1.1" output.mp4

# 强增强
ffmpeg -i input.mp4 -vf "unsharp=5:5:1.0,eq=brightness=0.05:contrast=1.2:saturation=1.3,hqdn3d" output.mp4

电影效果组合

# 胶片效果
ffmpeg -i input.mp4 -vf "curves=vintage,unsharp=3:3:0.5,eq=contrast=1.1:saturation=0.9" output.mp4

# 黑白效果
ffmpeg -i input.mp4 -vf "colorchannelmixer=rr=0.3:rg=0.4:rb=0.3:gr=0.3:gg=0.4:gb=0.3:br=0.3:bg=0.4:bb=0.3" output.mp4

社交媒体组合

# Instagram 风格
ffmpeg -i input.mp4 -vf "scale=1080:1080:force_original_aspect_ratio=decrease,pad=1080:1080:(ow-iw)/2:(oh-ih)/2,curves=vintage" output.mp4

# TikTok 风格
ffmpeg -i input.mp4 -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" output.mp4

注意事项

  1. 性能影响:复杂滤镜链会显著增加处理时间
  2. 内存占用:高分辨率视频处理需要大量内存
  3. 滤镜顺序:滤镜按顺序执行,顺序不同结果可能不同
  4. 格式兼容:某些滤镜对输入格式有要求
  5. 质量损失:多次处理会导致质量累积损失

业务场景

场景 1:视频水印批量添加

#!/bin/bash
# batch_watermark.sh

INPUT_DIR=$1
WATERMARK=$2
OUTPUT_DIR=${3:-output}

mkdir -p "$OUTPUT_DIR"

for file in "$INPUT_DIR"/*.mp4; do
    filename=$(basename "$file")
    output="$OUTPUT_DIR/$filename"
    
    ffmpeg -y -i "$file" -i "$WATERMARK" -filter_complex \
        "[1:v]scale=100:-1[wm]; \
         [0:v][wm]overlay=W-w-10:H-h-10[v]" \
        -map "[v]" -map 0:a -c:v libx264 -crf 23 -c:a copy "$output"
done

场景 2:视频片头片尾添加

#!/bin/bash
# add_intro_outro.sh

INPUT=$1
INTRO=$2
OUTRO=$3
OUTPUT=$4

ffmpeg -y -i "$INTRO" -i "$INPUT" -i "$OUTRO" -filter_complex \
    "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
    -map "[outv]" -map "[outa]" -c:v libx264 -crf 23 "$OUTPUT"

场景 3:视频转 GIF

# 高质量 GIF
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif

# 低质量 GIF
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1" output.gif

扩展阅读

  1. FFmpeg 滤镜文档
  2. FFmpeg 滤镜图
  3. FFmpeg 表达式
  4. FFmpeg 像素格式

总结

本章介绍了 FFmpeg 的滤镜系统,包括:

  • 视频滤镜(几何变换、颜色调整、模糊锐化、特效等)
  • 音频滤镜(音量、均衡、滤波、特效等)
  • 复合滤镜(画中画、拼接、混合等)
  • 滤镜图语法和高级用法

掌握滤镜系统可以帮助您实现各种复杂的音视频处理需求。