← All posts

FFmpeg 视频压缩最佳实践——参数怎么调才不踩坑

从 CRF、preset、二次编码到编码器选型、缩放、音频,一篇讲清 FFmpeg 视频压缩参数怎么权衡。

FFHub·2026-05-11
FFmpeg 视频压缩最佳实践——参数怎么调才不踩坑

FFmpeg 视频压缩说到底就是三个旋钮 —— CRF(画质)、preset(速度)、编码器(效率)。这篇深度指南覆盖 CRF 数学、两遍编码、H.264 vs H.265 vs AV1 实测对比、以及实战场景(web / 社交 / 归档 / HLS)。每条命令都能直接复制粘贴。

Try it in your browser

脚本化部署前先在浏览器里试一下参数——拖个片段,选 CRF / preset,下载结果。

先搞清楚 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 怎么调

简单粗暴的办法:

  1. 从默认开始(H.264 用 23,H.265 用 28)
  2. 看输出——画质能接受吗?
  3. 每次调 2-4 个点
  4. A/B 对比——同一段复杂场景跑两个 CRF,对着看

最容易暴露压缩瑕疵的画面是:快速运动、细密纹理(草地、布料)、渐变(天空、雾气)、暗部细节。如果是入门,先看FFmpeg 视频压缩入门

编码 preset:速度 vs 体积

preset 控制编码器愿意花多少 CPU 时间去优化压缩。preset 越慢、压缩效率越高(同画质文件更小),代价是耗时变长。

H.264 各 preset 实测

下面用 1080p 60fps、2 分钟的源视频,CRF 都用 23:

preset编码耗时文件大小画质(VMAF)
ultrafast15s85 MB92.1
superfast22s62 MB93.8
veryfast30s48 MB94.5
faster40s42 MB95.0
fast52s38 MB95.3
medium70s35 MB95.5
slow120s33 MB95.7
slower210s31 MB95.8
veryslow450s30 MB95.9
placebo1800s29.5 MB95.9

几个观察:

  • medium 是默认值,也是大多数场景的甜蜜区
  • mediumslow:体积小 6%,耗时多 70%
  • mediumveryslow:体积小 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 名字一样,但每档都明显更慢:

presetH.264 耗时H.265 耗时H.265 体积
fast52s180s25 MB
medium70s300s22 MB
slow120s600s20 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.2641 倍快、优化成熟
H.2653-5 倍明显慢
VP95-10 倍很慢(默认单线程)
AV1 (libaom)20-50 倍极慢
AV1 (SVT-AV1)3-8 倍快得多的 AV1 实现

播放兼容性(2026)

编码器浏览器移动端智能电视硬件解码
H.26499%+99%+99%+通用
H.265Safari、Edge(部分)iOS、Android 5+多数新款常见
VP9Chrome、Firefox、EdgeAndroid 5+有限在普及
AV1Chrome、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 优先、免版税VP9Chrome/Firefox 支持,无授权费
面向未来、最佳压缩AV1(SVT-AV1)节省 50%+,支持在涨
多端混合受众H.264 主 + H.265/AV1 备选按设备下发

容器格式之间怎么换,见视频格式转换指南

缩放:不止改个分辨率

下采样要做对,光改分辨率不够。

常见目标分辨率

名字分辨率典型码率(H.264)典型码率(H.265)
4K UHD3840x216015-30 Mbps8-15 Mbps
1440p2560x14408-15 Mbps4-8 Mbps
1080p Full HD1920x10804-8 Mbps2-4 Mbps
720p HD1280x7202-4 Mbps1-2 Mbps
480p SD854x4801-2 Mbps0.5-1 Mbps
360p640x3600.5-1 Mbps0.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

音频压缩

视频流水线里音频经常被忽视,但调一调能省不少带宽。

推荐设置

场景编码器码率命令
通用网页视频AAC128 kbps-c:a aac -b:a 128k
高质量视频AAC192 kbps-c:a aac -b:a 192k
音乐内容AAC256 kbps-c:a aac -b:a 256k
WebM/VP9Opus128 kbps-c:a libopus -b:a 128k
播客/语音AAC64 kbps-c:a aac -b:a 64k
播客/语音(Opus)Opus48 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

决策树

  1. 要最大兼容? 用 H.264
  2. 要更小? 苹果/移动端 H.265,Web 用 VP9
  3. 要最小且不赶时间? 用 AV1
  4. 要命中特定大小? 用二次编码
  5. 要稳定画质? 用 CRF
  6. 批量? fastveryfast
  7. 单个重要文件? slow

小结

视频压缩说到底就是平衡画质(CRF)、速度(preset)、体积(编码器)三件事。从默认值开始——CRF 23、medium preset、H.264——再按实际需求调。一定要拿真实素材测,因为人物对话和动作场景的压缩表现差得很远。

本文的命令都是标准 FFmpeg——本地、服务器、云服务(比如 FFHub)都能跑。把这些基本盘吃透,应付各种压缩需求都不成问题。

Try it in your browser

在脚本接入生产前,先用真实片段验一组 CRF / preset / 编码器组合。同一套 FFmpeg 参数,不用本地装。

常见问题(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 mediumlibx264 -preset medium 慢 3–5 倍,相同画质输出。

2026 年 AV1 能用在生产环境吗?

交付端可以了,有附加条件。AV1 硬解在主流旗舰手机、当代游戏机、Apple Silicon 上已经普及,但老设备仍需 H.264 回退。编码端,SVT-AV1libsvtav1)是务实选 —— 同画质下比 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 真能让文件更小吗?

能,但收益递减。mediumslow 画质不变下省 6%,但编码时间增 70%mediumveryslow 省 14%,编码时间增 6.4 倍。placeboveryslow 基本一样 ——别用 placebo。务实甜点:medium(默认)、slow(隔夜批处理、正式交付)、fast(实时或代理流程)。

延伸阅读

FFmpeg 视频压缩最佳实践——参数怎么调才不踩坑 | FFHub