转码核心参数:编码器选择、码率控制、帧率与分辨率

转码这件事,说白了就是让视频从一个格式变成另一个格式。但怎么变、变完之后质量如何、文件多大,全看这几个核心参数怎么配。我刚开始用 FFmpeg 的时候,也踩过不少坑,今天就把这些经验掰开揉碎讲给你听。

本章核心脉络:编码器决定压缩方式 → 码率控制决定文件大小与质量 → 帧率影响流畅度 → 分辨率影响清晰度。四者联动,缺一不可。

转码核心参数知识体系 FFmpeg 转码 编码器选择 码率控制 帧率设置 分辨率调整 libx264 libx265 CBR/VBR CRF -r 30 -r 60 -s 1920x1080 💡 核心原则 编码器决定压缩效率 → 码率控制决定质量与体积的平衡 帧率与分辨率直接影响最终文件的视觉体验

编码器选择:-c:v 与 -c:a

编码器,就是视频的「压缩引擎」。你告诉 FFmpeg 用哪种算法来压缩视频和音频。我个人习惯把编码器分成两类:硬件编码器和软件编码器。

类型 常见编码器 特点 适用场景
软件编码器 libx264, libx265, libvpx-vp9 压缩率高、画质好、速度慢 最终交付、存档、高质量转码
硬件编码器 h264_nvenc, h264_amf, hevc_qsv 速度快、功耗低、画质略差 直播推流、实时转码、预览

举个例子,你想把视频转成 H.264 格式:

ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4

这里 -c:v libx264 就是指定视频用 x264 编码器,-c:a aac 指定音频用 AAC 编码器。嗯,这里要注意:-c 是 codec 的缩写,:v 表示视频,:a 表示音频。

我的经验:如果你只是做本地预览,用硬件编码器 h264_nvenc 能快 3-5 倍。但如果是给客户交付的成片,我建议用 libx264,画质更稳定。我曾经有一次用硬件编码器交付,结果在老旧播放器上花屏了……从那以后,交付件一律用软件编码器。

码率控制:-b:v 与 -b:a

码率,说白了就是「每秒用多少比特来存储画面」。码率越高,画质越好,文件也越大。码率控制有三种常见模式:

  • CBR(固定码率):全程码率恒定,适合直播推流,但浪费带宽
  • VBR(可变码率):简单画面用低码率,复杂画面用高码率,效率更高
  • CRF(恒定质量):你告诉 FFmpeg 想要多高质量,它自动分配码率

我个人最常用的是 CRF 模式,因为它最省心。看这个例子:

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4

CRF 值的范围是 0-51,数值越小画质越好。23 是默认值,视觉上无损。18 以下基本看不出区别,但文件会大很多。

避坑指南:我曾经犯过一个错误——给一个 4K 视频设了 -b:v 1M,结果画面全是马赛克。码率要和分辨率匹配:1080p 建议 4-8 Mbps,4K 建议 20-40 Mbps。别指望用低码率跑高分辨率,那是在为难编码器。

如果你非要手动控制码率,可以这样:

ffmpeg -i input.mp4 -c:v libx264 -b:v 5M -maxrate 8M -bufsize 10M -c:a aac -b:a 192k output.mp4

这里 -b:v 5M 是目标码率,-maxrate 是峰值码率,-bufsize 是缓冲区大小。你想想看,这就像开车——目标速度 80,但允许短时间超车到 120,只要平均速度别超就行。

帧率设置:-r

帧率,就是每秒显示多少帧画面。常见的帧率有 24(电影)、30(电视/网络)、60(游戏/体育)。

设置帧率很简单:

ffmpeg -i input.mp4 -r 30 output.mp4

但这里有个坑——-r 放在 -i 前面和后面,效果完全不同:

  • 放在 -i 前面:先改变输入帧率,再编码。相当于丢帧或插帧。
  • 放在 -i 后面:编码时强制输出帧率。FFmpeg 会自动做帧率转换。

我的习惯:我一般把 -r 放在输出文件前面,也就是 -i input.mp4 -r 30 output.mp4。这样 FFmpeg 会智能处理帧率转换,不会乱丢关键帧。

举个例子,把 60fps 的游戏录像转成 30fps:

ffmpeg -i game_60fps.mp4 -r 30 -c:v libx264 -crf 23 output_30fps.mp4

FFmpeg 会每两帧取一帧,画面依然流畅,但文件大小直接减半。

分辨率设置:-s

分辨率,就是画面的宽高。常见的有 1920x1080(1080p)、1280x720(720p)、640x360(360p)。

设置分辨率用 -s 参数:

ffmpeg -i input.mp4 -s 1280x720 output.mp4

但直接硬缩放有个问题——画面比例会变形。如果你的源视频是 16:9,硬缩成 4:3,画面会被压扁。

我的做法:先用 ffprobe 查看源视频比例,再用 scale 滤镜保持比例。比如:

ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4

这个命令会保持原比例缩放,不足的部分用黑边填充。嗯,虽然命令长了点,但画面不会变形。

如果你懒得算比例,也可以用 -vf scale=-1:720,让 FFmpeg 自动计算宽度:

ffmpeg -i input.mp4 -vf "scale=-1:720" -c:v libx264 -crf 23 output_720p.mp4

这里 -1 表示按比例自动计算。宽度会根据高度 720 自动适配。

综合实战:一个完整的转码命令

把上面这些参数串起来,一个典型的转码命令长这样:

ffmpeg -i input_4k.mp4 \
  -c:v libx264 \
  -crf 23 \
  -r 30 \
  -s 1920x1080 \
  -c:a aac \
  -b:a 128k \
  output_1080p.mp4

这个命令做了四件事:

  1. 用 libx264 编码器压缩视频
  2. 用 CRF 23 控制质量
  3. 把帧率降到 30fps
  4. 把分辨率降到 1080p
  5. 音频用 AAC,码率 128k

记住这个公式:编码器 + 码率 + 帧率 + 分辨率 = 转码结果。这四个参数就像汽车的四个轮子,少一个都跑不稳。

最后说一句:别指望一次配出完美参数。我每次转码都会先截取一小段测试:

ffmpeg -i input.mp4 -ss 00:01:00 -t 10 -c:v libx264 -crf 23 -r 30 -s 1920x1080 test_output.mp4

先转 10 秒看看效果,满意了再全片转。这习惯帮我省了不知道多少时间。