Konvertieren von PNG-Bildern in Videos mit 1 FPS


20

Ich habe Videoframes im PNG-Format mit 1 FPS und versuche, sie mit ffmpeg in ein Video zu konvertieren.

Wenn ich so etwas mache:

ffmpeg -i data/input-%4d.png data/output.mp4

Ich erhalte ein Video mit 25 Bildern pro Sekunde, was im Grunde genommen ein sehr schneller Vorlauf des Eingangs ist (der mit 1 Bildern pro Sekunde aufgenommen wird).

Wenn ich es versuche:

ffmpeg -i data/input-%4d.png -r 1 data/output.mp4

Ich bekomme etwas, das VLC nicht spielen möchte :)

Wenn ich jetzt das erste Video (das FF-Video) nehme und einen Filter anwende, um es zu verlangsamen (z. B. -filter:v 'setpts=24.0*PTS'), kann ich es wie ein 1-fps-Video wiedergeben, aber der Preis ist natürlich die Dateigröße. Es generiert eine Reihe von wiederholten Frames, denke ich.

Die Frage ist also, wie erstelle ich ein Video, das genau 1 FPS hat und tatsächlich mit dieser Geschwindigkeit abgespielt wird? Das Ausgabeformat ist übrigens für mich nicht so wichtig.


Ich bin mir nicht sicher, ob ich ffmpegschlau genug bin , den Videocodec nur anhand der Dateierweiterung im Containerformat herauszufinden .mp4. Versuchen Sie -vcodec libx264 -vpre hq, der Befehlszeile den Codec und die Codierungsparameter hinzuzufügen .
Warren Young

Es hat es tatsächlich herausgefunden, ok, und ich habe erwähnt, dass es gut funktioniert hat und nur seltsame Ergebnisse hervorgebracht hat, als ich hinzugefügt habe -r 1.
Assaf Lavie

Ich glaube , du mehr Glück auf bei einer ffmpeg Antwort haben stackoverflow.com oder superuser.com .
Damien

Antworten:


18

Wenn Sie einen Einzeiler für FFMPEG benötigen, der ein Video mit einer Wiedergabegeschwindigkeit von 1 Frame pro Sekunde generiert, müssen Sie die Frameraten für Eingabe und Ausgabe wie folgt festlegen:

ffmpeg -r 1 -i Daten / Eingabe-% 4d.png -pix_fmt yuv420p -r 10 Daten / Ausgabe.mp4

Dies -r 1bedeutet, dass das Video mit 1 der Originalbilder pro Sekunde abgespielt wird.
Dies -r 10bedeutet, dass das Video mit 10 Bildern pro Sekunde abgespielt wird.

(Dies -pix_fmt yuv420pist nur erforderlich, um die Kompatibilität mit einer Vielzahl von Wiedergabeprogrammen zu gewährleisten. Dies ist beispielsweise erforderlich, damit das Video von Windows Media Player wiedergegeben werden kann.)

Ich habe viele verschiedene Ausgangs-Frameraten getestet, und 10 scheint die niedrigste Zahl zu sein, die Sie verwenden können, um ein Video zu produzieren, das VLC wiedergibt.

Der obige Befehl bedeutet natürlich, dass jedes Originalbild multipliziert wird, aber es ist eine einfachere Methode als die von Ihnen erwähnte "Verlangsamung" und abhängig vom Codec wird möglicherweise kein Video erzeugt, das viel größer als eine echte 1-FPS ist Video.

Um dies zu testen, habe ich gerade ein echtes 1-FPS-Video produziert, das 2,24 kiB groß war. Ich habe dann ein Video mit denselben Eingabebildern, aber einer Ausgabe von 24 FPS, erstellt und es ergab sich ein Wert von 5,76 kiB. Das ist etwas mehr als die doppelte Größe und bei weitem nicht die 24-fache Größe. :)


+1 auf -pix_fmt. Es ist leicht zu vergessen, dass einige Leute darauf bestehen, WMP zu verwenden :-)
Smalltown2k

warum soll das ausgabeformat 10 fps sein, während die eingabe nur 1 ist? Würde es nicht zu 90% redundante Frames geben, die genau gleich sind?
Herbert

@Herbert erstellt redundante Frames, sodass Sie die Framerate auf 10 erhöhen können. Dies geschieht nur, damit VLC sich nicht beschwert und das Video optisch nicht verändert. Der Encoder ist intelligent genug, um zu erkennen, dass alle Frames identisch sind, sodass Sie keine viel größere Datei erhalten
chiliNUT,

@chiliNUT klar, die Keyframe-Sache, die nicht alle Formate, sondern die meisten vernünftigen Formate können. Vielen Dank!
Herbert

