Converting DVD image with subtitles to MKV using avconv

57,466

Solution 1

Short answer: Skip down to section Full commandline and download ffmpeg from this site.

Originally, I planned to answer how to do this with avconv because (a) that answer is still missing and (b) avconv seems to be the default on ubuntu systems today. However it seems it's currently too buggy to accomplish this - at least for my testcases.

ffmpeg setup

Since you ask for either avconv or ffmpeg, and I just learned that avconv is a fork of ffmpeg (see this answer for a discussion), I downloaded a current version of ffmpeg from this site as the aforementioned answer explains. Windows builds are also available. For a typical current 64bit Linux build the direct link would be to this page. It contains daily builds. So scroll down until you see the latest and greatest, download, and unpack with e.g. tar xzvf ffmpeg.static.64bit.2014-02-14.tar.gz. The advantage of a static build is that it has less, if no, dependencies. Unpacking the tarfile created two new executables ffmpeg and ffprobe in the current dir.

Basic command line

Now we can use this latest ffmpeg to copy all streams inside the mymovie.vob* to a different format. For example:

./ffmpeg -i mymovie.vob -c:v copy -c:a copy -c:s copy -map 0 mymovie.mkv

This command line

  • reads in from the input file -i filename
  • copies video streams therein -c:v copy
  • copies audio streams therein -c:a copy
  • copies subtitles therein -c:s copy
  • and instead of just using the first of each, it uses, and copies all of them -map 0
  • to the output file outputfile

Let's expand the above command line to workaround some possible bugs in the tool, or corrupt input files, or just specifics about .vob files.

Work around for error Can't write packet with unknown timestamp

Add the options -fflags +genpts before the input file.

./ffmpeg -fflags +genpts -i mymovie.vob -c:v copy -c:a copy -c:s copy -map 0 mymovie.mkv

Options in ffmpeg always only affect input or output files named after the current option. Those two options must affect the input file, so they must come first.

This workaround is covered in this bug ticket and may not help in all cases.

Missing some or all subtitles

This is very typical behaviour when processing .vob files and is covered in the ffmpeg FAQ. Video container filetypes such as .avi or .mp4 or .mkv have headers (data at the start of a file) listing all content of the file. This makes it easy for players and conversion tools to know what kind of data to expect. .vob files do not have such an explicit header. So when ffmpeg or avconv start, they look at the first couple thousand bytes. In vob files, the subtitles may start very late. In my testcase the first subtitle appears after several seconds, so the tools do not see it during startup. Here's typical example output during coding in these situations:

Output #0, matroska, to 'test.mkv':
  Metadata:
    encoder         : Lavf55.32.101
    Stream #0:0: Video: mpeg2video (mpg2 / 0x3267706D), yuv420p, 720x576 [SAR 64:45 DAR 16:9], q=2-31, max. 9800 kb/s, 25 fps, 1k tbn, 90k tbc
    Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 448 kb/s
    Stream #0:2: Audio: dts ([1] [0][0] / 0x2001), 48000 Hz, 5.1(side), 768 kb/s
    Stream #0:3: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 448 kb/s
    Stream #0:4: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, stereo, 224 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #0:2 -> #0:2 (copy)
  Stream #0:3 -> #0:3 (copy)
  Stream #0:4 -> #0:4 (copy)
Press [q] to stop, [?] for help
[mpeg @ 0x31f2540] New subtitle stream 0:5 at pos:16945166 and DTS:22.2473s
[mpeg @ 0x31f2540] New subtitle stream 0:6 at pos:16951310 and DTS:22.2473s
[mpeg @ 0x31f2540] New subtitle stream 0:7 at pos:16957454 and DTS:22.2873s
[mpeg @ 0x31f2540] New subtitle stream 0:8 at pos:16963598 and DTS:22.2873s
[mpeg @ 0x31f2540] New subtitle stream 0:9 at pos:18405390 and DTS:25.4873s
[mpeg @ 0x31f2540] New subtitle stream 0:10 at pos:18417678 and DTS:25.4873s
[mpeg @ 0x31f2540] New subtitle stream 0:11 at pos:264593422 and DTS:288.207sts/s    
[mpeg @ 0x31f2540] New subtitle stream 0:12 at pos:264597518 and DTS:288.207s
frame=24694 fps=7322 q=-1.0 Lsize=  859345kB time=00:16:27.74 bitrate=7127.1kbits/s    
video:632823kB audio:224996kB subtitle:0 data:0 global headers:0kB muxing overhead 0.177935%

