FFmpeg 视频压缩进阶:MKV 支持与预设参数对比

一、问题:MP4 压缩命令能否用于 MKV

原始命令

ffmpeg -i zhao2.mp4 -c:v libx264 -crf 32 output_smaller.mp4

结论

可以,该命令完全适用于 MKV 格式的视频。

核心概念:容器 vs. 编码格式

概念说明示例
容器(Container)打包视频流、音频流、字幕等的文件格式MP4、MKV、AVI、MOV
编码格式(Codec)实际压缩视频画面的算法H.264(libx264)、H.265、AV1

-c:v libx264 指定的是编码格式(H.264),与输入文件的容器格式无关。FFmpeg 可以读取任何容器中的视频流并重新编码。

具体用法

压缩 MKV 视频并输出为 MP4:

ffmpeg -i input.mkv -c:v libx264 -crf 32 output.mp4

保持 MKV 容器格式:

ffmpeg -i input.mkv -c:v libx264 -crf 32 output.mkv

注意事项

问题解决方案
音频被重新压缩添加 -c:a copy 直接复制音频流
字幕被丢弃添加 -c:s copy 复制字幕流(需输出为 MKV)
MP4 对字幕支持有限如需保留字幕,建议输出为 MKV 格式

二、libx264 编码器的加速参数

问题:是否有类似 -cpu-used 8 -row-mt 1 的参数?

答案:

参数在 libx264 中的情况
-cpu-used不存在,此为 libaom-av1 特有参数
-row-mt 1默认已启用,无需额外指定

libx264 的核心加速参数:-preset

-preset 参数控制编码速度与压缩效率之间的权衡。

可用预设值(按速度从快到慢排列):

ultrafast > superfast > veryfast > faster > fast > medium > slow > slower > veryslow
  • medium 为默认值
  • 更快的预设 = 编码时间更短,但文件可能稍大
  • 更慢的预设 = 编码时间更长,但文件更小(压缩效率更高)

使用示例:

ffmpeg -i input.mkv -c:v libx264 -preset veryfast -crf 32 output.mp4

三、实际测试:-preset veryfast 对比测试

测试环境

  • 输入文件:Rec0002.mp4
  • 输入大小:约 900 MB
  • 视频时长:约 28 分 56 秒
  • 帧数:52088 帧
  • CPU:未指定(实际测试环境)

测试命令

命令一(默认 preset):

ffmpeg -i Rec0002.mp4 -c:v libx264 -crf 32 Rec00022.mp4

命令二(加 preset veryfast):

ffmpeg -i Rec0002.mp4 -c:v libx264 -preset veryfast -crf 32 Rec00022.mp4

测试结果对比

对比项默认(medium)-preset veryfast差异
编码速度12.9x22.6x速度提升约 75%
总耗时2分14秒1分16秒节省约 58 秒
视频大小172,945 KiB160,235 KiB反而减小约 7.3%
I 帧平均大小52,71238,112减小 27.7%
P 帧 skip 比例72.3%73.9%略高
B 帧 skip 比例81.3%84.6%略高
8x8 transform intra70.4%24.7%大幅降低

关键指标解读

1. 编码速度

  • 默认预设(medium):speed=12.9x,总耗时 2分14秒
  • veryfast 预设:speed=22.6x,总耗时 1分16秒
  • 结论:veryfast 速度快约 1.75 倍

2. 文件大小

  • veryfast 反而更小(约 7.3%),这与通常预期(更快预设 = 更大文件)不同,可能与视频源的具体内容有关

3. 画质指标

  • I 帧大小:veryfast 更小(38112 vs 52712),关键帧分配码率更少
  • skip 比例:veryfast 跳过更多宏块,细节保留更少
  • 8x8 transform:veryfast 使用率大幅降低(24.7% vs 70.4%),精细变换减少

4. 内部策略变化

  • ref B L0/L1 参考帧比例更低
  • 运动预测参考范围更小

结论与建议

场景推荐预设原因
批量处理、快速预览veryfast 或 faster时间节省显著
日常通用转换medium(默认)速度与画质平衡
存档或高质量需求slow 或 veryslow最佳压缩效率
实时推流ultrafast编码速度最快

四、FFmpeg 日志关键字段解读

编码日志示例