5

Verwenden Sie beide -framerateund-r

Zum Beispiel, um ein letztes Video zu haben, das wie 1FPS aussieht:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
    -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Dies ähnelt dem Konvertieren von PNG-Frames in Videos mit 1 FPS Unix und Linux - Stack von Exchange sagt, aber ich brauchte , -framerateanstatt -rfür sie zu arbeiten.

Dies wird im Wiki unter http://trac.ffmpeg.org/wiki/Slideshow#Framerates erwähnt

Hiermit wird die Ausgabeframerate auf festgelegt 30, mit der VLC umgehen kann, und jedes Bild wird 30 Mal kopiert, sodass das Ausgabevideo mit 1 FPS angezeigt wird. Siehe auch: Wiedergabeprobleme in VLC mit Videos mit niedriger Bildrate von Bildern mit ffmpeg | Paketüberfluss

VLC kann das Video dann normal abspielen.

Getestet unter Ubuntu 16.10, VLC 2.2.4, ffmpeg3.0.5 in einem Verzeichnis mit 10 PNGs.

Siehe auch: /programming/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg


Was ist der Unterschied zwischen -rund -framerate?
Royi

@ Royi Ich weiß es nicht wirklich, außer dass es das einzige ist, was bei mir funktioniert hat :-) Aber wenn du es geschafft hast, es aus den manSeiten zu extrahieren , lass es mich wissen ;-) Ein aussagekräftiges Zitat ist "-r als Bei der Eingabeoption werden alle in der Datei gespeicherten Zeitstempel ignoriert und stattdessen Zeitstempel mit einer konstanten Bildrate von fps generiert FFmpeg). Verwenden Sie im Zweifelsfall -framerate anstelle der Eingabeoption -r. "
Ciro Santilli

3

Was ist, wenn Sie Ihr zweites Beispiel wie folgt leicht erweitern:

$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4

Das -r 1muss vor den .png-Dateien kommen, nicht danach.

Aus der FFmpeg-Dokumentation :

In der Regel werden Optionen auf die nächste angegebene Datei angewendet. Daher ist die Reihenfolge wichtig, und Sie können dieselbe Option mehrmals in der Befehlszeile verwenden. Jedes Vorkommen wird dann auf die nächste Eingabe- oder Ausgabedatei angewendet.


Das geht leider nicht. Da ich jedoch erwähne, dass die Bestellung wichtig ist , habe ich viel Zeit gespart. Vielen Dank.
Mohammed Noureldin

0

Dies ist ein Fehler in VLC (der in Version 3.0.6 noch vorhanden ist). Nach einigen Experimenten stellte ich fest, dass VLC bei Videos mit FPS von weniger als 10 abstürzt . Daher sollten alle Videos mit 10 FPS oder mehr kein Problem sein. Daher gibt es derzeit keinen sauberen Weg, um ein Video mit 1 FPS zu erhalten, das in VLC wiedergegeben werden kann ( nicht aufgeben, weiterlesen ).

Eine Problemumgehung ist - wie in der obigen Antwort gezeigt - die Fälschung des Effekts von 1 FPS durch Duplizieren der Bilder (wenn wir tatsächlich eine FPS von 10 oder mehr haben, was für VLC in Ordnung ist).

Beispiel: Wenn Sie einen Ordner mit 12 Bildern haben und ein Video mit 1 FPS (das in VLC abgespielt werden kann) erstellen möchten, müssen Sie jedes Bild mehrmals duplizieren (sagen wir mal 10) und dann FFMPEG mitteilen um ein 10 FPS Video zu erzeugen. Auf diese Weise erhalten wir ein Video mit insgesamt 120 Bildern, in dem jedes Bild 1 Sekunde lang abgespielt wird (da es 10 Mal dupliziert wird), was einfach eine Fälschung für 1 FPS ist.

Ich bevorzuge es , fpsParameter-r zu verwenden , anstatt (was in einer anderen Antwort gezeigt wird), was in einigen Fällen problematisch sein kann (gemäß der offiziellen Dokumentation ).

ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv

Da die Eingabe -framerateniedriger als die Ausgabe ist fps, dupliziert FFMPEG Frames, um die gewünschte Framerate für die Ausgabe zu erreichen (entsprechend dem obigen Befehl 10).

Es ist auch wichtig zu beachten, dass die Reihenfolge von -framerateund -vf fpswichtig ist , da diese Konfiguration auf das nächste erwähnte Video (Ein- oder Ausgabe) angewendet wird. Das ist laut den offiziellen Dokumenten :

Optionen werden auf die nächste angegebene Datei angewendet. Daher ist Ordnung wichtig ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.