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

FFmpeg 多媒体处理教程 / 视频处理

视频处理

概述

FFmpeg 提供了丰富的视频处理功能,包括裁剪、缩放、旋转、翻转、去噪、稳定等操作。这些功能主要通过视频滤镜(Video Filter)实现。

视频裁剪

基本裁剪

裁剪滤镜语法:

crop=w:h:x:y
参数说明
w输出宽度
h输出高度
x左上角 x 坐标
y左上角 y 坐标
# 裁剪 640x480 区域(从左上角开始)
ffmpeg -i input.mp4 -vf crop=640:480 output.mp4

# 从指定位置裁剪
ffmpeg -i input.mp4 -vf crop=640:480:100:50 output.mp4

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

智能裁剪

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

# 保持宽高比裁剪到 4:3
ffmpeg -i input.mp4 -vf "crop=in_h*4/3:in_h" output.mp4

# 自动裁剪黑边
ffmpeg -i input.mp4 -vf "cropdetect=24:16:0" output.mp4

# 使用检测到的参数裁剪
ffmpeg -i input.mp4 -vf "crop=640:480:0:30" output.mp4

裁剪参数表达式

# 使用表达式
ffmpeg -i input.mp4 -vf "crop=in_w/2:in_h/2:in_w/4:in_h/4" output.mp4

# 使用变量
# iw, ih - 输入宽高
# ow, oh - 输出宽高
# n - 帧序号
# t - 时间(秒)
ffmpeg -i input.mp4 -vf "crop=iw/2:ih/2" output.mp4

视频缩放

基本缩放

缩放滤镜语法:

scale=w:h
# 缩放到固定尺寸
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4

# 缩放到 720p
ffmpeg -i input.mp4 -vf scale=-1:720 output.mp4

# 缩放到 1080p
ffmpeg -i input.mp4 -vf scale=-1:1080 output.mp4

# 缩放到 4K
ffmpeg -i input.mp4 -vf scale=3840:2160 output.mp4

保持宽高比缩放

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

# 保持宽高比,宽度自适应
ffmpeg -i input.mp4 -vf "scale=-1:720" output.mp4

# 保持宽高比,确保不超过目标尺寸
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease" output.mp4

# 填充黑边保持宽高比
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4

缩放算法

算法说明适用场景
bilinear双线性插值快速缩放
bicubic双三次插值通用缩放
lanczosLanczos 采样高质量缩放
spline样条插值高质量缩放
neighbor最近邻像素艺术
# 使用指定算法
ffmpeg -i input.mp4 -vf "scale=1280:720:flags=lanczos" output.mp4

# 使用 bicubic 算法
ffmpeg -i input.mp4 -vf "scale=1280:720:flags=bicubic" output.mp4

常用分辨率

名称分辨率宽高比
240p426×24016:9
360p640×36016:9
480p854×48016:9
720p1280×72016:9
1080p1920×108016:9
1440p2560×144016:9
4K3840×216016:9
8K7680×432016:9

视频旋转

旋转选项

# 顺时针旋转 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

# 使用 rotate 滤镜
ffmpeg -i input.mp4 -vf "rotate=PI/2" output.mp4

transpose 参数

说明
0逆时针旋转 90 度并垂直翻转
1顺时针旋转 90 度
2逆时针旋转 90 度
3顺时针旋转 90 度并垂直翻转

自动旋转

# 根据元数据自动旋转
ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=0 output.mp4

# 使用 autorotate
ffmpeg -i input.mp4 -autorotate 1 output.mp4

视频翻转

水平翻转

# 水平翻转(镜像)
ffmpeg -i input.mp4 -vf hflip output.mp4

垂直翻转

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

同时翻转

# 水平和垂直翻转
ffmpeg -i input.mp4 -vf "hflip,vflip" output.mp4

视频去噪

常用去噪滤镜

滤镜说明适用场景
hqdn3d高质量 3D 去噪通用去噪
nlmeans非局部均值去噪高质量去噪
dctdnoizDCT 去噪压缩噪声
removegrain去除颗粒胶片颗粒
atadenoiseATA 去噪实时去噪

hqdn3d 去噪

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

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

# 参数说明
# luma_spatial: luma 空间强度 (默认 4)
# chroma_spatial: chroma 空间强度 (默认 3)
# luma_tmp: luma 时间强度 (默认 6)
# chroma_tmp: chroma 时间强度 (默认 4.5)

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

