Communitygithub.com

lladbet/video-erklärvideo-skill

Erstelle erklärende Videos (MP4), indem du animierte 2D-Szenen in HTML/SVG/CSS mit GSAP schreibst und sie Frame für Frame mit Headless-Chromium + ffmpeg renderst. Verwende dies, wenn der Benutzer nach einem Erklärvideo, einer animierten Erklärung, einem Motion-Graphics-Clip oder einem animierten Diagramm/Chart als Video fragt. Nicht für generative/AI-Videos oder die Bearbeitung vorhandenen Filmmaterials.

Was ist video-erklärvideo-skill?

Dieser Skill ermöglicht es KI-Agenten, erklärende Videos im Motion-Design-Stil zu erstellen, indem sie jede Szene als JavaScript-Modul mit DOM/SVG und GSAP-Animationen definieren, die dann Frame für Frame mit Headless-Chromium und ffmpeg gerendert werden. Der Workflow beginnt mit einem Storyboard (video.json), gefolgt vom Erstellen der Szenenmodule in scenes/<id>.js, optionaler Sprachausgabe über das OpenRouter MCP, einer Lint-Prüfung, einer Vorschau als Kontaktbogen und schließlich dem Rendern des finalen MP4-Videos. Der Skill unterstützt die Plattformen Claude Code und andere KI-Agenten, die Node.js, Chromium und ffmpeg ausführen können. Er eignet sich für technische Erklärvideos, animierte Diagramme und Code-Demonstrationen und sorgt für deterministische, reproduzierbare Ergebnisse ohne Echtzeit-Abhängigkeiten.

Funktioniert mit~Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/lleadbet/video-explainer-skill/tree/HEAD

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Video-Erklärer

Du erstellst Videos so, wie ein Motion-Designer es tun würde, aber in Code: Jede Szene ist ein kleines JS-Modul, das DOM/SVG aufbaut und Tweens zu einer pausierten GSAP-Timeline hinzufügt. Der Renderer fährt die Timeline Frame für Frame ab (t = frame / fps), erstellt Screenshots von jedem Frame und leitet die Frames an ffmpeg weiter. Die Ausgabe ist deterministisch: Das gleiche Projekt rendert immer die gleichen Frames.

SKILL_DIR unten bezeichnet das Basisverzeichnis dieses Skills (der Ordner, der diese Datei enthält).

Einrichtung (einmal pro Maschine)

cd SKILL_DIR/scripts && npm install && npx playwright install chromium

Zudem muss ffmpeg im PATH verfügbar sein. Jedes Skript gibt diesen Befehl aus, wenn die Abhängigkeiten fehlen.

