FFmpeg无法检测字幕的问题求助:如何选择复制过程中才被识别的字幕
嘿,我完全懂你这个糟心的状况——处理《权力的游戏》第五季第六集的字幕时,FFmpeg在一开始探测文件时根本认不全所有字幕,非得等编码开始跑起来才会发现那些隐藏的字幕流,但这时候再指定索引去复制就直接失败了,确实够头疼的。
咱们先理清楚问题根源:你用的是MPG格式的源文件,这类老旧封装里的字幕(比如VobSub)经常不会把完整的流信息放在文件开头,FFmpeg默认的预探测只读取文件前一小部分,自然找不到这些“藏在后面”的字幕流,只有当它开始逐帧处理文件时,才会慢慢解析出来。
给你几个实用的解决思路,你可以挨个试试:
1. 先强制让FFmpeg完整分析整个文件
把probesize和analyzeduration调得更大,让FFmpeg直接读取更多甚至整个文件内容来探测流信息,比如试试这个“干运行”命令:
ffmpeg -fflags +genpts -probesize 1G -analyzeduration 1G -i E6-UnbowedUnbentUnbroken.mpg -f null -
这个命令不会生成任何输出文件,就是让FFmpeg从头到尾扫一遍源文件,把所有流信息都识别出来。跑完之后你再执行原来的复制命令,指定你需要的字幕索引(这时候索引应该能正确对应上了)。
2. 先复制所有流到临时文件,再提取目标内容
如果第一种方法还是不行,咱们换个思路:先把源文件里的所有流(包括那些没被初始探测到的字幕)完整复制到一个临时文件里,这时候FFmpeg已经解析出所有流了,再从这个临时文件里提取你需要的字幕、视频和音频:
# 第一步:复制所有流到临时文件 ffmpeg -fflags +genpts -probesize 300M -analyzeduration 180M -i E6-UnbowedUnbentUnbroken.mpg -c copy tmp_all.mkv # 第二步:从临时文件提取目标流 ffmpeg -i tmp_all.mkv -map 0:s:2 -map 0:v:0 -map 0:a:0 -c copy tmp_final.mkv
这样操作的好处是,第一次复制时FFmpeg会被迫解析整个文件,所有字幕流都会被保留在tmp_all.mkv里,第二次提取时就能精准指定索引了。
3. 用元数据匹配字幕,而非固定索引
如果你知道目标字幕的语言(比如英语),可以试试不用固定索引,而是通过语言元数据来选择字幕,这样哪怕索引变了也能正确匹配:
ffmpeg -fflags +genpts -probesize 300M -analyzeduration 180M -i E6-UnbowedUnbentUnbroken.mpg -map 0:s:m:language:eng -map 0:v:0 -map 0:a:0 -c copy tmp2.mkv
这里的eng是英语的代码,如果是其他语言可以换成对应的代码(比如chs对应简体中文)。
这些方法应该能解决你遇到的问题,本质都是让FFmpeg有足够的机会去解析那些藏在文件深处的字幕流。
备注:内容来源于stack exchange,提问作者Summers

