
Ich versuche, mit ffmpeg mehrere Muxing-/Neukodierungs-/Kopiervorgänge an einem Eingabevideo durchzuführen und bin mit den Methoden, die ich ausprobiert habe, auf Hindernisse gestoßen. Bevor ich mit dem Testen fortfahre, möchte ich bestätigen, ob dies mit der Software überhaupt möglich ist. (Dies ist für ein Live-Streaming-Setup, das einen Live-Stream von einem anderen PC in meinem LAN aufnimmt und ihn auf mehrere RTMP-Ziele archiviert/neu streamt, daher die -re
Markierung und die Notwendigkeit, alles in einem Vorgang zu erledigen.)
Das Eingangsvideo verfügt über einen H.264-Videostream mit hoher Bitrate und vier PCM-Audiospuren.
Die drei Ausgänge, die ich brauche:
- eine h.246-Kodierung mit 8 Mbit/s, AAC-Kodierung nur von Audiospur 1
- eine h.264-Kodierung mit 12 Mbit/s, AAC-Kodierung nur von Audiospur 1 (idealerweise mit derselben Kodierung wie beim ersten Ausgang, d. h. Audio muss nur einmal kodiert werden)
- eine reine Streamkopie des gesamten Inputs im MKV-Format
(Diese Befehle enthalten möglicherweise viele Fehler und schlechte Praktiken. Sie sollen lediglich eine allgemeine Vorstellung davon vermitteln, in welche Richtung ich gehe.)
Ich habe versucht, die split
/ asplit
-Filter in Kombination mit dem tee
Muxer in dieser Richtung zu verwenden, was theoretisch zu funktionieren scheint, mit der Ausnahme, dass die Verwendung von Filtern Streamcopy/Codec-Passthrough verhindert (ironischerweise wird in diesem Fall für den Videostream keine tatsächliche Filterung durchgeführt, außer dass er durchgelassen wird).
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"
Ich habe auch mit einfachem Streammapping auf mehrere Ausgänge herumprobiert, aber es scheint, als würde dabei tatsächlich nur jeweils ein Video- und Audioausgang verarbeitet, und ich bin nicht sicher, ob Streammapping überhaupt auf diese Weise verwendet werden kann, also ist das hier wahrscheinlich ein Durcheinander.
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"
Um die Sache noch komplizierter zu machen, verwende ich hier die Quick-Sync-Hardwarecodierung und würde sie -vf hwupload=extra_hw_frames=64,format=qsv
nach Möglichkeit auf jede Neucodierung anwenden wollen, aber bei meinen ersten Tests war unklar, ob zwei Filtersätze möglich sind, selbst bei unterschiedlichen Codierungen.
Ist dies überhaupt mit ffmpeg möglich und wenn ja, wie?
Antwort1
Wir können verwendenT-Stück Demuxerzur Wiederverwendung des codierten AAC-Audios und zur VerwendungStream-Mapping, UndStream-Spezifizierer:
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
Fügen Sie -re
die Eingabe und Ausgabe nach Bedarf hinzu und ersetzen Sie sie.
-c:v h264_qsv
– wendet die hardwarebeschleunigte Dekodierung von QSV H.264 an (wir können auch verwenden-hwaccel qsv
).-map 0:v -map 0:v -map 0:a
- ordnet den Eingangsvideostream dem „ersten“ (0
) und „zweiten“ (1
) Ausgangsvideostream zu (und ordnet den Audiostream zu).-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
- wählth264_qsv
den Video-Encoder mit allen Parametern aus, die auf den Ausgabe-Videostream angewendet werden0
.-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
- wählth264_qsv
den Video-Encoder mit allen Parametern aus, die auf den Ausgabe-Videostream angewendet werden1
.-c:a:0 aac -b:a:0 320k
- wählt den Audio-Encoder und die Bitrate aus.-f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv"
- „Muxen“ des gleichen codierten Audiostreams mit den beiden unterschiedlichen Videostreams.
Der erste Ausgabevideostream ( ) wird in die Ausgabedatei0
„Muxen“ . Der zweite Ausgabevideostream ( ) wird in die Ausgabedatei „Muxen“ .8mbps.mkv
1
12mbps.mkv
-map 0 -c copy copy.mkv
– Wendet eine zweite Ausgabe an (da diese nach der ersten Ausgabe kommt).
-map 0
– Ordnet alle Eingabeströme der Eingabe der Ausgabe zu.
-c copy
– Kopiert alle Eingabeströme ohne erneute Kodierung.
Zum Testen habe ich eine synthetische Videodatei erstellt 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
Anmerkungen:
-b:v:0 4M -minrate:v:0 4M -maxrate:v:0 4M
wendet eine konstante Bitrate an (ich bin nicht sicher, ob Sie das wirklich brauchen).bufsize
Argument funktioniert nicht mith264_qsv
dem Encoder (ich habe nicht versucht, dies zu lösen).