Ich habe eine große Anzahl von JPGs, die ich verlustfrei in ein Video konvertieren möchte (oder zumindest sehr nahe an verlustfrei, solange die Codierungszeit nicht viel länger als sonst ist).
Naiverweise würde ich denken, dass es einen Codec geben sollte, der jeden einzelnen JPG-Frame so speichern kann, wie er ist (ohne erneute Komprimierung), und vielleicht eine nette Komprimierung erreichen kann, indem er einige der Frames nur durch die Informationen zum Delta des vorherigen Frames ersetzt. In meinem Fall gibt es viele Sequenzen von Einzelbildern, die untereinander identisch sind oder einen winzigen Unterschied zwischen sich aufweisen.
Gibt es einen Codec und geeignete Einstellungen für ffmpeg, mit denen dies erreicht werden kann?
Sie können die JPG-Bilder einfach muxen, um ein Video zu erstellen:
ffmpeg -framerate 30 -i input%03d.jpg -codec copy output.mkv
Beachten Sie, dass, wenn Sie weglassen, -framerate
ein Standard von -framerate 25
auf die Eingabe angewendet wird.
Sie können verwenden jpegtran
, um eine verlustfreie Optimierung für jeden Frame durchzuführen, was zu erheblichen Einsparungen bei der Dateigröße führen kann:
mkdir outputdir
for f in *.jpg; do jpegtran -optimize -copy none -perfect -v "$f" > "outputdir/$f"; done
Jetzt muxen Sie mit ffmpeg
wie oben gezeigt.
Der Framehash-Muxer kann verwendet werden, um den eindeutigen Hash jedes Frames zu vergleichen, um sicherzustellen, dass das Ergebnis wirklich verlustfrei ist:
$ ffmpeg -i input%03d.jpg -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0, 0, 0, 1, 460800, 29bcc2db3726c7dfec1826c5740f603f
0, 1, 1, 1, 460800, b5fdc23d93cbd043dc2b9290dc8378f0
0, 2, 2, 1, 460800, ee0709942f24b458fd2380d134dcb59d
...
$ ffmpeg -i output.mkv -map 0:v -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0, 0, 0, 1, 460800, 29bcc2db3726c7dfec1826c5740f603f
0, 1, 1, 1, 460800, b5fdc23d93cbd043dc2b9290dc8378f0
0, 2, 2, 1, 460800, ee0709942f24b458fd2380d134dcb59d
...
In den obigen Beispielen teilen sich alle zugehörigen Frames für die Ein- und Ausgabe denselben Hash, wodurch sichergestellt wird, dass die Frames identisch und die Ausgabe verlustfrei ist.
framemd5
Befehle über das bloße Auflisten der Hashes hinaus erreichen sollen? Wie würde ich eine zusätzliche Komprimierung erhalten, wenn identische Frames so 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
Erläuterung der Optionen:
-f image2
- weist ffmpeg an, eine Gruppe von Bildern auszuwählen-r 30
- weist ffmpeg an, mit 30 Bildern (oder Bildern) pro Sekunde zu codieren (ändern Sie dies auf Ihre gewünschte Bildrate)-i %09d.jpg
- weist ffmpeg an, die Bilder 000000000.jpg bis 999999999.jpg als Eingabe zu verwenden. Ändern Sie das 9
in %09d.jpg
wie viele Nullen der Name Ihrer Bildsequenz hat. 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 Profil High 4:4:4 Predictive Lossless zu verwenden, was eine verlustfreie Codierung ermöglicht-refs 16
- weist libx264 an, 16 Bilder in einem Puffer zu speichern, damit sie von anderen Bildern im Video referenziert werden können-crf 0
- weist libx264 an, eine verlustfreie Codierung durchzuführen-preset ultrafast
- weist libx264 an, der Codierungsgeschwindigkeit Vorrang vor der Größe der Ausgabedatei zu gebena.mp4
- weist ffmpeg an, die Ausgabe in einer MP4-Datei namens a.mp4 zu speichern. Ändern Sie dies in den Dateinamen und das Format, das Sie verwenden möchten-f image2
ist hier überflüssig. Der Bilddatei-Demuxer sollte -framerate
anstelle von -r
. libx264 wählt automatisch die passende -profile
für verlustfrei aus und -preset
behandelt die -refs
.-refs 5
bei MOST, es sei denn, Sie wissen, dass Ihr Inhalt identische Bilder enthält, die durch mehrere andere getrennt sind, kann dies dazu führen, dass x264 die Referenz verliert, bevor es zum Duplikat gelangt. Höher als ultrafast
macht im verlustfreien Modus kaum einen Unterschied, abgesehen von CABACs ~ 10% Gewinn gegenüber CAVLC (für hohe CPU-Kosten bei den für verlustfreien Bitraten erforderlichen Bitraten). Im Ernst, bei einer Live-Action waren 720 x 480p60 (Deinterlace-Ausgabe) superfast
28 GB, slower
waren 27 GB. Wenn die Codierungszeit keine Rolle spielt, die Decodierungszeit jedoch, stellen Sie sicher, dass Sie CABAC vermeiden. Vielleicht sogar -tune fastdecode
. Eine moderate Anzahl von Refs sollte nicht schaden.-preset placebo
, ein paar Prozent mehr zu bekommen.-vcodec libx265 -x265-params lossless=1
ist die gleichwertige Option. (Aber nach meiner Erfahrung (= Aufzeichnung von Powerpoint-Diashow-Präsentationen) ist es nicht unbedingt besser und viel langsamer als h264) Bleiben Sie dran für AV1 von AOMedia/NETVC1 von IETF/Daala von Xiph/wie auch immer es bis dahin umbenannt wird ... im verlustfreien ModusSie können eine avi
Animation als eine Reihe von png
Bildern erstellen ( png
ist verlustfrei, sodass die jpeg => png
Konvertierung Ihre Bilder nicht beeinträchtigen sollte):
wenn Ihre Bilder einen Namen habenimg_0001.jpg
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec png video.avi
wobei "25" die Bildrate ist, die Sie im resultierenden Video haben möchten. -start_number
ist nicht erforderlich, wenn es 1 ist, aber es ist nützlich, wenn Ihre erste Videonummer nicht 1 ist.
Wenn Sie mit höchster Qualität kodieren möchten, mjpeg
ist die Befehlszeile:
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec mjpeg -qscale 1 video.avi
Und das Schöne an der Sache ist, dass Sie das Video wieder in eine Bilderserie umwandeln können:
ffmpeg -i video.avi "img_series_%04d.png"
ffmpeg -i video.avi "img_series_%04d.jpg"
etc...
Um die Antwort von LordNeckbeard zu erweitern, ja, muxen Sie einfach die JPEG-Daten in einen MJPEG-Videostream. Das 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 nicht einmal eine Intra-Vorhersage.
Sie können ein MJPEG-Video mit variabler Framerate erstellen, um die doppelten Bilder in Ihrer Eingabe zu nutzen.
ffmpeg -framerate 30 -i input%03d.jpg -vf mpdecimate -codec copy output.mkv # doesn't work.
Hrm, das wird nicht funktionieren, da mpdecimate bei komprimierten Daten nicht funktioniert und wir ffmpeg die Bilddaten nicht ohne Verlust und CPU-Kosten dekodieren und dann neu jpegieren können.
Vielleicht, wenn Sie doppelte JPG-Quelldateien durch leere Dateien mit dieser Sequenznummer oder so ersetzt haben?
Da diese Frage noch nicht einmal neu ist, werde ich mir nicht die Zeit nehmen, herauszufinden, wie es geht, es sei denn, jemand antwortet, um zu fragen, wie. Aber da MJPEG in einen mkv-Container gehen kann, bin ich sicher, dass es möglich ist, eine Datei zu haben, die die JPEG-Daten für wiederholte Frames nicht dupliziert, sondern einfach keinen Ausgabeframe zum Decodieren hat, bis die Sequenz von Duplikaten ist über.
Ach hier eine Idee:
ffmpeg -framerate blah -input blah -vf mpdecimate -f mkvtimestamp_v2 mpdecimate.timestamps
Entfernen (oder verschieben) Sie dann alle JPEGs für Frames, die mpdecimate löschen möchte (wahrscheinlich hat es einige Protokollierungsoptionen? Oder -vf showinfo, und analysieren Sie das und verschieben oder verlinken Sie nur die Frames, die in seiner Ausgabe angezeigt werden, und lassen Sie sie zurück die gelöschten JPEGs?). muxen Sie das in eine MJPEG.mkv, dann tun Sie etwas mit mkvmerge, um die Frame-Zeitstempel darin 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 einfach meinen ersten Befehl mit mpdecimate und einem anderen Codec als verwenden copy
würden, und es würde einfach funktionieren (tm).
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 Zeitstempel-Stream tatsächlich verwenden.
Freund von Georg
Freund von Georg
Peter Kordes