
Я пытаюсь выполнить несколько операций мультиплексирования/перекодирования/копирования входного видео с помощью ffmpeg и столкнулся с препятствиями при использовании методов, которые я пробовал; прежде чем продолжить тестирование, я хочу убедиться, возможно ли это вообще с помощью программного обеспечения. (Это касается настройки потоковой передачи в реальном времени, которая принимает один поток с другого ПК в моей локальной сети и архивирует/передает его на несколько целевых устройств RTMP, отсюда и флаг -re
и необходимость сделать все за одну операцию.)
Входное видео имеет один видеопоток h.264 с высоким битрейтом и четыре аудиодорожки PCM.
Три результата, которые мне нужны:
- один кодек h.246 на скорости 8 Мбит/с, кодек aac только для аудиодорожки 1
- один кодек h.264 на скорости 12 Мбит/с, кодек aac только для аудиодорожки 1 (в идеале с использованием того же кодека, что и для первого вывода, т.е. кодирование звука должно быть выполнено только один раз)
- одна чистая потоковая копия всего ввода в .mkv
(Эти команды могут содержать ошибки и плохие практики, но это просто общее представление о направлении, в котором я двигаюсь.)
Я пробовал использовать фильтры split
/ asplit
в сочетании с tee
мультиплексором по этой схеме, и, похоже, это сработает в теории, за исключением того, что использование фильтров запрещает streamcopy/проход кодека (по иронии судьбы в этом случае не выполняется никакой фактической фильтрации видеопотока, кроме его пропускания).
ffmpeg -re -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv -c:v h264_qsv -i $INPUT \
-filter_complex "[0:v]split=3[twitch][youtube][passv];[0:a]asplit[stream][passa]" \
-map:v "[twitch]" -map:v "[youtube]" -map:v "[passv]" -map:a "[stream]:0" -map:a "[passa]" \
-c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -maxrate:v:0 8M -bufsize:v:0 4M \
-c:v:1 h264_qsv -profile:v:1 high -preset:v:0 medium -g 120 -b:v:1 12M -maxrate:v:1 12M -bufsize:v:1 6M \
-c:v:2 copy \
-c:a:0 aac -b:a:0 320k \
-c:a:1 copy \
-f tee "[select=\'v:0,a:0\']8mbps.mkv|[select=\'v:1,a:0\']12mbps.mkv|[select=\'v:2,a:1\']copy.mkv"
Я также экспериментировал с простым сопоставлением потоков на несколько выходов, но, похоже, на самом деле он обрабатывает только один видео- и аудиовыход, и я не уверен, что сопоставление потоков вообще можно использовать таким образом, так что это, скорее всего, беспорядок.
ffmpeg -re -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv -c:v h264_qsv -i $INPUT \
-map 0:0 -c h264_qsv -profile high -preset medium -g 120 -b 8M -maxrate 8M -bufsize 4M \
-map 0:0 -c h264_qsv -profile high -preset medium -g 120 -b 12M -maxrate 12M -bufsize 6M \
-map 0:1 -c aac -b 320k \
-map 0:a -c copy \
-f tee "[select=\'v:0,a:0\']8mbps.mkv|[select=\'v:1,a:1\']12mbps.mkv|[select=\'v:2,a:1\']copy.mkv"
Чтобы еще больше усложнить ситуацию, я использую здесь аппаратное кодирование Quick Sync и хотел бы применять его -vf hwupload=extra_hw_frames=64,format=qsv
к каждому повторному кодированию, если это возможно, но в моем первоначальном тестировании было неясно, возможно ли использовать два набора фильтров, даже при разных кодированиях.
В любом случае, возможно ли это вообще сделать с помощью ffmpeg, и если да, то как?
решение1
Мы можем использоватьтройник демультиплексордля повторного использования закодированного аудио AAC и использованияотображение потока, испецификаторы потока:
ffmpeg -y -c:v h264_qsv -i in.mkv -map 0:v -map 0:v -map 0:a -c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -minrate:v:0 8M -maxrate:v:0 8M -c:v:1 h264_qsv -profile:v:1 high -preset:v:1 medium -g 120 -b:v:1 12M -minrate:v:1 12M -maxrate:v:1 12M -c:a:0 aac -b:a:0 320k -f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv" -map 0 -c copy copy.mkv
При необходимости добавьте -re
и замените входные и выходные данные.
-c:v h264_qsv
- применяется аппаратное ускоренное декодирование QSV H.264 (мы также можем использовать-hwaccel qsv
).-map 0:v -map 0:v -map 0:a
- сопоставляет входной видеопоток с «первым» (0
) и «вторым» (1
) выходными видеопотоками (и сопоставляет аудиопоток).-c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -minrate:v:0 8M -maxrate:v:0 8M
- выбираетh264_qsv
видеокодер со всеми параметрами, который применяет выходной видеопоток0
.-c:v:1 h264_qsv -profile:v:1 high -preset:v:1 medium -g 120 -b:v:1 12M -minrate:v:1 12M -maxrate:v:1 12M
- выбираетh264_qsv
видеокодер со всеми параметрами, который применяет выходной видеопоток1
.-c:a:0 aac -b:a:0 320k
- выбирает аудиокодер и битрейт.-f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv"
- "Мультиплексирование" одного и того же закодированного аудиопотока с двумя разными видеопотоками.
Первый выходной видеопоток (0
) "Мультиплексируется" в8mbps.mkv
выходной файл.
Второй выходной видеопоток (1
) "Мультиплексируется" в12mbps.mkv
выходной файл.-map 0 -c copy copy.mkv
- Применяет второй выход (потому что он идет после первого выхода).
-map 0
- Сопоставляет все входные потоки со входа на выход.
-c copy
- Копирует все входные потоки без повторного кодирования.
Для тестирования я создал синтетический видеофайл in.mkv
:
ffmpeg -y -f lavfi -i mandelbrot=size=1920x1080:rate=30 -f lavfi -i sine=frequency=400 -c:v libx264 -strict -2 -c:a dca -ar 44100 -pix_fmt yuv420p -t 5 in.mkv
Примечания:
-b:v:0 4M -minrate:v:0 4M -maxrate:v:0 4M
применяет постоянный битрейт (не уверен, что он вам действительно нужен).bufsize
аргумент не работает сh264_qsv
кодировщиком (я не пытался решить эту проблему).