Arbeitsablauf

  1. Storyboard zuerst. Stimme Thema, Zielgruppe, Ziellänge und ob es eine Sprachausgabe geben soll ab, dann schreibe die Szenenliste in video.json. Jede Szene erhält narration (was die Sprachausgabe sagt) und visual (was auf dem Bildschirm zu sehen ist). Lies reference/storyboard.md. Schreibe keinen Szenencode, bevor das Storyboard für sich allein sinnvoll ist.
  2. Gerüst: node SKILL_DIR/scripts/new.mjs <projekt-verz> --title "...", dann bearbeite video.json und schreibe ein Modul pro Szene in scenes/<id>.js. Verwende reference/animation-patterns.md für Rezepte und reference/design.md für Layout, Typografie und Farbe. Mit einer Sprachausgabe setze die Szenendauer auf "auto" und animiere mit cue('phrase'). Beide Beispiele sind vollständige Videos mit Sprachausgabe: examples/kubernetes-overview/ (ElevenLabs) und examples/how-dns-works/ (Gemini).
  3. Sprachausgabe (falls gewünscht): folge reference/voiceover.md. Kurz gefasst: Füge einen "voice"-Block in video.json ein, führe node SKILL_DIR/scripts/narration.mjs status <projekt-verz> aus, rufe das OpenRouter-MCP-Tool generate-speech einmal pro aufgeführter Szene mit genau den Argumenten auf, die es ausgibt, und registriere jede gespeicherte Datei mit narration.mjs add. Führe dies vor der Überprüfung (Schritt 4) durch, da echte Audiodateien die Szenenlängen und cue()-Zeitpunkte ändern.
  4. Überprüfen: node SKILL_DIR/scripts/lint.mjs <projekt-verz>. Es lädt jede Szene in Chromium und meldet Ladefehler, Animationen länger als ihre Szene, Animationen, die außerhalb von tl erstellt wurden, Elemente außerhalb des Rahmens, abgeschnittenen Text und eine zu lange Erzählung für ihre Szene. Behebe jede Warnung, sofern sie nicht beabsichtigt ist.
  5. Ansehen: node SKILL_DIR/scripts/render.mjs <projekt-verz> --contact-sheet, dann lies das PNG (<projekt-verz>/out/contact-sheet.png). Überprüfe Hierarchie, Überlappungen, Lesbarkeit, leere Frames und Timing. Für Details rendere bestimmte Momente: --stills 12.5,30. Iteriere, bis es richtig aussieht, und führe nach deiner letzten Bearbeitung einen weiteren Kontaktbogen-Durchlauf durch.
  6. Rendern: node SKILL_DIR/scripts/render.mjs <projekt-verz> → <projekt-verz>/out/video.mp4. Erzählclips werden automatisch eingemischt. Gib dem Benutzer den Pfad, die Dauer und die Szenenliste. Sie können interaktiv eine Vorschau anzeigen mit node SKILL_DIR/scripts/serve.mjs <projekt-verz> (Scrubber, Abspielen/Pause, Erzählwiedergabe, c schaltet Untertitel um, m stumm).

Nützliche Render-Flags: --out datei.mp4, --from 10 --to 20 (teilweise), --scale 0.5 (schneller Entwurf), --workers N, --crf 18, --audio track.mp3 (eigene Tonspur anstelle der Erzählung verwenden), --no-voice (stumm), --audio-codec aac (Standard ist MP3, das auch in VS Code abgespielt wird).

Projektstruktur

mein-video/
  video.json          # Titel, Breite, Höhe, fps, Seed, Übergang, Thema, Szenen[]
  scenes/<id>.js      # ein Modul pro Szene
  assets/             # Bilder/SVGs, referenziert als '/assets/x.svg'
  audio/              # Erzählclips + manifest.json (von narration.mjs; behalte sie, sie kosten Geld)
  style.css           # optional, wird automatisch geladen, falls vorhanden
  out/                # Renderings (contact-sheet.png, stills/, video.mp4)

video.json Szenenfelder: id (erforderlich, auch der Standard-Dateiname scenes/<id>.js), duration (Sekunden oder "auto": passt sich der Erzähl-Audio an oder einem Schätzlese-Tempo vor Audio-Erstellung und nie kürzer als die Animationen), narration, visual, optionales file und optionales transition ("fade", der Standard, oder "cut"). Der "voice"-Block auf oberster Ebene wird in reference/voiceover.md beschrieben.

Szenenvertrag

import { h, reveal, pop } from '/__runtime/helpers.js';

