3、简单滤镜实战:使用-vf参数、scale缩放滤镜、transpose旋转滤镜、crop裁剪滤镜
滤镜是 FFmpeg 的灵魂。说实话,我刚开始学 FFmpeg 的时候,被那一长串命令行搞得头晕。但后来我发现,只要搞懂几个基础滤镜,剩下的都是举一反三。
这一章,咱们就动手实操三个最常用的简单滤镜:scale、transpose、crop。它们分别对应缩放、旋转、裁剪,是视频处理里出现频率最高的操作。
3.1 -vf 参数:滤镜的入口
在 FFmpeg 里,所有视频滤镜都通过 -vf(video filter 的缩写)参数传入。它的基本语法是:
ffmpeg -i input.mp4 -vf "滤镜名=参数1:参数2" output.mp4
多个滤镜可以串联,用逗号分隔:
ffmpeg -i input.mp4 -vf "滤镜1,滤镜2,滤镜3" output.mp4
注意,这里的逗号是 顺序执行 的意思。前一个滤镜的输出,会成为后一个滤镜的输入。我在项目中见过有人把逗号写成冒号,结果滤镜链完全没生效——嗯,这种坑踩过一次就记住了。
ffmpeg -i input.mp4 -vf "..." -f null -。这样能快速验证滤镜链是否正确,不用等编码。
3.2 scale 滤镜:缩放视频尺寸
scale 滤镜用来改变视频的宽高。它的核心参数就两个:width 和 height。
3.2.1 基本用法
# 固定宽高
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
# 等比例缩放,只指定宽度,高度自动计算
ffmpeg -i input.mp4 -vf "scale=640:-1" output.mp4
# 等比例缩放,只指定高度,宽度自动计算
ffmpeg -i input.mp4 -vf "scale=-1:480" output.mp4
这里 -1 表示让 FFmpeg 自动计算另一边的尺寸,保持原始宽高比。我个人习惯用这种方式,因为手动算比例很容易算错,尤其是处理不同来源的视频素材时。
3.2.2 强制缩放与黑边处理
有时候我们需要把视频强制拉伸到某个尺寸,不管宽高比。这时候可以用 force_original_aspect_ratio 参数:
# 强制缩放,不保持比例(画面会变形)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=disable" output.mp4
# 保持比例,不足部分用黑边填充
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease" output.mp4
decrease 模式会在保持比例的前提下,把视频缩放到能完整放入目标尺寸内,多余部分用黑边补齐。这在做视频转码适配不同屏幕时非常实用。
3.2.3 常用缩放参数速查
| 参数 | 说明 | 示例 |
|---|---|---|
width |
目标宽度(像素) | 1280 |
height |
目标高度(像素) | 720 |
-1 |
自动计算,保持宽高比 | scale=640:-1 |
force_original_aspect_ratio |
宽高比处理策略:disable(强制)、decrease(缩小填充)、increase(放大裁剪) |
scale=1920:1080:force_original_aspect_ratio=decrease |
flags |
缩放算法,如 lanczos(高质量)、bilinear(快速) |
scale=1280:720:flags=lanczos |
3.3 transpose 滤镜:旋转与翻转
transpose 滤镜用来旋转视频画面。它接受一个数字参数,表示旋转方向和方式。
3.3.1 旋转模式对照
| 参数值 | 效果 | 适用场景 |
|---|---|---|
0 |
逆时针旋转 90° 并垂直翻转 | 矫正某些手机竖屏拍摄的视频 |
1 |
顺时针旋转 90° | 把横屏视频转成竖屏 |
2 |
逆时针旋转 90° | 把竖屏视频转成横屏 |
3 |
顺时针旋转 90° 并垂直翻转 | 特殊效果 |
# 顺时针旋转 90°
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
# 逆时针旋转 90°
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4
我记得有一次处理用户上传的婚礼视频,所有手机拍的素材都是倒着的。用 transpose=1 批量转了一下,问题就解决了。这种场景在实际工作中特别常见。
3.3.2 水平/垂直翻转
除了旋转,transpose 也能做镜像翻转。不过我更习惯用专门的 hflip 和 vflip 滤镜,语义更清晰:
# 水平翻转(镜像)
ffmpeg -i input.mp4 -vf "hflip" output.mp4
# 垂直翻转(上下颠倒)
ffmpeg -i input.mp4 -vf "vflip" output.mp4
transpose 放在 scale 前面。因为旋转会改变宽高,先旋转再缩放,能保证最终尺寸是你想要的。顺序搞反了,画面比例可能会出问题。
3.4 crop 滤镜:裁剪画面
crop 滤镜从视频中截取一个矩形区域。它的参数格式是:
crop=输出宽度:输出高度:起始X坐标:起始Y坐标
3.4.1 基本裁剪
# 从画面中心裁剪 640x480 区域
ffmpeg -i input.mp4 -vf "crop=640:480" output.mp4
# 从坐标 (100, 50) 开始裁剪 800x600 区域
ffmpeg -i input.mp4 -vf "crop=800:600:100:50" output.mp4
如果不指定起始坐标,默认从画面中心裁剪。这个默认行为很贴心,大多数时候我们确实想裁中间区域。
3.4.2 自动计算裁剪区域
FFmpeg 支持用表达式动态计算裁剪参数。比如,我想裁剪掉视频四周的黑边:
# 自动检测并裁剪黑边
ffmpeg -i input.mp4 -vf "cropdetect" output.mp4
先用 cropdetect 滤镜分析出黑边位置,然后手动应用裁剪参数。不过说实话,我更常用的是 crop 配合 iw(输入宽度)和 ih(输入高度)变量:
# 裁剪掉左右各 100 像素
ffmpeg -i input.mp4 -vf "crop=iw-200:ih" output.mp4
# 裁剪掉上下各 50 像素
ffmpeg -i input.mp4 -vf "crop=iw:ih-100" output.mp4
iw 和 ih 是 FFmpeg 内置的变量,分别代表输入视频的宽度和高度。在滤镜参数里可以直接用数学表达式,比如 iw/2、ih*0.8。这在做自适应裁剪时非常方便。
3.5 组合实战:滤镜链
实际项目中,很少只用单个滤镜。更多时候是把多个滤镜串起来用。下面是一个完整的例子:
# 先旋转,再缩放,最后裁剪
ffmpeg -i input.mp4 \
-vf "transpose=1, scale=1280:720:force_original_aspect_ratio=decrease, crop=1280:720" \
output.mp4
这个命令做了三件事:
- 把视频顺时针旋转 90°
- 缩放到 1280x720,保持比例,不足补黑边
- 裁剪掉黑边,得到纯 1280x720 画面
你看,三个滤镜串在一起,就解决了一个完整的转码需求。这就是滤镜链的魅力。
scale 和 crop 的顺序搞反了。先裁剪再缩放,结果裁剪的区域是原始尺寸的,缩放后画面内容完全不对。记住:先做几何变换(旋转、翻转),再做尺寸变换(缩放),最后做区域裁剪(crop)。这个顺序能避免大部分问题。
3.6 本章知识体系
下面这张图总结了本章三个滤镜的核心关系和使用流程:
这张图把本章的核心逻辑讲清楚了。你从输入视频开始,通过 -vf 进入滤镜链,然后根据需求选择 scale、transpose、crop 中的一个或多个,最后得到输出视频。记住那个顺序原则,基本不会出错。
3.7 本章小结
这一章我们动手实践了三个最基础的滤镜:
- scale:缩放视频尺寸,支持等比例和强制缩放
- transpose:旋转和翻转画面,四种模式对应不同方向
- crop:裁剪画面区域,支持坐标指定和表达式计算