在多音轨、多字幕的视频处理中,-map 是 FFmpeg 最关键也最容易用错的参数之一。
如果你不显式指定 -map,FFmpeg 会按默认规则自动挑选流,结果常常不是你想要的。比如:
- 导出后丢了字幕
- 选错了音轨语言
- 混入了不需要的数据流
这篇文章用最常见的场景,讲清楚 -map 怎么用。
先理解什么是“流”
一个容器文件(例如 mp4、mkv)里通常不止一个内容流(stream),常见包括:
- 视频流(
v) - 音频流(
a) - 字幕流(
s) - 附件/数据流(如字体、封面、章节等)
你可以先用 ffprobe 看清文件里有什么流:
|
|
-map 的基本语法
最常见写法:
|
|
例如:
0:v:第 1 个输入文件的所有视频流0:a:0:第 1 个输入文件的第 1 条音频流1:s:1:第 2 个输入文件的第 2 条字幕流
说明:
input_index从0开始,对应-i的顺序stream_index也从0开始
实战示例
1) 视频来自 A,音频来自 B
|
|
含义:
- 取
english.mp4的第 1 条视频流 - 取
french.mp3的第 1 条音频流 - 合并输出为
french.mp4
2) 保留第一个输入的全部流,再额外加一条音轨
|
|
含义:
-map 0先把第一个输入文件中的所有流都带上- 再追加第二个输入的第 1 条音频流
两个很实用的进阶技巧
1) 负映射:排除不想要的流
例如保留第一个输入的全部流,但去掉第 2 条音频流:
|
|
2) 可选映射:流不存在也不中断
某些文件可能没有字幕,这时可以用 ?:
|
|
0:s? 表示“有字幕就映射,没有就跳过,不报错”。
常见坑位
-map一旦使用,FFmpeg 就不再按默认自动选流,必须把你要的都写出来。-c copy只是封装复制,不做转码;若目标容器不支持某编码,仍会失败。- 多输入时最容易错的是输入序号,记住序号只看
-i的先后顺序。 - 想做稳定脚本时,先
ffprobe再生成-map,比手写更稳。
总结
-map 的核心就是一句话:明确告诉 FFmpeg,“从哪个输入,拿哪类流,拿第几条”。
掌握它之后,你就能稳定处理多音轨、多字幕、跨文件拼接等复杂场景,避免“导出结果不对但又不知道为什么”的问题。