export default function ({ el, tl, gsap, theme, width, height, random, onFrame, cue, voice }) {
  const title = h('div', { class: 'h1' }, 'Hallo');
  el.append(h('div', { class: 'center' }, title));
  reveal(tl, title, { at: 0.3 });                       // tl-Zeit 0 = Start dieser Szene
  tl.to(title, { color: 'var(--accent)', duration: 0.5 }, cue('die Schlüsselidee'));  // wenn diese Phrase gesprochen wird
}
  • el: Der Container dieser Szene. Er bedeckt die gesamte 1920×1080-Bühne und wird für dich ein- und ausgeblendet.
  • tl: Die Timeline dieser Szene. Alle Bewegungen müssen auf tl stattfinden (oder einer anderen zu tl hinzugefügten Timeline). Verwende niemals gsap.to(...) direkt, CSS animation/transition, setTimeout, setInterval, requestAnimationFrame, <video> oder irgendetwas, das von der Echtzeituhr abhängt. Der Renderer bewegt nur den Abspielkopf der Timeline, daher bleibt alles andere im MP4 eingefroren oder aus dem Takt geraten.
  • cue(phrase, offset = -0.15) gibt die Szenenzeit zurück, zu der phrase (Groß-/Kleinschreibung, muss in der Erzählung dieser Szene vorkommen) gesprochen wird. Sobald Audio vorhanden ist, wird es an den gemessenen Pausen des Clips ausgerichtet, so dass Sätze, die einen Satz beginnen, auf dem gesprochenen Wort landen. Es wirft einen Fehler, wenn die Phrase nicht gefunden wird. Verwende es für jeden mit der Erzählung synchronisierten at. voice gibt { start, duration, end, estimated } für die Sprache in dieser Szene (z.B. um einen Schleifeneffekt bis voice.end laufen zu lassen).
  • Für Frame-für-Frame-Zeichnungen (Canvas, prozedurale Bewegungen) verwende onFrame((sceneTime) => draw(sceneTime)). Es wird in jedem Frame aufgerufen, während die Szene sichtbar ist.
  • Overlay (optional): "overlay": "scenes/_overlay.js" in video.json fügt ein Modul hinzu, das für das gesamte Video über jeder Szene gezeichnet wird, z.B. für einen Zeitcode, Fortschrittsbalken, Logo oder Bildrahmen. Es erhält { el, tl, onFrame, scenes, duration, ... }, wobei onFrame((t) => ...) die globale Zeit erhält und scenes die start/end-Werte jeder Szene auflistet.
  • random() ist pro Szene gesetzt, und auch Math.random ist gesetzt, so dass zufällige Layouts reproduzierbar sind.
  • Die Funktion kann async sein (z.B. um fetch('/assets/data.json') zu verwenden). Schriftarten werden vor der Szenenausführung geladen, so dass Textmessungen funktionieren.
  • Themenfarben sind CSS-Variablen: var(--bg) --surface --surface2 --fg --muted --accent --accent2 --accent3 --accent4 --danger, plus --font und --mono. Überschreibe sie in video.json → "theme": { "accent": "#ff3366" }.
  • GSAP-Plugins sind global registriert: DrawSVG, MotionPath, MorphSVG, SplitText, Text, ScrambleText, CustomEase.

Qualitätsanspruch

  • Eine Idee pro Szene. Auf dem Bildschirm sollte sich mindestens alle 2–3 Sekunden etwas bewegen oder ändern, und jede Animation sollte synchron mit der Erzählzeile landen, die sie illustriert (verwende cue(); Erzählung läuft mit ~2,5 Wörtern/Sekunde).
  • Text ist groß: Textkörper ≥ 40px und Beschriftungen ≥ 26px auf der 1920×1080-Bühne. Halte ihn innerhalb des sicheren Bereichs (.safe, 96/128px Ränder).
  • Baue Diagramme Stück für Stück auf, anstatt ein fertiges Diagramm zu zeigen.
  • Lasse am Ende jeder Szene eine kurze Pause vor dem Ausblenden, damit der Endzustand gelesen werden kann.

Sprachausgabe

Audio kommt vom OpenRouter MCP-Server (generate-speech); dieser Skill plant und zeichnet es nur auf. Wenn diese Tools nicht verfügbar sind, teile dem Benutzer mit, dass die Sprachausgabe die Verbindung zum OpenRouter MCP-Server benötigt, und rendere vorerst ohne Sprachausgabe. reference/voiceover.md enthält das vollständige Verfahren, die Modell- und Sprachauswahl sowie die Kosten.

Verwandte Skills