Как использовать FFMPEG с Nvidia Acceleration (Nvenc) для жесткого кодирования / записи субтитров

Поэтому я пытаюсь использовать Nvenc для ускорения кодирования видео. Цель состоит в том, чтобы иметь 1 входной видеофайл и 1 входной субтитр, а также получить несколько выходных файлов с разным разрешением с жестко закодированными или записанными в видео субтитрами. Я пробовал несколько подходов, но не могу понять, как это сделать.

Вот команда, которую я сейчас использую:

ffmpeg -hwaccel cuvid -i 3030025890-TEST.mp4 -i output_ar.srt  -filter_complex "[0:v]scale_npp=1920:1080, hwdownload,format=nv12[base], [base]subtitles=output_ar.srt[marked]" -map "[marked]" -c:v h264_nvenc -map 0:v:0 -map 0:a:0 -g 50 -b:v 5M -maxrate 5.5M -minrate 4M -bufsize 5M -preset fast 1080_output.mp4

и вот результат:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '3030025890-TEST.mp4':
  Metadata:
    major_brand     : M4V 
    minor_version   : 1
    compatible_brands: isomavc1mp42
    creation_time   : 2021-01-05T13:45:58.000000Z
  Duration: 00:45:04.28, start: 0.000000, bitrate: 5574 kb/s
    Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 5000 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Video Media Handler
      encoder         : Elemental H.264
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
    Stream #0:2(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
    Stream #0:3(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
    Stream #0:4(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
    Stream #0:5(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
    Stream #0:6(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      creation_time   : 2021-01-05T13:45:58.000000Z
      handler_name    : ETI ISO Audio Media Handler
Input #1, srt, from 'output_ar.srt':
  Duration: N/A, bitrate: N/A
    Stream #1:0: Subtitle: subrip
[Parsed_subtitles_3 @ 0x5601070b1dc0] Shaper: FriBidi 0.19.7 (SIMPLE)
Fontconfig error: Cannot load default config file
[Parsed_subtitles_3 @ 0x5601070b1dc0] No usable fontconfig configuration file found, using fallback.
Fontconfig error: Cannot load default config file
[Parsed_subtitles_3 @ 0x5601070b1dc0] Using font provider fontconfig
Stream mapping:
  Stream #0:0 (h264) -> scale_npp (graph 0)
  subtitles (graph 0) -> Stream #0:0 (h264_nvenc)
  Stream #0:0 -> #0:1 (h264 (native) -> h264 (h264_nvenc))
  Stream #0:1 -> #0:2 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[h264 @ 0x56010792f980] Error creating a NVDEC decoder: 1
[h264 @ 0x56010792f980] Failed setup for format cuda: hwaccel initialisation returned error.
[Parsed_subtitles_3 @ 0x560107364cc0] Shaper: FriBidi 0.19.7 (SIMPLE)
Fontconfig error: Cannot load default config file
[Parsed_subtitles_3 @ 0x560107364cc0] No usable fontconfig configuration file found, using fallback.
Fontconfig error: Cannot load default config file
[Parsed_subtitles_3 @ 0x560107364cc0] Using font provider fontconfig
Impossible to convert between the formats supported by the filter 'graph 0 input from stream 0:0' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0
[aac @ 0x56010734d400] Qavg: 65536.000
[aac @ 0x56010734d400] 2 frames left in the queue on closing
Conversion failed!

Изменить: достигнут некоторый прогресс. Теперь я больше не получаю сообщение об ошибке, но при просмотре вывода субтитры не выгорели. Команда:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 3030025890-TEST.mp4  -c:v h264_nvenc -map 0:v:0 -map 0:a:0 -g 50 -b:v 5M -maxrate 5.5M -minrate 4M -bufsize 5M -vf "scale_npp=1920:1080, hwdownload, format=nv12, subtitles=output_ar.srt, hwupload" -preset fast 1080_output.mp4

person Ibraheem Nofal    schedule 18.02.2021    source источник


Ответы (1)


Хорошо, мне удалось решить проблему. Я запускал ffmpeg внутри контейнера докеров, и это представляло свой собственный набор проблем.

  1. Если вы используете Linux и видите что-то вроде ошибки Fontconfig: не удается загрузить файл конфигурации по умолчанию, убедитесь, что у вас установлен fontconfig. В Ubuntu:
sudo apt-get update -y
sudo apt-get install -y fontconfig-config

Если, как и я, вы используете контейнер докеров и получили указанную выше ошибку, обязательно добавьте следующие команды в свой файл докеров:

ЗАПУСТИТЬ apt-get update -y
ЗАПУСТИТЬ apt-get install -y fontconfig-config

  1. Если вы планируете запускать какие-либо фильтры на своем процессоре (некоторые фильтры, такие как субтитры и libass, не поддерживаются на графическом процессоре / с использованием аппаратного ускорения), вам придется загружать кадры (только при использовании флага -hwaccel) после декодирование в вашу оперативную память перед применением фильтров и повторной загрузкой во VRAM графического процессора. В моем случае я не буду использовать флаг -hwaccel, так как это упрощает запуск фильтров, связанных с ЦП, согласно документация Nvidia. В моих тестах это также немного ускоряет работу. Команда фильтра становится такой:

-vf subtitles = mysubtitles.srt, hwupload_cuda, scale_npp = 1920: 1080

  1. Объедините вышеперечисленные пункты, и вы получите следующую команду. Обратите внимание на отсутствие флага -hwaccel.

ffmpeg -threads 16 -vsync 0 -c: v h264_cuvid -i 3030025890-TEST.mp4 -c: v h264_nvenc -vf subtitles = mysubtitles.srt, hwupload_cuda, scale_npp = 1920: 1080p_output.mpitles. hwupload_cuda, scale_npp = 1280: 720 -c: v h264_nvenc -preset fast 720p_output.mp4

Изменить: не был удовлетворен производительностью вышеуказанной команды, поэтому я потратил некоторое время на ее оптимизацию. Я обнаружил, что вы можете использовать фильтр разделения для разделения выходного потока. По сути, я сделал декодирование с помощью графического процессора, затем загрузил его в память процессора, применил фильтры с помощью процессора один раз, загрузил его в графический процессор, разделил выходной поток на 2 (один для вывода 1080p, а другой для 720p. ), а затем позвольте графическому процессору обрабатывать масштабирование + кодирование. Это дало 5-кратное увеличение скорости кодирования по сравнению с предыдущей командой.

Это команда, которую я сейчас использую (обратите внимание, что есть другие флаги, такие как -g для интервала ключевых кадров и -b: v для установки целевого битрейта, который в зависимости от вашего варианта использования может не понадобиться):

ffmpeg -i Input.mp4 -c: v h264_nvenc -map 0: a: 0 -g 50 -b: v 5.0M -maxrate 5.5M -minrate 4.2M -bufsize 4.5M -filter_complex [0: v] subtitles = mySubs. srt, hwupload_cuda, split = 2 [c0] [c1]; [c0] scale_npp = 1920: 1080 [1080]; [c1] scale_npp = 1280: 720 [720]; -map [1080] -preset fast 1080p_output.mp4 -c: v h264_nvenc -map 0: a: 0 -g 50 -b: v 3,4M -maxrate 3,7M -minrate 2,8M -bufsize 3,1M -map [720] - предустановка быстро 720p_output.mp4

person Ibraheem Nofal    schedule 21.02.2021