Escenario complejo de codificación múltiple/copia de flujo/muxing de ffmpeg: ¿es esto realmente factible?

Escenario complejo de codificación múltiple/copia de flujo/muxing de ffmpeg: ¿es esto realmente factible?

Estoy intentando realizar múltiples operaciones de mezcla/recodificación/copia en un video de entrada con ffmpeg y me he topado con obstáculos con los métodos que probé; Antes de continuar con las pruebas, quiero confirmar si esto es realmente posible con el software. (Esto es para una configuración de transmisión en vivo que toma una transmisión en vivo desde otra PC en mi LAN y la archiva/retransmite a múltiples destinos RTMP, de ahí la -rebandera y la necesidad de hacer todo en una sola operación).

El vídeo de entrada tiene una transmisión de vídeo h.264 de alta tasa de bits y cuatro pistas de audio PCM.

Las tres salidas que necesito:

  • una codificación h.246 a 8 Mbps, codificación aac de la pista de audio 1 únicamente
  • una codificación h.264 a 12 Mbps, codificación aac solo de la pista de audio 1 (idealmente usar la misma codificación que la primera salida, es decir, solo tener que codificar el audio una vez)
  • una copia pura de toda la entrada a .mkv

(Estos comandos pueden estar llenos de errores y malas prácticas, solo una idea general de la dirección en la que voy).

Intenté usar los filtros split/ aspliten combinación con el teemuxer en este sentido, lo que parece que funcionaría en teoría, excepto que el uso de filtros no permite el paso de copia de flujo/códec (irónicamente, en este caso no se realiza ningún filtrado real en la transmisión de video). aparte de pasarlo).

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"

También jugué con el mapeo de transmisión simple a múltiples salidas, pero parece que en realidad solo procesa una salida de video y audio cada una, y no estoy seguro de que el mapeo de transmisión pueda usarse de esta manera, por lo que probablemente esto sea un desastre.

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"

Para complicar aún más las cosas, estoy usando codificación de hardware Quick Sync aquí y me gustaría aplicarla -vf hwupload=extra_hw_frames=64,format=qsva cada recodificación si es posible, pero en mis pruebas iniciales no estaba claro si dos conjuntos de filtros son posibles, incluso en codificaciones diferentes.

En cualquier caso, ¿esto se puede lograr con ffmpeg y, de ser así, cómo?

Respuesta1

Podemos usarcamiseta demuxerpara reutilizar el audio aac codificado y utilizarmapeo de corrientes, yespecificadores de flujo:

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

Agregue -rey reemplace la entrada y salida según sea necesario.


  • -c:v h264_qsv- aplica decodificación acelerada por hardware QSV H.264 (también podemos usar -hwaccel qsv).
  • -map 0:v -map 0:v -map 0:a- asigna la secuencia de vídeo de entrada a la "primera" ( 0) y la "segunda" ( 1) secuencias de vídeo de salida (y asigna la secuencia de audio).
  • -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- selecciona h264_qsvel codificador de video, con todos los parámetros que aplica la transmisión de video de salida 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- selecciona h264_qsvel codificador de video, con todos los parámetros que aplica la transmisión de video de salida 1.
  • -c:a:0 aac -b:a:0 320k- selecciona el codificador de audio y la tasa de bits.
  • -f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv"- "Muxing" la misma secuencia de audio codificada con dos secuencias de vídeo diferentes.
    La primera secuencia de vídeo de salida ( 0) se "Muxed" en el 8mbps.mkvarchivo de salida.
    La segunda secuencia de vídeo de salida ( 1) se "muxed" en el 12mbps.mkvarchivo de salida.
  • -map 0 -c copy copy.mkv- Aplica una segunda salida (porque viene después de la primera salida).
    -map 0- Asigna todos los flujos de entrada desde la entrada a la salida.
    -c copy- Copie todos los flujos de entrada sin volver a codificarlos.

Para realizar pruebas, creé un archivo de vídeo sintético 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


Notas:

  • -b:v:0 4M -minrate:v:0 4M -maxrate:v:0 4Maplica una tasa de bits constante (no estoy seguro de si realmente la necesita).
  • bufsizeEl argumento no funciona con h264_qsvel codificador (no intenté resolver esto).

información relacionada