code-video: Mit großen Sprachmodellen Code schreiben und erklärende Videos Frame für Frame zeichnen
Die Bilder werden nicht von einem Videomodell generiert oder gefilmt: Das Modell schreibt eine Webseite (Canvas / SVG / Three.js / WebGL),
die Seite legt __render(t) offen, das Skript erstellt Screenshots Frame für Frame und kodiert sie mit ffmpeg in MP4.
Der Vorteil ist reproduzierbar, modifizierbar, Text und Zahlen absolut genau, null Generierungskosten.
Der gesamte Ablauf besteht aus nur drei Schritten: Stil wählen → Prompt präzise formulieren → Testframes prüfen, korrigieren, dann volles Video rendern.
0. Vorbereitung (bei erster Nutzung)
cd <skill-Verzeichnis>
npm install # Playwright-Core installieren
npx playwright-core install chromium-headless-shell # oder CHROME=/pfad/zu/chrome setzen
# ffmpeg / ffprobe müssen im PATH sein; chinesische Schriftart empfehle: Noto Sans CJK (fonts-noto-cjk / noto-fonts-cjk)
pip install edge-tts numpy scipy # optional: Erzählung, Untertitel, Hintergrundmusik
1. Stil wählen: Der Stil folgt dem Thema
Zunächst prüfen, zu welcher Kategorie das Thema gehört, dann in references/styles/ die entsprechende Stildatei lesen (jede Datei enthält: für welche Themen geeignet,
Kurzprompt, vollständiger Prompt, Produktionsnotizen, Faktenquellen, Beispielquellcode in examples/<name>/).
| Thema | Zuerst probieren | Auch möglich |
|---|---|---|
| Anekdoten, historische Geschichten | Schattenfiguren piying | Pixel pixel, Comic comic |
| Kinderwissen, Naturwachstum | Bilderbuch picturebook | Flaches Mograph flatmg |
| Schriftzeichen, Artefakte, Dynastien | Hanzi-Entwicklung hanzi | Tuschemalerei ink |
| Routen, Gesandtschaften, Migrationen | Alte Karten oldmap | Isometrischer Ablauf isometric |
| Mechanische Strukturen, Produktzerlegung | 3D-Explosion explode3d | Whiteboard whiteboard |
| Arbeitsabläufe, Produktionslinien | Isometrischer Ablauf isometric | Flaches Mograph flatmg |
| Größe, Tiefe, Entfernung | Maßstab scale | Dateninfografik infographic |
| Zeiträume, Größenordnungen | Dateninfografik infographic | Maßstab scale |
| Theoreme, Formeln | Mathematikvisualisierung math | Strichzeichnung lineart |
| Einzelnes Prinzip, Kausalität | Whiteboard whiteboard | Strichzeichnung lineart |
| Slogans, Intro/Outro | Kinetic-Typografie kinetic | — |
Alle 16 Stile siehe references/styles/README.md. Wenn der Benutzer einen bestimmten Stil nennt, die entsprechende Datei direkt lesen.
2. Den Prompt präzise formulieren: Ein Satz gibt nur den Stil vor
Ein Ein-Satz-Prompt wie "Mach ein 10-Sekunden-Schattenfigurenstück" sagt dem Modell nur den Stil, nicht worum es geht, welche Zahlen verwendet werden, wie lange jeder Abschnitt dauert. Nach folgendem Gerüst vier Dinge klar beschreiben (die vollständigen Prompts in den Stildateien folgen diesem Aufbau):
Zeichne eine 1920×1080, 30fps, etwa 12 Sekunden lange „Stil“-Erklärungsanimation mit Canvas: Farbschema, Textur, Schriftart jeweils festlegen.
Das Thema ist „…“: Aufteilung in Szenen, jede Szene zeigt was, welcher Text auf dem Bildschirm erscheint, am Ende mit einem Satz auf den Punkt kommen.
Zu verwendende Zahlen: …, Quellen in notes.txt schreiben; unsichere Zahlen nicht auf die Einzelstelle genau angeben.
Jeder Frame wird nur durch die Zeit t bestimmt (keine Timer, Zufallszahlen mit festem Seed).
Zuerst 4–6 Frames prüfen, ob Untertitel groß genug, Labels überlappen oder außerhalb des Bildes liegen, korrigieren, dann volles Video rendern.
Zusätzlich die physikalischen/faktischen Regeln des Themas ergänzen, die falsch gezeichnet werden könnten. Beispiel: Bei der Geschichte von Cao Chong wiegt das Schiff nach Beladung, sonst stimmen Markierung und Wasserlinie nicht überein – ohne diese Regel zeichnet das Modell es falsch.
3. Seite schreiben: Verbindlicher Seitenvertrag
Jedes Video ein Verzeichnis <work>/<name>/, mindestens mit index.html, empfohlen auch prompt.txt (verwendeter Prompt)
und notes.txt (Quellen der Zahlen und Fakten). Von templates/canvas/index.html ausgehen.
- Seite fest 1920×1080,
overflow:hidden. - Muss diese Zeile enthalten (render.sh liest sie per Regex):
const FPS = 30, DUR = 12; window.__info = { fps: FPS, duration: DUR, frames: Math.round(FPS * DUR) };window.__render = t => { ...; return { seg: '<Szenenname>', tau: t.toFixed(2) }; }Jeder Frame nur durch t bestimmt: Kein CSS animation/transition, setTimeout, requestAnimationFrame,Date.now(),Math.random(); Zufall mit festem Seed (z. B. mulberry32); Partikel, Vibration, Physik müssen direkt aus t berechenbar sein, kein Zustand zwischen Frames.- Schriftarten und Ressourcen laden, dann
window.__ready = truesetzen (WebGL-Seiten nach erstem Frame-Rendering). - Kein externer Zugriff (das Frame-Skript blockiert alle externen Anfragen). Schriftarten systeminstalliert verwenden.
- Auf dem Handy lesbar: Textlabels ≥ 36px, Titel ≥ 64px, optional kleine Fußnote unten links.
- Three.js-Seiten:
scripts/fetch_three.sh <name>nach<name>/vendor/herunterladen, dann<script type="importmap">{ "imports": { "three": "./vendor/three.module.js", "three/addons/": "./vendor/jsm/" } }</script>; renderer mitpreserveDrawingBuffer: truesetzen, in__render(t)synchronrenderer.render()(oder composer) aufrufen.
Details und häufige Fallstricke siehe references/page-contract.md.
4. Erst Testframes dem Modell zeigen, korrigieren, dann volles Video rendern
scripts/render.sh <work>/<name> 30,120,210,300 # nur diese Frames -> <work>/_preview/<name>/
Mit einem Bildbetrachter einzeln durchgehen, nach dieser Checkliste Probleme suchen, korrigieren, dann erneut Testframes rendern (mindestens eine Iteration):
- Text: groß genug, keine Überlappungen, außerhalb des Bildes, verdeckt; chinesische Zeichen echte Schriftart (keine Tofublöcke).
- Fakten: Zahlen, Zeitangaben, Ortsnamen, Formeln auf dem Bild stimmen mit notes.txt überein; schematische Darstellungen mit „Schema“ kennzeichnen.
- Komposition: Hauptmotiv groß genug (Fernaufnahme Hauptfigur mindestens 1/4 der Bildhöhe), Bild nicht zu leer, Farbschema passend.
- Bewegung: Schlüsselbewegungen tatsächlich passiert (zwei benachbarte Frames vergleichen), Übergänge nicht ruckartig.
- WebGL: Keine schwarzen Blöcke/Flecken, Flackern.
Wenn okay, volles Video rendern:
scripts/render.sh <work>/<name> # -> <work>/<name>.mp4
N=8 scripts/render.sh <work>/<name> # parallele Frame-Prozesse (Standard min(6, Kernzahl/2))
GPU_ANGLE=vulkan scripts/render.sh ... # WebGL mit Grafikkarte (schneller, aber bei kontinuierlichem Framing können schwarze Flecken auftreten, vorher Testframes prüfen)
Codec automatisch: Wenn NVENC verfügbar, h264_nvenc, sonst libx264.
Frame-Rendering verbraucht hauptsächlich CPU; zeitaufwändigster Teil ist meist „Modell schreibt Seite, Screenshots ansehen, Code korrigieren“, nicht das Rendern selbst.
5. Optional: Erzählung, Untertitel, Hintergrundmusik, Vorschaubild
# Erzählung + Untertitel (Standard kostenloses edge-tts; gesamte Erzählung auf einmal synthetisieren, damit die Stimme konsistent ist)
python3 scripts/tts.py script.txt -o out/narration --voice zh-CN-YunyangNeural --rate -5%
# Hintergrundmusik: selbst synthetisieren (keine Urheberrechtsprobleme) oder lizenzfreie Musikbibliothek nutzen (siehe references/narration.md)
python3 scripts/chiptune.py out/bgm.wav 30 # 8-Bit-Chipmusik
python3 scripts/beat.py out/beat.wav --bpm 120 --beats 20 # Beat-Takte, auf Frames abgestimmt
# Zusammensetzen: Musik automatisch unter Stimme ducken, Lautstärke auf -16 LUFS normalisieren; --burn brennt Untertitel ins Bild
scripts/mux.sh out/<name>.mp4 out/<name>.final.mp4 --voice out/narration.mp3 --music out/bgm.wav --srt out/narration.srt --burn
# Vorschaubild / Coverframe
scripts/gif.sh out/<name>.mp4 2.5 4 # ab 2,5 Sekunden 4 Sekunden
scripts/gif.sh --poster out/<name>.mp4 6.0 # einen Frame als jpg extrahieren
Wenn Untertitel eingebrannt werden sollen, das untere Fünftel der Seite freilassen und keine eigenen Untertitel zeichnen (oder SUB_MARGIN=60 zum Anheben verwenden);
Ziel-Lautstärke -16 LUFS, bei hohen Spitzen der Stimme etwas niedriger (True-Peak-Limit -1,5 dBTP).
Optionen für Sound, eigene TTS-Integration, Takt-Anpassung siehe references/narration.md.
6. Mehrere Videos gleichzeitig erstellen (Stilvergleich, Serien)
Jedes Video ein eigenes Verzeichnis, ein eigener Prompt, unabhängig voneinander. Können mehreren Sub-Agenten parallel zum Schreiben und Selbstprüfen zugewiesen werden, der Hauptagent übernimmt nur das finale Rendern, Zusammenfügen und Prüfen. In der Anweisung an jeden Sub-Agenten klarstellen: Seitenvertrag, Verzeichnis-Konvention, Frame-Test-Checkliste, Fakten in notes.txt schreiben, nach Fertigstellung Dauer und Selbsteinschätzung melden.
Vor dem Erstellen erklären
- Zahlen zu Fakten müssen echt und überprüfbar sein; bei Nachrichten/neuen Themen nur öffentlich bekannte Informationen zeichnen, in der Ecke „Schema“ kennzeichnen.
- Zahlen aus Beispielen nicht als universelle Fakten wiederverwenden; bei Themenwechsel neu prüfen.
- Vom Modell generierte Musik (z. B. MusicGen-Gewichte) ist meist nicht kommerziell lizenziert; bei kommerzieller Veröffentlichung selbst synthetisierte oder klar lizenzierte Musik verwenden.