把视频转成 MP4,有时很快,有时却要等很久,还可能改变画质。差别常在处理路线:复制已有音视频数据,还是重新编码。FFmpeg 是一套开源音视频处理工具与程序库,能读取媒体、处理画面和声音,再写出文件。看懂它怎样转换,就能判断只换容器是否够用,什么时候需要转码。

你看到 MP4,里面装的是什么
FFmpeg 通常指整个项目,包括程序库和命令行工具。“用 FFmpeg 转视频”,通常是运行其中的 ffmpeg;ffprobe 用来查看媒体信息,ffplay 用来播放[1]。某个转换软件有没有调用 FFmpeg,仍要查该软件的说明。
日常所说的“一段视频”,文件里往往包含视频流和音频流,也可能有字幕、多条音轨及其他信息。画面和声音可以采用不同的编码方式,再装进同一个文件。
MP4、MKV 是封装格式,也叫容器;H.264、H.265 是视频编码方式,AAC 是音频编码方式。容器规定这些流和相关信息怎样组织,编码方式规定画面或声音怎样表示。常见视频使用压缩编码,但“容器”和“编码”是两层事情。
可以把容器想成有目录的文件夹,分别放着画面和声音的记录。但真实媒体文件还要按格式保存索引、时间戳等信息,才能同步播放,不是把普通文件随意塞在一起。同样是 .mp4,里面的编码也可能不同;播放器能读容器,还得支持其中的编码,视频才播得出来。

需要转码时,画面会经过哪些环节
假设把画面从 1280×720 缩到 640×360,再输出成 MP4。这条视频流需要经历解封装、解码、滤镜处理、编码和封装[2],每一步处理的东西不同:
解封装:取出要处理的流。先读取输入文件的结构,把选中的视频、音频等流的已编码数据交给后续环节。“解封装”不是把画面解成图片,也没有自动改变编码。
解码:得到可以处理的画面。视频解码器把编码数据还原成一帧帧可供处理的图像。音频如果也需要处理,则会由相应解码器得到音频采样数据。这里的“还原”不表示能找回有损编码时已经丢失的细节。
滤镜处理:按要求修改内容。缩放、裁剪、叠加画面等操作,在解码后的帧上进行。FFmpeg 中的“滤镜”不仅指调色特效,改变分辨率也是滤镜处理;如果没有这类修改,就不需要特意加一个缩放步骤。
编码:重新生成编码数据。处理后的画面交给编码器,例如用 libx264 生成 H.264 视频。即使输入、输出都叫 H.264,只要画面经过解码再编码,这条流仍然发生了转码。编码器和质量、码率等设置,会影响输出体积、耗时和画质;常见的有损转码可能进一步损失细节。
封装:组织成输出文件。最后,封装器把编码好的流和所需信息写成 MP4 等目标格式。每帧画面、每段声音都需要合适的时间信息,不能只把字节拼在一起就指望它们同步播放。
实际处理时,数据沿这些环节流动,不需要先把整部视频全部解码到硬盘,再开始编码。同一文件中的流也可以走不同路线:画面要缩放,声音不需要变,就可以只转码视频、直接复制音频。
只换容器,可以绕过重新编码
如果原有音视频编码已经适合目标容器和播放器,只想把 MKV 中的流写进 MP4,可以尝试重封装:解封装之后,把选中的已编码数据直接交给新的封装器。
这种不经过解码、滤镜和重新编码的方式,叫流复制(streamcopy),命令中的 -c copy 就是这个意思[3]。它可以用于更换容器、调整流的数量;省去重新编码,通常处理较快,也避免了这次重新编码带来的画质损失。
但它有适用条件:目标容器必须接得住这些流及所需信息,播放端也要能解码。某些字幕、音频编码或源文件信息不适合目标格式时,直接复制可能失败;保留不兼容的视频编码,也不会让旧设备突然支持它。流复制不能同时完成缩放、裁剪、把字幕烧进画面等需要改动图像的操作。
重封装也不是在资源管理器里把 .mkv 改名为 .mp4。改名只改文件名,原来的内部结构仍然存在;重封装会实际读取源容器,再写出目标容器的结构。音视频数据可以不重新编码,整个文件的字节却会变化。

