project-demo-video
Erstelle das Demo-Video als Code, damit es nach Änderungen in Minuten neu gerendert werden kann. Alles auf dem Bildschirm ist echt: die laufende Anwendung, die tatsächliche Terminal-Ausgabe, die echten Quelldateien. Nichts ist ein Mock-up.
Dieses Skill wurde so geschrieben, dass ein weniger leistungsfähiger Code-Agent es Schritt für Schritt befolgen kann. Folgen Sie den Phasen in der angegebenen Reihenfolge. Jede Phase hat eine Erledigt, wenn-Zeile: fahren Sie erst fort, wenn diese Bedingung erfüllt ist. Kopieren Sie Dateien aus templates/, anstatt sie neu zu schreiben.
Installation: Kopieren Sie den gesamten Ordner (SKILL.md und templates/) in den Skills-Ordner des Agenten, z. B. ~/.claude/skills/project-demo-video/, oder verweisen Sie den Agenten einfach auf SKILL.md.
Was Sie produzieren
| Ausgabe | Hinweise |
|---|---|
<name>-voiced.mp4 | 1920x1080, 30 fps, H.264 + AAC, Untertitel eingebrannt, mit Stimme |
<name>-captions-only.mp4 | gleiches Bild, stille Audiospur (der Benutzer kann diese wählen oder seine eigene Stimme aufnehmen) |
<name>.srt | Untertitel als Datei, gleicher Text wie die Erzählung |
thumbnail.png | 1280x720 |
narration.md, shotlist.md | Skript mit echten Zeitstempeln; jede Szene mit ihrer Quelle |
frames/ | die QA-Frames, die Sie tatsächlich angesehen haben |
repo/ | geänderte oder neue Projektdateien, gespiegelt in ihren Repository-Pfaden |
COPY_LIST.md, README-snippet.md, REPORT.md | Was wohin kopieren, ein „See it work“-README-Abschnitt, was erledigt ist und was riskant ist |
0. Regeln, die Sie nicht brechen dürfen
- Nur-Lesen-Quelle. Schreiben Sie niemals in, committen Sie niemals in oder pushen Sie von den echten Repositorys des Benutzers. Arbeiten Sie in einer Kopie (
robocopy/cp, unter Ausschluss vonnode_modules,.git, Build-Ausgabe), führen Sie dannnpm cidort aus. Bewahren Sie erhaltenswerte Änderungen im Ausgabeordner auf, gespiegelt in Repository-Pfaden, plusCOPY_LIST.md. Ein anderes Tool oder eine andere Person erledigt die Git-Arbeit. - Seien Sie ehrlich auf dem Bildschirm. Alles, was simuliert ist (ein Gerät, ein Connector, eine Zahlung, ein Modell), wird im Video als simuliert gekennzeichnet. Implizieren Sie niemals Hardware, Bereitstellungen oder Benutzer, die nicht existieren. Kopieren Sie die eigene Tabelle des Projekts „echt vs. simuliert“; wenn das README falsch ist, sagen Sie dies im Bericht und wiederholen Sie die Behauptung nicht.
- Keine Geheimnisse auf dem Bildschirm oder in Dateien, die Sie ausliefern: Tokens, API-Schlüssel,
.env-Inhalte, private Schlüssel, echte E-Mails. Entwicklungs-Tokens, die das Projekt dokumentiert (z. B.Bearer dev-alice), sind in Ordnung. Wenn Sie Code zeigen, wählen Sie Zeilenbereiche, die Geheimnisse ausschließen. - Keine Erwähnung des KI-Tools, das den Code geschrieben hat, oder seines Anbieters in Frames, Erzählung, Untertiteln oder ausgelieferten Dokumenten, es sei denn, der Benutzer sagt etwas anderes. Eine Laufzeit-Modell-ID, die Teil der Produktkonfiguration ist, kann als Modellname erscheinen. Überprüfen Sie dies mit
grep -ri, bevor Sie fertig sind. - Beachten Sie die Wettbewerbsregeln. Lesen Sie die Längenbegrenzung (normalerweise „weniger als 3:00“; zielen Sie auf 2:50) und die Regel zur erforderlichen Technologie. Das Video muss zeigen, dass die erforderliche Technologie tatsächlich läuft, und sie nicht nur erwähnen.
- Kostenloser Tarif, keine Bereitstellungen, keine Käufe. Stellen Sie keine Cloud-Ressourcen bereit, erstellen Sie keine oder geben Sie kein Geld aus. Wenn ein Schritt einen Credential oder eine Aufzeichnung vom Benutzer erfordert, fragen Sie einmal, deutlich, und fahren Sie mit allem anderen fort.
- Fragen Sie den Benutzer nur nach Credentials, seinen eigenen Aufzeichnungen oder einer Wahl, die wirklich seine ist (z. B. welche Stimme). Entscheiden Sie alles andere selbst und sagen Sie, was Sie entschieden haben.
1. Voraussetzungen (überprüfen, nicht annehmen)
node --version # 22+ (24 empfohlen; .mjs-Dateien müssen einfaches JavaScript sein, keine TypeScript-Casts)
- In der Projektkopie:
@playwright/test(mit installiertem Chromium) undffmpeg-staticmüssen vorhanden sein. Überprüfen Sie:node -e "import('@playwright/test').then(async m=>{const b=await m.chromium.launch();console.log(b.version());await b.close()})"undnode -e "import('ffmpeg-static').then(m=>console.log(m.default))". Wenn sie fehlen und das Projekt neue Abhängigkeiten verbietet, legen Sie sie in einem separaten Tools-Ordner ab und verweisen Sie darauf. - Sprache: Windows PowerShell mit
System.Speech(integriert). Verwenden Sie auf macOSsay, auf Linuxespeak-ng; dann müssen Sietemplates/lib/tts.mjsanpassen (nursynthAllundtts.ps1sind betriebssystemspezifisch). ffprobewird nicht mit ffmpeg-static ausgeliefert: Messen Sie Dauern aus WAV-Headern (wavSecondsintemplates/lib/tts.mjs) und aus der eigenen Zeitsteuerung des Recorders.- Windows-Shell-Hinweise: Bevorzugen Sie die Write- und Edit-Tools für Dateien, die Backslashes, Regexes oder
$enthalten. Inlinepython -c/heredoc-Umschreibung von JS beschädigt stillschweigend Escapes. Vordergrund-sleepist in einigen Agenten blockiert: Warten Sie mituntil grep -q "done" log; do sleep 10; done.
2. Phasen
Phase A: Anforderungen und Nachweiskarte
Lesen Sie die Regelseite, das README, die eigenen Dokumente des Projekts und etwaige Storyline-Notizen. Schreiben Sie eine Tabelle in Ihre Notizen:
| Der Richter muss überzeugt sein, dass | Wo das Video es beweist | Szene |
|---|---|---|
| die erforderliche Technologie im Code aufgerufen wird | echter Aufruf sichtbar: Anfragenprotokoll, Terminal, Codeauszug | ... |
| die Erfahrung funktioniert | Anwendung läuft in einem Browser | ... |
| was echt vs. simuliert ist | die eigene Tabelle des Projekts | ... |
Erledigt, wenn jede Zeile eine Szene hat.
Phase B: Arbeitsbereich
- Kopieren Sie das Repo in einen Scratch-Ordner, installieren Sie dann:
npm ci. - Kopieren Sie
templates/in die Kopie alsvideo/(behalten Sie die Struktur bei:video/lib,video/pages,video/scenes,video/final.mjs,video/narration.mjs, ...). Fügen Sie zupackage.json-Skripten hinzu:"video:final": "node video/final.mjs". Fügen Sie keine Abhängigkeiten hinzu. - Fügen Sie
video/out/zur.gitignorein der Kopie hinzu.
Phase C: Trockentest der echten Anwendung und Fehlerjagd (tun Sie dies, bevor Sie etwas aufnehmen)
Starten Sie die Anwendung so, wie ein Richter es tun würde (npm run demo oder der README-Befehl) auf ihrem dokumentierten Standard-Port, damit jeder auf dem Bildschirm gezeigte Befehl wörtlich ist. Treiben Sie sie mit einem kleinen Playwright-Skript an, machen Sie Screenshots bei 1920x1080 nach jedem Schritt der Geschichte und sehen Sie sie sich an. Überprüfen Sie:
- Anmeldung, leere Panels, rote Fehlerbanner, Konsolenfehler;
- jeder Zustand, den die Geschichte benötigt, wird tatsächlich gerendert (der erste Lauf des Referenzprojekts zeigte eine fehlgeschlagene Anmeldung, einen leeren Posteingang und eine fehlende Schlüsselansicht, alle versteckt durch einen alten Videoentwurf);
- Text dupliziert oder abgeschnitten.
Beheben Sie echte Fehler in der Kopie, minimal, führen Sie die eigenen Prüfungen des Projekts durch (npm run verify, Tests, Typprüfung) und notieren Sie jede Behebung für COPY_LIST.md. Wenn die Anwendung keine Möglichkeit hat, den Netzwerkverkehr zu zeigen, fügen Sie einen kleinen optionalen Hook (ein Anfragenprotokoll) hinzu, anstatt einen zu fälschen.
Erledigt, wenn die gesamte Geschichte zweimal hintereinander sauber läuft und die Prüfungen des Projekts bestehen.
Phase D: Storyboard und Erzählung
- Wählen Sie Szenen. Referenzgeschichte (ca. 2:50):
| Szene | Länge | Zeigt |
|---|---|---|
| Hook | 12 s | Eine Änderung wirkt sich auf mehrere Commitments aus (animierte Karte) |
| Boot | 6 s | Der eine Befehl, der alles startet, echte Ausgabe |
| Sim (die App) | 60 s | 8-10 Beats; Anfragenprotokoll bei 2 Beats geöffnet |
| Beweis-Terminal(s) | 17-30 s | Offizieller Client oder CLI gegen denselben Server; Auth-Prüfungen |
| Code-Tour | 16 s | 3-4 echte Auszüge, die die erforderliche Technologie beweisen |
| Architektur, Cloud-Stack, echt vs. simuliert | 30 s | Diagramm, Stack-Quelle, Ehrlichkeitstabelle, Open-Source-Karte |
| Schluss | 12 s | Tagline, Repo-Links, Build-Credits, „X ist simuliert“-Footer |
- Schreiben Sie
video/narration.mjs:scenes = [{ id, title, segs: [{ id, text }] }]. Jedersegist eine gesprochene Zeile und ein Untertitel (textwird wörtlich angezeigt). Regeln: ca. 2,4 Wörter pro Sekunde; insgesamt 330-380 gesprochene Wörter; eine Idee pro Zeile; nicht mehr als ca. 12 Wörter auf einer Bildschirmkarte; Satzfall; keine Übertreibungen. - Fügen Sie Aussprachehinweise in der
say-Tabelle für die Sprach-Engine hinzu (Akronyme buchstabieren, „Alexa+“ als „Alexa plus“); ändern Sie niemals den Untertiteltext. Erledigt, wenn die Erzählung sich wie eine Geschichte liest, die ein Fremder versteht, und jede Zeile der Nachweiskarte gesprochen oder gezeigt wird.
Phase E: Vorlagen anpassen
Bearbeiten Sie nur das Projektspezifische:
| Datei | Bearbeitung |
|---|---|
video/narration.mjs | Ihre Szenen und Zeilen |
video/scenes/sim.mjs | Die Schritte Ihrer App: was eingeben oder klicken, Selektoren, die Kamera-Zooms (lens(...), zoomWire) |
video/scenes/static.mjs | Terminal-Befehle (CMD), codeBlocks (Datei + Regex der ersten Zeile + Zeilenanzahl + Hervorhebungs-Regexes), Hook/Close-Seitenaufrufe |
video/proofs.mjs, video/proof-auth.mjs | Die echten Befehle, die Ihre Behauptungen beweisen; sie geben nur Statuscodes und Fehlernamen aus |
video/pages/*.html | Text, Farben, Kacheln, Diagramm-Boxen, Tabellenzeilen, Links |
video/lib/overlay.mjs | SIM_CSS-Selektoren für das Layout Ihrer App (siehe Layout-Regeln), die Datenquelle des Tickers |
video/final.mjs | Die LIMIT-Konstante und Szenenreihenfolge (Reihenfolge kommt von narration.mjs) |
video/thumbnail.mjs, video/docs.mjs | Titel und die SHOT-Tabelle |
Bearbeiten Sie nicht lib/recorder.mjs, lib/director.mjs, lib/tts.*, es sei denn, etwas ist defekt.
Phase F: Echte Beweisausgabe erfassen
node video/proofs.mjs startet einen neuen Server, führt die echten Befehle aus (offizieller Inspector oder Client-CLI, Auth-Prüfungen, Installations-/Boot-Ausgabe) und speichert das, was sie ausgegeben haben, in video/out/proofs.json. Die Terminal-Szenen spielen diese erfasste Ausgabe in einem HTML-Terminal in lesbarer Größe ab. Regeln: Zeigen Sie den echten Befehlstext (kürzen Sie nur den Paketpfad); kürzen Sie sehr lange Ausgaben sichtbar (eine gedimmte „... N Zeilen ...“-Zeile) und setzen Sie „Aufgezeichneter Lauf“ in den Chip; geben Sie niemals Tokens aus; pretty-printen Sie JSON und sagen Sie dies, wenn Sie es tun.
Phase G: Erzählungsaudio
Standard (kein Konto erforderlich): node video/final.mjs --rate 2 erstellt ein WAV pro Zeile mit der integrierten Windows-Stimme (Microsoft Zira) und misst jede Länge. Rate 1 entspricht etwa 150 s Sprache für das Referenzskript, Rate 2 etwa 139 s, Rate 3 ist zu schnell. Wählen Sie die langsamste Rate, die das gesamte Video unter dem Limit hält.
Optionale menschlich klingende Stimme: siehe Anhang A. Alles unten funktioniert mit beiden gleich.
Phase H: Aufnehmen und zusammenstellen
node video/final.mjs --rate 2 # alles: TTS, Beweise, alle Szenen aufnehmen, beide Schnitte zusammenstellen
node video/final.mjs --rate 2 --reuse-proofs # Beweise nicht erneut ausführen
node video/final.mjs --scenes sim,close --reuse-tts --reuse-proofs # nur einige Szenen neu aufnehmen
node video/final.mjs --assemble-only # neu muxen (Untertitel, Audio) ohne erneute Aufnahme
node video/final.mjs --tts-dir video/out/tts-human --name my_video --single # aus einem anderen Audio-Ordner bauen
Ein vollständiger Lauf dauert 6-10 Minuten; führen Sie ihn im Hintergrund aus und fragen Sie das Log ab. Das Skript schlägt fehl, wenn die Gesamtzeit 180 s oder mehr beträgt. Zielen Sie auf 170 s.
Wichtig: Wenn Sie den Erzählungstext oder die Stimme ändern, ändern sich die Dauern, daher muss jede Szene neu aufgenommen werden (die Markierungen stammen von den Dauern). Wenn Sie nur die Bilder einer Szene ändern, bedeutet dies --scenes <id> --reuse-tts.
Phase I: Qualitätssicherung (niemals überspringen, niemals dem Log vertrauen)
- Extrahieren Sie Frames am Ende jeder Erzählungszeile aus dem endgültigen MP4:
ffmpeg -ss <markEnd-0.3> -i final.mp4 -frames:v 1 frame.png(die Timeline befindet sich invideo/out/timeline.json). Sehen Sie sie sich an. Überprüfen Sie Lesbarkeit bei 1080p, leeren Raum, abgeschnittenen Text, Position und Größe der Untertitel, Synchronisation (das Untertitel-Ereignis ist auf dem Bildschirm), keine Geheimnisse, keine Anbietererwähnung, Vorhandensein von Ehrlichkeitskennzeichnungen. ffmpeg -i final.mp4 -af volumedetect -f null -: Mittelwert etwa -22 dB, Maximum unter 0 dB.- Dauer unter dem Limit in beiden Schnitten; beide Dateien haben einen Video- und einen Audiostream.
grep -ril "<Anbieterwörter>" video/pages video/narration.mjs <Ausgabedokumente>gibt nichts zurück außer einer erlaubten Modell-ID.- Führen Sie die Prüfungen des Projekts erneut durch (
npm run verify; E2E, wenn die UI geändert wurde). - Beheben und neu rendern, bis alle bestehen.
Phase J: Liefergegenstände
Generieren Sie narration.md und shotlist.md mit node video/docs.mjs <outdir> (echte Zeitstempel). Kopieren Sie die MP4s, SRT, Thumbnail (node video/thumbnail.mjs <png>), die QA-Frames und die geänderten Repo-Dateien (alle unterschiedlichen Dateien zwischen dem Original und Ihrer Kopie, in ihren Repo-Pfaden). Schreiben Sie COPY_LIST.md (Fehlerbehebungen zuerst, dann neue Dateien, vorgeschlagene Commit-Nachrichten, „führen Sie Build und Überprüfung nach dem Kopieren aus“), README-snippet.md (Befehl ausführen, Einstiegspunkt-Datei:Zeile, Client-Datei:Zeile, Skill-Datei, Video-Link-Platzhalter) und REPORT.md (erledigt, was der Benutzer tun muss, Risiken). Sagen Sie klar, was Sie nicht überprüfen konnten (z. B. konnten Sie die Stimme nicht hören).
3. Wie die Pipeline funktioniert (lesen Sie dies, bevor Sie sie ändern)
Recorder (lib/recorder.mjs). Playwrights eigenes recordVideo begrenzt die Bitrate und macht kleine Texte unscharf, daher verwendet dieses Chromium-Screencast: JPEG-Frames (Qualität 92) werden gestempelt, wenn sie ankommen, auf die Festplatte geschrieben und mit konstanten 30 fps mit libx264 crf 17 codiert. Statische Bildschirme erzeugen wenige Frames; der letzte Frame wird gehalten. Zeitstempel stammen von einer Uhr (performance.timeOrigin + performance.now()), derselben, die der Director verwendet.
Director (lib/director.mjs). Jede Erzählungszeile ist ein Segment. d.seg(id, actions, {tail}) zeichnet die Startzeit auf, führt die Aktionen auf dem Bildschirm aus und hält dann, bis die Zeile fertig abgespielt ist, plus tail * 0,45 Sekunden (Enden werden global beschnitten, um das Limit einzuhalten). Die Markierungen (id, Start, Ende, Text) werden in video/out/<szene>.marks.json gespeichert. Da Audio später an den aufgezeichneten Markierungen platziert wird, können Bild und Stimme nicht driften. Regel für einen Beat: Führen Sie die Aktion innerhalb des Segments aus und stellen Sie sicher, dass die Aktion beendet ist, bevor die Erzählung endet; wenn die Zeile kürzer als die Aktion ist, teilen Sie sie in zwei Zeilen auf (deshalb wurde aus einem Story-Beat sim9 und sim10).
Audio (final.mjs). Jedes WAV wird mit adelay auf seinen globalen Start verzögert, mit amix=normalize=0 gemischt, mit alimiter begrenzt und mit apad=whole_dur=<gesamt> aufgefüllt (ohne das Pad schneidet -shortest das Ende des Videos ab).
Untertitel. Cues sind der Erzählungstext, aufgeteilt an Satzenden (Dezimalzahlen wie „2.0“ sind geschützt) und an Kommas, wenn über 82 Zeichen, mit Zeitaufteilung proportional zur Länge. Die .srt wird ausgeliefert. Die eingebrannte Version verwendet eine generierte ASS-Datei mit PlayResX: 1920, PlayResY: 1080 und Schriftgröße 36. Brennen Sie kein SRT mit force_style ein: libass skaliert es gegen eine 288 Pixel hohe Leinwand und der Text kommt etwa viermal zu groß heraus.
Overlay (lib/overlay.mjs), das nur in die aufgezeichnete App-Seite eingefügt wird (die App selbst wird nicht editiert), fügt hinzu: Ticker-Logos (USB/Cloud/Client), Wahrheitsindikatoren („Echt“, „Simuliert“, „Aufgezeichnet“), Code-Tooltips, Maus-Click-Feedback und Anbieterabspann. Das Overlay ist während der Aufnahme interaktiv (es kann über einen WebSocket mit director.mjs kommunizieren, um z. B. den Ticker zu aktualisieren).
Thumbnail (lib/thumbnail.mjs). Erzeugt ein 1280x720 PNG aus einem bestimmten Frame des endgültigen Videos, beschriftet mit dem Projekttitel und einem Untertitel.
Dokumente (lib/docs.mjs). Liest timeline.json und die .marks.json-Dateien und schreibt narration.md und shotlist.md mit tatsächlichen Zeitstempeln.
4. Layout-Regeln für die App-Seite
- Die App muss in einem Container mit
width: 1920px; height: 1080px; overflow: hidden;laufen. - Der Director erwartet, dass die App bei
top: 0; left: 0;beginnt. - Der Recorder erfasst den gesamten Viewport des Browsers; stellen Sie sicher, dass die App den gesamten Bildschirm ausfüllt.
- Wenn die App scrollt, verwenden Sie
overflow: autound stellen Sie sicher, dass der Inhalt in den 1920x1080 passt. - Verwenden Sie relative Einheiten (
%,vw,vh) für die Schriftgröße, um die Skalierung zu handhaben. - Testen Sie die App bei 1920x1080, bevor Sie mit der Aufnahme beginnen.
5. Fehlerbehebung
| Problem | Lösung |
|---|---|
ffmpeg nicht gefunden | Installieren Sie ffmpeg-static und führen Sie node -e "import('ffmpeg-static').then(m=>console.log(m.default))" aus, um den Pfad zu erhalten, und setzen Sie die Umgebungsvariable FFMPEG_PATH auf diesen Pfad. |
| Kein Audio in der Ausgabe | Stellen Sie sicher, dass die TTS-Dateien im Ordner video/out/tts vorhanden sind. Führen Sie node video/final.mjs --tts-dir video/out/tts aus. |
| Untertitel erscheinen zu groß | Verwenden Sie die ASS-Datei (generiert von final.mjs) anstatt SRT mit force_style. |
| Das Video ist zu lang | Kürzen Sie den Text oder erhöhen Sie die Vortragsrate (--rate 3). Das Skript schlägt fehl, wenn die Gesamtzeit >= 180 s beträgt. |
| App startet nicht | Überprüfen Sie die Node-Version, Abhängigkeiten und Port-Konflikte. Führen Sie node -e "..." aus, um die Umgebung zu testen. |
Anhang A: Optionale menschliche Stimme (ElevenLabs)
- Installieren Sie
elevenlabs-ttsim Kopierordner:npm install elevenlabs-tts. - Setzen Sie die Umgebungsvariable
ELEVENLABS_API_KEYauf Ihren API-Schlüssel. - Führen Sie
node video/final.mjs --rate 1 --voice elevenlabsaus (Rate 1 wird empfohlen, da ElevenLabs natürlich klingt, aber langsamer ist). - Die Stimme wird heruntergeladen und zwischengespeichert; Sie können sie mit
--reuse-ttswiederverwenden.
Anhang B: Plattform-spezifische Hinweise
Windows
- Standard-Sprach-Engine ist
System.Speech. Stellen Sie sicher, dass PowerShell verfügbar ist. - Verwenden Sie
WriteundEditfür Dateien mit Backslashes. - Vermeiden Sie
sleepim Vordergrund; verwenden Siewaitmit einer Schleife.
macOS
- Verwenden Sie
sayfür TTS. Standardstimme istSamantha. - Ändern Sie
templates/lib/tts.mjs, umsayzu verwenden.
Linux
- Installieren Sie
espeak-ng:apt-get install espeak-ng. - Ändern Sie
templates/lib/tts.mjs, umespeak-ngzu verwenden. - Möglicherweise müssen Sie einen Audio-Treiber (ALSA/PulseAudio) installieren.
Anhang C: Referenz-Skript-Längen
| Rate | Dauer | Wörter |
|---|---|---|
| 1 | ~150 s | ~380 |
| 2 | ~139 s | ~380 |
| 3 | ~130 s | ~380 |
Zielen Sie auf Rate 2 für einen natürlichen Sprachfluss, es sei denn, das Video ist zu lang.
Lizenz
Dieses Skill ist MIT-lizenziert. Siehe LICENSE für Details.