FFmpeg 视频压缩最佳实践——参数怎么调才不踩坑
从 CRF、preset、二次编码到编码器选型、缩放、音频,一篇讲清 FFmpeg 视频压缩参数怎么权衡。

FFmpeg 视频压缩说到底就是三个旋钮 —— CRF(画质)、preset(速度)、编码器(效率)。这篇深度指南覆盖 CRF 数学、两遍编码、H.264 vs H.265 vs AV1 实测对比、以及实战场景(web / 社交 / 归档 / HLS)。每条命令都能直接复制粘贴。
先搞清楚 CRF(Constant Rate Factor)
CRF 是基于画质的压缩里最重要的一个参数。它告诉编码器:保住画质,码率随便变。CRF 越低 = 画质越高 = 文件越大;CRF 越高 = 画质越低 = 文件越小。
H.264(libx264)的 CRF
ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
H.264 的 CRF 范围是 0(无损)到 51(最差)。各档大概是这样:
| CRF | 画质等级 | 典型用途 | 文件大小(相对 CRF 23) |
|---|---|---|---|
| 0 | 无损 | 存档、剪辑母版 | 10-50 倍 |
| 14 | 接近无损 | 专业后期 | 4-6 倍 |
| 18 | 视觉无损 | 高端分发、付费流媒体 | 2-3 倍 |
| 20 | 优秀 | 高质量网页视频 | 1.5-2 倍 |
| 23 | 良好(默认) | 通用、网页分发 | 1 倍(基准) |
| 26 | 可用 | 社交媒体、移动端 | 0.5-0.7 倍 |
| 28 | 凑合 | 带宽受限 | 0.3-0.5 倍 |
| 32 | 低 | 预览、缩略图 | 0.15-0.25 倍 |
| 40 | 很差 | 极限压缩(勉强能看) | 0.05-0.1 倍 |
| 51 | 最差 | 别用 | 极小 |
多数场景的甜蜜区是 CRF 18-28。 低于 18,多花的码率换来的画质差异多数观众感知不到;高于 28,瑕疵开始肉眼可见。
H.265(libx265)的 CRF
H.265 在同等画质下码率比 H.264 低 40-50%。CRF 刻度也跟着错位:H.265 的 CRF 28 大致等同于 H.264 的 CRF 23。
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
| CRF(H.265) | 等效 H.264 CRF | 画质等级 |
|---|---|---|
| 18 | ~14 | 接近无损 |
| 22 | ~18 | 视觉无损 |
| 24 | ~20 | 优秀 |
| 28 | ~23 | 良好(默认) |
| 32 | ~26 | 可用 |
| 36 | ~30 | 低 |
CRF 怎么调
简单粗暴的办法:
- 从默认开始(H.264 用 23,H.265 用 28)
- 看输出——画质能接受吗?
- 每次调 2-4 个点
- A/B 对比——同一段复杂场景跑两个 CRF,对着看
最容易暴露压缩瑕疵的画面是:快速运动、细密纹理(草地、布料)、渐变(天空、雾气)、暗部细节。如果是入门,先看FFmpeg 视频压缩入门。
编码 preset:速度 vs 体积
preset 控制编码器愿意花多少 CPU 时间去优化压缩。preset 越慢、压缩效率越高(同画质文件更小),代价是耗时变长。
H.264 各 preset 实测
下面用 1080p 60fps、2 分钟的源视频,CRF 都用 23:
| preset | 编码耗时 | 文件大小 | 画质(VMAF) |
|---|---|---|---|
| ultrafast | 15s | 85 MB | 92.1 |
| superfast | 22s | 62 MB | 93.8 |
| veryfast | 30s | 48 MB | 94.5 |
| faster | 40s | 42 MB | 95.0 |
| fast | 52s | 38 MB | 95.3 |
| medium | 70s | 35 MB | 95.5 |
| slow | 120s | 33 MB | 95.7 |
| slower | 210s | 31 MB | 95.8 |
| veryslow | 450s | 30 MB | 95.9 |
| placebo | 1800s | 29.5 MB | 95.9 |
几个观察:
medium是默认值,也是大多数场景的甜蜜区medium到slow:体积小 6%,耗时多 70%medium到veryslow:体积小 14%,耗时是 6.4 倍placebo相比veryslow几乎没改善——别用ultrafast出来的文件比medium大 2.4 倍——别拿来当最终交付
# 大多数场景用这个
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium output.mp4
# 时间比体积重要
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset fast output.mp4
# 体积比时间重要
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow output.mp4
H.265 的 preset 表现
preset 名字一样,但每档都明显更慢:
| preset | H.264 耗时 | H.265 耗时 | H.265 体积 |
|---|---|---|---|
| fast | 52s | 180s | 25 MB |
| medium | 70s | 300s | 22 MB |
| slow | 120s | 600s | 20 MB |
H.265 同 preset 大约比 H.264 慢 3-5 倍,但同等画质下文件小 30-40%。
二次编码(Two-Pass)
要精确控制输出码率(比如「这视频必须 50 MB 以内」),就得用二次编码。
怎么跑
- 第一遍:FFmpeg 分析整段视频,写一个复杂度日志
- 第二遍:根据日志分配码率——复杂场景多给点,简单场景少给点
基本命令
# 第一遍——分析(输出丢弃)
ffmpeg -i input.mp4 -c:v libx264 -b:v 4M -pass 1 -f null /dev/null
# 第二遍——根据分析结果编码
ffmpeg -i input.mp4 -c:v libx264 -b:v 4M -pass 2 output.mp4
算目标码率
要把视频塞进特定大小:
视频码率 = (目标大小比特数 - 音频比特数) / 时长秒数
例:10 分钟视频,100 MB 目标,128 kbps 音频:
音频大小 = 128,000 bps × 600s = 76,800,000 bits = 9.6 MB
视频码率 = (100 MB - 9.6 MB) × 8,000,000 / 600 = 1,205,333 bps ≈ 1.2 Mbps
ffmpeg -i input.mp4 -c:v libx264 -b:v 1200k -pass 1 -c:a aac -b:a 128k -f null /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 1200k -pass 2 -c:a aac -b:a 128k output.mp4
CRF vs 二次编码:什么时候用哪个
| 方式 | 适合场景 | 关注点 |
|---|---|---|
| CRF | 一致画质,文件大小不限 | 画质优先 |
| 二次编码 | 命中目标大小或码率 | 体积优先 |
| CRF + maxrate | 画质优先但有码率上限 | 流媒体 |
流媒体加码率上限:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -maxrate 4M -bufsize 8M output.mp4
按 CRF 23 的画质走,但码率最高 4 Mbps——带宽受限的流媒体场景常用。
编码器对比:H.264 vs H.265 vs VP9 vs AV1
挑编码器是在压缩效率、编码速度、播放兼容性之间做权衡。
压缩效率
同等画质(VMAF 95)下的相对体积:
| 编码器 | 相对体积 | 相对 H.264 节省 |
|---|---|---|
| H.264 (libx264) | 100% | 基准 |
| H.265 (libx265) | 55-65% | 小 35-45% |
| VP9 (libvpx-vp9) | 55-65% | 小 35-45% |
| AV1 (libaom-av1) | 40-50% | 小 50-60% |
编码速度
1080p 60fps 同等画质下的相对耗时:
| 编码器 | 编码耗时(相对) | 备注 |
|---|---|---|
| H.264 | 1 倍 | 快、优化成熟 |
| H.265 | 3-5 倍 | 明显慢 |
| VP9 | 5-10 倍 | 很慢(默认单线程) |
| AV1 (libaom) | 20-50 倍 | 极慢 |
| AV1 (SVT-AV1) | 3-8 倍 | 快得多的 AV1 实现 |
播放兼容性(2026)
| 编码器 | 浏览器 | 移动端 | 智能电视 | 硬件解码 |
|---|---|---|---|---|
| H.264 | 99%+ | 99%+ | 99%+ | 通用 |
| H.265 | Safari、Edge(部分) | iOS、Android 5+ | 多数新款 | 常见 |
| VP9 | Chrome、Firefox、Edge | Android 5+ | 有限 | 在普及 |
| AV1 | Chrome、Firefox、Edge、Safari 17+ | 旗舰机 | 有限 | 新兴 |
实战命令
# H.264——兼容性优先
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4
# H.265——文件小 40%,移动端好
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4
# VP9——免版税,适合 Web
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -row-mt 1 -c:a libopus -b:a 128k output.webm
# AV1(SVT-AV1)——最佳压缩,新设备
ffmpeg -i input.mp4 -c:v libsvtav1 -crf 30 -preset 6 -c:a libopus -b:a 128k output.mp4
怎么选
| 场景 | 推荐编码器 | 原因 |
|---|---|---|
| 兼容性最大化 | H.264 | 哪都能播 |
| 节流量、苹果生态 | H.265 | 压缩好,iOS/macOS 原生 |
| Web 优先、免版税 | VP9 | Chrome/Firefox 支持,无授权费 |
| 面向未来、最佳压缩 | AV1(SVT-AV1) | 节省 50%+,支持在涨 |
| 多端混合受众 | H.264 主 + H.265/AV1 备选 | 按设备下发 |
容器格式之间怎么换,见视频格式转换指南。
缩放:不止改个分辨率
下采样要做对,光改分辨率不够。
常见目标分辨率
| 名字 | 分辨率 | 典型码率(H.264) | 典型码率(H.265) |
|---|---|---|---|
| 4K UHD | 3840x2160 | 15-30 Mbps | 8-15 Mbps |
| 1440p | 2560x1440 | 8-15 Mbps | 4-8 Mbps |
| 1080p Full HD | 1920x1080 | 4-8 Mbps | 2-4 Mbps |
| 720p HD | 1280x720 | 2-4 Mbps | 1-2 Mbps |
| 480p SD | 854x480 | 1-2 Mbps | 0.5-1 Mbps |
| 360p | 640x360 | 0.5-1 Mbps | 0.3-0.5 Mbps |
保持宽高比
一个维度用 -1 自动算,再用 -2 保证能被 2 整除(多数编码器要求):
# 缩到 720p 宽,高自动算(保证偶数)
ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:v libx264 -crf 23 output.mp4
# 缩到 1080 高,宽自动算
ffmpeg -i input.mp4 -vf "scale=-2:1080" -c:v libx264 -crf 23 output.mp4
缩放滤镜的画质
FFmpeg 有多种缩放算法。默认(bilinear)够用,但要追求最佳缩小画质,用 Lanczos:
# Lanczos 高质量缩小
ffmpeg -i input.mp4 -vf "scale=1280:720:flags=lanczos" -c:v libx264 -crf 23 output.mp4
| 算法 | 速度 | 缩小画质 | 适合场景 |
|---|---|---|---|
| fast_bilinear | 最快 | 低 | 实时处理 |
| bilinear | 快 | 中等 | 默认、通用 |
| bicubic | 中等 | 好 | 中等画质需求 |
| lanczos | 较慢 | 最好 | 最终交付、画质关键 |
| spline | 较慢 | 优秀 | Lanczos 替代 |
不要放大
通则:别上采样。720p 编成 1080p 只会浪费带宽,不会真增加细节。如果非放不可,幅度小一点,用 Lanczos:
# 实在要放大(尽量避免)
ffmpeg -i input_720p.mp4 -vf "scale=1920:1080:flags=lanczos" -c:v libx264 -crf 20 output.mp4
音频压缩
视频流水线里音频经常被忽视,但调一调能省不少带宽。
推荐设置
| 场景 | 编码器 | 码率 | 命令 |
|---|---|---|---|
| 通用网页视频 | AAC | 128 kbps | -c:a aac -b:a 128k |
| 高质量视频 | AAC | 192 kbps | -c:a aac -b:a 192k |
| 音乐内容 | AAC | 256 kbps | -c:a aac -b:a 256k |
| WebM/VP9 | Opus | 128 kbps | -c:a libopus -b:a 128k |
| 播客/语音 | AAC | 64 kbps | -c:a aac -b:a 64k |
| 播客/语音(Opus) | Opus | 48 kbps | -c:a libopus -b:a 48k |
响度归一化
视频之间响度不一致是个常见问题。FFmpeg 的 loudnorm 可以归到广播标准:
# 归一化到 -16 LUFS(流媒体标准)
ffmpeg -i input.mp4 -c:v copy -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:a aac -b:a 128k output.mp4
去掉音频
不要音频:
ffmpeg -i input.mp4 -an -c:v libx264 -crf 23 output.mp4
音频原样复制
如果音频本来就合适,不用重编:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4
几个实战例子
网页分发(通用)
最常见的场景——压视频塞进网页:
ffmpeg -i input.mp4 \
-c:v libx264 -crf 23 -preset medium \
-vf "scale=1920:1080:flags=lanczos" \
-c:a aac -b:a 128k \
-movflags +faststart \
output.mp4
要点:
-movflags +faststart把元数据搬到文件头,能边下边播(Web 必备)- CRF 23 在画质和体积之间够平衡
- AAC 128k 对网页内容够用
社交媒体优化
Twitter/X、Instagram、TikTok 这类平台有自己的口味:
# 社交平台优化(H.264、AAC、faststart)
ffmpeg -i input.mp4 \
-c:v libx264 -crf 23 -preset medium \
-profile:v high -level:v 4.0 \
-pix_fmt yuv420p \
-vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
-c:a aac -b:a 128k -ar 44100 \
-movflags +faststart \
output.mp4
-profile:v high -level:v 4.0保证广泛兼容-pix_fmt yuv420p保证所有设备能播scale+pad把画面塞进 9:16 竖屏,加黑边
归档(最高画质、最小损失)
长期存储,文件大小不是首要考虑:
ffmpeg -i input.mp4 \
-c:v libx264 -crf 16 -preset slow \
-c:a flac \
output.mkv
- CRF 16 几乎保留所有视觉细节
- FLAC 音频无损
- MKV 容器比 MP4 更包容
流媒体(HLS 自适应码率)
一次出多档画质做自适应播放:
ffmpeg -i input.mp4 \
-map 0:v -map 0:a -map 0:v -map 0:a -map 0:v -map 0:a \
-c:v libx264 -crf 22 \
-c:a aac -b:a 128k \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
-b:v:0 5M -maxrate:v:0 5.5M -bufsize:v:0 10M -s:v:0 1920x1080 \
-b:v:1 2.5M -maxrate:v:1 2.75M -bufsize:v:1 5M -s:v:1 1280x720 \
-b:v:2 1M -maxrate:v:2 1.1M -bufsize:v:2 2M -s:v:2 854x480 \
-f hls -hls_time 6 -hls_list_size 0 \
-master_pl_name master.m3u8 \
stream_%v/playlist.m3u8
批量压缩脚本
一次处理整目录视频:
#!/bin/bash
# 批量压缩目录下所有视频
for f in *.mp4; do
ffmpeg -i "$f" \
-c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k \
-movflags +faststart \
"compressed_${f}"
done
用 FFHub 在云上压
本文所有命令都能直接发给 FFHub.io:
# 云端压缩(本地不用装 FFmpeg)
curl -X POST https://api.ffhub.io/v1/tasks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"command": "ffmpeg -i https://example.com/input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart output.mp4"
}'
CPU 重活丢到云端,本地或应用服务器不被吃满。批量转码或者跑在应用服务器会拖累性能时特别好用。
速查
一行命令版
# 默认好用的压缩
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k -movflags +faststart output.mp4
# 激进压缩(更小)
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 96k output.mp4
# 高质量(更大)
ffmpeg -i input.mp4 -c:v libx264 -crf 18 -preset slow -c:a aac -b:a 192k output.mp4
# H.265 极限压缩
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4
# AV1 面向未来
ffmpeg -i input.mp4 -c:v libsvtav1 -crf 30 -preset 6 -c:a libopus -b:a 128k output.mp4
决策树
- 要最大兼容? 用 H.264
- 要更小? 苹果/移动端 H.265,Web 用 VP9
- 要最小且不赶时间? 用 AV1
- 要命中特定大小? 用二次编码
- 要稳定画质? 用 CRF
- 批量?
fast或veryfast - 单个重要文件?
slow
小结
视频压缩说到底就是平衡画质(CRF)、速度(preset)、体积(编码器)三件事。从默认值开始——CRF 23、medium preset、H.264——再按实际需求调。一定要拿真实素材测,因为人物对话和动作场景的压缩表现差得很远。
本文的命令都是标准 FFmpeg——本地、服务器、云服务(比如 FFHub)都能跑。把这些基本盘吃透,应付各种压缩需求都不成问题。
常见问题(FAQ)
流媒体场景 CRF 用多少?
HLS / DASH 自适应流的标准做法是 CRF 21–23 + -maxrate 和 -bufsize 限顶。CRF 保证画质在复杂场景下不掉,码率上限保护观众带宽不被突发流量打爆。最高档用 CRF 23,中档 CRF 24–25,最低档 CRF 26–28。
两遍编码(Two-Pass)vs CRF,什么时候用哪个?
关心画质一致用 CRF(绝大多数 web 和归档场景)。必须命中指定大小才用 two-pass(Discord 25MB 上限、广播规范、广告投放规格)。Two-pass 比 CRF 慢约 2 倍,但能精确控制体积。需要画质优先但有码率上限的场景,CRF 配 -maxrate 和 -bufsize 是更好的折中。
H.265 为什么比 H.264 慢那么多?
H.265 每帧要评估更多块尺寸、预测模式、运动矢量才能达到 30–40% 的压缩率优势。HEVC 规范设计上就比 H.264 复杂,复杂度换效率。实测:libx265 -preset medium 比 libx264 -preset medium 慢 3–5 倍,相同画质输出。
2026 年 AV1 能用在生产环境吗?
交付端可以了,有附加条件。AV1 硬解在主流旗舰手机、当代游戏机、Apple Silicon 上已经普及,但老设备仍需 H.264 回退。编码端,SVT-AV1(libsvtav1)是务实选 —— 同画质下比 H.264 慢 3–8 倍,比 libaom-av1 的 20–50 倍快太多。Netflix、YouTube、Vimeo 都已经给支持 AV1 的客户端发 AV1 流了。
批量压缩不同来源的视频怎么保画质一致?
用 CRF 模式,别用 bitrate 模式 —— CRF 会跟着源的复杂度自适应。一个简单 shell 循环 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart 能对各种输入产出体感一致的画质。如果需要硬性体积上限,再叠 -maxrate + -bufsize(比如 -maxrate 4M -bufsize 8M)。
-preset slow 真能让文件更小吗?
能,但收益递减。medium → slow 画质不变下省 6%,但编码时间增 70%。medium → veryslow 省 14%,编码时间增 6.4 倍。placebo 跟 veryslow 基本一样 ——别用 placebo。务实甜点:medium(默认)、slow(隔夜批处理、正式交付)、fast(实时或代理流程)。
延伸阅读
- 如何用 FFmpeg 压缩视频 - 入门版命令讲解
- 如何用 FFmpeg 转换视频格式 - 在 MP4、MKV、WebM 之间切换并控制编码器
- 批量视频转码 API - 用云 API 自动化大规模视频压缩