Ich habe eine große Anzahl von JPEGs, die ich verlustfrei in ein Video konvertieren möchte (oder zumindest nahezu verlustfrei, solange die Kodierungszeit nicht viel höher ist als sonst).
Naiv würde ich denken, dass es einen Codec geben sollte, der die einzelnen JPG-Frames so speichert, wie sie sind (ohne erneute Komprimierung), und möglicherweise eine nette Komprimierung erzielt, indem einige der Frames nur durch die Delta-Informationen aus dem vorherigen Frame ersetzt werden. In meinem Fall gibt es viele Sequenzen von Frames, die identisch sind oder einen winzigen Unterschied zwischen ihnen aufweisen.
Gibt es einen Codec und geeignete Einstellungen für ffmpeg, die dies erreichen können?
Antworten:
Muxen Sie einfach die Bilder
Sie können die JPG-Bilder einfach muxen, um ein Video zu erstellen:
Beachten Sie, dass beim Weglassen
-framerate
ein Standardwert von-framerate 25
auf die Eingabe angewendet wird.Verlustfreie Optimierung
Mit dieser Option können Sie
jpegtran
verlustfreie Optimierungen für jeden Frame durchführen, wodurch möglicherweise erhebliche Einsparungen bei der Dateigröße erzielt werden:Nun muxen Sie mit
ffmpeg
wie oben gezeigt.Überprüfen, ob es tatsächlich verlustfrei ist
Mit dem Framehash-Muxer kann der eindeutige Hash jedes Frames verglichen werden, um sicherzustellen, dass das Ergebnis wirklich verlustfrei ist:
In den obigen Beispielen hat jeder zugeordnete Frame für die Eingabe und die Ausgabe den gleichen Hash, um sicherzustellen, dass die Frames identisch sind und die Ausgabe verlustfrei ist.
Siehe auch
quelle
framemd5
Befehle bewirken sollen, ohne nur die Hashes aufzulisten? Wie würde ich zusätzliche Komprimierung erhalten, wenn identische Frames identifiziert werden?Dadurch wird ein verlustfreies H.264-Video ausgegeben, bei dem Frames Informationen aus anderen Frames verwenden
ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4
Erklärung der Optionen:
-f image2
- weist ffmpeg an, eine Gruppe von Bildern auszuwählen-r 30
- Weist ffmpeg an, mit 30 Frames (oder Bildern) pro Sekunde zu codieren (ändern Sie dies auf die gewünschte Framerate)-i %09d.jpg
- Weist ffmpeg an, die Bilder 000000000.jpg bis 999999999.jpg als Eingabe zu verwenden. Ändern Sie den Wert9
in%09d.jpg
, wie viele Nullen die Namen Ihrer Bildsequenz haben. Wenn Ihre Dateinamen beispielsweise img0001.jpg lauten, wird dies als img% 04d.jpg ausgedrückt-vcodec libx264
- Weist ffmpeg an, in eine H.264-kompatible Datei auszugeben-profile:v high444
- Weist libx264 an, das High 4: 4: 4 Predictive Lossless-Profil zu verwenden, um verlustfreie Codierung zu ermöglichen-refs 16
- weist libx264 an, 16 Bilder in einem Puffer zu speichern, damit auf sie von anderen Bildern im Video verwiesen werden kann-crf 0
- weist libx264 an, eine verlustfreie Codierung durchzuführen-preset ultrafast
- weist libx264 an, der Kodierungsgeschwindigkeit Vorrang vor der Größe der Ausgabedatei zu gebena.mp4
- weist ffmpeg an, die Ausgabe in einer MP4-Datei mit dem Namen a.mp4 zu speichern. Ändern Sie dies in den Dateinamen und das Format, das Sie verwenden möchtenquelle
-f image2
ist hier überflüssig. Der Image File Demuxer sollte-framerate
anstelle von verwenden-r
. libx264 wird automatisch die entsprechende Auswahl-profile
für störfreie und-preset
wird behandeln-refs
.-refs 5
Wenn Sie nicht wissen, dass in Ihren Inhalten identische Bilder enthalten sind, die durch mehrere andere getrennt sind, kann dies dazu führen, dass x264 den Verweis verliert, bevor das Duplikat vorliegt. Höher alsultrafast
macht im verlustfreien Modus wenig anders, abgesehen von CABACs ~ 10% Gewinn gegenüber CAVLC (für hohe CPU-Kosten bei den für verlustfrei erforderlichen Bitraten). Im Ernst, auf einigen Live-Action-720x480p60 (Deinterlace-Ausgang),superfast
war 28 GB,slower
war 27 GB. Wenn die Kodierungszeit keine Rolle spielt, die Dekodierungszeit jedoch, sollten Sie CABAC vermeiden. Vielleicht sogar-tune fastdecode
. Eine moderate Ref-Anzahl sollte nicht schaden.-preset placebo
ein paar zusätzliche Bruchteile prozentual versuchen .-vcodec libx265 -x265-params lossless=1
ist die entsprechende Option. (Aber meiner Erfahrung nach (= Aufzeichnung von Powerpoint-Diashow-Präsentationen) ist es nicht unbedingt besser und viel langsamer als h264.) Seien Sie gespannt auf das NETVC1 / Xiph's Daala von AOMedia / IETF / was auch immer es bis dahin umbenannt wird ... verlustfreier ModusSie können eine
avi
Animation als eine Reihe vonpng
Bildern erstellen (png
ist verlustfrei, sodass diejpeg => png
Konvertierung Ihre Bilder nicht beeinträchtigen sollte):wenn deine bilder einen namen haben
img_0001.jpg
Dabei ist "25" die Bildrate, die Sie im resultierenden Video wünschen.
-start_number
wird nicht benötigt, wenn es 1 ist, aber es ist nützlich, wenn Ihre erste Videonummer nicht 1 ist.Wenn Sie
mjpeg
mit der Befehlszeile höchster Qualität codieren möchten, gilt Folgendes :Und das Schöne an der Sache ist, dass Sie das Video wieder in eine Bilderserie umwandeln können:
etc...
quelle
Um die Antwort von LordNeckbeard zu erweitern, muxen Sie einfach die JPEG-Daten in einen MJPEG-Videostream. Dies ist die kleinste Darstellung der exakten Folge von Ausgabebildern, obwohl MJPEG nach heutigen Maßstäben ein schrecklich ineffizienter Codec ist. (keine zeitliche Redundanz und auch keine Intra-Vorhersage.
Sie können ein MJPEG-Video mit variabler Bildrate erstellen, um die doppelten Bilder in Ihrer Eingabe zu nutzen.
Hrm, das wird nicht funktionieren, da mpdecimate nicht für komprimierte Daten geeignet ist und wir es nicht zulassen können, dass ffmpeg die Bilddaten ohne Verlust und ohne CPU-Kosten dekodiert und erneut jpegiert.
Vielleicht, wenn Sie doppelte JPG-Quelldateien durch leere Dateien mit dieser Sequenznummer ersetzt haben, oder so?
Da diese Frage noch nicht ganz aktuell ist, werde ich mir nicht die Zeit nehmen, um herauszufinden, wie es geht, es sei denn, jemand antwortet und fragt, wie. Da MJPEG jedoch in einen mkv-Container verschoben werden kann, ist es sicher möglich, dass eine Datei die JPEG-Daten für wiederholte Frames nicht dupliziert, sondern nur einen Ausgabeframe zum Dekodieren hat, bis die Sequenz der Duplikate erreicht ist Über.
Oh, hier ist eine Idee:
Entfernen (oder verschieben) Sie dann alle JPEG-Dateien für Frames, die mpdecimate löschen möchte (wahrscheinlich hat es einige Protokollierungsoptionen). Oder -vf showinfo und parsen Sie diese und verschieben oder verknüpfen Sie nur die Frames, die in der Ausgabe angezeigt werden die abgelegten JPEGs?). muxen Sie das in eine MJPEG.mkv, und machen Sie dann etwas mit mkvmerge, um die Frame-Zeitstempel durch die Zeitstempel von zu ersetzen
mpdecimate.timestamps
.Wenn Sie xcodieren würden, anstatt nur JPEG-Daten in MJPEG zu muxen, wäre dies VIEL einfacher, da Sie nur meinen ersten Befehl mit mpdecimate und einem anderen Codec als verwenden würden
copy
, und es würde einfach funktionieren .Ich habe nichts davon ausprobiert, da dies eine alte Frage war. Auch der Grund, warum ich die Lücken nicht ausgefüllt habe, wie Sie Ihr JPEG-Verzeichnis basierend auf der mpdecimate-Ausgabe tatsächlich filtern oder wie Sie den Timestamp-Stream tatsächlich verwenden.
quelle