26、FFmpeg 命令行实战:常用滤镜、裁剪拼接、转码参数、ffprobe分析

说实话,FFmpeg 这玩意儿,我用了快十年了。每次项目里遇到音视频处理的需求,第一个想到的就是它。你想想看,一个命令行工具,能搞定格式转换、滤镜特效、裁剪拼接、甚至流媒体推拉,这得多强大。

今天这一章,咱们就来点实在的。不扯理论,直接上手。我会带着你过一遍 FFmpeg 最常用的几个场景:滤镜怎么加、视频怎么剪、参数怎么调、以及怎么用 ffprobe 分析文件。嗯,都是我在项目里踩过坑之后总结出来的经验。

核心提示:FFmpeg 的命令行参数顺序是有讲究的。输入文件、输出文件、滤镜链、编码参数,写错顺序很可能导致报错。我个人习惯是先写输入,再写滤镜,最后写输出参数。

26.1 常用滤镜:给视频加点料

滤镜是 FFmpeg 最吸引人的功能之一。说白了,就是给视频加特效。比如调色、加文字、画中画、甚至人脸模糊。我最早接触滤镜是在一个直播项目里,需要给主播加美颜效果,当时就是用 FFmpeg 的滤镜链搞定的。

26.1.1 基础滤镜:缩放、裁剪、旋转

先来几个最常用的。缩放视频尺寸,用 scale 滤镜:

ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4

这里 -vf 是视频滤镜的缩写。1280:720 就是目标分辨率。我曾经遇到过一个需求,要把 4K 视频压到 1080p,直接写 scale=1920:1080 就行。但要注意,如果原视频不是 16:9,直接缩放会变形。这时候可以加个 -1 让 FFmpeg 自动计算宽高比:

ffmpeg -i input.mp4 -vf "scale=1280:-1" output.mp4

裁剪视频用 crop 滤镜。格式是 crop=宽:高:x:y。比如我想从视频左上角 (100, 50) 的位置,裁剪出 640x480 的区域:

ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4

旋转视频用 transpose 滤镜。0 表示逆时针旋转 90 度,1 表示顺时针旋转 90 度,2 和 3 是翻转加旋转。我有个朋友拍视频总喜欢竖着拍,传到电脑上就是横着的,用这个命令一秒搞定:

ffmpeg -i input.mp4 -vf "transpose=1" output.mp4

26.1.2 文字水印与图片叠加

给视频加文字水印,用 drawtext 滤镜。这个我太熟了,以前做短视频工具的时候,每天都要跟它打交道。基本用法:

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

这里 x=10:y=10 是文字的位置,从左上角算起。如果你想用中文字体,得指定字体文件:

ffmpeg -i input.mp4 -vf "drawtext=text='你好':fontfile=/path/to/simsun.ttc:fontsize=24:fontcolor=white:x=10:y=10" output.mp4

注意:Windows 系统下字体路径要用双反斜杠或者正斜杠。我曾经因为路径写错,排查了半天才发现是转义问题。

图片水印用 overlay 滤镜。比如在视频右上角加个 Logo:

ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=W-w-10:10" output.mp4

W-w-10 的意思是:视频宽度减去图片宽度再减 10 像素,这样图片就贴在右边了。10 是上边距。

26.1.3 多滤镜组合:滤镜链

实际项目中,很少只用单个滤镜。比如既要缩放又要加水印,怎么办?用逗号连接:

ffmpeg -i input.mp4 -vf "scale=1280:720,drawtext=text='Test':x=10:y=10" output.mp4

滤镜的执行顺序是从左到右。先缩放,再画文字。顺序很重要,搞反了可能效果不对。

26.2 裁剪拼接:视频的剪刀手

裁剪和拼接,是视频编辑里最基础的操作。FFmpeg 做这个非常快,比 Premiere 导出快多了。

26.2.1 裁剪视频片段

-ss-t 参数。比如从第 10 秒开始,截取 30 秒:

ffmpeg -ss 00:00:10 -i input.mp4 -t 30 -c copy output.mp4

这里 -c copy 表示直接复制编码,不重新编码,速度极快。但要注意,-ss 放在 -i 前面是「快速定位」,精确到关键帧;放在后面是「精确到帧」,但速度慢。我一般用前者,除非对精度要求极高。

小技巧:如果你想截取从 10 秒到 40 秒的片段,可以用 -to 参数:ffmpeg -ss 00:00:10 -i input.mp4 -to 00:00:40 -c copy output.mp4。注意 -to 是结束时间,不是时长。

26.2.2 拼接多个视频

拼接视频有两种方式。简单粗暴的方法是用 concat 协议,适合同格式同编码的视频:

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

更推荐的方法是用文件列表。先创建一个 list.txt

file 'input1.mp4'
file 'input2.mp4'
file 'input3.mp4'

