ffmpeg: Ausgabe von mpegts mit einem einzigen Programm, das 1 Audio und 3 Video enthält

479
BobC

Ich versuche, einen simulierten Live-HLS / DASH-Server mit dem Äquivalent der folgenden Kette zu erstellen:

tsplay -loop multi_resolution.ts | shaka_packager | nginx 

Das Problem ist das Erstellen der Datei "multi_resolution.ts": Sie muss ein einzelnes Programm mit 1 Audio- und 3 Video-PIDs enthalten, jeweils eine für 720p, 480p und 360p. Warum? Weil shaka_packager es so braucht.

Ich denke, ich bin verwirrt darüber, wie ich die transkodierten Streams der Ausgabedatei zuordnen kann. Hier der nicht funktionierende Befehl, mit dem ich zu kämpfen hatte:

ffmpeg -i "big_buck_bunny_1080p.mov" -threads 16 \ -c:a aac -ac 2 -b:a:0 128k \ -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \ -vsync cfr -x264-params "nal-hrd=cbr" \ -b:v:1 5000k -minrate 2000k -maxrate 2000k -bufsize 4000k -g 30 -s 1280x720 \ -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \ -vsync cfr -x264-params "nal-hrd=cbr" \ -b:v:2 1500k -minrate 1000k -maxrate 1000k -bufsize 2000k -g 30 -s 854x480 \ -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \ -vsync cfr -x264-params "nal-hrd=cbr" \ -b:v:3 500k -minrate 500k -maxrate 500k -bufsize 1000k -g 30 -s 640x360 \ -program program_num=1:title=multi_p30:st=0:st=1:st=2:st=3 \ -f mpegts "big_buck_bunny_720_480_360.ts" 

Ich habe jede Kodierung isoliert getestet, und sie sehen gut aus. Ich vermute, das Problem liegt in meinem Stream-Management / Mapping.

Hilfe?

2

1 Antwort auf die Frage

2
Gyan

Um mehrere Streams in eine Ausgabe einzufügen, muss jeder Eingangsstream ausdrücklich zugeordnet werden. Die Codierungsoptionen selbst erzeugen keine Streamzuweisung in der Ausgabe. Es gibt eine Frage der automatischen Stream-Auswahl, die hier nicht anwendbar ist, aber Sie können dies unter https://ffmpeg.org/ffmpeg.html#Stream-selection nachlesen

So,

