ffmpegdvdvideo-subtitles

Hardcoding subtitles from DVD or VOB file with ffmpeg


I have some DVDs that I would like to encode so that I can play them on a Chromecast, with subtitles. It seems that Chromecast only supports text-based subtitle formats, while DVD subtitles are in a bitmap format, so I need to hardcode the subtitles onto the video stream.

First I use vobcopy to create a VOB file:

vobcopy -I /dev/sr0

Next I want to use ffmpeg to encode it as a video stream in a format that is supported by the Chromecast. This is the closest I've come so far (based on the 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 

The -filter_complex "[0:v:0] [0:s:0]overlay[vid] parameters should overlay the first subtitle stream on the first video stream (-map 0:3 is for the audio). This partially works, but the subtitles are only shown for a fraction of a second (I'm guessing one frame).

How can I make the subtitles display for the correct duration?

I'm using ffmpeg 4.4.1 on Linux, but I've also tried the latest snapshot version, and tried gstreamer and vlc (but didn't get far).


Solution

  • The only solution I found that worked perfectly was a tedious multi-stage process.

    Copy the DVD with vobcopy

    vobcopy -I /dev/sr0
    

    Extract the subtitles in vobsub format using mencoder. This command will write subs.idx and subs.sub. The idx file can be edited if necessary to tweak the appearance of the subtitles.

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

    Copy the audio and video from the VOB into an mkv file. ffprobe can be used to identify the relevant video and audio stream numbers.

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

    Merge the subtitles with the audio/video stream.

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

    Then ffmpeg will work reliably with the mkv file to write hardcoded subtitles to the video stream.

    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