video-flow: Code-gestützter Workflow für universelle Erklärvideos
Ein Satz: Überlege zuerst, was genau vermittelt werden soll, verwandle diese Idee dann in eine berechenbare Zeitachse und lasse den Browser schließlich jeden Frame zeichnen. Endprodukt =
render(t)in Canvas/HTML + Headless Chrome-Screenshots + FFmpeg + optional TTS/Musik/Untertitel.
Dieses Skill zerlegt ein Video in 8 überprüfbare Phasen. Jede Phase liefert ein konkretes Ergebnis und hat einen Prüfpunkt; sollte ein Schritt nicht bestanden werden, darf der nächste nicht begonnen werden.
0. Wann verwenden / nicht verwenden
Verwenden:
- Aus einer PDF, PPT, DOCX, einem Artikel, einer Webseite, einem Video oder einem Thema ein 1–5-minütiges Erklärvideo erstellen.
- Benötigt ein Video, bei dem „Text klar, Daten genau, ein einzelner Frame änderbar und das Ganze reproduzierbar“ ist (struktureller Vorteil der Code-Renderung gegenüber Videogeneratoren).
- Mehrere Versionen im Hoch-/Quadrat-/Querformat oder in mehreren Sprachen benötigen.
- Sprachausgabe, Untertitel und Hintergrundmusik benötigen, wobei der gesamte Ablauf wiederholbar sein muss.
Nicht verwenden:
- Echte Personen/Realaufnahmen/fotorealistische Szenen benötigen → Videogenerator oder echte Aufnahmen verwenden; dieses Skill ist nur für die „Code-Ebene“ zuständig.
- Nur vorhandenes Material schneiden → Schnittprogramm/Agent verwenden.
- Einfach eine MP4 generieren wollen, ohne Storyboard und Text festzulegen → das Ergebnis wird schablonenhaft; zuerst Schritt 1–2 durchführen.
1. Harte Regeln (Verstoß führt zu Nacharbeit)
- Das Bild ist eine reine Funktion der Zeit: Die Seite stellt
window.render(t)bereit; bei gegebenemtist das Bild eindeutig bestimmt.- Verboten:
Date.now(), ungesäter Zufall, durchrequestAnimationFramegetriebene Zustände, CSStransition/animation, frameübergreifende Caches. - Akkumulierende Animationen (Partikel/Wasseroberfläche) mit fester Schrittweite von 0 bis
tschieben oder analytische Formel verwenden.
- Verboten:
- Die Zeitachse ist die einzige Quelle der Wahrheit: Storyboard, Sprachausgabe, Musik, Soundeffekte und Untertitel stammen alle aus derselben
timeline.json. - Erst Storyboard, dann Code: Ohne
storyboard.mdundscript.jsondarf kein Szenencode geschrieben werden. - Quelltexte nicht verfälschen: Zahlen, Jahreszahlen, Personennamen, Formeln müssen aus dem Quellmaterial stammen; bei Unsicherheit mit
[zu prüfen]markieren und bei Auslieferung separat auflisten. - Standardmäßig kein Branding/Wasserzeichen: Nur wenn der Nutzer ein Logo/einen Markennamen angibt; in der Fußzeile erscheint standardmäßig nur Kurs-/Themeninfo.
- Einmalige Codierung: Audio wird in der WAV-Phase gemischt und auf Lautstärke gebracht, die finale AAC-Codierung erfolgt nur einmal; vermeide wiederholtes Transcodieren.
- Vor der Auslieferung muss die Qualitätssicherung (QA) bestanden sein: Ausfallframes, schwarze Frames, Lautstärke, Dauer, Untertitel, Audio-Video-Synchronisation; siehe Schritt 8.
2. Eingabe und Ergebnisse
Eingabe (beliebig, gemischt möglich)
| Typ | Verarbeitung |
|---|---|
scripts/ingest.py extrahiert Text; bei Scans/Garstige automatische Rasterung in PNG, damit das Modell „die Seiten sehen“ kann. | |
| PPTX | Seitenweise Extraktion: Titel, Text, Notizen; optional Schlüsselseiten als Bilder exportieren. |
| DOCX / Markdown / TXT | Direkte Extraktion in source/source.md. |
| Webseiten-URL | Haupttext erfassen; Quellenlink behalten. |
| Video | ffprobe-Metadaten + gezielte Bildausgabe; ohne ASR wird der Inhalt manuell ergänzt. |
| Reines Thema | Ein Satz/eine Gliederung vom Nutzer; zuerst die „unbedingt zu nennenden Fakten“ vom Nutzer bestätigen lassen. |
Verzeichnisstruktur jedes Projekts
<project>/
project.json # Metainformationen: Titel/Zielgruppe/Ziel/Format/Stil/Stimme/Musik/Marke
source/ # Quellmaterialien (source.md, pages/*.png, meta.json)
storyboard.md # Storyboard-Tabelle: Jede Szene erklärt: Inhalt, Bild, Dauer, Sprechertext, Prüfpunkte
script.json # Maschinenlesbar: scenes[] (Typ/Text/Visuelles/Sprachausgabe/Dauer)
build/ # index.html + lib.js + theme.js + scenes.js + timeline.js
audio/ # vo/*.wav, bgm, mix.wav
frames/ # Frame-für-Frame JPEGs
out/ # final.mp4 / final.srt / poster.png
qa/ # report.md + Kontaktbögen + Stichprobenframes
Verwende scripts/init_project.py zum einmaligen Erstellen des Skeletts.
3. Workflow (8 Schritte)
Schritt 0: Umgebungsprüfung
python scripts/check_env.py
Erforderlich: Python 3.10+, FFmpeg/ffprobe, ein Chromium-basierter Browser, numpy/scipy.
Empfohlen: edge-tts (Online-Neurostimme), pypdf, python-pptx, python-docx, Pillow.
Fehlende Abhängigkeiten nach Anleitung installieren; falls nicht möglich, downgraden (ohne Sprachausgabe / Systemstimme / manuelle Audioaufnahme).
Schritt 1: Quellmaterial lesen und „Lehrstruktur“ extrahieren
Beantworte zuerst 5 Fragen (in project.json unter brief):
- Wer ist die Zielgruppe? Was können sie bereits?
- Was sollen sie nach dem Video sagen/tun können? (1–3 überprüfbare Ziele)
- Was ist der am leichtesten zu missverstehende/schwierigste Punkt?
- Welche Fakten/Formeln/Daten müssen vorkommen? Von wo stammen sie?
- Dauer und Format? Plattform (Unterricht/Handy/Soziale Medien)?
Nicht die ursprüngliche Seitenreihenfolge verwenden. Mit einer der 4 Strukturen aus references/storytelling.md neu organisieren:
- Kausalkette (empfohlen für Naturwissenschaften/Technik);
- Problem → Lösung → Validierung;
- Missverständnis → Korrektur → Transfer;
- Zeitstrahl/Prozess.
Schritt 2: Stil und Format festlegen
Wähle einen von 5 Stilen aus references/styles.md (silicon / paper / blueprint / neon / swiss) und bestimme das Format gemäß references/formats.md.
Regeln:
- Inhalt eher „Chip/Technik/Daten“ → silicon / blueprint;
- eher „Geisteswissenschaften/Biologie/Geschichte“ → paper;
- eher „Launch/Marketing/jung“ → neon / swiss;
- Ein Bildschirm zeigt nur eine Sache; Hochformat muss umgebrochen werden – nicht das Querformat zuschneiden.
Schritt 3: Storyboard und Skript schreiben
Erstelle storyboard.md (für Menschen) und script.json (für Maschinen). Jede Szene muss enthalten:
type(title/concept/process/compare/formula/bars/quote/recap/custom)kicker(Untertitel),headline(Ein-Satz-Fazit),points(≤3 Punkte)vo(Sprachausgabe, 1–2 Sätze; ohne Sprachausgabe leer lassen)visual(konkrete Daten für Diagramme/Flüsse/Formeln)duration(kann leer bleiben; wird automatisch anhand der Sprachdauer bestimmt)
5 harte Regeln für das Schreiben des Textes:
- Bildschirmtext ≠ Sprachtext: Auf dem Bildschirm nur Schlüsselwörter/Fazit; die Sprachausgabe erklärt.
- Maximal 1 Fazit + 3 unterstützende Punkte pro Bildschirm; Überschrift ≤ 18 Zeichen, Zeilen ≤ 22 Zeichen.
- Alle 2–4 Sekunden sollte eine Änderung erfolgen (Element/Kamera/Betonung), aber keine Partikelexplosion.
- Zuerst eine „Verbotsliste“ schreiben: Farbverlaufshintergrund + großer zentrierter Text, alle Elemente eingeblendet, winziger Vollbildtext, sinnlose Lichteffekte.
- Fakten separat mit Quelle kennzeichnen; Unsicheres mit
[zu prüfen]markieren.
Schritt 4: Sprachausgabe und Zeitachse erstellen
# Optional: Ohne Sprachausgabe überspringen, dann explizite duration für jede Szene schreiben
python scripts/tts.py --project . --voice zh-CN-XiaoxiaoNeural --rate +3%
python scripts/timeline.py --project .
tts.pygibtaudio/vo/<id>.wav(48 kHz) aus, mit leichtem EQ/Compressor; unterstützt--from-dirfür echte Aufnahmen.timeline.pygeneriert aus den gemessenen Sprachdauernbuild/timeline.jsundtimeline.json:scene.duration = head + voDuration + tail; Szenen ohne Sprachausgabe verwenden eine expliziteduration.- Danach nur
script.jsonändern und diese beiden Schritte erneut ausführen; nicht die Timeline von Hand bearbeiten.
Schritt 5: Seite aufbauen und Szenen implementieren
Mit der Vorlage:
python scripts/init_project.py --dir my-video --title "..." --format 16:9 --style silicon
# Bearbeite build/content: wird von timeline.py generiert; universelle Szenen bereits implementiert, nur script.json ändern
- Universelle Szenen (8 Typen) in
build/scenes.js, lesenCONTENTund rendern; reichen für die meisten Erklärvideos. - Für spezielle Grafiken (Chip/Schaltkreis/Anatomie/Karte/Molekül)
build/custom.jsschreiben:Setze denwindow.CUSTOM['s3'] = function(u, D, sc, ctx){ /* mit den Hilfsfunktionen aus lib.js zeichnen */ };typedieser Szene inscript.jsonaufcustom. - Immer nur eine Szene bearbeiten: Zuerst 3 Standbilder rendern (
scripts/render.py --still 1.2,2.4,3.6), auf Textüberlauf/Überschneidung/Größe der Hauptelemente prüfen, dann weitermachen.
Schritt 6: Rendern
python scripts/render.py --project . --fps 30
# Nur einen bestimmten Abschnitt: --start 8 --duration 4
# Vorhandenes Chrome wiederverwenden: --cdp http://127.0.0.1:9333
# Skript Chrome starten lassen: --launch-chrome
Ausgabe: frames/f00000.jpg...; kann unterbrochen und fortgesetzt werden (vorhandene Frames > 2 KB werden übersprungen).
Headless Chrome und Sandbox: Wenn die Ausführungsumgebung Chrome-IPC/Pipes verbietet, muss in einer erlaubten Umgebung ausgeführt werden oder
--cdpverwenden, um eine Verbindung zu einem bereits gestarteten Chrome herzustellen.
Schritt 7: Musik, Soundeffekte, Mischung, Untertitel
python scripts/audio.py --project . # BGM synthetisieren + Sprachausgabe + Ducking + Mastering
python scripts/srt.py --project . # out/final.srt generieren
- Ohne Sprachausgabe:
audio.py --no-bgmoder nur vom Nutzer bereitgestellte Musik verwenden. - Nutzer stellt Musik bereit: In
audio/music.*ablegen,audio.pyloopt/schneidet automatisch und duckt. - Ziellautstärke: Standard −14.2 LUFS, True Peak ≤ −1.5 dBFS; Audio nur einmal codieren.
Schritt 8: Codierung + QA + Auslieferung
python scripts/encode.py --project . # frames+mix+srt → out/final.mp4
python scripts/qa.py --project . # qa/report.md + Stichprobenframes-Collage
Die QA muss vollständig bestanden sein (siehe references/qa.md):
- Dauer/Format/Bildrate/Audiospur/Untertitel korrekt;
- Keine schwarzen Frames ≥ 0,25 s; Stichprobenframes ohne Leerraum/Überlappungen/Überlauf;
- Lautstärke im Ziel ±1 LU, True Peak ≤ −1.5 dBFS;
- Erster Frame nicht rein schwarz; letzte Szene hat einen Abschluss;
- Faktenliste stimmt mit Quellmaterial überein;
[zu prüfen]-Einträge separat aufgeführt.
Auslieferung: out/final.mp4, out/final.srt, poster.png, storyboard.md, script.json, qa/report.md, Renderzeit und bekannte Mängel.
4. Universelle Szenentypen (Vorlage bereits implementiert)
| Typ | Verwendung | Schlüsselfelder |
|---|---|---|
title | Anfang/Kapitel | title/subtitle/kicker |
concept | Ein Konzept + 3 Punkte | headline/points/visual |
process | Ablauf/Schritte (3–5 Schritte) | steps[] |
compare | Zweiseitiger Vergleich | left/right |
formula | Formel + Erklärung | formula/notes[] |
bars | Datenvergleich | items[{label,value}] |
quote | Zitat/Fazit | quote/author |
recap | Zusammenfassungslandkarte | nodes[]/takeaway |
custom | Spezielle Grafik | Eigene custom.js |
Wenn ein neuer Typ benötigt wird: In scenes.js ein window.SCENES_IMPL['type'] hinzufügen und den Datenvertrag in references/pipeline.md dokumentieren.
5. Formate und Sicherheitszonen
| Format | Auflösung | Sicherheitszone | Titel-Schriftgröße | Text-Schriftgröße |
|---|---|---|---|---|
| 16:9 | 1920×1080 | L/R 96 / O/U 64 | 72–120 | 28–40 |
| 9:16 | 1080×1920 | L/R 64 / O/U 160 | 64–96 | 32–44 |
| 1:1 | 1080×1080 | Rundum 72 | 56–88 | 28–40 |
| 4:5 | 1080×1350 | Rundum 80 | 60–92 | 30–42 |
Hochformat muss umgebrochen werden: Titel oben, Grafik mitte, Fazit unten; nicht horizontales Querformat stauchen. Die Vorlage verwendet layout() entsprechend des Formats; siehe references/formats.md.
6. Häufige Fehler → Lösungen
| Phänomen | Grund | Lösung |
|---|---|---|
| Schwarzer/weißer Bildschirm | JS-Fehler, render nicht definiert, Canvas-Größe 0 | render.py --still, Konsole prüfen; Canvas explizit Höhe/Breite zuweisen |
| Falsche Schrift / Fallback-Schrift im ersten Frame | Schrift geladen | Auf document.fonts.ready warten, dann READY=true setzen; CJK mit System-Fallback-String |
| Gleiches t liefert zweimal unterschiedlich / Flimmern parallel | rAF/Timer/Zufall/Frame-übergreifender Zustand verwendet | Reine Funktion; hash(seed); geschlossene Feder |
| Textüberlappung/Überlauf | Keine Einzelszenen-Standbildprüfung | 3 Standbilder pro Szene + Hochformat-Stichproben mit 360 px Breite |
| Audio-Video-Synchronisation | Audio von 0 begonnen vs. Video mit Start; TTS Satz für Satz | Gleiche Timeline; gesamte TTS; -ss vor -i setzen |
| Lautstärkeschwankungen | Mehrmaliges loudnorm/Transcodieren | Nur in WAV-Phase statische Verstärkung; einmal AAC |
| Rendern zu langsam | 4K/Subframes/Pinsel/WebGL | Zuerst 960×540-Vorschau; Subframes nur für schnelle Bewegungen; parallele Worker |
| Chrome startet nicht | Sandbox-Einschränkungen von IPC/Pipes | In erlaubter Umgebung ausführen oder --cdp verwenden, um vorhandenen Chrome zu nutzen |
7. Erweiterungspunkte
- Neuer Stil:
templates/styles/*.jsonkopieren, Farbpalette/Schrift/Hintergrundtyp ändern; instyles.mdeinen Eintrag ergänzen. - Neue Szene: In
build/scenes.jsregistrieren; oder inbuild/custom.jsspezielle Grafiken schreiben. - Echte Sprachaufnahme: Aufnahmen als
<scene-id>.wavinaudio/vo_human/ablegen,tts.py --from-dirführt nur Resampling/leichte Bearbeitung durch. - Mehrsprachigkeit: Ein
script.<lang>.json+ entsprechende TTS-Stimme; die Zeitachse kann denselben Bildsatz wiederverwenden (Textlängenunterschiede beachten). - Mehrere Formate: Gleiche
script.jsonmit anderemproject.formaterneut init/render; Layout wird durchlayout()angepasst. - Branding:
project.json.brandstellt Logo-Text/-Farbe/-Fußzeile; standardmäßig deaktiviert.
8. Referenzdokumentation
references/pipeline.md: Vollständige technische Pipeline,render(t)-Vertrag, CDP-Rendering, FFmpeg-Parameter, Zeitachsen-Datenmodell.references/inputs.md: Extraktion aus PDF/PPT/DOCX/URL/Video und OCR-Fallback.references/storytelling.md: 4 Unterrichtsstrukturen, Rhythmustabelle, Textregeln.references/styles.md: Farbpaletten/Schriften/Animationen/geeignete Themen der 5 Stile.references/formats.md: Formate, Sicherheitszonen, Umbrechungsregeln für Hochformat.references/audio.md: TTS-Optionen, echte Aufnahmen, Musikmischung, Ducking, Lautstärke, einmalige Codierung.references/qa.md: Prüfliste und automatisierte Prüfbefehle.