拿同一段短片,走两条转换路线
下面沿用 2026 年 10 月 2 日制作的 3 秒人工样本:1280×720、每秒 25 帧的测试画面,配上 440 Hz 测试音,编码为 H.264 视频和 AAC 音频,装进 input.mkv。当时使用 Windows、FFmpeg 8.1.2 的 Gyan 构建;这是生成的测试素材,没有使用手机或电影片段。
第一条路线只换容器:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c copy -n output.mp4
第二条路线缩小画面,同时保留已编码的声音:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -vf scale=640:360 -c:v libx264 -preset medium -crf 23 -c:a copy -n smaller.mp4
两条命令都选择第一条视频流和第一条音频流;-n 表示输出文件已存在就停止,避免覆盖。第二条中的 scale 修改画面尺寸,libx264 重新编码视频,-c:a copy 复制音频。质量参数用于这个样本,其他素材仍需按要求调整。
| 输出文件 | 视频编码与尺寸 | 音频编码 | 本次核验结果 |
|---|---|---|---|
output.mp4 |
H.264,1280×720 | AAC | 视频和音频的数据包内容均与输入一致 |
smaller.mp4 |
H.264,640×360 | AAC | 视频数据包改变,音频数据包与输入一致 |
2026 年 10 月 5 日复核已有文件时,用 ffprobe 重新读取编码、尺寸和流类型,并逐条比较已编码音视频数据包的 SHA-256 摘要,结果与原记录一致。表中的“一致”只针对数据包内容,不代表整个文件、时间戳、字幕和所有元数据都相同。这组样本验证了两条命令的处理路线,没有测转换速度或所有格式的兼容性。
两份结果的后缀都叫 MP4,内部经历却不同。是否转码,要看各条流的处理方式,不能只看输入、输出的文件名。
提取声音、缩小体积,要先确定目标
提取声音也不一定要重新编码。原实验将样本的 AAC 音频直接复制到 M4A 文件,音频数据包的复核结果仍一致。如果要求输出 MP3,就需要先解码 AAC,再生成 MP3;把文件改成 .mp3 不会完成转换。能否直接复制,取决于原音频编码和目标容器的支持情况。
“让文件小一点”则需要另一种判断。只换容器不能保证明显缩小;压低码率、改变质量设置或缩小画面,通常涉及重新编码,结果取决于素材与设置。本站的文件压缩原理文章解释了为什么把视频放进 ZIP 往往省不了多少空间,和这里的音视频转码处理对象不同。
实际转换前,可以用 ffprobe -v error -show_format -show_streams input.mkv 查看容器、各条流的编码、画面尺寸等信息,再确认接收端的要求:它只是要求 MP4 文件,还是还要求特定编码、分辨率或音频格式?多音轨或带字幕的文件还要确认保留哪些流;FFmpeg 没有显式指定 -map 时会自动选择,不能默认所有音轨、字幕都进入输出。
只需要换容器,且原有编码兼容时,可以尝试流复制;要改尺寸、画面内容或不兼容的编码,就需要相应转码。输出成功后,还要检查所需声音和字幕是否保留,并在目标设备上确认能否播放。上面的媒体信息查看方式可查 ffprobe 文档[4]。
参考资料
- [1] FFmpeg 官方介绍:https://ffmpeg.org/about.html
- [2] 官方转换流程文档:https://ffmpeg.org/ffmpeg.html#Detailed-description
- [3] 官方流复制说明:https://ffmpeg.org/ffmpeg.html#Streamcopy
- [4] ffprobe 官方文档:https://ffmpeg.org/ffprobe.html