Communitygithub.com

Synthetische UI-Demos

Produkt-Demos und Release-Notes-Videos ohne Bildschirmaufnahme. Baue die App-Bildschirme als statisches React aus dem Quellcode nach und steuere sie in Remotion mit einem skriptgesteuerten Cursor und einer Kamera.

Was ist Synthetische UI-Demos?

Dieses Skill ermöglicht es, hochwertige Produkt-Walkthroughs, Feature-Demos, Release-Notes- oder Changelog-Videos zu erstellen, ohne auf Bildschirmaufnahmen oder flaky Playwright-Aufzeichnungen angewiesen zu sein. Stattdessen liest Claude Code das Repository des Produkts, rekonstruiert die benötigten Bildschirme als statisches React auf einer festen Leinwand (Standard 1440×810) und lässt einen skriptgesteuerten Cursor und eine Kamera die Abläufe in Remotion ausführen. Die Cursor-Pfade, Klicks und Kamerabewegungen sind als Frame-Konstanten definiert, sodass eine Szene jedes Mal identisch gerendert wird – ohne echte Konten, Live-Umgebungen oder Testdaten. Das Skill wird durch Cursor-Pfade, Kamerabewegungen und Audio-Anker gesteuert; jede Aktion ist an ein gesprochenes Wort gebunden (cue-System). Die erstellten Szenen können durch Code-Bearbeitung aktualisiert werden, wenn sich das Produkt ändert. Plattformen: Claude Code, Remotion. Es eignet sich besonders für Release-Notes, die mehrfach wiederverwendet werden, sowie für Szenarien, in denen echte Daten oder Live-Umgebungen nicht verfügbar sind.

Funktioniert mit✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/digitalsamba/claude-code-video-toolkit/tree/HEAD/.claude/skills/synthetic-ui-demo

In Ihrer bevorzugten KI fragen

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

Dokumentation

Was macht Synthetische UI-Demos?

Nichts wird per Bildschirmaufnahme erstellt. Claude Code liest das Repository des Produkts, baut nur die Bildschirme einer Szene als statisches React nach, und ein skriptgesteuerter Cursor und eine Kamera führen den Ablauf in Remotion aus. Jeder Klick ist eine Framenummer, sodass eine Szene identisch neu gerendert wird, nie ein eingeloggtes Konto oder eine Live-Umgebung benötigt und durch Bearbeiten des Codes aktualisiert wird, wenn sich das Produkt ändert.

Referenz-Builds (parallel zu diesem Skill lesen; beide bauen ohne die Produkt-Repos):

  • examples/ds-free-schedule-demo: ein 26-Sekunden-Ablauf (Termin planen) mit einer Sprecher-Kachel. Der einfachste vollständige Fall. Seine src/Demo.tsx ist eine einzelne Timeline mit jedem Cursor-Keyframe, Klick und jeder Kamerabewegung.
  • examples/ds-release-649: ein 80-Sekunden-Release-Notes-Video, acht Szenen über drei Apps. templates/ds-release-notes ist die wiederverwendbare Form davon (ausgeliefert als Release 650). src/Release.tsx sequenziert die Szenen, src/scenes/ enthält eine Datei pro Release-Element, und src/room/ und src/ac/ sind die Bildschirm-Kits.

Wann dies statt Playwright verwenden

Synthetisch (dieses Skill)Playwright-Aufzeichnung (/record-demo)
Du kannst den Quellcode der App lesenDu hast nur die laufende App
Release Notes und Feature-Touren, die pro Release neu gemacht werdenEinmalige Aufnahme von echtem Verhalten oder echten Daten
Der Ablauf benötigt Daten, die du nicht hast (ein kompletter Anruf, andere Benutzer, eine Admin-Ansicht)Das echte Ding ist leicht erreichbar und sieht so aus wie es ist
Kamerabewegungen, exaktes Klick-Timing, Neurendering nach einer SprachänderungLange, komplexe Interaktionen, deren Nachbau aufwändig wäre

Bausteine (lib/components)

import { Stage, typed, cursorAt, near } from '../../../../lib/components';

