stream标签是视频容器中标识字幕流的语言元数据,-metadata:s:s:0参数用于为第0个字幕流显式设置language=zh等语言标识,确保播放器正确识别并显示该轨道,ffmpeg默认不自动写入此字段,必须在output()中显式指定才能生效。

什么是 STREAM 标签和 -metadata:s:s:0 参数
视频容器(如 MP4)里的每个字幕轨道本身不带语言标识,播放器靠 lang 字段识别语言。FFmpeg 不会自动写入这个字段,必须手动用 -metadata:s:s:N 指定——其中 s:s:0 表示“第 0 个字幕流(subtitle stream)”,lang=zh 才会让 VLC、mpv 或网页 video 标签正确显示该轨道为中文。
用 ffmpeg-python 封装 SRT 并打上语言标签
直接复制字幕流时,-c:s mov_text 只负责格式转换,不写元数据。必须显式加 metadata 参数:
import ffmpeg
(
ffmpeg
.input('video.mp4')
.input('zh.srt')
.output(
'out.mp4',
vcodec='copy',
acodec='copy',
scodec='mov_text',
**{'metadata:s:s:0': 'language=zh'}
)
.run(overwrite_output=True)
)
-
scodec='mov_text'是 MP4 容器唯一支持的内封字幕编码格式,不能用ass或webvtt - 若添加第二个轨道(如英文字幕),需用
**{'metadata:s:s:1': 'language=en'},且输入顺序必须和轨道索引一致 - Windows 下路径含空格或中文时,
ffmpeg-python可能解析失败,建议先用os.path.abspath()转绝对路径
验证标签是否生效:用 ffprobe 查看字幕流信息
封装后务必检查,否则多数播放器会默认只启用第一个字幕轨道,且不显示语言名:
一款AI工具,主要用于在主代理响应前,并行运行Kimi K2.5和GPT 5.3 Codex,注入双方观点以增强认知多样性,适合需要提升相关任务效率的用户。
ffprobe -v quiet -show_entries stream=index,codec_type,tags=language -of default out.mp4
正确输出应包含类似:
index=2 codec_type=subtitle TAG:language=zh
- 如果
TAG:language缺失或为空,说明-metadata:s:s:N没生效,常见原因是参数位置错误(必须放在.output()内,不能塞进.filter()) -
index=2表示这是第三个流(0=视频,1=音频,2=字幕),多轨道时需逐个核对 index 和 language 是否匹配
多语言同步的关键:时间轴必须完全对齐
不同语言字幕文件即使内容一致,SRT 时间戳也可能因人工校准产生毫秒级偏移。播放器不会自动对齐,而是各自按原始时间戳渲染——导致双语切换时画面错位。
- 用
autosub生成初版后,再用ffmpeg -i zh.srt -i en.srt -filter_complex "asplit=2[a][b]; [a]setpts=PTS-STARTPTS[aa]; [b]setpts=PTS-STARTPTS[bb]"强制归零起始时间(仅适用于纯文本字幕) - 真正可靠的同步方式是用同一份语音识别结果 + 翻译,而非分别生成两份 SRT;
ffmpeg-python的filter_multi_output可基于同一音频流并行生成双语字幕流,避免时间轴漂移 - MP4 中最多支持 16 个字幕轨道,但 iOS Safari 只读取第一个非空轨道,Android 原生播放器则依赖
lang字段排序,这点常被忽略










