Hello,大家好,我是 Ivan。
FFmpeg 在很多音视频项目里都会出现。视频压缩、格式转换、截取片段、提取音频,或者让程序自动处理一批视频,最后基本都会用到它。不过 FFmpeg 本身没有图形界面,安装完成以后主要通过命令行操作,第一次接触时比较容易卡在环境变量和参数上。
一、FFmpeg 是什么
FFmpeg 是一套开源的音视频处理工具。平时说的 FFmpeg,既可以指整个项目,也可以指其中最常用的 ffmpeg 命令。
安装目录里的三个程序分别负责不同的事情:
| 程序 | 作用 |
|---|---|
ffmpeg |
转换、压缩、裁剪和处理音视频 |
ffprobe |
查看媒体文件的编码、分辨率、码率和时长 |
ffplay |
播放音视频,主要用于测试和预览 |
FFmpeg 能处理 MP4、MOV、MKV、AVI、MP3、AAC 等常见格式,也支持 H.264、H.265、AV1、AAC 等编码。具体能不能使用某个编码器,还要看下载的 FFmpeg 版本在编译时包含了哪些组件。
二、Windows 安装 FFmpeg
1. 下载 Windows 版本
FFmpeg 官网主要提供源代码,Windows 用户一般直接下载已经编译好的版本。打开下面的下载页面:
进入页面以后,我们选择 ffmpeg-git-full.7z,它包含的组件更完整,文件也会大一些。如果只是做常见的转码、压缩和裁剪,essentials 通常也够用

下载完成以后,会得到一个 .7z 压缩文件。文件名里的日期和 Git 版本会随着构建更新,所以和截图不完全一致也没关系。

2. 解压 FFmpeg
如果电脑不能直接打开 .7z 文件,可以安装 7-Zip:
一般选择 Windows 64-bit x64 版本即可。如果使用的是 ARM Windows,再选择对应的 ARM64 版本。

安装 7-Zip 后,右键 FFmpeg 压缩包进行解压。解压完成的目录中会有 bin 文件夹,里面可以看到 ffmpeg.exe、ffprobe.exe 和 ffplay.exe。


建议把解压后的目录移动到一个固定位置,例如:
txt
E:\OpenSource\FFmpeg
后面添加环境变量时会使用这个目录。如果以后把文件夹移动到其他位置,原来的环境变量也要跟着修改。
3. 配置环境变量
只完成解压还不能在任意目录直接使用 ffmpeg。Windows 需要知道 ffmpeg.exe 在什么位置,所以还要把 FFmpeg 的 bin 目录加入 Path。
右键桌面上的"此电脑",选择"属性"。

在系统信息页面中找到"高级系统设置"。

接着依次打开"环境变量",在系统变量中找到 Path,点击"编辑"和"新建",加入 FFmpeg 的 bin 目录。按照前面的示例,应该填写:
txt
E:\OpenSource\FFmpeg\bin
这里必须指向 bin,不能只填 FFmpeg 的上一级目录。添加完成后,把打开的窗口逐层点击"确定"保存。

4. 验证安装
环境变量保存以后,要重新打开 PowerShell、CMD 或 Windows Terminal,之前已经打开的终端可能还没有读取新的 Path。
现在输入下面这条命令,检查 FFmpeg 是否已经可以正常运行。
powershell
ffmpeg -version
如果终端打印出 FFmpeg 版本、编译参数和各个库的版本号,说明安装已经完成。

如果提示"无法将 ffmpeg 识别为命令"或者"不是内部或外部命令",先检查 Path 中填写的是不是完整的 bin 目录,然后关闭终端重新打开。
三、macOS 和 Linux 安装
Windows 以外的系统可以直接通过包管理器安装,所以这部分不需要手动配置目录。
macOS 已经安装 Homebrew 的情况下,可以使用下面的命令安装 FFmpeg。
bash
brew install ffmpeg
Ubuntu 和 Debian 可以更新软件源以后,通过 APT 安装仓库中的 FFmpeg。
bash
apt update
apt install ffmpeg
Fedora 可以使用 DNF 安装,不过具体软件源和可用编码器可能跟系统版本有关。
bash
dnf install ffmpeg
安装完成以后,三个系统都可以使用 ffmpeg -version 验证。系统仓库中的版本可能不会和 FFmpeg 官网最新版本完全一致,但一般不影响本文这些基础操作。
四、FFmpeg 是怎么处理一个视频的
开始写命令之前,需要先分清容器和编码。很多人会把 MP4、H.264 都叫作视频格式,但是它们不在同一层。
- MP4、MOV 和 MKV 是容器,负责把视频、音频、字幕和元数据放在一个文件里;
- H.264、H.265 和 AV1 是视频编码;
- AAC、MP3 和 Opus 是音频编码。
一个 input.mp4 文件里面,可能是 H.264 视频和 AAC 音频。把后缀改成 .mkv,只改变文件名,并不会改变里面的编码。

