Wie erstelle ich ein Video aus Bildern mit FFmpeg?

86

Ist es möglich ffmpeg, ein Video aus einer Reihe von Sequenzen zu erstellen, bei denen die Zahl nicht bei Null beginnt?

Ich habe beispielsweise einige Bilder [test_100.jpg, test_101.jpg, test_102.jpg, ..., test_200.jpg] und möchte sie in ein Video konvertieren. Ich habe den folgenden Befehl ausprobiert, aber er hat nicht funktioniert (die Zahl sollte anscheinend bei Null beginnen):

ffmpeg -i test_% d.jpg -vcodec mpeg4 test.avi

Irgendwelche Ratschläge?

JakeGould
quelle
Es ist schon eine Weile her, dass Sie dies gefragt haben, aber wenn Sie immer noch an der Frage interessiert sind, lautet die Antwort JA - ich habe die Details und ein Beispiel unten veröffentlicht: stackoverflow.com/a/12160155/181638
Assad Ebrahim
@casperOne wäre nützlich, um eine Idee zu haben, warum dies nicht zum Thema gehört. Es scheint ein spezifisches Programmierproblem zu sein. Das FFmpeg-Tag hat 3.7k Follower und mit 27k Views finden es die Leute eindeutig nützlich.
Geotheory
2
@geotheory Die Tag-Statistiken sind irrelevant. ffmpeg ist ein Programm wie WinRar. Während Sie gegen die Bibliotheken in ffmpeg programmieren können , geht es bei dieser Frage nicht darum. Wenn Sie ffmpeg von der Befehlszeile aus verwenden, müssen Sie bei Super User nachfragen , wo es zum Thema gehört.
casperOne

Antworten:

80

Es ist nicht erforderlich, Dateien umzubenennen, wenn Sie den -start_numberSchalter wie folgt verwenden :

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

wo nist der Beginn der Sequenz von Standbildern.

Beachten Sie, dass dies so lange funktioniert, wie die Sequenz nach dem Start nicht unterbrochen wird. Wenn Lücken vorhanden sind und Sie möchten, dass alle Standbilder enthalten sind, müssen Sie möglicherweise neu nummerieren, um die Lücken zu schließen.

Es gibt einige andere Schalter, die Sie möglicherweise nützlich finden.

Ich verwende den folgenden Einzeiler, um eine langsamere Bildrate zu erzielen, die Bilder zu komprimieren und ein kleineres Video zu erhalten:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

Die -r 3Option setzt die Bildrate des resultierenden Videos auf 3 Bilder pro Sekunde, so dass ich jedes für einen kurzen Zeitraum noch sehen kann. Die -sOption skaliert die Bilder auf die gewünschte Auflösung, um die Größe des resultierenden Videos zu verwalten.

