4、格式转换实战:常见容器格式互转(MP4/MKV/AVI/FLV)、编码器选择策略

格式转换,说白了就是给视频「换包装」。

很多人以为转格式就是改个后缀名。我见过不少新手直接把 .mkv 改成 .mp4,然后问我为什么播放器还是打不开。嗯,这里要说明白:容器格式和编码格式是两码事。

核心概念:容器(Container)是外壳,编码(Codec)是内核。转容器 ≠ 转编码。

4.1 容器格式的本质差异

我习惯把容器比作「快递箱」。MP4 是标准纸箱,MKV 是多功能收纳箱,AVI 是老式木箱,FLV 是轻便小盒。它们能装的东西不一样。

容器 常见编码 流支持 适用场景
MP4 H.264/H.265 + AAC 1 视频 + 1 音频 + 字幕(有限) 网页、移动端、通用播放
MKV 几乎任何编码 多视频/多音频/多字幕/章节 本地收藏、蓝光原盘、多轨需求
AVI MPEG-4 Visual / DivX / XviD 1 视频 + 1~2 音频 老旧设备、兼容性兜底
FLV H.264 + MP3/AAC 1 视频 + 1 音频 直播、Flash 遗留系统

你看,MP4 对字幕支持很弱。我曾经想把一个带 ass 特效字幕的 MKV 直接转 MP4,结果字幕全丢了。后来才知道,MP4 只支持内嵌字幕或 timed text,ass 这种高级格式根本塞不进去。

4.2 纯容器转换(不重新编码)

如果源文件的编码格式目标容器也支持,我们可以只换壳,不伤画质。速度极快,几秒搞定。

举个例子,一个 H.264 + AAC 的 MKV 文件,想转成 MP4:

ffmpeg -i input.mkv -c copy output.mp4

-c copy 就是「直接复制流,不重新编码」。我项目里经常用这招给客户交付 MP4 版本,省时省力。

小技巧:如果只想换容器,先查一下源文件的编码信息:ffmpeg -i input.mkv。确认视频和音频编码目标容器都支持,再用 -c copy。

但有些情况不能直接 copy。比如 AVI 不支持 AAC 音频,你硬 copy 过去,播放器会直接罢工。

注意:AVI 容器对音频编码有限制。常见兼容组合是 MP3 或 PCM。如果源文件是 AAC,转 AVI 时必须重编码音频。

4.3 常见互转场景与命令

下面是我工作中最常用的几个转换场景,直接贴命令,你拿去就能用。

4.3.1 MKV → MP4(H.264 + AAC)

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

这个命令会重新编码视频和音频。为什么不用 copy?因为 MKV 里可能装了 H.265 或 DTS 音频,MP4 不认。重编码是保险做法。

4.3.2 MP4 → MKV(保留多音轨)

ffmpeg -i input.mp4 -c copy -map 0 output.mkv

-map 0 的意思是「把输入文件的所有流都映射到输出」。MP4 转 MKV 通常可以直接 copy,因为 MKV 什么都能装。

4.3.3 AVI → MP4(老旧视频现代化)

ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output.mp4

AVI 里的视频编码通常是 MPEG-4 Visual,压缩效率低,画质差。我建议重编码成 H.264,体积能缩小 50% 以上。

4.3.4 FLV → MP4(直播录播转通用)

ffmpeg -i input.flv -c:v libx264 -preset fast -crf 24 -c:a aac -b:a 96k output.mp4

FLV 的封装比较老,很多现代播放器不支持。转成 MP4 是标准做法。

4.4 编码器选择策略

选编码器,说白了就是平衡三个东西:画质、体积、速度。你不可能全都要。

我个人习惯按场景选:

  • 最终交付给客户:H.264 + AAC,兼容性最好。用 libx264,CRF 设 18~23。
  • 自己收藏:H.265(HEVC),体积小画质高。用 libx265,CRF 设 22~28。
  • 快速预览:H.264 的 ultrafast preset,牺牲一点画质换速度。
  • 直播推流:硬件编码器,比如 h264_nvenc(NVIDIA)或 h264_amf(AMD)。
编码器 画质 体积 速度 适用场景
libx264 高 中等 中等 通用、兼容性优先
libx265 更高 小 慢 本地收藏、高压缩比需求
h264_nvenc 中等 较大 极快 直播、实时转码
libvpx-vp9 高 极小 极慢 Web 分发、YouTube 标准

我的经验:CRF 值不是玄学。18 以下基本看不出区别,但文件大得离谱。23 是视觉无损的起点。我一般用 22 做存档,24 做网络分发。

4.5 避坑指南:我踩过的几个坑

做格式转换这么多年,有些坑我至今记忆犹新。

  • 坑一:我曾经把一个 DTS 音轨的 MKV 直接 copy 成 MP4,结果播放器没声音。DTS 需要重编码成 AAC 或 AC3。
  • 坑二:AVI 文件超过 2GB 会出问题。老格式的索引机制有限制。解决方案是转成 MKV 或 MP4。
  • 坑三:FLV 转 MP4 时,如果源文件是 Sorenson Spark 编码(老 Flash 专用),libx264 不认。需要先解码成原始帧再编码。
  • 坑四:硬件编码器(NVENC)虽然快,但同码率下画质不如软件编码器。交付给客户时我从来不用硬件编码。

4.6 知识体系总览

下面这张图帮你理清本章的核心逻辑:

格式转换核心逻辑 源文件 编码兼容? -c copy 换壳 重编码 目标文件 判断依据 源编码是否被目标容器支持 (查 ffmpeg -i 输出)

你看,整个流程其实就两个分支:编码兼容就换壳,不兼容就重编码。别把事情想复杂了。

4.7 实战建议

最后给你几条实在的建议:

  • 先查再转:每次转格式前,先用 ffmpeg -i 看一眼源文件的编码信息。我吃过亏才知道这步不能省。
  • 批量转换用脚本:写个 for 循环,别一个个敲命令。比如把所有 MKV 转 MP4:for f in *.mkv; do ffmpeg -i "$f" -c copy "${f%.mkv}.mp4"; done
  • 保留原始文件:转码有损,别删源文件。等确认输出没问题了再清理。
  • 测试播放兼容性:转完的文件,至少用两个播放器打开看看。VLC 能播不代表手机也能播。

格式转换这事,说难不难,说简单也不简单。你只要记住「容器是壳,编码是核」,再配合我上面给的命令和策略,基本不会翻车。