FFmpeg 处理视频时,会先由解封装器从容器中取出视频、音频和字幕数据包。需要修改画面或编码时,数据包还要经过解码、滤镜和重新编码,最后由封装器写入输出文件。
如果只是把原有音视频流换一个容器,或者从视频中取出某一条音轨,可以使用 -c copy。这时 FFmpeg 不会重新编码,速度很快,也不会产生二次画质损失。
不过流复制不能修改画面内容。调整分辨率、修改帧率、压缩视频和烧录字幕都需要滤镜或重新编码。
五、一条基础的 FFmpeg 命令
FFmpeg 官方给出的基本命令结构是:
txt
ffmpeg [全局参数] [输入参数] -i 输入文件 [输出参数] 输出文件
下面这条命令会从视频第 10 秒开始,处理 20 秒内容,并使用 H.264 重新编码。
powershell
ffmpeg -ss 00:00:10 -i input.mp4 -t 20 -c:v libx264 -crf 23 -c:a aac output.mp4

这条命令可以拆成下面几部分:
| 参数 | 作用 |
|---|---|
ffmpeg |
启动 FFmpeg |
-ss 00:00:10 |
定位到第 10 秒 |
-i input.mp4 |
指定输入文件 |
-t 20 |
输出 20 秒内容 |
-c:v libx264 |
视频使用 H.264 编码 |
-crf 23 |
设置视频质量 |
-c:a aac |
音频使用 AAC 编码 |
output.mp4 |
指定输出文件 |
参数顺序会影响结果。像 -ss 这种参数放在 -i 前后,执行方式可能不同;输出编码、滤镜和质量参数一般写在输出文件之前。
命令中的文件默认从终端当前目录查找。如果文件不在当前目录,可以先切换目录,也可以直接使用完整路径。路径中包含空格时要加双引号。
powershell
ffmpeg -i "D:\Video Files\input.mp4" "D:\Video Files\output.mp4"
六、查看视频信息
直接执行 ffmpeg -i 也能看到媒体信息,但是它还会尝试处理输出。专门检查文件时,使用 ffprobe 更合适。
下面这条命令会显示容器、视频流、音频流、分辨率、编码、码率和时长等信息。
powershell
ffprobe -hide_banner input.mp4
输出中经常会看到类似下面的内容:
txt
Stream #0:0: Video: h264, yuv420p, 1920x1080, 30 fps
Stream #0:1: Audio: aac, 48000 Hz, stereo, 128 kb/s
Stream #0:0 表示第一个输入文件中的第一条流,Stream #0:1 是同一文件里的第二条流。后面使用 -map 选择指定视频或音频时,就会用到这些编号。
如果后面要在程序中读取这些信息,可以让 ffprobe 输出 JSON。
powershell
ffprobe -v error -show_format -show_streams -of json input.mp4
七、转换视频格式
最简单的格式转换只需要指定输入和输出文件。下面会把 MOV 转成 MP4,FFmpeg 会根据输出容器选择默认编码器。
powershell
ffmpeg -i input.mov output.mp4
不过默认编码器会受到当前构建和输出格式影响。如果希望结果更加明确,可以把视频和音频编码器直接写出来。
powershell
ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4
只想更换容器,并且原有视频、音频编码能被目标容器接受时,可以使用流复制。
powershell
ffmpeg -i input.mkv -c copy output.mp4

