19、FFmpeg命令行工具:常用命令参数解析、批量处理脚本、自定义滤镜链
说实话,FFmpeg 这玩意儿,我用了快十年了。每次接手新项目,第一件事就是拿它探路——看看视频是什么编码、音频什么格式、有没有隐藏流。它就像音视频开发者的瑞士军刀,啥都能干。
这一章,咱们就聊聊 FFmpeg 的命令行。别小看它,很多高级功能其实都是命令行参数的组合。我个人习惯把常用命令记在一个小本本上,省得每次都要翻文档。
19.1 核心命令参数解析
先说说最常用的几个参数。你想想看,FFmpeg 的命令结构其实很简单:
ffmpeg [全局参数] [输入文件参数] -i 输入文件 [输出文件参数] 输出文件
就这么个套路。但里面的门道可不少。
19.1.1 常用全局参数
| 参数 | 说明 | 示例 |
|---|---|---|
| -y | 覆盖输出文件,不询问 | ffmpeg -y -i input.mp4 output.avi |
| -n | 不覆盖输出文件 | ffmpeg -n -i input.mp4 output.avi |
| -loglevel | 设置日志级别 | ffmpeg -loglevel debug -i input.mp4 ... |
| -hide_banner | 隐藏编译信息 | ffmpeg -hide_banner -i input.mp4 ... |
我记得刚入行那会儿,有个同事在服务器上跑 FFmpeg,日志刷了满屏,把监控系统都搞报警了。后来我告诉他加个 -loglevel error,世界清净了。嗯,这里要注意,调试的时候别加,否则看不到错误信息。
19.1.2 视频参数
| 参数 | 说明 | 示例 |
|---|---|---|
| -c:v | 指定视频编码器 | -c:v libx264 |
| -b:v | 设置视频码率 | -b:v 2M |
| -r | 设置帧率 | -r 30 |
| -s | 设置分辨率 | -s 1920x1080 |
| -vf | 视频滤镜链 | -vf "scale=1280:720" |
这里有个坑,我踩过好几次。码率设置 -b:v 2M 这个 M 是大写,小写 m 会被当成毫比特。曾经有个项目,我写成了 -b:v 2m,结果出来的视频糊得没法看,排查了半天才发现是单位写错了。
19.1.3 音频参数
| 参数 | 说明 | 示例 |
|---|---|---|
| -c:a | 指定音频编码器 | -c:a aac |
| -b:a | 设置音频码率 | -b:a 128k |
| -ar | 设置采样率 | -ar 44100 |
| -ac | 设置声道数 | -ac 2 |
19.2 批量处理脚本
实际工作中,很少只处理一个文件。我经常要处理几百个视频,这时候就得写脚本了。
19.2.1 Shell 脚本批量转码
#!/bin/bash
# 批量转码脚本:将当前目录下所有 .mov 转为 .mp4
for file in *.mov; do
filename=$(basename "$file" .mov)
ffmpeg -i "$file" -c:v libx264 -c:a aac -b:v 2M "${filename}.mp4"
echo "已处理: $file"
done
这个脚本看着简单,但有个细节——文件名里有空格怎么办?我建议用双引号把变量包起来,就像上面那样。曾经有个同事没加引号,结果文件名带空格的视频全都没转成功,还报了一堆莫名其妙的错。
19.2.2 带参数校验的脚本
#!/bin/bash
# 带参数校验的批量处理脚本
if [ $# -lt 2 ]; then
echo "用法: $0 <输入目录> <输出目录> [码率]"
exit 1
fi
input_dir="$1"
output_dir="$2"
bitrate="${3:-2M}"
mkdir -p "$output_dir"
for file in "$input_dir"/*.mp4; do
if [ -f "$file" ]; then
filename=$(basename "$file")
ffmpeg -i "$file" -b:v "$bitrate" -y "$output_dir/$filename"
fi
done
echo "批量处理完成!"
19.3 自定义滤镜链
滤镜链是 FFmpeg 最强大的功能之一。说白了,就是把多个滤镜串起来,像流水线一样处理视频。
19.3.1 滤镜链的基本语法
ffmpeg -i input.mp4 -vf "filter1=param1=value1,filter2=param2=value2" output.mp4
滤镜之间用逗号分隔,按顺序执行。我刚开始学的时候,老是把分号和逗号搞混。记住:逗号是串联,分号是并联。
19.3.2 常用滤镜组合
这里分享几个我项目中常用的滤镜链:
# 缩放+裁剪+添加文字水印
ffmpeg -i input.mp4 -vf "scale=1280:720,crop=1200:680:40:20,drawtext=text='Hello':fontsize=24:fontcolor=white:x=10:y=10" output.mp4
# 去噪+调色+变速
ffmpeg -i input.mp4 -vf "hqdn3d=4:3:6:4,eq=brightness=0.1:contrast=1.2,setpts=0.8*PTS" output.mp4
# 画中画效果
ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex "[0:v][1:v]overlay=10:10" output.mp4
我记得有个项目要做画中画,客户要求小窗口能拖动。我折腾了半天,最后发现 FFmpeg 的 overlay 滤镜支持动态位置,用 overlay=x='if(gte(t,2),100,10)':y=10 就能实现两秒后自动移动。嗯,这个技巧后来成了我的保留节目。
19.3.3 复杂滤镜图
当滤镜链变得复杂时,可以用 -filter_complex 参数。它支持更灵活的分流和合并:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split[base][overlay]; \
[base]scale=1280:720[bg]; \
[overlay]scale=320:240[small]; \
[bg][small]overlay=W-w-10:H-h-10" \
output.mp4
这个例子把视频分成两路,一路做背景,一路缩小后叠加到右下角。你想想看,这种效果在直播推流、视频会议里特别常见。
19.4 知识体系图
下面这张图,是我整理的本章知识结构。你可以把它当成一个快速索引:
19.5 避坑指南与实战经验
最后,分享几个我这些年踩过的坑:
- 路径问题:Windows 下路径用反斜杠,但 FFmpeg 里最好用正斜杠或者双反斜杠。我曾经在 Windows 上写脚本,路径里用了单反斜杠,结果 FFmpeg 把它当成了转义符。
- 编码器选择:不是所有编码器都支持所有参数。比如 libx264 支持
-preset和-crf,但硬件编码器 h264_nvenc 就不支持-crf。我建议先ffmpeg -encoders | grep 264看看有哪些可用。 - 滤镜顺序:滤镜的执行顺序会影响最终效果。比如先缩放再裁剪,和先裁剪再缩放,结果完全不同。我一般先做几何变换(缩放、裁剪),再做色彩调整,最后加文字水印。
- 内存管理:处理 4K 视频时,滤镜链可能会消耗大量内存。如果遇到内存不足,可以试试
-threads 4限制线程数,或者用-vf "scale=1920:1080"先降低分辨率。
-vf "null" 看看原始画面,然后逐个添加滤镜,每加一个就输出一帧看看效果。这样能快速定位是哪个滤镜出了问题。
好了,这一章的内容就到这里。FFmpeg 命令行工具看着简单,但真正用好它,需要大量的实践和踩坑。我建议你找个视频文件,把上面这些命令都跑一遍,感受一下参数变化带来的效果差异。只有亲手试过,才能真正理解。