Ich hatte die Aufgabe, die Zeit zu verkürzen, die benötigt wurde, um ein animiertes GIF so nahe wie möglich an 30 Frames bei 150 Pixel Breite zu erzeugen. Die meisten von uns generierten Sequenzen liegen unter 1000 Frames. Wir hatten eine 15.000-Frame-Sequenz und unsere Render-Knoten brauchten 17 Minuten, um dieses GIF mit 30 Frames zu erzeugen, was inakzeptabel langsam ist.
Wir haben ffmpeg als Demuxer und Pipe zum Imagemagick benutzt. Durch mehrere Stunden des Experimentierens 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 Sie den concat Demuxer zum Überspringen von Eingabebildern verwenden, wird dies den größten Leistungsunterschied bewirken. Mit jedem fünften Frame konnte ich die Gesamtberechnungszeit auf 1 Minute 45 Sekunden reduzieren, indem Sie die Lanczos mit hoher Qualität skalieren und die Palette pro Frame berechnen. Die Erstellung eines Vorschaubildes mit 30 Bildern dauert nun weniger als 1 Sekunde .
Der Algorithmus für die Neuskalierung war der nächstgrößere Performance-Impaktor (jedoch eine weit entfernte Sekunde). Die Verwendung von fast_bilinear anstelle von lanczos sparte bei allen 15.000 Frames 150 Sekunden Rechenzeit.
Die am wenigsten beeinflussbare Variable war die Palettenberechnung, und diese variierte mit dem Algorithmus für die Neuskalierung. Bei mehr als 15.000 Frames mit lanczos haben wir etwa 17 Sekunden Ausführungszeit eingespart, wenn die Palettenberechnung entfällt. Mit fast_bilinear haben wir rund 75 Sekunden Ausführungszeit eingespart.
Da der Algorithmus für die Neuskalierung und die Palettenberechnung vernachlässigbar waren, haben wir sie auf höchstem Niveau gehalten. Wir haben unsere Rechenzeit von 17 Minuten auf unter 1 Sekunde reduziert, meistens, indem wir ffmpeg mitteilten, das Lesen von Eingabedateien zu überspringen.
KEY TAKEAWAY: EINGEBAUTE SKIFE vs SPIELAUSGABEN
Der Grund, warum unser Prozess so lange gedauert hat, ist, dass der Frame-Drop beim Ausführen des image2-Demuxers nicht zur Ausführungszeit beiträgt. Wenn Sie das -r
Flag und den fps
Filter verwenden, wirkt sich dies auf die Anzahl der Frames aus, die in der endgültigen GIF-Datei angezeigt werden, aber ffmpeg scheint immer noch mit allen 15.000 Eingaberahmen zu tun.
Die einzige Möglichkeit, die Eingabemasken von ffmpeg zu überspringen, ist der concat
Demuxer.
So generiere ich jetzt in weniger als einer Sekunde animierte GIF-Miniaturbilder auf meiner Entwicklungsmaschine, indem ich Eingabefelder überspringe:
# create text file which describes the ~30 input frames we want ffmpeg to process seq -f "file 'left_frames.%04g.jpg'" 10000 500 25000 > tmp.txt # generate the animated gif using ffmpeg only ffmpeg -f concat -i tmp.txt -filter_complex "scale=150:-1:flags=lanczos,split=2 [a][b]; [a] palettegen [pal]; [b] fifo [b]; [b] [pal] paletteuse" output.gif