ffmpeg -i "big_buck_bunny_1080p.mov" -threads 16 \ -map 0:a -map 0:v -map 0:v -map 0:v \ -c:a aac -ac 2 -b:a 128k \ -s:v:0 1280x720 -s:v:1 854x480-s:v:2 640x360 \ -g 30 -c:v libx264 -pix_fmt yuv420p -profile:v high -level 4.0 -preset veryslow -tune film \ -vsync cfr -x264-params "nal-hrd=cbr" \ -b:v:0 5000k -minrate:v:0 2000k -maxrate:v:0 2000k -bufsize:v:0 4000k \ -b:v:1 1500k -minrate:v:1 1000k -maxrate:v:1 1000k -bufsize:v:1 2000k \ -b:v:2 500k -minrate:v:2 500k -maxrate:v:2 500k -bufsize:v:2 1000k \ -program program_num=1:title=multi_p30:st=0:st=1:st=2:st=3 \ -f mpegts "big_buck_bunny_720_480_360.ts" 
Ah, also erstelle ich das Mapping * am Anfang * und überlagere es dann mit anderem Inhalt. Ich muss jedoch die 3 Kodierungen immer noch mit unterschiedlichen Auflösungen durchführen, nicht nur mit unterschiedlichen Bitraten. und mein ": n" folgt dem -c: v, nicht dem -b: v, oder? BobC vor 5 Jahren 0
size, codec, bitrates sind alle Optionen für jeden Stream. Für jeden Ausgabestrom sollte die Option mit dem Schlüssel `-option: stream_type: index` festgelegt werden Gyan vor 5 Jahren 0
Ich werde wieder verwirrt: Sagen wir, ich wollte eine Textüberlagerung hinzufügen. Kann ich es vor dem Mapping auf den einzelnen Videostream anwenden, so dass jede der folgenden 3 Ausgabecodierungen es enthalten wird? Oder muss es nach dem Mapping auf jeden der 3 Video-Streams angewendet werden? BobC vor 5 Jahren 0
"-vf" ist die Abkürzung für "-filter: v", also würde ein Argument "-vf" oder "-filter: v" auf alle Ausgabevideodaten angewendet. Wenn Sie für jeden Stream einen anderen Overlay-Ausdruck anwenden möchten, fügen Sie `-filter: v: 0 filters0`` -filter: v: 1 filters1` und `-filter: v: 2 filters2` hinzu. Innerhalb einer einzelnen Ausgabedatei spielt die Reihenfolge der Optionen keine Rolle, daher können die Karten vor oder nach den Filtern oder der Bitrate angezeigt werden. Gyan vor 5 Jahren 0
Siehe auch meine Antwort an https://superuser.com/q/1219784/114058 Gyan vor 5 Jahren 0
Danke vielmals! Ich denke, ein Teil meiner Verwirrung ist, dass ich nicht verstehe, welche ffmpeg-Optionen Stream-Spezifizierer akzeptieren oder nicht akzeptieren. Die Dokumentation scheint es zu vermeiden, es auf der Definitionsebene zu erwähnen, und ich muss es aus unkommentierten Beispielen herausfinden. Gibt es ein Spickzettel, das ich verwenden könnte? Edit: Die BNF für die ffmpeg-Optionssyntax wäre gut ... BobC vor 5 Jahren 0
Ich kann auch durch die Codec-Optionen und die ffmpeg-Optionen verwirrt sein. Für mich ist das alles nur Buchstabensuppe: Der Kontext und die Bindung sind überhaupt nicht intuitiv, daher wäre ein umfassendes ffmpeg-Befehlszeilensyntaxdiagramm sehr hilfreich. BobC vor 5 Jahren 0
Im Allgemeinen sind Codec-bezogene und Filteroptionen pro Stream und formatbezogene oder andere Optionen nicht. Ausnahmen wie Metadaten sind formatabhängig, können jedoch pro Stream sein. Eine BNF für Filter steht unter https://ffmpeg.org/ffmpeg-filters.html#Filtergraph-syntax-1 zur Verfügung Gyan vor 5 Jahren 0
* Ein vollständig integriertes ffmpeg-Befehlszeilensyntaxdiagramm wäre sehr nützlich * -> in meiner ToDo-Funktion, es dauert jedoch eine Weile. Gyan vor 5 Jahren 0
OK, zurück zum ursprünglichen Befehl: Was ist der Kontext und Umfang für libx264-Optionen wie -preset und -tune? Da sie keinen Stream-Bezeichner akzeptieren, gelten sie automatisch für * alle * Verwendungszwecke von libx264? Oder nur in einem magischen Raum zwischen "-c [stream_specifier] libx264" und dem nächsten "was auch immer" das *** ist, ist keine libx264-Option? Beendet das Erscheinen einer solchen Option die Verarbeitung von libx264-Optionen? Wann muss ich -preset wiederholen und wann muss ich es nicht wiederholen? BobC vor 5 Jahren 0
"-preset" und "-tune" sind Codec-Optionen, auch wenn sie privat sind und daher Stream-Spezifizierer akzeptieren. Gyan vor 5 Jahren 0
Wenn ich dagegen die Stream-Spezifizierer für "-preset" und "-tune" auslasse, gelten sie für alle Verwendungen von "libx264" und müssen daher im Befehl "ffmpeg" genau einmal erwähnt werden. Recht? Wo ist dieses geheimnisvolle Zeug dokumentiert? Google kann kein einziges Beispiel finden! BobC vor 5 Jahren 0
Recht. Und siehe https://ffmpeg.org/ffmpeg.html#AVOptions Gyan vor 5 Jahren 0
Stream-Spezifizierer werden für *** jede *** Option in *** jeder *** -b-Zeile benötigt, andernfalls werden alle mit den zuletzt gesehenen Optionen codiert. BobC vor 5 Jahren 0
Ja, das habe ich vermisst. Gyan vor 5 Jahren 0
Ich habe zu jeder Codierung soeben einen Lauftext-Overlay hinzugefügt, der die Auflösung anzeigt: `-filter: v :? "drawtext = fontfile = / usr / share / fonts / truetype / freefont / FreeSans.ttf \: text = '??? p30? Mbps": fontcolor=white@1.0 \: fontsize = 40: y = h-line_h-30 : x = w / 20 * mod (t \, 20) "\` Ersetzen Sie Fragezeichen für jede Kodierung durch einen geeigneten Wert. BobC vor 5 Jahren 0