# 参数说明
# s: 去噪强度 (默认 7)
# p: 补丁大小 (默认 7)
# r: 搜索区域大小 (默认 15)

dctdnoiz 去噪

# 基本去噪
ffmpeg -i input.mp4 -vf "dctdnoiz=4.5" output.mp4

# 自定义参数
ffmpeg -i input.mp4 -vf "dctdnoiz=4.5:2:3:all" output.mp4

atadenoise 去噪

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

# 自定义参数
ffmpeg -i input.mp4 -vf "atadenoise=0.2:0.2:0.2:0.5:0.5:0.5" 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

vidstab 参数

参数说明默认值
shakiness抖动程度 (1-10)5
accuracy检测精度 (1-15)15
stepsize步长6
mincontrast最小对比度0.25
smoothing平滑帧数10
zoom缩放百分比0
optzoom自动缩放 (0-2)1
interpol插值方法bilinear

完整稳定脚本

#!/bin/bash
# stabilize.sh

INPUT=$1
OUTPUT=$2
SHAKINESS=${3:-5}
SMOOTHING=${30:-30}

# 第一遍分析
ffmpeg -y -i "$INPUT" \
    -vf "vidstabdetect=shakiness=$SHAKINESS:accuracy=15:result=transforms.trf" \
    -f null -

# 第二遍应用
ffmpeg -y -i "$INPUT" \
    -vf "vidstabtransform=input=transforms.trf:smoothing=$SMOOTHING:zoom=5:optzoom=1" \
    -c:v libx264 -crf 23 \
    -c:a copy \
    "$OUTPUT"

# 清理
rm -f transforms.trf

echo "稳定完成: $OUTPUT"

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:edge=mirror" output.mp4

画面增强

亮度对比度调整

# 调整亮度和对比度
ffmpeg -i input.mp4 -vf "eq=brightness=0.1:contrast=1.2" output.mp4

# 参数说明
# brightness: 亮度 (-1.0 到 1.0)
# contrast: 对比度 (0.0 到 2.0)
# saturation: 饱和度 (0.0 到 3.0)
# gamma: 伽马值 (0.1 到 10.0)

色彩调整

# 调整饱和度
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

锐化

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

# 参数说明
# luma_msize_x: luma 水平尺寸 (默认 5)
# luma_msize_y: luma 垂直尺寸 (默认 5)
# luma_amount: luma 锐化强度 (默认 1.0)
# chroma_msize_x: chroma 水平尺寸 (默认 5)
# chroma_msize_y: chroma 垂直尺寸 (默认 5)
# chroma_amount: chroma 锐化强度 (默认 0.0)

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

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

色彩校正

# 白平衡调整
ffmpeg -i input.mp4 -vf "colorbalance=rs=0.1:gs=-0.1:bs=-0.1" output.mp4

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

# 曲线调整
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 "pad=1920:1080:0:0:black" output.mp4

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

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

裁剪与填充组合

# 缩放并填充到 16:9
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4

# 缩放并填充到 4:3
ffmpeg -i input.mp4 -vf "scale=1440:1080:force_original_aspect_ratio=decrease,pad=1440:1080:(ow-iw)/2:(oh-ih)/2" output.mp4

画面叠加

水印叠加

# 右下角水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4

# 左上角水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" output.mp4

# 居中水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=(W-w)/2:(H-h)/2" output.mp4

# 带透明度的水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "[1:v]format=rgba,colorchannelmixer=aa=0.5[wm];[0:v][wm]overlay=W-w-10:H-h-10" 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" output.mp4

# 左上角画中画
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[1:v]scale=320:240[pip];[0:v][pip]overlay=10:10" output.mp4

# 可切换位置
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[1:v]scale=320:240[pip];[0:v][pip]overlay='if(gte(t,2),W-w-10,10)':H-h-10" output.mp4

画面特效

淡入淡出

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

# 淡出(最后 2 秒)
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

模糊效果

# 高斯模糊
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

# 智能模糊(保留边缘)
ffmpeg -i input.mp4 -vf "smartblur=5:1.0:-0.5" output.mp4

边缘检测

# 边缘检测
ffmpeg -i input.mp4 -vf "edgedetect=low=0.1:high=0.4" output.mp4

# Canny 边缘检测
ffmpeg -i input.mp4 -vf "edgedetect=mode=canny" output.mp4

