ffmpeg pipe, Container bringen unterschiedliche sync- Ergebnisse

  • Hallo zusammen!

    Ich habe eine Methode gefunden, wie ich mit ffmpeg beliebig viele Videos aneinanderreihen kann, ohne dass es zur Unterbrechung kommt. Damit kann ich z.B. Playlisten streamen, brauche mir keine Gedanken über das Quellformat machen und die Listen sind jederzeit dynamisch editierbar (nicht wie bei concat).
    Dazu entwickle ich gerade ein Python Tool: https://github.com/jb-alvarado/ffplayout

    Im Prinzip funktioniert das ganze so, dass ich über einen Haufen Clips loope und mit ffmpeg abspiele, das ganze in einen Buffer (pv, oder mbuffer) pipe und den Output wieder in ffmpeg einspeise. Als Shell Script würde das dann so aussehen:

    Code
    for i in *.mp4, do
        ffmpeg -i "$i" [codec settings] -f mpegts -
    done | muffer -m 31000k | ffmpeg -i pipe: [codec settings] -f flv rtmp://address...

    Jetzt ist mir nur folgendes Aufgefallen:

    • nehme ich mpegts als pipe Format, muss ich den Stream verlustbehaftet kodieren bevor die zweite ffmpeg das ganze noch mal komprimieren muss. Am besten würde hier mpeg2 funktionieren, es kommt nur gelegentlich mal zu Warnungen das die PTS korrigiert werden müssen
    • verwende ich hingegen avi als pipe Format kann ich einen rawvideo Stream in die Pipe schicken, es kommt zu keinen Fehlermeldungen wegen PTS und ich habe einen (fast) verlustfreien Stream in der Pipe. Allerdings läuft hier Audio und Video mit der Zeit asynchron.
    • würde ich nur Clips nehmen die alle gleich kodiert sind und ich mit Stream Copy arbeiten wollte, funktioniert das nur reibungslos mit dem Format ismv, allerdings habe ich wieder das gleiche Problem, dass der Stream asynchron wird.

    Am liebsten wäre mir Szenario 2 und 3. Ich hätte zwei verschiedene Anwendungen, wo das für mich praktisch wäre, allerdings bekomme ich es nicht hin Audio und Video synchron zu halten.

    Habt ihr eine Idee, warum sich die Container unterschiedlich verhalten und wie ich das hinbekommen könnte das alles synchron bleibt?

    Grüße

    Jonathan

  • Puh, ich habe da nicht wirklich Ahnung von. Meine Vermutung, warum es irgendwann Async wird: Video- und Tonspur sind nicht immer gleich lang. Sagen wir mal, die Tonspuren sind immer 50ms kürzer. Dann addiert sich dieser Fehler mit jeder weiteren Datei, bis er irgendwann bemerkbar wird.
    Vielleicht könnte man da mit einem Kommando with -shortest gegenwirken?

  • Puh, ich habe da nicht wirklich Ahnung von. Meine Vermutung, warum es irgendwann Async wird: Video- und Tonspur sind nicht immer gleich lang.

    Die Vermutung hatte ich auch schon, dafür habe ich: -af apad -shortest mit eingebaut, aber das hilft nicht. Auch hat mpegts nicht das Problem, da bleibt es sync.

    Ich habe das Python Projekt noch gefunden: https://github.com/Zulko/moviepy . Da geht man generell anders mit Videofiles um - es werden die Clips in einzelne Frames auf gesplittet und gepipet. Auch ein interessanter Ansatz! Allerdings bin ich in Python noch nicht so fit um da komplett durch zu steigen. Vielleicht versuche ich mich da mehr einzuarbeiten und diesen Ansatz zu verwenden.

  • Hier an ganz einfaches Beispiel:

    Habe das Video verwendet:
    https://www.youtube.com/watch?v=ybPtPFAww_A

    umbenannt zu talking.mp4 und dann folgenden Befehl für rawvideo abgesetzt:

    Code
    for i in talking.mp4 talking.mp4 talking.mp4 talking.mp4; do ffmpeg -i $i -pix_fmt yuv420p -r 25 -af apad -shortest -c:v rawvideo -c:a pcm_s16le -ar 44100 -ac 2 -threads 2 -f avi -; done | ffmpeg -thread_queue_size 256 -i pipe: -c:v libx264 -c:a aac test.mp4

    Am Ende siehst du schon dass es nicht mehr sync ist. Hingegen mit:

    Code
    for i in talking.mp4 talking.mp4 talking.mp4 talking.mp4; do ffmpeg -i $i -pix_fmt yuv420p -r 25 -af apad -shortest -c:v mpeg2video -b:v 50000k -minrate 50000k -maxrate 50000k -intra -c:a mp2 -ar 44100 -ac 2 -threads 2 -f mpegts -; done | ffmpeg -thread_queue_size 256 -i pipe: -c:v libx264 -c:a aac test-sync.mp4

    bleibt es sync.

    Normalerweise würde ich dazwischen noch einen Buffer setzten, aber so geht es zu Not auch.

    Edit:
    ich glaube du hast doch recht, apad funktioniert nur wenn Audio kürzer ist, aber nicht wenn Audio länger ist. Werde mal noch weiter testen ob es wirklich das ist und was ich dagegen tun kann, vielleicht reicht ein -shortest wirklich schon. Habe das immer nur in Kombination mit apad verwendet.

  • Samples von Youtube sind schlecht, weil da mehrere Streams angeboten werden und ich nicht weiß, ob wir beide denselben benutzen. Ich habe jetzt über "youtube-dl -f 22 ybPtPFAww_A" runtergeladen. Allerdings sind Video- und Tonspur nur 9ms an Länge Unterschied. Bei 3 oder 4 Dateien würde man das noch nicht wirklich wahrnehmen.

Jetzt mitmachen!

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