Wir generieren eine Menge von Miniatur-GIFs, deren Qualität nicht annähernd so wichtig ist wie die Zeit, die für deren Generierung erforderlich ist. Das Generieren von qualitativ hochwertigen GIFs mit ffmpeg ist sehr gut abgedeckt, aber ich habe nicht viel Glück, herauszufinden, wie Sie qualitativ minderwertige GIFs so schnell wie möglich generieren können.
Die Palettenberechnung nimmt mit dem folgenden Befehl die meiste Ausführungszeit in Anspruch (entnommen aus der Antwort des Filtergraphen mit mehreren Ketten hier: So erstellen Sie effizient ein GIF mit der besten Palette aus einem Videoteil direkt aus dem Web ):
ffmpeg -y -threads 8 -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter_complex "fps=24,scale=150:-1:flags=fast_bilinear,split=2 [a][b]; [a] palettegen [pal] fifo [b]; [b] [pal] paletteuse" output.gif
Die Ausführungszeit dieses Befehls mit 1000 Bildern beträgt ungefähr 72 Sekunden. Ungefähr 67 Sekunden davon sind der Palettendurchlauf, und dann durchläuft er die eigentliche GIF-Erzeugung in ungefähr 5 Sekunden. Ich möchte die gesamte Ausführungszeit so weit wie möglich verkürzen und bereit sein, viel Bildqualität für die Geschwindigkeit zu opfern.
[b]
Etikett. In beiden Fällen ist die Verwendung der Palette nach einem Schnelltest etwa 200 ° langsamer. Es überhaupt nicht zu benutzen, ist für Sie keine Option?ffmpeg -y -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter:v "scale=150:-1:flags=fast_bilinear" output.gif
Die beiden folgenden Probleme: 1) Es wurden nur 13 Sekunden gespart (59 Sekunden statt 72) und 2 ) Ich bin nicht zu 100% sicher, dass dieser Befehl die Palettenberechnung vollständig eliminiert (nur dass die Palettenberechnung, die ich zuvor angegeben habe, nicht enthalten ist).ffmpeg -i <input> <scale> <output.gif>
.Antworten:
Ihre Verwendung der
palettegen
/paletteuse
-Filter verlangsamt die Ausführung des Befehls. Der einfache Weg, um ein GIF mit geringerer Qualität zu erhalten, wäre:Mit zusätzlicher Skalierung:
Sie können auch Frames in das Ausgabe-GIF einfügen, dh die Frames abtasten, damit nicht alle verarbeitet werden. Um zB nur 1 FPS-Ausgabe zu haben, verwenden Sie einen
fps
Filter:quelle
fps
Filters trägt den Namenfps
, diese sind also gleichwertig. Wenn Ihre Quelle 120fps ist, müssen Sie angeben-framerate 120 -i "frames…"
, da der Standard für Eingang 24.Ich hatte die Aufgabe, die Zeit zu verkürzen, die erforderlich war, um ein animiertes GIF mit einer Länge von 30 Bildern und einer Breite von 150 Pixeln zu erstellen. Die meisten Sequenzen, die wir generieren, sind unter 1000 Frames. Wir hatten eine Sequenz von 15.000 Bildern und unsere Renderknoten brauchten 17 Minuten , um dieses ~ 30-Bilder-GIF zu erzeugen, was inakzeptabel langsam ist.
Wir haben ffmpeg als Demuxer und Piping für imagemagick verwendet. Durch mehrstündiges Experimentieren bin ich zu folgenden Schlussfolgerungen gekommen:
Die Anzahl der Eingaberahmen Sie ffmpeg Prozess fragen , ist bei weitem die meisten impactful Eingabe in Bezug auf die Ausführungsgeschwindigkeit. Wenn die Verwendung des Concat-Demuxers zum Überspringen von Eingaberahmen eine Option ist, macht dies den größten Leistungsunterschied aus. Bei jeder fünften Aufnahme konnte ich die Gesamtberechnungszeit auf 1 Minute und 45 Sekunden reduzieren, indem ich hochwertige Lanczos neu skalierte und die Palette pro Bild berechnete. Das Erstellen unseres Vorschaubilds mit 30 Bildern dauert jetzt weniger als 1 Sekunde .
Der Neuskalierungsalgorithmus war der zweitgrößte Leistungsfaktor (aber eine weit entfernte Sekunde). Die Verwendung von fast_bilinear anstelle von lanczos sparte über alle 15.000 Frames hinweg 150 Sekunden Rechenzeit.
Die Variable mit der geringsten Auswirkung war die Palettenberechnung, die mit dem Rescale-Algorithmus variiert wurde. Über 15.000 Frames mit Lanczos konnten wir etwa 17 Sekunden Ausführungszeit einsparen, wenn wir die Palettenberechnung eliminierten. Mit fast_bilinear konnten wir rund 75 Sekunden Ausführungszeit einsparen.
Da der Neuskalierungsalgorithmus und die Palettenberechnung vernachlässigbar waren, haben wir sie letztendlich auf höchstem Qualitätsniveau gehalten. Wir haben die Rechenzeit von 17 Minuten auf unter 1 Sekunde verkürzt, hauptsächlich, indem wir ffmpeg angewiesen haben, das Lesen von Eingabedateien zu überspringen.
KEY TAKEAWAY: SKIPPING INPUT FRAMES vs. SKIPPING OUTPUT FRAMES
Der Grund, warum unser Prozess so lange gedauert hat, ist, dass das Löschen von Frames die Ausführungszeit bei Verwendung des Image2-Demuxers nicht verkürzt. Wenn Sie mit dem
-r
Flag und demfps
Filter herumspielen, werden Sie die Anzahl der Bilder beeinflussen, die im endgültigen GIF erscheinen, aber ffmpeg scheint mit allen 15.000 Eingangsbildern noch etwas zu tun.Der einzige Weg, wie ich FFMPEG-Eingabeframes überspringen lassen kann, ist die Verwendung des
concat
Demuxers.So generiere ich jetzt auf meinem Entwicklungscomputer animierte GIF-Thumbnails in hoher Qualität in weniger als 1 Sekunde, indem ich Eingaberahmen überspringe:
quelle