As one can see, new subtitle streams were found during the actual encoding. If one would try to add -map 5 option to include that stream, ffmpeg would complain during startup that this stream number does not exist.

The solution is to tell ffmpeg to analyze more bytes at the start of the file in order to find all streams.

Try adding the options -analyzeduration 1000000k -probesize 1000000k before the input file.

Try increasing the numbers if the streams are still not found. In my testcases those numbers were big enough. The output then changes to:

Input #0, mpeg, from 'mymovie.vob':
  Duration: 00:59:39.90, start: 0.287267, bitrate: 5915 kb/s
    Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt470bg), 720x576 [SAR 64:45 DAR 16:9], max. 9800 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:2[0x89]: Audio: dts (DTS), 48000 Hz, 5.1(side), fltp, 768 kb/s
    Stream #0:3[0x82]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:4[0x83]: Audio: ac3, 48000 Hz, stereo, fltp, 224 kb/s
    Stream #0:5[0x20]: Subtitle: dvd_subtitle
    Stream #0:6[0x21]: Subtitle: dvd_subtitle
    Stream #0:7[0x22]: Subtitle: dvd_subtitle
    Stream #0:8[0x23]: Subtitle: dvd_subtitle
    Stream #0:9[0x24]: Subtitle: dvd_subtitle
    Stream #0:10[0x25]: Subtitle: dvd_subtitle
    Stream #0:11[0x26]: Subtitle: dvd_subtitle
    Stream #0:12[0x27]: Subtitle: dvd_subtitle
File 'test.mkv' already exists. Overwrite ? [y/N] y
Output #0, matroska, to 'test.mkv':
  Metadata:
    encoder         : Lavf55.32.101
    Stream #0:0: Video: mpeg2video (mpg2 / 0x3267706D), yuv420p, 720x576 [SAR 64:45 DAR 16:9], q=2-31, max. 9800 kb/s, 25 fps, 1k tbn, 90k tbc
    Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 448 kb/s
    Stream #0:2: Audio: dts ([1] [0][0] / 0x2001), 48000 Hz, 5.1(side), 768 kb/s
    Stream #0:3: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 448 kb/s
    Stream #0:4: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, stereo, 224 kb/s
    Stream #0:5: Subtitle: dvd_subtitle
    Stream #0:6: Subtitle: dvd_subtitle
    Stream #0:7: Subtitle: dvd_subtitle
    Stream #0:8: Subtitle: dvd_subtitle
    Stream #0:9: Subtitle: dvd_subtitle
    Stream #0:10: Subtitle: dvd_subtitle
    Stream #0:11: Subtitle: dvd_subtitle
    Stream #0:12: Subtitle: dvd_subtitle

Full commandline

./ffmpeg -fflags +genpts -analyzeduration 1000000k -probesize 1000000k -i mymovie.vob -c:v copy -c:a copy -c:s copy -map 0 mymovie.mkv

Any of the copies can be replaced with a codec to actually convert, and likely compress, the data. But if it's just the three copies, then the command can be simplified to:

./ffmpeg -fflags +genpts -analyzeduration 1000000k -probesize 1000000k -i mymovie.vob  -c copy -map 0 mymovie.mkv

All of these options are also supported by avconv. However this tool seems to still have a problem with some subtitles. If you see this error:

[matroska @ 0x383aee60] Application provided invalid, non monotonically increasing dts to muxer in stream 7: 58280 >= 58280
av_interleaved_write_frame(): Invalid argument

You can workaround by downloading the latest ffmpeg and using that tool instead, as I've explained above.

Solution 2

If you need a quality saving solution you should try MakeMKV.
If you want to compress the video track or convert MPEG-2 to H.264 you can use handbrake.

Share:
57,466

Related videos on Youtube

Carlos Eugenio Thompson Pinzón
Author by

Carlos Eugenio Thompson Pinzón

Human being, or so they say. A soul that likes to know about computers and solving problems with them, attempting a living as freelance developer.

Updated on July 09, 2022

