21

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
4

2 回答 2

43

简短回答:跳至完整命令行部分并ffmpeg该站点下载。

最初,我计划回答如何做到这一点,avconv因为(a)该答案仍然缺失,并且(b)avconv似乎是当今 ubuntu 系统的默认设置。但是,目前似乎无法做到这一点-至少对于我的测试用例而言。

ffmpeg 设置

由于您要求avconvor ffmpeg,而我刚刚了解到这avconv是一个 fork ffmpeg(请参阅此答案进行讨论),因此我ffmpeg该站点下载了当前版本,正如上述答案所解释的那样。Windows 版本也可用。对于当前典型的 64 位 Linux 构建,直接链接将指向此页面。它包含每日构建。所以向下滚动,直到你看到最新最好的,下载,并用例如解压tar xzvf ffmpeg.static.64bit.2014-02-14.tar.gz。静态构建的优点是它具有更少的依赖关系(如果没有的话)。解压 tar 文件在当前目录中ffmpeg创建了两个新的可执行文件。ffprobe

基本命令行

现在我们可以使用这个最新ffmpeg的将里面的所有流复制mymovie.vob*到不同的格式。例如:

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

这个命令行

  • 从输入文件中读入-i filename
  • 复制其中的视频流-c:v copy
  • 复制其中的音频流-c:a copy
  • 复制其中的字幕-c:s copy
  • 而不是只使用每个中的第一个,而是使用并复制所有这些-map 0
  • 到输出文件outputfile

让我们扩展上面的命令行来解决工具中的一些可能的错误,或者损坏的输入文件,或者只是关于.vob文件的细节。

解决错误Can't write packet with unknown timestamp

在输入文件-fflags +genpts 之前添加选项。

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

中的选项总是只影响以当前选项命名的输入ffmpeg或输出文件。这两个选项必须影响输入文件,所以它们必须排在第一位。

此错误票证中涵盖了此解决方法,并且可能并非在所有情况下都有帮助。

缺少部分或全部字幕

.vob这是处理文件时非常典型的行为,ffmpeg常见问题解答中对此进行了介绍。视频容器文件类型,例如.avi或具有列出文件所有内容的标题(文件开头的数据)。这让玩家和转换工具很容易知道期望什么样的数据。文件没有这样一个明确的标题。因此,当或开始时,他们会查看前几千个字节。在 vob 文件中,字幕可能会很晚才开始。在我的测试用例中,第一个字幕会在几秒钟后出现,因此工具在启动过程中看不到它。以下是在这些情况下编码期间的典型示例输出:.mp4.mkv.vobffmpegavconv

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%

可以看到,在实际编码过程中发现了新的字幕流。如果尝试添加-map 5选项以包含该流,ffmpeg则会在启动期间抱怨该流号不存在。

解决方案是告诉ffmpeg在文件开头分析更多字节以查找所有流。

尝试在输入文件-analyzeduration 1000000k -probesize 1000000k 之前添加选项。

如果仍未找到流,请尝试增加数字。在我的测试用例中,这些数字已经足够大了。然后输出变为:

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

完整的命令行

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

任何副本都可以替换为编解码器,以实际转换并可能压缩数据。但如果只是三份,那么命令可以简化为:

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

也支持所有这些选项avconv。然而,这个工具似乎仍然有一些字幕的问题。如果您看到此错误:

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

ffmpeg正如我在上面解释的那样,您可以通过下载最新版本并使用该工具来解决问题。

于 2014-02-14T22:32:18.200 回答
5

如果您需要节省质量的解决方案,您应该尝试MakeMKV
如果您想压缩视频轨道或将 MPEG-2 转换为 H.264,您可以使用handbrake

于 2013-10-07T10:09:30.837 回答