Converting DVD image with subtitles to MKV using avconv

扶醉桌前 提交于 2019-12-02 19:09:50
cfi

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.

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!