然后执行:

ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

这个方法更灵活,支持不同编码的视频(但会重新编码)。我曾经用这个方法拼接了 100 多个短视频片段,跑了一整夜,第二天早上起来一看,完美。

26.3 转码参数:压制的艺术

转码是 FFmpeg 的核心功能。说白了,就是把一种编码格式转成另一种。比如 H.264 转 H.265,或者 MP4 转 MKV。参数调得好,文件小画质高;调不好,要么文件巨大,要么画质稀烂。

26.3.1 视频编码参数

最常用的视频编码器是 libx264libx265。基本命令:

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium output.mp4

这里 -crf 是质量参数,范围 0-51。数值越小质量越高,文件越大。23 是默认值,我觉得够用了。18 以下基本看不出区别,但文件大很多。

-preset 是编码速度,有 ultrafastfastmediumslowveryslow 等。越慢压缩率越高,文件越小。我一般用 mediumslow,平衡速度和大小。

避坑指南:我曾经为了追求极致压缩,用了 veryslowcrf 28,结果一个 10 分钟的视频压了 3 个小时,画质还惨不忍睹。后来学乖了,crf 不超过 25,presetslow 就够了。

26.3.2 音频编码参数

音频编码相对简单。常用的是 aacmp3

ffmpeg -i input.mp4 -c:a aac -b:a 128k output.mp4

-b:a 是音频码率。128k 对于大多数场景够用了。如果是音乐,我会用 192k 或 256k。

如果想提取音频,可以这样:

ffmpeg -i input.mp4 -vn -c:a mp3 output.mp3

-vn 表示不要视频流。

26.3.3 硬件加速编码

如果你的电脑有独立显卡,可以用硬件编码器,速度飞起。NVIDIA 显卡用 h264_nvenc

ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -b:v 5M output.mp4

Intel 显卡用 h264_qsv,AMD 用 h264_amf。硬件编码的缺点是画质略差于软件编码,但速度快很多。我一般在预览阶段用硬件编码,最终输出用软件编码。

26.4 ffprobe 分析:视频的体检报告

ffprobe 是 FFmpeg 家族里的分析工具。它能告诉你一个视频文件的所有信息:编码格式、分辨率、码率、帧率、时长、甚至元数据。我每次拿到一个陌生视频,第一件事就是跑一下 ffprobe。

26.4.1 基本用法

最简单的用法:

ffprobe input.mp4

输出会显示流信息。但信息太多,看着乱。我一般用 -show_format-show_streams

ffprobe -show_format -show_streams input.mp4

这样会以键值对的形式输出,方便程序解析。如果你想看人类可读的格式,加个 -pretty

ffprobe -show_format -show_streams -pretty input.mp4

26.4.2 常用分析场景

查看视频分辨率:

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=noprint_wrappers=1 input.mp4

查看视频时长:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4

查看视频编码:

ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 input.mp4

实用技巧:我写过一个脚本,用 ffprobe 批量检查一个目录下所有视频的编码格式,找出那些不是 H.264 的文件,然后统一转码。这样能保证所有视频在网页上都能播放。

26.5 知识体系图

下面这张图,是我根据多年经验总结的 FFmpeg 命令行知识体系。你可以把它当作一个快速参考。

FFmpeg 命令行 常用滤镜 scale 缩放 crop 裁剪 transpose 旋转 drawtext 文字 overlay 叠加 裁剪拼接 -ss 开始时间 -t 时长 / -to 结束 -c copy 快速截取 concat 拼接 文件列表拼接 转码参数 -c:v libx264 -crf 质量参数 -preset 编码速度 -b:a 音频码率 硬件加速编码 ffprobe 分析 -show_format 格式 -show_streams 流 -select_streams 筛选

26.6 实战:一个完整的转码脚本

最后,分享一个我常用的转码脚本。它能把一个目录下所有 MP4 文件转成 H.264 编码,同时加上水印和缩放:

#!/bin/bash
# 批量转码脚本
for file in *.mp4; do
  output="processed_$file"
  ffmpeg -i "$file" \
    -vf "scale=1280:720,drawtext=text='My Watermark':fontsize=20:fontcolor=white:x=W-w-10:y=H-th-10" \
    -c:v libx264 -crf 23 -preset slow \
    -c:a aac -b:a 128k \
    "$output"
  echo "完成: $file -> $output"
done

这个脚本我用了好几年,每次有新视频需要批量处理,直接跑一遍就行。你想想看,要是手动用剪辑软件一个一个处理,得花多少时间。

好了,这一章的内容就到这里。FFmpeg 的命令行参数虽然多,但常用的就那几个。多练练,你也能像我一样,闭着眼睛写出转码命令。


公众号:蓝海资料掘金营,微信deep3321