Преобразование образа DVD с субтитрами в MKV с помощью avconv

Это известная мне процедура преобразования образа DVD в другой видеоформат (например, MP4):

  1. объединить VTS_01_n.VOB файлов в папке VIDEO_TS (для n >= 0) в один VOB-файл.
  2. используйте avconv или ffmpeg, чтобы преобразовать этот VOB в другой формат.

Пока все хорошо, однако теперь я хочу преобразовать образ DVD с субтитрами. Насколько я знаю, формат MKV поддерживает субтитры, так что это очевидный выбор. В качестве альтернативы я мог бы использовать любой другой формат с жесткими субтитрами (субтитры как часть видеоизображения).

Однако кодировка субтитров в образе DVD — dvdsub, и я получаю следующую ошибку

Only SUBTITLE_ASS type supported.
Subtitle encoding failed

Однако при запуске avconv -codecs я получаю:

...
 DES    dvdsub          DVD subtitles
...

А переключатель -c:s copy, хотя и предотвращает сбой команды, похоже, не создает субтитров, понятных игроку.

Итак, как я могу создать ass субтитров из dvdsub с помощью avconv?

Мой файл VOB имеет восемь каналов субтитров и два аудиоканала. Видеоприложение Ubuntu не показывает никаких субтитров, и кажется, что работает только первый аудиоканал, возможно, изображение DVD повреждено.

В другом файле для двухслойного DVD отображается ошибка кодирования субтитров, однако при использовании переключателя -c:s copy отображается следующее:

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

Заранее благодарим вас за любые идеи о том, как решить эти проблемы.

(Я использую Ubuntu, где ffmpeg — это псевдоним для avconv. Я знаю, что можно установить настоящий ffmpeg, но до сих пор я этого не сделал.)


update: команды и вывод консоли:

команды

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

вывод

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

команда

avconv -i mymovie.VOB mymovie.mkv

вывод

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

команда

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

вывод опущен.

команда

avconv -i mymovie.mkv

вывод

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

Теперь для двойного слоя: команды

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

вывод

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

команда

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

вывод

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

person Carlos Eugenio Thompson Pinzón    schedule 05.10.2013    source источник
comment
Вставлены команды и выходные данные @LordNeckbeard   -  person Carlos Eugenio Thompson Pinzón    schedule 06.10.2013
comment
Преобразование DVD в MKV: с кодировкой используйте Handbrake, без кодировки MakeMKV.   -  person Endoro    schedule 06.10.2013
comment
@Endoro: MakeMKV у меня сработало. Хотя я хотел бы полное решение с открытым исходным кодом (для этого требуется установка двоичных файлов), это отлично сработало для моих непосредственных нужд. Если вы напишете это как ответ, я проголосую за него и (если не будет avconv ответа) приму его. Спасибо.   -  person Carlos Eugenio Thompson Pinzón    schedule 07.10.2013
comment
@CarlosEugenioThompsonPinzón mkvmerge имеет открытый исходный код, и он лучше справляется с этой задачей — очень прост в использовании (сохраняет все дорожки по умолчанию, никаких причудливых магических опций не требуется) и устойчив к различным ошибкам формата, которые могут, например, убить ffmpeg. Я предполагаю, что MakeMKV просто использует его под капотом.   -  person Display Name    schedule 17.12.2015


Ответы (2)


Краткий ответ: перейдите к разделу Полная командная строка и загрузите ffmpeg с этого сайта.

Первоначально я планировал ответить, как это сделать, с помощью avconv, потому что (а) этот ответ все еще отсутствует и (б) avconv сегодня используется по умолчанию в системах Ubuntu. Однако кажется, что в настоящее время для этого слишком много ошибок - по крайней мере, для моих тестовых случаев.

настройка ffmpeg

Поскольку вы запрашиваете либо avconv, либо ffmpeg, и я только что узнал, что avconv является ответвлением 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, .mp4 или .mkv, имеют заголовки (данные в начале файла), перечисляющие все содержимое файла. Это позволяет игрокам и инструментам конвертации легко узнать, каких данных ожидать. .vob файлы не имеют такого явного заголовка. Поэтому, когда запускаются ffmpeg или avconv, они смотрят на первые пару тысяч байтов. В vob-файлах субтитры могут начинаться очень поздно. В моем тестовом примере первый субтитр появляется через несколько секунд, поэтому инструменты не видят его при запуске. Вот типичный пример вывода во время кодирования в таких ситуациях:

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 и используя вместо нее этот инструмент, как я объяснил выше.

person cfi    schedule 14.02.2014
comment
По моему опыту, ffmpeg полностью подавляет некоторые входные данные (генерирует недопустимый файл и/или зависает), но я успешно конвертировал (ремультиксировал) их в формат MKV с помощью mkvmerge, и он сгенерировал полностью правильный файл. Хотя я не проверял, передает ли он также субтитры, но я уверен, что он должен позаботиться и о них. - person Display Name; 17.12.2015
comment
Отличный ответ! Я не знал о +genpts, и было приятно видеть, что вы упомянули analyzeduration и probesize. В большинстве ответов, которые я видел, просто говорится, что нужно объединить файлы VOB, а затем использовать fmpeg для создания видео. К сожалению, как сказано в Display Name, ffmpeg по-прежнему задыхается от некоторых входных файлов. Я только что попробовал, и он завис в конце преобразования. Я думаю, что в сгенерированном файле есть все, но он не должен был так задыхаться. - person user1593842; 28.12.2020

Если вам нужно решение для сохранения качества, попробуйте MakeMKV.
Если вы хотите сжать видеодорожку или преобразовать MPEG-2 в H.264 можно с помощью ручного тормоза.

person Endoro    schedule 07.10.2013
comment
MakeMKV у меня сработало. Спасибо. Handbrake вызывает отключение моей системы до завершения первого преобразования. - person Carlos Eugenio Thompson Pinzón; 09.10.2013
comment
@CarlosEugenioThompsonPinzón Вы пробовали ночную сборку? - person Endoro; 10.10.2013