CONCAT - wie "klebt" man mehrere Videosegmente mit ffmpeg aneinander?

  • Hallo allerseits,

    ich habe hier 2 Videos von verschiedenen Videoportalen gezogen und möchte beide mittels ffmpeg zusammen in einem Video vereinen. Mir ist klar, daß es zu diesem Zweck etliche schicke GUIs gibt. Meine Frage ist daher eher aus Neugier: Gibt es einen Weg, das mit ffmpeg möglichst in einem Rutsch (ohne lästiges Zwischenspeichern) zu bewerkstelligen?
    Beide Clips sind gänzlich unterschiedlich geartet, ich werde also um eine Neukodierung nicht herumkommen. Für die Ausgabe würde ich die verlustfreie Variante wählen. Zunächst müßte die Größe der beiden auf einen Nenner gebracht werden. Das klappt im einzelnen schon ganz gut:

    Code
    ffmpeg -i video1.flv -vf scale=640:360 -acodec pcm_s16le -vcodec ffv1 output.avi


    Beim Zusammenfügen beider Videos würde die Kommandozeile wohl etwa so beginnen:

    Code
    ffmpeg -i video1.flv -i video2.flv -filter_complex scale=640:360 ...


    Wie genau funktioniert das jetzt mit 'concat'? Ich habe mich eine Stunde durch die ffmpeg-Doku gekämpft und bin kein Bißchen schlauer. Ist mein Ansatz überhaupt richtig?

  • Zitat

    Wie genau funktioniert das jetzt mit 'concat'?


    1. lies mal: http://ffmpeg.org/trac/ffmpeg/wi…20media%20files
    2. concat macht nur Sinn, wenn Auflösung, Framerate, usw. gleich sind, wenn man zum Zusammenfügen also nichts reencoden müsste.
    -> concat alleine macht so für Deinen Anwendungsfall also keinen Sinn
    (+ concat, macht intern etwas wie Copy/b video1.flv+video2.flv input.flv und ich bin mir nicht sicher ob das bei flv erlaubt wäre,..)

    Zitat

    Gibt es einen Weg, das mit ffmpeg möglichst in einem Rutsch (ohne lästiges Zwischenspeichern) zu bewerkstelligen?


    Theoretisch ja, wenn man '-filter_complex' und 'concat' kombiniert.
    Problem: Mir ist die Syntax von '-filter_complex' nicht klar und da mir noch keine Quelle untergekommen ist die es ordentlich erklärt, hier mal was ich vermutet hätte wie es gehen müsste, aber nicht tut:

    Code
    ffmpeg -i video1.flv -i video2.flv -filter_complex '[0:0] scale=640:360 [v1];[1:0] scale=640:360 [v2];[v1] [v2] concat [outv];[0:1] [1:1] concat [outa]' joined.flv


    (da Ausgabe Audio-&Videoformat nicht angegeben sind würde ffmpeg da die Defaultwerte für den Container nehmen, was aber erst mal egal ist)

    zur Erklärung was ich mir gedacht hatte:
    [0:0] = aus Quelle mit Index 0 der Stream mit Index 0 also der Videostream von video1.flv (davon ausgegangen, dass der Videostream den Index 0 hat)
    [0:1] = aus Quelle mit Index 0 der Stream mit Index 1 also der Audiostream von video1.flv (davon ausgegangen, dass der Videostream den Index 0 hat)
    [1:0] = aus Quelle mit Index 1 der Stream mit Index 0 also der Videostream von video2.flv (davon ausgegangen, dass der Videostream den Index 0 hat)
    [1:1] = aus Quelle mit Index 1 der Stream mit Index 1 also der Audiostream von video2.flv (davon ausgegangen, dass der Videostream den Index 0 hat)
    scale=640:360 sollte den entsprechenden Stream auf 640x360 skalieren

    [0:0] scale=640:360 [v1]; sollte den Videostream des ersten Inputs nehmen, ihn nach 640x360 skalieren und das Ergebnis der Variable [v1] zuweisen
    [1:0] scale=640:360 [v2]; sollte den Videostream des zweiten Inputs nehmen, ihn nach 640x360 skalieren und das Ergebnis der Variable [v2] zuweisen
    [v1] [v2] concat [outv]; sollte [v1] und [v2] aneinanderhängen und das Ergebnis der Ausgabevariable [outv] zuweisen
    [0:1] [1:1] concat [outa] sollte [0:1] und [1:1] (also die Audiostreams der Inputs) aneinanderhängen und das Ergebnis der Ausgabevariable [outa] zuweisen

    Zitat

    Ist mein Ansatz überhaupt richtig?


    Keine Ahnung, da mir nicht klar ist wie der Ansatz von Dir aussieht, da er mit "..." viel Freiraum zur Interpretation offen lässt.

    => Denke es ist an sich möglich was Du willst in einem einzelnen ffmpeg-Aufruf zu machen, wenn man herausbekommt, wie die '-filter_complex' syntax wirklich aussehen muss. Meine Interpretation von dem was ich gelesen habe ist offensichtlich falsch.

    Cu Selur

  • Hätte mich jetzt auch gewundert, wenn man die Frage in einem kurzen Satz hätte beantworten können. :D
    Ich werde mal sehen, ob ich das mit dem filter_complex Syntax gebacken kriege. Auf jeden Fall danke für die guten Hinweise (das ffmpeg-Wiki kannte ich noch gar nicht).

  • Der Chat ist mir bekannt. Bin ich auch schon zwei mal drin gewesen, allerdings nur, als ich Probleme beim bauen von ffmpeg hatte. Irgendwo habe ich mal gelesen, daß die Entwickler sehr beschäftigt sind und man sie - wenn überhaupt - nur mit "Entwicklerfragen" nerven soll.

  • Das mag für den Entwickler-Channel (#ffmpeg-devel) durchaus stimmen, aber nicht für den Benutzer-Channel (#ffmpeg): Hier sind hoffentlich auch erfahrene Anwender zu finden, die neben den Entwicklern auch kompetent Fragen beantworten können sollten ... nun ja. Manchmal ist ein Channel auch bloß ein "Schlafsaal" mit unbeaufsichtigt angemeldeten IRC-Clients oder -Proxies.

  • Diese Beiträge hier haben schon etwas Staub angesetzt, aber nachdem ich nun immer wieder über diese Problematik gestolpert bin, habe ich nun einmal kurz und verbissen nach einer Lösung gesucht und auch prompt gefunden:

    Code
    ffmpeg -i test_001.mp4 -i test_002.mp4 -filter_complex "[0:0] scale=640:360 [v1];[0:1] anull [a1];[1:0] scale=640:360 [v2];[1:1] anull [a2];[v1] [v2] concat [outv];[a1] [a2] concat=v=0:a=1 [outa]" -map "[outv]" -map "[outa]" -vcodec ffv1 -acodec pcm_s16le test.avi

    Kurze Erklärung: filter_complex erwartet, daß ALLE vorhandenen Streams aufgeführt werden, also auch jene, die man eigentlich gar nicht durch einen Filter jagen will. Sie müssen in der richtigen Reihenfolge angegeben werden und jeder Stream muß durch einen Filter wandern - auch die, die man nicht bearbeiten will (ffmpeg erwartet [Video1] filter; [Audio1] filter; [Video2] filter; [Audio2] filter; ... usw). Für alle Streams, die von Filtern unberührt bleiben sollen, wurden extra Null-Filter eingerichtet ("null" für Video, "anull" für Audio). Zu erwähnen wäre auch noch die unterschiedliche Handhabung von concat bei Video und Audio. In diesem Beispiel muß ich zunächst Bild und Ton separat zusammenpappen und dann beide Streams Richtung stdout leiten. Dabei hat concat kein Problem, Video ohne Audio zu bearbeiten, wohl aber Audio ohne Video, denn da wird standardgemäß ein Video-Stream erwartet. Also muß man ihm explizit mitteilen, daß kein Video dabei ist (v=0:a=1).

  • Zitat

    filter_complex erwartet, daß ALLE vorhandenen Streams aufgeführt werden, also auch jene, die man eigentlich gar nicht durch einen Filter jagen will. Sie müssen in der richtigen Reihenfolge angegeben werden und jeder Stream muß durch einen Filter wandern - auch die, die man nicht bearbeiten will (ffmpeg erwartet [Video1] filter; [Audio1] filter; [Video2] filter; [Audio2] filter; ... usw). ...


    Ahhh,.. Danke für die Erklärung. :)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!