Comments

  • Carlos Eugenio Thompson Pinzón
    Carlos Eugenio Thompson Pinzón almost 2 years

    This is the procedure I know to convert a DVD image to another videoformat (v.g. MP4):

    1. concatenate the VTS_01_n.VOB files inside VIDEO_TS folder (for n >= 0) into a single VOB file.
    2. use avconv or ffmpeg in order to convert that VOB into another format.

    So far so good, however now I want to convert the DVD image with the subtitles. As far as I know the MKV format supports subtitles, so it seems an obvious choice. Alternatively I might use any other format with hard subtitles (subtitles as part of the video image).

    However, the subtitle encoding in the DVD image is dvdsub and I get the following error

    Only SUBTITLE_ASS type supported.
    Subtitle encoding failed
    

    However, when running avconv -codecs I get:

    ...
     DES    dvdsub          DVD subtitles
    ...
    

    And the -c:s copy switch, while it prevents the command to fail, it does not seem to produce a subtitle that the player can understand.

    So, how can I create ass subtitles from dvdsub using avconv?

    My VOB file has eight subtitle channels and two audio channels. The Ubuntu video app does not show any subtitles, and only the first audio channel seems to be working, do the DVD image might be broken.

    Another file, for a double-layer DVD, displays the Subtitle encoding error, however when using the -c:s copy switch it further displays:

    Application provided invalid, non monotonically increasing dts to muxer in stream 2: 49 >= 49
    av_interleaved_write_frame(): Invalid argument
    

    Thank you in advance for any ideas on how to solve these problems.

    (I am using Ubuntu where ffmpeg is an alias for avconv. I know it is possible to install the real ffmpeg but so far I have not done so.)


    update: commands and console outputs:

    commands

    cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB VTS_01_4.VOB VTS_01_5.VOB > ~/temp/mymovie.VOB
    cd ~/temp
    avconv -i mymovie.VOB
    

    output

    avconv version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2000-2013 the Libav developers
      built on Mar 30 2013 22:20:06 with gcc 4.7.2
    [mpeg @ 0x1a64d40] max_analyze_duration reached
    Input #0, mpeg, from 'mymovie.VOB':
      Duration: 00:00:01.95, start: 0.280633, bitrate: -2147483 kb/s
        Stream #0.0[0x1e0]: Video: mpeg2video (Main), yuv420p, 720x480 [PAR 8:9 DAR 4:3], 7500 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
        Stream #0.1[0x20]: Subtitle: dvdsub
        Stream #0.2[0x21]: Subtitle: dvdsub
        Stream #0.3[0x22]: Subtitle: dvdsub
        Stream #0.4[0x23]: Subtitle: dvdsub
        Stream #0.5[0x24]: Subtitle: dvdsub
        Stream #0.6[0x25]: Subtitle: dvdsub
        Stream #0.7[0x26]: Subtitle: dvdsub
        Stream #0.8[0x27]: Subtitle: dvdsub
        Stream #0.9[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
        Stream #0.10[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    At least one output file must be specified
    

    command

    avconv -i mymovie.VOB mymovie.mkv
    

    output

    avconv version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2000-2013 the Libav developers
      built on Mar 30 2013 22:20:06 with gcc 4.7.2
    [mpeg @ 0x1cdad40] max_analyze_duration reached
    Input #0, mpeg, from 'mymovie.VOB':
      Duration: 00:00:01.95, start: 0.280633, bitrate: -2147483 kb/s
        Stream #0.0[0x1e0]: Video: mpeg2video (Main), yuv420p, 720x480 [PAR 8:9 DAR 4:3], 7500 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
        Stream #0.1[0x20]: Subtitle: dvdsub
        Stream #0.2[0x21]: Subtitle: dvdsub
        Stream #0.3[0x22]: Subtitle: dvdsub
        Stream #0.4[0x23]: Subtitle: dvdsub
        Stream #0.5[0x24]: Subtitle: dvdsub
        Stream #0.6[0x25]: Subtitle: dvdsub
        Stream #0.7[0x26]: Subtitle: dvdsub
        Stream #0.8[0x27]: Subtitle: dvdsub
        Stream #0.9[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
        Stream #0.10[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    File 'mymovie.mkv' already exists. Overwrite ? [y/N] y
    [buffer @ 0x1ce23c0] w:720 h:480 pixfmt:yuv420p
    Output #0, matroska, to 'mymovie.mkv':
      Metadata:
        encoder         : Lavf53.21.1
        Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 8:9 DAR 4:3], q=2-31, 200 kb/s, 1k tbn, 29.97 tbc
        Stream #0.1: Audio: libvorbis, 48000 Hz, 5.1, s16
        Stream #0.2: Subtitle: ass, 200 kb/s
    Stream mapping:
      Stream #0:0 -> #0:0 (mpeg2video -> mpeg4)
      Stream #0:9 -> #0:1 (ac3 -> libvorbis)
      Stream #0:1 -> #0:2 (dvdsub -> ass)
    Press ctrl-c to stop encoding
    [ass @ 0x1ce0140] Only SUBTITLE_ASS type supported.
    Subtitle encoding failed
    

    command

    avconv -i mymovie.VOB -c:s copy mymovie.mkv
    

    output omitted.

    command

    avconv -i mymovie.mkv
    

    output

    avconv version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2000-2013 the Libav developers
      built on Mar 30 2013 22:20:06 with gcc 4.7.2
    [matroska,webm @ 0xbc1d40] Estimating duration from bitrate, this may be inaccurate
    Input #0, matroska,webm, from 'mymovie.mkv':
      Metadata:
        ENCODER         : Lavf53.21.1
      Duration: 01:05:09.47, start: 0.000000, bitrate: N/A
        Stream #0.0: Video: mpeg4 (Simple Profile), yuv420p, 720x480 [PAR 8:9 DAR 4:3], 29.97 fps, 29.97 tbr, 1k tbn, 30k tbc (default)
        Stream #0.1: Audio: vorbis, 48000 Hz, 5.1, s16 (default)
        Stream #0.2: Subtitle: dvdsub (default)
    At least one output file must be specified
    

    Now, for the double-layer: commands

    cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB VTS_01_4.VOB VTS_01_5.VOB VTS_01_6.VOB VTS_01_7.VOB VTS_01_8.VOB > ~/temp/mylongmovie.VOB
    cd ~/temp
    avconv -i mylongmovie.VOB mylongmovie.mkv
    

    output

    avconv version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2000-2013 the Libav developers
      built on Mar 30 2013 22:20:06 with gcc 4.7.2
    [mpeg @ 0x13c2d40] max_analyze_duration reached
    Input #0, mpeg, from 'Cosmos-0203.VOB':
      Duration: 00:00:30.24, start: 0.280633, bitrate: 2103365 kb/s
        Stream #0.0[0x1e0]: Video: mpeg2video (Main), yuv420p, 720x480 [PAR 8:9 DAR 4:3], 8000 kb/s, 27.46 fps, 59.94 tbr, 90k tbn, 59.94 tbc
        Stream #0.1[0x20]: Subtitle: dvdsub
        Stream #0.2[0x21]: Subtitle: dvdsub
        Stream #0.3[0x22]: Subtitle: dvdsub
        Stream #0.4[0x23]: Subtitle: dvdsub
        Stream #0.5[0x24]: Subtitle: dvdsub
        Stream #0.6[0x25]: Subtitle: dvdsub
        Stream #0.7[0x26]: Subtitle: dvdsub
        Stream #0.8[0x27]: Subtitle: dvdsub
        Stream #0.9[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
        Stream #0.10[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    File 'mylongmovie.mkv' already exists. Overwrite ? [y/N] y
    [buffer @ 0x13ca3c0] w:720 h:480 pixfmt:yuv420p
    Output #0, matroska, to 'mylongmovie.mkv':
      Metadata:
        encoder         : Lavf53.21.1
        Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 8:9 DAR 4:3], q=2-31, 200 kb/s, 1k tbn, 59.94 tbc
        Stream #0.1: Audio: libvorbis, 48000 Hz, 5.1, s16
        Stream #0.2: Subtitle: ass, 200 kb/s
    Stream mapping:
      Stream #0:0 -> #0:0 (mpeg2video -> mpeg4)
      Stream #0:9 -> #0:1 (ac3 -> libvorbis)
      Stream #0:1 -> #0:2 (dvdsub -> ass)
    Press ctrl-c to stop encoding
    [ass @ 0x13d19c0] Only SUBTITLE_ASS type supported.
    Subtitle encoding failed
    

    command

    avconv -i mylongmovie.VOB -c:s copy mylongmovie.mkv 
    

    output

    avconv version 0.8.6-6:0.8.6-1ubuntu2, Copyright (c) 2000-2013 the Libav developers
      built on Mar 30 2013 22:20:06 with gcc 4.7.2
    [mpeg @ 0xce1d40] max_analyze_duration reached
    Input #0, mpeg, from 'mylongmovie.VOB':
      Duration: 00:00:30.24, start: 0.280633, bitrate: 2103365 kb/s
        Stream #0.0[0x1e0]: Video: mpeg2video (Main), yuv420p, 720x480 [PAR 8:9 DAR 4:3], 8000 kb/s, 27.46 fps, 59.94 tbr, 90k tbn, 59.94 tbc
        Stream #0.1[0x20]: Subtitle: dvdsub
        Stream #0.2[0x21]: Subtitle: dvdsub
        Stream #0.3[0x22]: Subtitle: dvdsub
        Stream #0.4[0x23]: Subtitle: dvdsub
        Stream #0.5[0x24]: Subtitle: dvdsub
        Stream #0.6[0x25]: Subtitle: dvdsub
        Stream #0.7[0x26]: Subtitle: dvdsub
        Stream #0.8[0x27]: Subtitle: dvdsub
        Stream #0.9[0x81]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
        Stream #0.10[0x80]: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    File 'mylongmovie.mkv' already exists. Overwrite ? [y/N] y
    [buffer @ 0xce93c0] w:720 h:480 pixfmt:yuv420p
    Output #0, matroska, to 'mylongmovie.mkv':
      Metadata:
        encoder         : Lavf53.21.1
        Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 8:9 DAR 4:3], q=2-31, 200 kb/s, 1k tbn, 59.94 tbc
        Stream #0.1: Audio: libvorbis, 48000 Hz, 5.1, s16
        Stream #0.2: Subtitle: dvdsub
    Stream mapping:
      Stream #0:0 -> #0:0 (mpeg2video -> mpeg4)
      Stream #0:9 -> #0:1 (ac3 -> libvorbis)
      Stream #0:1 -> #0:2 (copy)
    Press ctrl-c to stop encoding
    [matroska @ 0xce4b40] Application provided invalid, non monotonically increasing dts to muxer in stream 2: 49 >= 49
    av_interleaved_write_frame(): Invalid argument
    
    • Carlos Eugenio Thompson Pinzón
      Carlos Eugenio Thompson Pinzón over 10 years
      @LordNeckbeard commands and outputs inserted
    • Endoro
      Endoro over 10 years
      Converting DVD to MKV: with encoding use Handbrake, without encoding MakeMKV.
    • Carlos Eugenio Thompson Pinzón
      Carlos Eugenio Thompson Pinzón over 10 years
      @Endoro: MakeMKV worked for me. While I would've like a complete open source solution (this requires installing binaries), this worked perfectly for my immediate need. If you write it as an answer I will upvote it and (if no avconv answer given) accept it. Thank you.
    • Display Name
      Display Name over 8 years
      @CarlosEugenioThompsonPinzón mkvmerge is open source and it's superior in this task — very easy to use (keeps all tracks by default, no fancy magic options required), and tolerant to various format errors which can kill ffmpeg, for example. I guess MakeMKV just uses it under the hood.
  • Carlos Eugenio Thompson Pinzón
    Carlos Eugenio Thompson Pinzón over 10 years
    MakeMKV worked for me. Thank you. Handbrake is causing a shutdown in my system before it finish the first conversion.
  • Endoro
    Endoro over 10 years
    @CarlosEugenioThompsonPinzón have you tried the Nightly build ?
  • Display Name
    Display Name over 8 years
    From my experience, ffmpeg chokes on some inputs completely (generates invalid file and/or hangs), but I converted (re-muxed) them to MKV format with mkvmerge successfully and it generated completely correct file. Although I did not test if it also transfers subtitles, but I am sure it should take care of them, too.
  • user1593842
    user1593842 over 3 years
    Great answer! I didn't know about +genpts, and it was nice seeing you mentioning analyzeduration and probesize. Most answers I saw simply say to concatenate the VOB files and then use fmpeg to generate the video. Unfortunately as Display Name said, ffmpeg still chokes on some input files. I just tried and it froze at the end of the conversion. I think the generated file has everything, but it shouldn't have choked like that.