[out#0/mp4 @ ...] video:160235KiB audio:27124KiB ... frame=52088 fps=678 q=-1.0 Lsize=189192KiB time=00:28:56.10 bitrate=892.7kbits/s speed=22.6x elapsed=0:01:16.78

关键字段说明

字段含义
video:160235KiB输出视频流大小
audio:27124KiB输出音频流大小
frame=52088处理的帧总数
fps=678每秒编码帧数(编码速度)
time=00:28:56.10输出视频时长
bitrate=892.7kbits/s输出视频码率
speed=22.6x相对于实时播放速度的编码倍率
elapsed=0:01:16.78编码实际耗时

libx264 编码统计字段

字段含义
frame I关键帧(I帧)数量及平均QP
frame P预测帧(P帧)数量及平均QP
frame B双向预测帧(B帧)数量及平均QP
skip跳过编码的宏块比例,越高则细节保留越少
8x8 transform使用 8x8 变换的比例,越高则压缩精细度越高
kb/s视频平均码率

五、实用命令速查

MKV 压缩为 MP4(保留音频)

ffmpeg -i input.mkv -c:v libx264 -crf 32 -c:a copy output.mp4

MKV 压缩为 MKV(保留音频和字幕)

ffmpeg -i input.mkv -c:v libx264 -crf 32 -c:a copy -c:s copy output.mkv

使用 faster 预设加速压缩

ffmpeg -i input.mp4 -c:v libx264 -preset faster -crf 32 output.mp4

极速压缩(ultrafast)

ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -crf 32 output.mp4

高质量压缩(缓慢但文件更小)

ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 28 output.mp4

六、使用显卡加速

  • libx264:使用 CPU 进行编码(软件编码)。
  • h264_nvenc:使用 NVIDIA 显卡 进行编码(硬件编码)。

6.1. 显卡(h264_nvenc)能用吗?

能用,但有前提条件:

  • 你必须有一块 NVIDIA 显卡(GTX 600系列及以上,大部分民用卡都支持)。
  • 你的 FFmpeg 必须编译时带上了 --enable-nvenc 支持(可以通过运行 ffmpeg -encoders | findstr nvenc 检查)。
  • 注意:如果是在虚拟机Docker 中使用,可能需要直通显卡或安装额外的驱动,否则会报错。

6.2. 使用显卡的命令写法

如果你要把命令改成显卡压缩,应该这样写:

ffmpeg -i input.mkv -c:v h264_nvenc -preset p1 -cq 32 output.mp4

特别注意这里的参数变化(这是新手最容易踩坑的地方):

参数CPU (libx264)显卡 (h264_nvenc)说明
质量参数-crf 32-cq 32显卡不用 crf,用 cq(恒定质量)。数值越大,画质越差,文件越小。
预设-preset veryfast-preset p1 (或 p2, p3)显卡预设是 p1(最快)、p2(默认)、p3(画质最好)。不推荐使用 veryfast,会报错。

6.3. CPU 和 显卡(硬件编码)的核心区别

既然能用,你应该选哪个?请根据你的需求选择:

  • libx264(CPU)画质最好,文件最小。适合最终成片的存储或发布。缺点是速度慢(尤其开了高清预设)。
  • h264_nvenc(显卡)速度极快(通常是CPU的3-5倍)。适合直播推流快速粗剪预览。缺点是同码率下画质不如CPU,且文件体积会比CPU压出来的大(如果追求相同画质)。

6.4. 针对你原命令的修改建议

如果你追求快速压缩且不care体积,用显卡:

ffmpeg -i input.mkv -c:v h264_nvenc -preset p2 -cq 28 output.mp4

(注:cq 28 在显卡上的画质约等于CPU的 crf 23,建议别用32,画质损失较大)

如果你追求小体积和高画质,坚持用CPU,但建议把 veryfast 改成 slowmedium(压缩率更高):

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

三版本综合对比表

对比项CPU (libx264)
crf 32
显卡 (NVENC)
cq 32
显卡 (NVENC)
cq 28
输出文件大小47.6 MB105.5 MB156.6 MB
视频码率459 kbps1329 kbps1973 kbps
压缩用时28.0 秒22.9 秒22.4 秒
画质(理论)较好一般较好(但不如CPU)
体积对比1 倍(基准)2.2 倍3.3 倍

关键发现

1. 显卡的 cq 值对体积影响巨大

  • cq 32 → 105 MB
  • cq 28 → 157 MB(增加了 50%
  • 虽然 cq 28 画质更好,但代价是体积暴涨。

2. CPU 的压缩效率碾压显卡

  • CPU 用 459 kbps 的码率,画质已经不错(crf 32 是比较省体积的设置)。
  • 显卡要用 1973 kbps 的码率(4.3 倍),才能达到接近的画质水平。
  • 结论:同画质下,CPU 压缩出来的文件只有显卡的 1/3 到 1/4

3. 速度差距几乎可以忽略

  • 最快(显卡 cq 28)22.4 秒 vs 最慢(CPU)28.0 秒
  • 只差了 5.6 秒,对于 11 分钟的视频来说,这点时间差异没有任何实际意义。

最终结论

你的需求推荐方案命令
追求画质 + 小体积(推荐)CPU libx264-c:v libx264 -preset faster -crf 23
追求极致小体积CPU libx264-c:v libx264 -preset faster -crf 32(就是你用的)
追求速度(但你已经很快了)显卡 h264_nvenc-c:v h264_nvenc -preset p1 -cq 28
硬盘很大,不在乎体积显卡 h264_nvenc-c:v h264_nvenc -preset p1 -cq 23(画质更好)

给你的最终建议

在这个场景下(低分辨率、11分钟视频),完全没有必要用显卡。

原因很简单:

  1. CPU 只慢了 5 秒,但文件小了 2/3(从 157MB 降到 48MB)。
  2. 如果你有大量视频要压缩,节省的硬盘空间非常可观。压 10 个视频,CPU 占 480MB,显卡占 1.5GB。

所以,以后压缩这类视频,直接用 CPU 就行:

ffmpeg -i s1.mp4 -c:v libx264 -preset faster -crf 23 s1_compressed.mp4
  • crf 23 是公认的“平衡点”,画质和体积都很好。
  • 如果你想更小一点,用 crf 28;想更清晰一点,用 crf 20

需要我帮你解释 crf 数值的具体含义吗?或者你想测试一下 crf 23 的实际效果?

标签: none

添加新评论