FFmpeg 的 `-map` 参数详解:精准选择视频、音频与字幕流

一篇可直接上手的 FFmpeg `-map` 指南:从流命名规则到多输入合成、负映射与可选映射。

在多音轨、多字幕的视频处理中,-map 是 FFmpeg 最关键也最容易用错的参数之一。

如果你不显式指定 -map,FFmpeg 会按默认规则自动挑选流,结果常常不是你想要的。比如:

  • 导出后丢了字幕
  • 选错了音轨语言
  • 混入了不需要的数据流

这篇文章用最常见的场景,讲清楚 -map 怎么用。

先理解什么是“流”

一个容器文件(例如 mp4mkv)里通常不止一个内容流(stream),常见包括:

  • 视频流(v
  • 音频流(a
  • 字幕流(s
  • 附件/数据流(如字体、封面、章节等)

你可以先用 ffprobe 看清文件里有什么流:

1
ffprobe -hide_banner input.mkv

-map 的基本语法

最常见写法:

1
-map input_index[:stream_type][:stream_index]

例如:

  • 0:v:第 1 个输入文件的所有视频流
  • 0:a:0:第 1 个输入文件的第 1 条音频流
  • 1:s:1:第 2 个输入文件的第 2 条字幕流

说明:

  • input_index0 开始,对应 -i 的顺序
  • stream_index 也从 0 开始

实战示例

1) 视频来自 A,音频来自 B

1
2
3
4
ffmpeg -i english.mp4 -i french.mp3 \
  -map 0:v:0 -map 1:a:0 \
  -c:v copy -c:a aac \
  french.mp4

含义:

  • english.mp4 的第 1 条视频流
  • french.mp3 的第 1 条音频流
  • 合并输出为 french.mp4

2) 保留第一个输入的全部流,再额外加一条音轨

1
2
3
4
ffmpeg -i english.mp4 -i french.mp3 \
  -map 0 -map 1:a:0 \
  -c copy \
  english-french.mp4

含义:

  • -map 0 先把第一个输入文件中的所有流都带上
  • 再追加第二个输入的第 1 条音频流

两个很实用的进阶技巧

1) 负映射:排除不想要的流

例如保留第一个输入的全部流,但去掉第 2 条音频流:

1
ffmpeg -i input.mkv -map 0 -map -0:a:1 -c copy output.mkv

2) 可选映射:流不存在也不中断

某些文件可能没有字幕,这时可以用 ?

1
ffmpeg -i input.mp4 -map 0:v -map 0:a -map 0:s? -c copy output.mp4

0:s? 表示“有字幕就映射,没有就跳过,不报错”。

常见坑位

  1. -map 一旦使用,FFmpeg 就不再按默认自动选流,必须把你要的都写出来。
  2. -c copy 只是封装复制,不做转码;若目标容器不支持某编码,仍会失败。
  3. 多输入时最容易错的是输入序号,记住序号只看 -i 的先后顺序。
  4. 想做稳定脚本时,先 ffprobe 再生成 -map,比手写更稳。

总结

-map 的核心就是一句话:明确告诉 FFmpeg,“从哪个输入,拿哪类流,拿第几条”。

掌握它之后,你就能稳定处理多音轨、多字幕、跨文件拼接等复杂场景,避免“导出结果不对但又不知道为什么”的问题。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计