首页 / FFmpeg 入门教程 / 流选择与映射

FFmpeg 入门教程

流选择与映射

本教程共 32 篇 · 第 9 篇 · 更新于 2026-08-09 · 约 7 分钟阅读

FFmpeg-map流选择多音轨多字幕stream specifier编码器

本节目标:看懂多音轨、多字幕文件里的流编号,能用 -map 精确指定要哪些流,并给不同流分别指定编码器。

前面几章都是一进一出的简单情况。实际文件常常有多条音轨、多条字幕。这一章讲清楚 FFmpeg 怎么决定「输出里到底放哪些流」。

流的编号规则

每个输入文件都有编号,里面的每条流也有编号,都从 0 开始。用 ffprobe 看:

ffprobe -hide_banner input.mkv

输出里会看到:

Stream #0:0: Video: hevc
Stream #0:1: Audio: flac
Stream #0:2: Audio: ac3
Stream #0:3: Subtitle: ass
Stream #0:4: Subtitle: ass

#0:0 表示「第 0 个输入文件里的第 0 条流」。第一个数字是输入文件编号,第二个是流编号。多个输入文件时,就会出现 #1:0#2:3 这样的编号。

默认选择:不写 -map 时

如果你不写 -map,FFmpeg 会自动选流。规则是这样的:

  1. 看输出容器支持什么类型(视频/音频/字幕)。
  2. 视频:在所有输入里选分辨率最高的那条。
  3. 音频:选声道数最多的那条。
  4. 字幕:选找到的第一条,但要求字幕类型和输出容器的默认字幕编码器匹配(文本或图形)。
  5. 同等级别时选编号最小的。
  6. 数据流和附件不会自动选,只能用 -map 手动加。

举个例子,一个 MKV 文件有 1 条视频、2 条音频(一条立体声、一条 5.1 声道)、3 条字幕。直接转 MP4:

ffmpeg -i input.mkv output.mp4

FFmpeg 会选视频、5.1 音轨、第一条可转成 mov_text 的字幕——其他音轨和字幕全部丢弃。这往往不是你想要的。

Note

字幕的自动选择有点坑:MP4 默认字幕编码器是文本型的 mov_text,如果源文件里的字幕是图形型(dvdsub、pgssub、xsub),自动选择会跳过它们。你可以手动指定 -c:s dvdsub 之类来强制选择,但能否封装进 MP4 还要看容器支持。

用 -map 手动选流

一旦你写了 -map,自动选择就完全失效——只有你 map 到的流才会进输出。

基本语法

-map 输入文件编号:流编号

例如:

# 只要第 0 个输入的第 0 条流(视频)
ffmpeg -i input.mkv -map 0:0 output.mp4

# 要视频(0:0)和第一条音轨(0:1)
ffmpeg -i input.mkv -map 0:0 -map 0:1 output.mp4

按类型选

vasd 分别代表视频、音频、字幕、数据:

# 选第 0 个输入的所有视频流
ffmpeg -i input.mkv -map 0:v output.mp4

# 选所有视频和所有音频
ffmpeg -i input.mkv -map 0:v -map 0:a output.mp4

# 选第 0 个输入的第一条音频流
ffmpeg -i input.mkv -map 0:a:0 output.mp4

0:v:0 表示「第 0 个输入的第 0 条视频流」,0:a:1 表示「第 0 个输入的第 1 条音频流」。

选所有流

ffmpeg -i input.mkv -map 0 output.mkv

-map 0 表示把第 0 个输入的所有流都搬过去。配合 -c copy 就是完整转封装,连字幕、附件都不丢。

多输入合并

# 把 A 的视频和 B 的音频合在一起
ffmpeg -i A.mp4 -i B.aac -map 0:v -map 1:a -c copy output.mp4

每个 -map 对应输出里的一条流,按书写顺序排列。

排除某条流(负向 map)

