使用 ffmpeg 从 DVD 或 VOB 文件硬编码字幕

Hardcoding subtitles from DVD or VOB file with ffmpeg

我有一些 DVD,我想对其进行编码,以便我可以在 Chromecast 上播放它们并带字幕。 Chromecast 好像只支持文字字幕格式,而 DVD 字幕是位图格式,所以我需要把字幕硬编码到视频流上。

首先我使用vobcopy创建一个VOB文件:

vobcopy -I /dev/sr0

接下来我想使用 ffmpeg 将其编码为 Chromecast 支持的格式的视频流。这是我到目前为止最接近的(基于 ffmpeg documentation):

ffmpeg -analyzeduration 100M -probesize 100M -i in.vob \
    -filter_complex "[0:v:0][0:s:0]overlay[vid]" -map "[vid]" \
    -map 0:3 -codec:v libx264 -crf 20 -codec:a copy out.mkv 

-filter_complex "[0:v:0] [0:s:0]overlay[vid] 参数应在第一个视频流上覆盖第一个字幕流(-map 0:3 用于音频)。这部分有效,但字幕只显示几分之一秒(我猜是一帧)。

如何让字幕显示正确的时长?

我在 Linux 上使用 ffmpeg 4.4.1,但我也尝试了最新的快照版本,并尝试了 gstreamer 和 vlc(但没走多远)。

我发现唯一有效的解决方案是一个乏味的 multi-stage 过程。

vobcopy

复制DVD
vobcopy -I /dev/sr0

使用mencoder提取vobsub格式的字幕。此命令将写入 subs.idx 和 subs.sub。如有必要,可以编辑 idx 文件以调整字幕的外观。

mencoder *.vob -nosound -ovc frameno -o /dev/null \
    -vobsuboutindex 0 -sid 0 -vobsubout subs

将音频和视频从 VOB 复制到 mkv 文件中。 ffprobe可用于识别相关的视频和音频流号。

ffmpeg -fflags genpts -i *vob -map 0:1 -map 0:3 \
    -codec:v copy -codec:a copy copied_av.mkv

将字幕与 audio/video 流合并。

mkvmerge -o merged.mkv copied_av.mkv subs.sub subs.idx

然后 ffmpeg 将可靠地使用 mkv 文件将硬编码字幕写入视频流。

ffmpeg -i merged.mkv -filter_complex "[0:v:0][0:s:0]overlay[vid]" \
     -map [vid] -map 0:1 -codec:v libx264 -codec:a copy hardcoded.mkv