(In der Windows - Shell, ersetzen -i Imgp%04d.jpgmit -i "Imgp%%04d.jpg". Kredit für diese Mike Fitzpatrick https://superuser.com/a/344178/153054 )

Assad Ebrahim
quelle
4
Was ist der Unterschied zwischen -r und -framerate?
1
Sie sind die gleichen IIRC
Rogerdpack
22
Sie brauchen keinen Unsinn beim Nummerieren zu machen, solange Sie die Reihenfolge akzeptieren, in der sie erscheinen (sagen wir 'ls') ... verwenden Sie einfach: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile
2
Gibt es einen Schalter, um die zeitliche Lücke zwischen den Bildern zu kontrollieren , zum Beispiel möchte ich das erste Bild 13s, das zweite 15s, das dritte 24s anzeigen, die zeitliche Lücke ist benutzerdefiniert, ist das möglich?
Zionpi
2
Siehe auch trac.ffmpeg.org/wiki/…
david.libremone
38

Sie können dieses Code-Snippet unten verwenden:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

quelle
Dadurch werden JPGs nicht auf die in den Metadaten angegebene Drehung gedreht.
Erik Johansson
17

Ein Beispielskript finden Sie in der ffmpeg-Dokumentation :

3.2 Wie verschlüssele ich einzelne Bilder in Filme?

Wenn Sie eine große Anzahl von Bildern umbenennen müssen, können Sie den folgenden Befehl verwenden, um die Belastung zu verringern. Der Befehl verknüpft mit der Bourne-Shell-Syntax symbolisch alle Dateien im aktuellen Verzeichnis, die mit * jpg /tmp' directory in the sequence ofübereinstimmen, mit der Datei img001.jpg ', `img002.jpg' usw.

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

Dann renne:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
Gaizka
quelle
2
Sie sollten x = 0 setzen, damit der Bildname img000.jpg startet, da dies von ffmpeg erwartet wird. Auch Symlinking funktionierte bei mir nicht, da ffmpeg die Dateien nicht finden konnte, so dass ich stattdessen cp verwenden musste (offensichtliche Geschwindigkeits- und Platzmängel, aber ich rme sie trotzdem nach). mv würde auch funktionieren, wenn es Ihnen nichts ausmacht, die Originale zu verlieren.
Beachten Sie, dass in dieser Antwort mit dem angegebenen Befehl Hardlinks und keine Symlinks erstellt werden. Im Hinblick auf die Verwendung , cpwenn Verknüpfung funktioniert nicht, wenn Ihr Dateisystem unterstützt es cp --reflink=autoviel bessere Geschwindigkeit / Raumnutzung erreichen wird.
Félix Saparelli,
12

Aus den Dokumenten von ffmpeg:

Verwenden eines Glob-Musters

ffmpeg unterstützt auch bash-artiges Globbing (* steht für eine beliebige Anzahl beliebiger Zeichen).

Dies ist nützlich, wenn Ihre Bilder sequentiell sind, jedoch nicht unbedingt in numerischer Reihenfolge wie in den vorherigen Beispielen.

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

Solange Ihre Dateien sortiert sind, sollte die Verwendung des -pattern_type globSchalters für Sie funktionieren.

Nevin Williams
quelle
Beachten Sie, dass dieser Glob begrenzter ist als normale Shell-Globs: trac.ffmpeg.org/ticket/3620, anscheinend, weil der Bildtyp von der Erweiterung abgeleitet wird.
Ciro Santilli - 996ICU
11

Soweit ich weiß, können Sie die Sequenz nicht in zufälligen Zahlen starten (ich erinnere mich nicht, ob Sie sie bei 0 oder 1 beginnen sollten). Außerdem kann es keine Lücken geben. Wenn dies der Fall ist, geht ffmpeg davon aus, dass die Sequenz vorbei ist und Stoppen Sie das Hinzufügen weiterer Bilder.

Denken Sie auch daran, wie in den Kommentaren zu meiner Antwort angegeben, dass Sie die Breite Ihres Index angeben müssen. Mögen:

image% 03d.jpg

Und wenn Sie einen% 03d-Indextyp verwenden, müssen Sie Ihre Dateinamen mit 0 auffüllen, z.

image001.jpg image002.jpg image003.jpg

usw.

Francisco Soto
quelle
1
Wenn die Bilddateinamen führende Nullen haben, muss die Formatzeichenfolge auch die Breite wie "% 03d" angeben.
1
Wenn dies das einzige Hindernis ist, können Sie einfach ein Skript schreiben, um Ihre Bilder entweder umzubenennen oder mit einem ordnungsgemäß neu indizierten Satz zu verknüpfen.
Cascabel
1
Ja, ich habe schon früher damit gearbeitet. Ich habe vor einiger Zeit in Ruby einen Wrapper geschrieben, in dem Sie instance.addImage () und dann instance.processVideo () aufgerufen haben. Dann wurde ein temporäres Verzeichnis erstellt und die Bilder mit den richtigen Indizes kopiert / umbenannt und erstelle das Video. Das ist ganz einfach.
@Jefromi Ich habe einen Symlink erstellt, aber wie gebe ich den Pfad der Symlink-Datei zu ffmpeg an? Es wird nur angenommen, dass die Symlink-Datei das Bild ist, das ich konvertieren möchte. Ich bin auf win7 BTW
Die Sequenz kann von 0 bis einschließlich 4 beginnen.
Assad Ebrahim
5

Ich stimme Francisco zu, aber als Workaround können Sie einfach ein schnelles Skript schreiben, um symbolische Links zu den Dateien mit den von ffmpeg benötigten Folgenummern zu erstellen. Das Skript könnte dann ffmpeg aufrufen und dann die Verknüpfungen entfernen oder die Dateien wieder an ihren ursprünglichen Speicherort verschieben.

Jason B
quelle
1

Sieh nach oben

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i"
/tmp/img"$counter".jpg; x=$(($x+1)); done

quelle
1

Ich weiß, dass dies eine alte Frage ist, aber ich bin auf Google gestoßen, als ich nach der gleichen Antwort gesucht habe. Keine der Antworten hier hat mich vollständig zufriedengestellt, also habe ich mehr gesucht und gelesen, und dies ist ein Befehl, den ich für mein eigenes Problem entwickelt habe.

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

Der Grund, warum ich einen Befehl wie diesen verwenden würde, ist ...

  1. Mit Cat und -f image2pipe können Sie genauer steuern, welche Bilder Sie verwenden. Beispielsweise können Sie Bash-Funktionen wie die Erweiterung von Klammern und andere Befehle wie grep verwenden, um Ihre Ergebnisse zu optimieren, falls Sie dies wünschen.
  2. Weniger Schalter zum Erinnern.
  3. Ich empfehle -r NICHT zu verwenden und verwende stattdessen -framerate. Nach meiner Erfahrung neigt -r dazu, Frames öfter fallen zu lassen.
  4. Weniger komplex, keine unnötigen Schalter im Einsatz und es wird so funktionieren, wie es ist. Sie können die Komplexität erhöhen (z. B. Encoder angeben) und die Einstellungen an Ihre Bedürfnisse anpassen.
David Bobb
quelle
Für die Frage des OP -start_numberist alles, was benötigt wird.
Gyan
0

Ich habe den FLV-Encoder verwendet, da mein Video in einem Flash-Player (Jwplayer) abgespielt wurde.

ffmpeg -i% d.jpg -vcodec flv test.flv


quelle
0

Aus der Dokumentation geht hervor , dass Sie einfach Folgendes verwenden können: *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

Um die Qualität zu verbessern, kann die Rate / fps wichtig sein (z. B. zuerst eine sehr niedrige / hohe Bildrate festlegen und dann von einem zweiten Filter übergehen, der das Zeitlupenvideo normalisiert?).

ntg
quelle
0

In meinem Fall war es aufgrund der Zahlen in den Dateien etwas kniffliger. So sehen meine Bilder aus:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

Und hier ist der Befehl, den ich verwendet habe:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg  -vcodec mpeg4 test.avi
Mona Jalal
quelle
0

Sie können dies tun mit convert -morph:

convert *.jpg -delay 10 -morph 10 %05d.jpg

Wenn Sie verwenden möchten ffmpeg, habe ich verwendet

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

10*PTSWobei das ffmpeg anweist, es 10 mal zu verlangsamen. Sie können dort auch Brüche eingeben, um die Geschwindigkeit zu erhöhen.

Martin Thoma
quelle
Dies interpoliert nur Ihre ursprüngliche Bildsequenz in einen neuen Bereich. Es wird keine Videodatei wie im OP erstellt.
18.
0

-pattern_type glob konkrete Beispiele mit Audio

Diese Option wurde unter https://superuser.com/a/782520/128124 erwähnt. Hier sind jedoch einige konkrete Beispiele für ihre Verwendung, einschließlich des Hinzufügens von Audio zum ausgegebenen Video.

Diashow-Video mit einem Bild pro Sekunde

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

Fügen Sie etwas Musik hinzu und unterbrechen Sie die Audiowiedergabe, wenn die Bilder enden:

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

Hier sind zwei Demos auf YouTube:

Sei ein Hippie und nutze das von Theora patentfreie Videoformat :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

Ihre Bilder sollten natürlich alphabetisch sortiert sein, normalerweise wie folgt:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

und so weiter.

Siehe auch: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Normalgeschwindigkeitsvideo mit einem Bild pro Bild bei 30 Bildern pro Sekunde

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

So sieht es aus:

GIF generiert mit: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

Fügen Sie etwas Audio hinzu:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

Ergebnis: https://www.youtube.com/watch?v=HG7c7lldhM4

Konvertieren Sie eine Musikdatei in ein Video mit einem festen Bild für den YouTube-Upload

Beantwortet bei: Wie konvertiere ich MP3 in das von YouTube zugelassene Videoformat?

Erhalten Sie einige synthetische Testeingabebilder

Dies sind die Testbilder, die ich in dieser Antwort verwendet habe:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

Bilder generiert mit: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

Es ist cool zu beobachten, wie stark das Video die Bildsequenz besser komprimiert als ZIP, da es mit speziellen Algorithmen über Frames hinweg komprimiert werden kann:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7,3M

Über die CLI-Optionen

Beachten Sie jedoch, dass dies trotz des Namens -globnicht so allgemein ist wie Shell-Glob-Muster, z. B .: failed -i '*': https://trac.ffmpeg.org/ticket/3620 (anscheinend, weil der Dateityp von der Erweiterung abgeleitet wird).

-r 30macht das -framerate 1Video 30 FPS, um Fehler in Playern wie VLC für niedrige Frameraten zu überwinden: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using- ffmpeg / 41797724 # 41797724 Daher wird jeder Frame 30-mal wiederholt, um den gewünschten Effekt von 1 Bild pro Sekunde beizubehalten .

Nächste Schritte

Sie möchten auch:

TODO: Erfahren Sie, wie Sie mehrere Audiodateien über die Befehlszeile ausschneiden und in das Video verketten können:

Getestet am

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Literaturverzeichnis

Entfernung von Ciro Santilli nach 996ICU
quelle