TL;DR:使用 ffmpeg 剪切视频后,即使有字幕流,VLC 播放器中也不会看到字幕。
我有一个电影电视录像的 MP4 文件,我想剪掉开头和结尾属于其他节目的部分。
该文件包含一个视频流、两个音频流(不会造成问题)和一个字幕流:
Stream #0:3(deu): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
Metadata:
handler_name : SubtitleHandler
为了根据我的需要剪切文件同时保留所有流,我使用了以下-map 0
选项:
ffmpeg -ss 00:06:49 -i in.mp4 -to 02:15:38 -map 0 -c copy out1.mp4
效果很好,所有流都完好无损,但字幕出现一些错位,整个电影的延迟在零到几秒之间变化。此外,ffmpeg 给了我一堆错误,形式如下
[mp4 @ 0000023b9c3cb4c0] Application provided duration: -401 / timestamp: 8136600 is out of range for mov/mp4 format
[mp4 @ 0000023b9c3cb4c0] pts has no value
但文件 out1.mp4 仍然已创建并正常运行。
我读到,把放在-ss
输入后面会更准确,所以接下来我尝试
ffmpeg -i in.mp4 -ss 00:06:49 -to 02:22:27 -map 0 -c copy out2.mp4
同样,所有流都在那里(这次没有任何 ffmpeg 错误),但现在即使选择了 VLC,字幕也不会显示。同时,在 Microsoft Films & TV 中,我可以看到字幕在屏幕上闪烁一瞬间,然后消失。
我提取了所有字幕文件。在 out1.srt 中,字幕如下
8
00:00:57,204 --> 00:00:58,204
<font face="Serif" size="18">(Trinity:) Ist alles vorbereitet?</font>
9
00:00:58,205 --> 00:00:59,205
<font face="Serif" size="18">(Trinity:) Ist alles vorbereitet?</font>
因此字幕会显示一秒或其倍数,尽管原始文件中并不一致。同时,两个都in.srt 和 out2.srt 字幕的形式为
8
00:00:56,520 --> 00:00:56,520
<font face="Serif" size="18">(Trinity:) Ist alles vorbereitet?</font>
9
00:00:56,600 --> 00:00:56,600
<font face="Serif" size="18">(Trinity:) Ist alles vorbereitet?</font>
即,仅显示(有时重复)一毫秒。这可以解释观看 out2.mp4 时字幕闪烁/不显示的原因,但为什么 in.mp4 不会发生这种情况?我该如何完全防止这种情况发生?
回顾一下:
- 未经剪辑的 in.mp4 文件的字幕显示效果很好。根据 in.srt 的显示效果,字幕显示时间为 1ms。
- out1.mp4 有字幕,但有点错位,且有不同程度的延迟。根据 out1.srt,字幕显示时间为 1 秒。时间戳中可以看到看似随机的错位。
- out2.mp4 的字幕流无法正常工作。in.srt 和 out2.srt 之间的唯一区别是前者还包含剪切部分的字幕,并且根据时间戳,所有字幕都恰好移动了 6 分 49 秒。
因此看起来 out2.mp4 的字幕已经完全按照我的需要移动,没有任何延迟,但我该如何让它们显示出来呢?