<Stage
  url="app.example.com/settings"             // Adressleiste; Host dunkler als Pfad
  camera={CAMERA}                             // [{ f, z, x, y }] in Canvas-Px, eased, auf das Fenster begrenzt
  path={PATH}                                 // [{ f, x, y }] Cursor-Keyframes in Canvas-Px
  clicks={CLICKS}                             // Frames, die den Cursor zusammendrücken und eine Welle auslösen
  aiNote                                      // "Die gezeigten Personen sind KI-generiert" (oder eigener Text)
  canvasWidth={1440} canvasHeight={810}       // die Standardwerte
>
  <SettingsScreen field={typed(frame, 'Q4 Produktbewertung', 128)} />
</Stage>
  • Stage zeichnet einen Browser-Chrome um eine feste App-Leinwand, wendet die Kamera an und platziert den Cursor darüber bei zIndex 100. Bei Zoom 1 ist das Fenster fit (0,8625) der Framebreite. Keyframes wiederholen einen Wert, um ihn zu halten.
  • Cursor und cursorAt funktionieren auch eigenständig für eine Nicht-Browser-Szene; near(cursor, target) steuert Hover-Zustände.
  • Produktspezifische Bildschirm-Kits (Theme, Icons, Layouts) bleiben im Projekt. Sie sind kein Lib-Material.

Methode

1. Ein visuelles Spezifikation aus dem App-Repo ziehen, mit Unteragenten

