流选择与映射
本教程共 32 篇 · 第 9 篇 · 更新于 2026-08-09 · 约 7 分钟阅读
本节目标:看懂多音轨、多字幕文件里的流编号,能用
-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 会自动选流。规则是这样的:
- 看输出容器支持什么类型(视频/音频/字幕)。
- 视频:在所有输入里选分辨率最高的那条。
- 音频:选声道数最多的那条。
- 字幕:选找到的第一条,但要求字幕类型和输出容器的默认字幕编码器匹配(文本或图形)。
- 同等级别时选编号最小的。
- 数据流和附件不会自动选,只能用
-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
按类型选
用 v、a、s、d 分别代表视频、音频、字幕、数据:
# 选第 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,别靠默认行为。
下一章我们用这些知识做最常见的操作之一:从视频里提取音频或视频。