Как в ffmpeg масштабировать субтитры dvdsub в соответствии с размером видео с помощью фильтра scale2ref?

У меня есть файл mpeg, записанный с прямого эфира, содержащий видео и несколько потоков аудио и субтитров. Моя конечная цель - создать видеофайл меньшего размера, поскольку размер файла mpeg составляет несколько гигабайт. Мой первый шаг на этом пути - просто выбрать по одному потоку видео, аудио и субтитров и скопировать их в файл mkv, отбросив потоки, которые мне неинтересны. (Я выбрал mkv, поскольку он позволяет сохранять поток субтитров dvdsub, где другие форматы контейнеров не используются.)

Проблема, с которой я сталкиваюсь, заключается в том, что субтитры dvdsub выглядят очень маленькими, когда я воспроизводю выходное видео, когда я исследовал это, я обнаружил, что ffmpeg не автоматически масштабирует субтитры в соответствии с исходным видео: https://trac.ffmpeg.org/ticket/4744

Я пробовал использовать фильтр scale2ref, но не понимаю документации, и приведенный в них пример не имеет для меня смысла (см. Примеры ниже).

У меня есть команда, которая выбирает три потока и копирует 1 минуту на вывод, как показано ниже:

ffmpeg -ss 00:28:00.200 -i Hillary-2016-08-21.mpg -t 00:01:00.000 -map 0:0 -c:v copy -map 0:3 -c:a copy -map 0:6 -c:s dvdsub cut.mkv

Вот результат:

Input #0, mpegts, from 'Hillary-2016-08-21.mpg':
  Duration: 01:30:00.06, start: 20852.199389, bitrate: 6813 kb/s
  Program 1 
    Stream #0:0[0xfa]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x12c](eng): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp
    Stream #0:2[0x131](ita): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp (visual impaired)
    Stream #0:3[0x191](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:4[0x3ea]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:5[0x3ec]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:6[0x3fc](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
    Stream #0:7[0x1f40]: Unknown: none ([5][0][0][0] / 0x0005)
File 'cut.mkv' already exists. Overwrite ? [y/N] y
Output #0, matroska, to 'cut.mkv':
  Metadata:
    encoder         : Lavf57.56.100
    Stream #0:0: Video: h264 (Main) (H264 / 0x34363248), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 25 fps, 50 tbr, 1k tbn, 90k tbc
    Stream #0:1(eng): Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 384 kb/s
    Stream #0:2(eng): Subtitle: dvd_subtitle (dvdsub) (hearing impaired)
    Metadata:
      encoder         : Lavc57.64.101 dvdsub
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:3 -> #0:1 (copy)
  Stream #0:6 -> #0:2 (dvb_subtitle (dvbsub) -> dvd_subtitle (dvdsub))
Press [q] to stop, [?] for help
frame= 2956 fps=0.0 q=-1.0 Lsize=   39612kB time=00:00:59.99 bitrate=5408.7kbits/s speed= 216x    
video:36702kB audio:2896kB subtitle:23kB other streams:0kB global headers:0kB muxing overhead: unknown

В документации для scale2ref приведен пример с наложением, и я не хочу ничего накладывать, я просто хочу изменить размер потока субтитров. Вот их пример:

'scale2ref[b][a];[a][b]overlay'

Ближайшее, что у меня есть, это что-то вроде этого:

ffmpeg -ss 00:28:00.200 -i Hillary-2016-08-21.mpg -t 00:01:00.000 -map 0:0 -c:v copy -map 0:3 -c:a copy -filter_complex "[0:6]scale2ref[b]" -map "[b]"   cut.mkv

И результат:

Input #0, mpegts, from 'Hillary-2016-08-21.mpg':
  Duration: 01:30:00.06, start: 20852.199389, bitrate: 6813 kb/s
  Program 1 
    Stream #0:0[0xfa]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x12c](eng): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp
    Stream #0:2[0x131](ita): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp (visual impaired)
    Stream #0:3[0x191](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:4[0x3ea]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:5[0x3ec]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:6[0x3fc](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
    Stream #0:7[0x1f40]: Unknown: none ([5][0][0][0] / 0x0005)
Streamcopy requested for output stream 0:0, which is fed from a complex filtergraph. Filtering and streamcopy cannot be used together.

И я действительно не понимаю, как я могу использовать фильтр и направлять поток субтитров с измененным размером в выходной файл.

Любая помощь приветствуется! Спасибо!


person Steve Moseley    schedule 24.01.2017    source источник


Ответы (1)


scale2ref помечает оба своих вывода как видеопотоки, каковыми они и являются почти всегда. Итак, ffmpeg применяет значение c:v к масштабируемым сабвуферам.

Вместо этого вы должны попробовать

ffmpeg -ss 28:00.2 -canvas_size 1920x1080 -i Hillary-2016-08-21.mpg -t 1:00 -map 0:0 -c:v copy -map 0:3 -c:a copy -map 0:6 -c:s dvdsub cut.mkv

Использование

ffmpeg -ss 28:00.2 -i Hillary-2016-08-21.mpg -t 1:00 -filter_complex "[0:6][0:0]scale2ref[b][a]" -map 0:0 -c:v copy -map 0:3 -c:a copy -map "[b]" cut.mkv -map "[a]" -f null -

scale2ref принимает два входа и выводит два выхода. Второй элемент на обоих концах - это видео reference. Итак, ffmpeg нужно указать, что делать с сквозной копией этой ссылки. В приведенной выше команде назначается нулевой мультиплексор, который отправляет его в забвение.

person Gyan    schedule 24.01.2017
comment
Вот результат, который я получаю: Streamcopy запрошен для выходного потока 0: 2, который подается из сложного графа фильтров. Совместное использование фильтрации и потокового копирования невозможно. - person Steve Moseley; 24.01.2017
comment
Ух ты. Похоже, -canvas_size был той магией, которой мне не хватало. Спасибо !! - person Steve Moseley; 25.01.2017