# 选第 0 个输入的所有流,但去掉所有音频
ffmpeg -i input.mp4 -map 0 -map -0:a output.mp4

-map -0:a 里的减号表示「从已选集合里移除」。这个写法很适合「整体都要,就不要某一类」的场景。

给不同流指定编码器

-c-codec 的简写,可以加流类型后缀来分别指定:

  • -c:v:视频编码器(也可以写 -vcodec)。
  • -c:a:音频编码器(-acodec)。
  • -c:s:字幕编码器(-scodec)。
  • -c:d:数据。
# 视频转 H.264,音频转 AAC,字幕转 mov_text
ffmpeg -i input.mkv \
  -map 0 \
  -c:v libx264 \
  -c:a aac \
  -c:s mov_text \
  output.mp4

还可以用编号指定具体某一条流。比如有两条音轨,第一条直接复制,第二条转成 AAC 128k:

ffmpeg -i input.mkv \
  -map 0 \
  -c:v copy \
  -c:a:0 copy \
  -c:a:1 aac -b:a:1 128k \
  output.mkv

-c:a:0 里的 :0 是「输出中的第 0 条音频流」的意思,不是输入编号。

-c copy 对所有流生效

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

-c copy 是「所有流都直接复制」,速度最快。但如果某条流和 MP4 容器不兼容,命令会报错。这时再对那条流单独指定编码器,其他保持 copy:

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

视频和音频直接复制,只有字幕转码。

排除整类流:-vn/-an/-sn/-dn

这四个选项可以粗暴地不要某类流:

  • -vn:不要视频(video no)。
  • -an:不要音频(audio no)。
  • -sn:不要字幕(subtitle no)。
  • -dn:不要数据(data no)。
# 只要音频,不要视频和字幕
ffmpeg -i input.mp4 -vn -sn output.aac

它们和 -map 可以配合使用,但通常 -map 更灵活。如果你已经 -map 0:a 选了音频,就不需要再写 -vn 了。

设置默认音轨/字幕

输出里有多条同类流时,可以用 -disposition 标记哪条是默认:

# 把第二条音轨设为默认,清除第一条的默认标记
ffmpeg -i input.mkv -c copy \
  -disposition:a:0 0 \
  -disposition:a:1 default \
  output.mkv

字幕语言标记:

ffmpeg -i input.mkv -i input.ass -c copy -c:s ass \
  -metadata:s:s:0 language=chi \
  -disposition:s:0 default \
  output.mkv

-metadata:s:s:0 language=chi 给第 0 条字幕流设置语言为中文(ISO 639-2 三位代码)。

常见组合

完整转封装,所有流都保留:

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

MKV 转 MP4,字幕转成 mov_text:

ffmpeg -i input.mkv \
  -map 0:v -map 0:a -map 0:s? \
  -c:v copy -c:a copy -c:s mov_text \
  output.mp4
Tip

-map 0:s? 末尾的问号表示「可选」——如果这条流不存在也不报错。适合处理「有的文件有字幕,有的没有」的批处理场景。

只要视频,完全静音:

ffmpeg -i input.mp4 -map 0:v -c:v copy -an output.mp4

添加外部音轨:

ffmpeg -i video.mp4 -i audio.aac \
  -map 0:v -map 0:a? -map 1:a \
  -c:v copy -c:a copy \
  output.mp4

0:a? 保留原视频的音轨(如果有),1:a 加入外部音频。

小结

  • 不写 -map 时,FFmpeg 自动选:视频最高分辨率、音频最多声道、字幕第一条匹配的。
  • -map 0:v-map 0:a:1-map 0 精确控制;-map -0:a 用于排除。
  • -c:v-c:a-c:s 给不同类型流指定编码器,-c copy 全部复制。
  • -map 0:s? 里的问号表示这条流可选,不存在也不报错。
  • 多音轨/多字幕场景,建议总是写 -map,别靠默认行为。

下一章我们用这些知识做最常见的操作之一:从视频里提取音频或视频。