-c copy 并不保证所有文件都能转换成功。比如 MKV 中使用了 MP4 容器不支持的音频或字幕编码,FFmpeg 仍然会报错。这种情况需要重新编码不兼容的流,或者换一个能够容纳这些编码的输出容器。
八、压缩视频
视频压缩一般需要重新编码。下面使用 H.264 编码视频,AAC 编码音频。
powershell
ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4
这里主要看两个参数。
1. CRF
-crf 用来控制恒定质量。对于 libx264,数字越小,画质越高,输出文件一般也越大;数字越大,压缩更明显,但画质会下降。
可以先从 23 开始测试:
| CRF | 大致用途 |
|---|---|
| 18 | 画质较高,文件也会比较大 |
| 20~23 | 日常压缩可以先在这个范围测试 |
| 24~28 | 文件更小,画质损失会更加明显 |
CRF 并不能直接指定输出文件大小,因为不同视频的画面复杂度不同。同样使用 CRF 23,静态画面和运动画面生成的文件大小可能差很多。
2. preset
-preset 控制编码速度和压缩效率。常用值包括 ultrafast、fast、medium、slow。
slow 会花更多时间寻找更好的压缩方式,通常能在相近画质下得到更小的文件,但它不会像降低 CRF 那样直接提高画质。日常使用可以先用 medium,批量快速处理时再尝试 fast。
九、修改视频分辨率
修改分辨率需要使用视频滤镜。下面把视频高度缩放到 720,宽度按照原始比例自动计算。
powershell
ffmpeg -i input.mp4 -vf "scale=-2:720" -c:v libx264 -crf 23 -c:a copy output-720p.mp4
这里使用 -2 而不是直接写死宽度,可以保持原始宽高比,同时让计算出来的宽度满足常见编码器对偶数尺寸的要求。
如果确定要输出 1920×1080,也可以直接指定两个尺寸。不过原视频比例不同的时候,画面可能会被拉伸。
powershell
ffmpeg -i input.mp4 -vf "scale=1920:1080" output-1080p.mp4
十、截取一段视频
下面从第 10 秒开始截取 20 秒,并重新编码输出。重新编码需要的时间更长,但是截取位置通常更准确。
powershell
ffmpeg -ss 00:00:10 -i input.mp4 -t 20 -c:v libx264 -crf 23 -c:a aac clip.mp4
如果更在意速度,也可以使用 -c copy:
powershell
ffmpeg -ss 00:00:10 -i input.mp4 -t 20 -c copy clip-fast.mp4
第二种方式不会重新编码,但是起点可能落在附近的关键帧上,所以不一定能精确到指定时间。简单截取预览片段时可以用,要求精确时还是重新编码更稳。
-t 20 表示截取 20 秒。如果想指定结束位置,可以改用 -to,但是 -t 和 -to 不要同时使用。
十一、提取或删除音频
如果视频中的音频本身就是 AAC,可以直接复制音频流,不重新编码。
powershell
ffmpeg -i input.mp4 -vn -c:a copy output.m4a
-vn 表示不要视频流。如果希望输出通用的 MP3 文件,需要重新编码音频。
powershell
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3
反过来,如果要保留视频并删除声音,可以使用 -an。视频流可以直接复制,所以处理速度会比较快。
powershell
ffmpeg -i input.mp4 -c:v copy -an silent.mp4
十二、合并多个视频
多个片段的编码、分辨率、帧率和音频参数一致时,可以使用 concat demuxer 直接合并。
先在视频所在目录创建一个 list.txt 文件,并按顺序写入片段名称。
txt
file 'part1.mp4'
file 'part2.mp4'
file 'part3.mp4'
文件列表准备好以后,执行下面的合并命令。
powershell
ffmpeg -f concat -safe 0 -i list.txt -c copy merged.mp4
如果出现时间戳错误、音画不同步或者无法合并,通常不是命令写错了,而是几个片段的编码参数不一致。这时需要先把片段统一成相同的编码、分辨率和帧率,再进行合并。
十三、把视频转换成 GIF
直接输出 GIF 虽然命令短,但是颜色和文件大小通常不太理想。更稳妥的做法是先生成调色板,再使用调色板生成 GIF。
下面从第 5 秒开始取 5 秒内容,生成一张适合后续转换的调色板。
powershell
ffmpeg -ss 00:00:05 -i input.mp4 -t 5 -vf "fps=12,scale=640:-1:flags=lanczos,palettegen" palette.png
调色板生成以后,再执行第二条命令输出 GIF。
powershell
ffmpeg -ss 00:00:05 -i input.mp4 -t 5 -i palette.png -filter_complex "fps=12,scale=640:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
fps=12 控制 GIF 帧率,scale=640:-1 把宽度缩放到 640,高度自动计算。GIF 本身压缩效率不高,所以时间越长、尺寸越大、帧率越高,文件就越大。
十四、给视频烧录字幕
如果要把 SRT 字幕直接画进视频画面,可以使用 subtitles 滤镜。
下面会读取 subtitle.srt,把字幕烧录到视频中,并复制原来的音频流。
powershell
ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt" -c:v libx264 -crf 23 -c:a copy output-subtitle.mp4
烧录字幕属于修改画面,所以视频必须重新编码。如果提示找不到 subtitles 滤镜,说明当前 FFmpeg 构建没有包含 libass,可以用下面的命令检查。
powershell
ffmpeg -filters | findstr subtitles
Windows 路径里如果包含盘符、空格或特殊字符,字幕滤镜的转义会比较麻烦。最省事的处理方式是把视频和字幕放在同一个目录,先使用简单文件名运行。
十五、几个常见问题
1. 找不到 ffmpeg 命令
先检查环境变量中保存的是不是 FFmpeg 的 bin 目录,然后重新打开终端。还可以直接进入 bin 目录运行下面的命令,判断程序本身能不能启动。
powershell
.\ffmpeg.exe -version
如果这样可以运行,问题基本就在 Path 配置上。
2. 提示 No such file or directory
FFmpeg 会从终端当前目录查找输入文件。可以使用 pwd 或 PowerShell 的 Get-Location 查看当前目录,也可以给输入和输出文件写完整路径。
文件名和路径里有空格时,要使用双引号包起来。
3. 输出文件已经存在
FFmpeg 默认会询问是否覆盖同名文件。脚本或批量任务中可以使用 -y 自动覆盖,也可以用 -n 禁止覆盖。
下面这条命令会直接覆盖已经存在的输出文件,使用前要确认文件是否还需要保留。
powershell
ffmpeg -y -i input.mp4 output.mp4
4. 提示 Unknown encoder
不同构建包含的编码器可能不同。可以列出当前版本支持的编码器,再搜索需要的名称。
powershell
ffmpeg -encoders | findstr 264
如果列表中没有 libx264,需要更换包含该编码器的 FFmpeg 构建,或者改用当前版本已经支持的编码器。
5. 使用 -c copy 转换失败
-c copy 只复制已有数据流。如果源文件里的编码不被目标容器支持,就无法直接复制。可以换成 MKV 等兼容范围更广的容器,或者对不兼容的视频、音频流重新编码。