Sende einen Unteragenten pro App oder Bereich parallel und lasse jeden eine kompakte Spezifikation statt Datei-Dumps zurückgeben:

  • Theme: Palette, Schriftstapel, Radien, Abstände, Schatten (aus der Theme-Datei oder CSS-Variablen).
  • Strings: die exakten deutschen Locale-Strings für jedes Label, Menüelement, Dialog und Toast, das die Szene zeigt (public/locales/en/*.json, src/i18n/locales/en/*). UI-Text niemals paraphrasieren.
  • Icons: Wenn die App eine Icon-Schriftart verwendet, enthält ihre Icomoon/Fontello selection.json die SVG-Pfade jedes Glyphen. Extrahiere die benötigten in ein kleines JSON und rendere sie als <svg><path d="...">. Kopiere andernfalls die SVG-Komponenten.
  • Layout und Verhalten: Komponentenbaum für die gezeigten Bildschirme, Toolbar-Reihenfolge, Standardwerte, was jedes Steuerelement tut.

Lese den Standard-Branch vom Remote (git show origin/main:path, oder git fetch dann origin/<default> lesen). Lokale Checkouts sind oft veraltet und zeigen die UI des letzten Quartals.

Bei Release Notes verfolge jedes Element bis zum Commit und der Komponente zurück, die es zuerst ausliefert. Das liefert die exakten Strings und die Standardwerte, die gezeigt werden sollen.

2. Nur das nachbauen, was eine Szene zeigt, auf einer festen Leinwand

  • Platziere jedes Element mit absoluten Positionen auf einer festen Leinwand (1440x810 ist ein guter Standard). Exportiere die relevanten Rechtecke als Konstanten (SAVE_BTN = { x, y, w, h }), damit Klickziele arithmetisch sind, nicht geraten.
  • Baue nur das, was die Kamera sieht. Ein Panel, das nie im Bild ist, kann eine einfarbige Fläche sein.
  • Halte es statisch React: kein State, keine Effekte. Jede visuelle Änderung ist eine Funktion von frame.
  • Lege das Kit in einem eigenen Ordner (src/ui/, src/room/) mit einer theme.ts für Konstanten.

3. Sprache zuerst, dann die Timeline in Frames setzen

  • Schreibe eine Zeile pro Szene, an Satzgrenzen geteilt (eine .txt pro Phrase), und generiere zuerst das Audio (voiceover.py --scene-dir ...). Drei Aufnahmen und tools/pick_takes.py schlagen eine einzelne Aufnahme plus --max-wpm: ein Klon kopiert das Tempo und die Flachheit des Referenzclips. Wenn die Zeilen also gehetzt oder monoton klingen, korrigiere den Clip mit tools/voice_prosody.py expand, anstatt das Ausgabe zu dehnen (siehe "Clone Prosody" in CLAUDE.md). Lies die gemessenen Dauern, und tools/captions.py für Wort-Zeitangaben.
  • Messe jede Szene an ihrer Zeile plus einem Beat und behalte einen Header-Kommentar, der den Start und die Länge jeder Zeile auflistet. Dieser Kommentar ist die Quelle der Wahrheit (siehe "Audio-Anchored Timelines" in CLAUDE.md).
  • Alles ist eine Frame-Konstante am Anfang der Szenendatei: Cursor-Keyframes, CLICKS, Kamera-Keyframes, UI-State-Wechsel (frame >= C.save zeigt den Dialog). Exportiere die Klick-Frames, damit das Elternteil Klick-SFX platzieren kann.
  • Suche die Frames aus der Erzählung, setze sie nicht von Hand. voice() (lib/components/cues.ts; die ds-release-notes-Vorlage hat eine Kopie) nimmt die Phrasen der Szene mit ihren .captions.json und Start-Frames entgegen, und cue('save') gibt den Frame zurück, an dem das Wort beginnt. Verankere jede Aktion an dem Wort, das sie veranschaulicht, mit einem Offset, und jeden Cursor- und Kamera-Keyframe an diesen Ankern:
    import line06a from '../../public/audio/scenes/06a_link.captions.json';
    export const LINK_VOICE = voice([{ file: '06a_link', at: 10, captions: line06a }, ...]);
    const { cue } = LINK_VOICE;
    const C = { field: cue('before', { offset: -3 }), save: cue('save') };
    const PATH = [{ f: C.field - 6, ...field }, { f: C.save - 24, ...saveBtn }];
    
    Regeneriere oder verschiebe eine Phrase, und die Klicks, das Tippen, der Cursor und die Kamera folgen ihr. Ein Cue, dessen Wörter nicht mehr gesprochen werden, lässt den Build mit den betreffenden Wörtern fehlschlagen. Optionen: offset, edge: 'end', after (ein Frame, für ein wiederholtes Wort), nth, in (eine Phrase). Das Elternteil platziert das Audio aus LINK_VOICE.lines, sodass der Start-Frame einer Phrase einmal geschrieben wird. templates/ds-release-notes/src/scenes/FreeCustomLink.tsx ist das ausgearbeitete Beispiel.

4. Dichte Listenzeilen an ihren Pausen teilen

Eine Zeile, die mehrere Dinge auflistet ("Terminplanung, Kontakte, Aufzeichnungen und Transkripte"), ist für eine einzige Einstellung zu schnell. Teile das Audio an seinen Pausen in Phrasen-Dateien (07a, 07b, ...), gib jeder Phrase ihre eigene Einstellung und platziere jede Phrase auf ihrem eigenen Beat. ds-release-649's moreVo-Feld tut dies.

5. Klickziele aus einem Kontaktbogen vor dem vollständigen Render messen

Eine geratene Koordinate liegt nach dem Zoomen der Kamera meist 20-50 Pixel daneben. Rendere Standbilder bei jedem Klick-Frame und ein paar Frames davor, kachel sie zusammen und überprüfe, ob die Cursor-Spitze auf dem Ziel sitzt:

i=1; for f in 46 78 122 212; do npx remotion still MyComp out/stills/s$i.png --frame=$f; i=$((i+1)); done
ffmpeg -start_number 1 -i out/stills/s%d.png -vf "scale=640:-1,tile=2x2" -frames:v 1 out/contact.png

Korrigiere die Konstanten, rendere die Standbilder neu und erst dann rendere das Video.

6. KI-generierte Personen auf dem Bildschirm kennzeichnen

Jede Person, die nicht real ist (FLUX.2-Porträts in Kacheln, Avatare, eine Sprecherin) erhält ein sichtbares Label: aiNote auf dem Stage oder ein "KI"-Abzeichen auf einer Sprecher-Kachel. Namen, Kontakte und Anrufdaten sind ebenfalls erfunden, also halte sie deutlich als fiktiv erkennbar.

7. Rendern, dann normalisieren

tools/qc.py --project ... vor dem Rendern, dann qc.py --render out/video.mp4 --fix für -14 LUFS. qc.py --project ... --layout prüft den eigenen Text des Videos (Untertitel, Karten, die KI-Notiz) auf Größe und Kontrast und listet die UI des Produkts separat auf. Stage markiert sein Fenster mit data-qc="product"; setze dasselbe Attribut auf jeden Telefon- oder Tablet-Mockup, den du außerhalb baust, sonst wird sein UI-Text als Teil des Videos beurteilt.

Fallstricke

  • Monochrom-SVG-Logos werden schwarz gerendert. Ein logo_mono.svg hat normalerweise schwarze Füllungen; auf dunklem Hintergrund verwende filter: brightness(0) invert(1).
  • Veraltete lokale Branches. Lese origin/<default>, nicht den Branch, auf dem der lokale Checkout gerade ist.
  • rsync --exclude src verwirft auch node_modules/*/src. Beim Kopieren eines Projekts oder Kits verankere Ausschlüsse am Übertragungsstamm mit einem führenden Schrägstrich: --exclude /src.
  • Die Kamera wird begrenzt. Ein Kamerazentrum nahe der Canvas-Kante wird nach innen gezogen, damit der Fensterrand niemals über den Frame hinausragt. Wenn ein Zoom an einer unerwarteten Stelle landet, liegt es daran; ziele auf einen weiter innen liegenden Punkt.
  • Menüs und Dialoge müssen innerhalb der Leinwand sitzen. Die Leinwand schneidet ihre Kinder zu. Positioniere ein Menü so, dass es nach innen öffnet, wie die echte App es tut.
  • Hover-Zustände kommen vom Cursor-Pfad. Verwende near(cursorAt(frame, PATH), target) anstelle eines zweiten Satzes von Frame-Konstanten, damit das Verschieben eines Keyframes den Hover mit verschiebt.
  • Eine geänderte Sprachzeile verschiebt alles danach. In einer gecue-ten Szene folgen Klicks, Cursor und Kamera von selbst, aber die Szenenlänge und die at der späteren Phrasen müssen noch überprüft werden. In einer von Hand gesetzten Szene musst du jeden Frame neu messen. In jedem Fall den Header-Kommentar und die Szenenlängen aktualisieren, dann Klick-Standbilder erneut prüfen. Wenn das Lippen-synchrone eines Sprechers von der zusammengestellten Sprachspur gesteuert wird, generiere es ebenfalls neu.
  • Ein Kit überlebt seine Demo. Ein nachgebautes Bildschirm-Kit kann andere Videos hosten: Der Raum von ds-release-649 wurde zur Bühne einer Parodie-Kurzversion einer Markenedition, mit animierten Gesichtern in seinen Kacheln und keiner neuen Bildschirmarbeit. Kopiere das Kit in das neue Projekt und skaliere seine logische Leinwand auf den Frame (.claude/skills/parody-short/formats.md).

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

digitalsamba/claude-code-video-toolkit

Python video composition with moviepy 2.x — overlaying deterministic text on AI-generated video (LTX-2, SadTalker), compositing clips, single-file build.py video projects. Use when adding labels/captions/lower-thirds to LTX-2 or SadTalker outputs, building short ad-style spots in pure Python without Remotion, or doing programmatic video composition. Triggers include text overlay on video, label LTX-2 clip, caption SadTalker output, lower third, build.py video, moviepy, Python video composition, sub-30s ad spot.

digitalsamba/claude-code-video-toolkit

Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.

digitalsamba/ideogram4

Prompting patterns for Ideogram 4 text-to-image — best-in-class in-image text rendering and exact color/layout control via structured JSON captions. Use when generating images that need legible on-image text (title cards, thumbnails, logos, signage, CTAs), precise brand colors, or controlled spatial layout. Triggers include title slide image, thumbnail with text, on-image text, legible text in image, brand color palette image, bounding-box layout, Ideogram.

digitalsamba/parody-short

Comedy shorts about a group's own life - a team's launch, quarter end, office move or leaving do; a club's season; a class's year; a family's Christmas - or about a shared topic everyone recognises (video calls, the return to the office), told in a borrowed genre (80s action intro, creature feature, Dickens Christmas ad, heist, nature documentary) and starring the group's real, animated photos or an invented cast. Covers mining the group's own context for in-jokes (chat, email, calendars,...

Verwandte Skills