In meinem kürzlichen Post über mein kleines PeerPressure-Kunstprojekt habe ich ja versprochen, dass noch ein Video kommt. Das kommt jetzt auch. Vorher aber ein paar kleine Anmerkungen dazu.
…
Meine Güte war es schwierig, die Videodatei klein zu halten. Aber fange ich mal vorne an.
Änderungen am Ablauf
Beim letzten Mal hatte ich ja etwa 100.000 Rechenschritte gemacht. Ich habe das Programm danach erweitert und eine Obergrenze bei einer Million gesetzt, wobei das Programm vorzeitig abbrechen sollte, wenn nur noch eine Farbe auf dem Spielfeld ist (weil sich dann nichts mehr verändert). Außerdem habe ich nur noch von jedem 10. Schritt ein Bild abgespeichert.
Wann (ob?) dieser vorzeitige Abbruchpunkt erreicht ist, ist unterschiedlich. Ich habe mich am Ende für einen Durchlauf entschieden, wo nach weniger als 428.240 Schritten abgebrochen wurde. Ich hatte also 42825 Bilder. Und damit kommen wir zum Encoding.
Video-Encoding-Herausforderungen
Letztes Mal hatte ich eine WEBM-Datei mit VP9 als Encoding verwendet. Das hatte zwei Probleme: Erstens hat es mit dem Ecndoing ewig gedauert, zweitens gab es hinterher bei der Darstellung ganz scheußliche Kompressionsartefakte.
Also habe ich es mit MP4 als container unf H.264 als Encoding versucht. Das ging deutlich schneller, hatte kaum Kompressionsartefakte, aber die Datei war am Ende für etwa eine Stunde Laufzeit 1.1 GiB groß (1.5 GiB mit H.264). Habe ich erwähnt, dass die Auflösung 240p ist, als nur 426×240 Pixel? Zum Vergleich: Die rohen Bilddateien (PNG) waren nur weniger als 400 MiB groß. Wo soll ich denn bitte so ein Monster hochladen?
Ich vermute mal, dass das an den scharfen Kanten und den zufälligen Änderungen zwischen den Kanten lag. Also habe ich mal ausprobiert, die Bilder vorher zu glätten. Ein 3×3 Gaußfilter, so dass alles viel unschärfer aussieht. Man kann die einzelnen Zellen kaum noch erkennen, aber vielleicht sieht es ja trotzdem gut aus. Und die Kompressionsartefakte sollten auch nicht mehr so ins Gewicht fallen.

Das Ergebnis war super: Die Videodatei (MP4, H.264) war nur noch 223 MiB groß. Immer noch ziemlich groß, aber schon deutlich besser. Mit VP9 wurde das Video in diesem Fall gröer als H.264. Nur: Das ist natürlich immer noch zu groß für Pixelfed, Youtube will ich eigentlich vermeiden, und für PeerTube brauche ich erst einmal noch ein bisschen Zeit, weil die Instanz meiner Wahl meinen Accountantrag erst prüfen will.
Also kommt jetzt erst einmal nur ein kurzes, dafür aber nicht geglättetes Video auf Pixelfed.
Update, 2026-02-16: Hier kommt das geglättete Video auf Peertube. Unglücklicherweise sind dort beim Umcodieren doch wieder einige extreme Kompressionsartefakte eingefügt worden. Ich habe auch noch ein bisschen herumprobiert: H.265 wäre hier tatsächlich kleiner, allerdings sieht man deutlich ein paar Kompressionsartefakte (wenn auch nicht so schlimm wie auf der Peertube-Version. Und ein APNG, also eine animierte PNG-Datei (ungeglättet) ist noch kleiner und sogar verlustfrei (ich habe es aber nur mit 1000 Frames getestet). Aber eine APNG ist undhandlich, weil sie von Browsern wie eine Bilddatei und nicht wie ein Video behandelt wird. Also bleibt mir nur die Version mit Kompressionsartefakten. Mein nächstes Projekt wird wieder leichter komprimierbar sein, versprochen!
Statistik
Hatte ich erwähnt, dass ich auch mit jedem Bild abgespeichert habe, wie viele schwarze Pixel es im Bild gibt? Daraus habe ich dann für den Durchlauf, aus dem das Video oben stammt, eine Grafik gemacht:
Bonus: Wie glätte ich tausende Bilder?
Eigentlich geht das Glätten eines Bildes mit imagemagick ganz einfach (Warnung: mogrify überschreibt das Eingabebild. Verwendet convert, wenn ihr eine veränderte Kopie erstellen wollt):
mogrify -gaussian-blur 3x3 image.png
Oder mehr als 3x3, wenn man es stärker glätten möchte. Mehrere Dateien sind dann eigentlich ganz einfach:
mogrify -gaussian-blur 3x3 *.png
Hier gibt es aber ein Problem: in Bash wird der Wildcard-Operator * von der Shell ausgewertet und dann eine Liste von Dateinamenn and das Programm gegeben. Irgendwo ist aber mit der Anzahl der Dateinamen Schluss. Wenn man 100.000 Bilder hat, passiert, kriegt man den Fehler Argument list too long.
Manche Programme erlauben es, als Input ein Verzeichnis anzugeben. mogrify nicht, zumindest habe ich keine Möglichkeit dazu gefunden. Also habe ich einen Workaround genutzt:
find . -name '*.png' -execdir mogrify -gaussian-blur 3x3 {} \;
Das sucht alle Dateien, die mit .png enden im aktuellen Verzeichnis und ruft drauf den mogrify-Befehl auf. Nachteil: Der Befehl wird sehr oft aufgerufen, das erzeugt einen Overhead. Stattdessen kann man auch folgendes machen:
find . -name '*.png' -execdir mogrify -gaussian-blur 3x3 {} \+
Das ruft den Unterbefehl mit langen, aber nicht zu langen Listen von Treffern auf, so dass ein Mittelweg gefunden ist.