画面合成

拼接视频

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

# 垂直拼接
ffmpeg -i top.mp4 -i bottom.mp4 -filter_complex "[0:v][1:v]vstack" 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" \
    output.mp4

画面混合

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

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

# 变亮混合
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v][1:v]blend=all_mode=lighten" output.mp4

画面裁剪区域

动态裁剪

# 随时间移动裁剪区域
ffmpeg -i input.mp4 -vf "crop=640:480:n*10:0" output.mp4

# 跟踪移动对象
ffmpeg -i input.mp4 -vf "crop=640:480:'if(gte(t,2),100,0)':0" output.mp4

画面缩放动画

缩放动画

# 缩放动画(从 1x 到 2x)
ffmpeg -i input.mp4 -vf "zoompan=z='min(zoom+0.0015,1.5)':d=125:s=1280x720" output.mp4

# Ken Burns 效果
ffmpeg -i input.mp4 -vf "zoompan=z='min(max(zoom,pzoom)+0.0015,1.5)':d=125:s=1280x720:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)'" output.mp4

批量处理

批量裁剪脚本

#!/bin/bash
# batch_crop.sh

INPUT_DIR=${1:-.}
OUTPUT_DIR=${2:-cropped}
CROP=${3:-640:480:0:0}

mkdir -p "$OUTPUT_DIR"

for file in "$INPUT_DIR"/*.mp4; do
    filename=$(basename "$file")
    output="$OUTPUT_DIR/$filename"
    
    echo "裁剪: $file"
    ffmpeg -y -i "$file" -vf "crop=$CROP" -c:v libx264 -crf 23 -c:a copy "$output"
done

echo "批量裁剪完成"

批量缩放脚本

#!/bin/bash
# batch_scale.sh

INPUT_DIR=${1:-.}
OUTPUT_DIR=${2:-scaled}
RESOLUTION=${3:-1280:720}

mkdir -p "$OUTPUT_DIR"

for file in "$INPUT_DIR"/*.mp4; do
    filename=$(basename "$file")
    output="$OUTPUT_DIR/$filename"
    
    echo "缩放: $file"
    ffmpeg -y -i "$file" -vf "scale=$RESOLUTION" -c:v libx264 -crf 23 -c:a copy "$output"
done

echo "批量缩放完成"

注意事项

  1. 性能考虑:复杂的滤镜链会增加处理时间
  2. 内存占用:高分辨率视频处理需要大量内存
  3. 质量损失:多次处理会导致质量累积损失
  4. 编解码器选择:处理后建议使用高质量编解码器
  5. 测试优先:处理前先用短视频测试效果

业务场景

场景 1:视频缩略图

# 提取缩略图
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 -vf "scale=320:180" thumbnail.jpg

场景 2:社交媒体视频

# 竖屏视频(9:16)
ffmpeg -i input.mp4 -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 23 output.mp4

# 方形视频(1:1)
ffmpeg -i input.mp4 -vf "scale=1080:1080:force_original_aspect_ratio=decrease,pad=1080:1080:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 23 output.mp4

场景 3:视频监控

# 添加时间戳水印
ffmpeg -i input.mp4 -vf "drawtext=text='%{localtime\:%Y-%m-%d %H\\\:%M\\\:%S}':x=10:y=10:fontsize=24:fontcolor=white:box=1:boxcolor=black@0.5" output.mp4

场景 4:视频画廊

# 创建 2x2 视频画廊
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 \
    -filter_complex \
    "[0:v]scale=640:360[v0]; \
     [1:v]scale=640:360[v1]; \
     [2:v]scale=640:360[v2]; \
     [3:v]scale=640:360[v3]; \
     [v0][v1]hstack[top]; \
     [v2][v3]hstack[bottom]; \
     [top][bottom]vstack[out]" \
    -map "[out]" -map 0:a? output.mp4

扩展阅读

  1. FFmpeg 视频滤镜文档
  2. FFmpeg 滤镜表达式
  3. vid.stab 稳定库
  4. FFmpeg 滤镜图

总结

本章介绍了 FFmpeg 的视频处理功能,包括:

  • 视频裁剪与缩放
  • 旋转与翻转
  • 去噪与稳定
  • 画面增强与特效
  • 画面叠加与合成

掌握这些功能可以帮助您完成各种视频处理任务。