Communitygithub.com

Erzähltes A/B-Video

Erstelle ein erzähltes A/B-Beweisvideo eines PR oder Features: Zeichne jede Seite mit Playwright auf, füge Titel-/Beweiskarten und A/B-Eckenbanner hinzu, vertone jedes Segment mit macOS say, beschleunige Modellwartezeiten, friere das letzte Bild ein, sodass die Erzählung passt, und verkette alles zu einer MP4-Datei.

Was ist B-Video?

Das Skill „Erzähltes A/B-Video“ ermöglicht es, ein vollständig automatisiertes Video zu erstellen, das zwei Varianten (A und B) einer Webanwendung nebeneinander demonstriert. Es ist speziell für Entwickler konzipiert, die Pull-Requests oder Features visuell dokumentieren möchten. Der Workflow beginnt mit der Aufnahme von Browser-Interaktionen für beide Seiten mittels Playwright in TypeScript. Anschließend werden mit einem Python-Skript Titel-, Beweis- und Urteilskarten als PNGs generiert. Das finale Video vertont jedes Segment mit macOS `say` (oder ElevenLabs für bessere Sprachqualität), beschleunigt Wartezeiten auf Modellantworten (standardmäßig 10×) und hält das letzte Bild so lange wie nötig, damit die Narration vollständig ist. Das Skill unterstützt dynamische Eingaben (z. B. OTP-Codes) durch Hooks und vermeidet häufige Fallstricke wie fehlende Playwright-Abhängigkeiten (`ffmpeg`) oder den nicht vorhandenen `drawtext`-Filter von ffmpeg. Es ist optimiert für macOS auf Apple Silicon, kann aber mit Umgebungsvariablen (`CHROMIUM_EXE`, `ELEVENLABS_API_KEY`) an andere Plattformen angepasst werden. Das Ergebnis ist eine einzelne MP4-Datei, die ohne Wiedergabe direkt an den Benutzer übergeben wird.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sblattj/agent-chandlery/tree/main/skills/narrated-ab-video

In Ihrer bevorzugten KI fragen

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

Dokumentation

Was macht B-Video?

Weitere Auslöser

Video-Durchlauf des PR, Demo-Aufnahme erstellen, Voiceover-Demo, beide Stacks aufnehmen, Erklärvideo, kein drawtext-Filter, Playwright recordVideo, headless shell fehlt

Eine MP4 pro Anspruchsgruppe: Titel-Karte, A-Clip, B-Clip, Beweis-Karte, Urteils-Karte, alle vertont.

Gebaut für macOS auf Apple Silicon (say, Playwright-Cache unter ~/Library/Caches/ms-playwright, chrome-mac-arm64). Woanders CHROMIUM_EXE setzen und --eleven für die Stimme nutzen. Benötigt Bun, ffmpeg und Python 3.

So geht's

S=${SKILL_DIR:-~/.claude/skills/narrated-ab-video}
$S/preflight.sh /tmp/vid                                  # chromium, playwright ffmpeg, ffmpeg, say voice
bun $S/record.ts a.json raw/a-run                         # ein Szenario pro Seite (Beispiele in examples/scenario.json)
bun $S/record.ts b.json raw/b-run
bun $S/cards.ts cards.json cards                          # Titel-/Beweis-/Urteils-PNGs + banner-A/B.png
python3 $S/build.py plan.json                             # [--voice Samantha] [--rate 182]
open -a "QuickTime Player" demo.mp4                       # öffnet pausiert; niemals selbst abspielen

Beispiele in examples/: scenario.json (Schritte: wait, select, click, clickIfPresent, type, send, waitStable, expand, fetchText, waitText, probeEnabled, reload; siehe Kopf von record.ts), cards.json, plan.json. Planpfade sind relativ zur Plan-Datei. Ende-zu-Ende getestet mit einem 4-Segment-, 40s-Build aus zwei echten Clips.

Warum es so gebaut ist (gesammelte Reibungspunkte)

  • Playwrights festgelegte headless shell ist oft nicht heruntergeladen. record.ts und cards.ts starten den neuesten gecachten chromium-* Vollbuild (oder $CHROMIUM_EXE) statt zu scheitern.
  • recordVideo benötigt Playwrights eigenes ffmpeg-Build. Fehlt es, gibt es kein webm. preflight liest die Revision aus browsers.json und führt bunx playwright install ffmpeg aus.
  • Homebrew ffmpeg könnte drawtext fehlen. Banner sind transparente PNGs aus cards.ts, in build.py überlagert. Keine Schriftarten- oder Filtersuche.
  • Modellantworten dauern 10 bis 60 Sekunden tote Luft. send markiert „gesendet“ und waitStable markiert „geantwortet“. build.py spielt diesen Bereich mit speed (Standard 10×) ab und den Rest mit 1×.
  • Die Erzählung ist meist länger als der Clip. build.py hält das letzte Bild (tpad stop_mode=clone) bis die Stimme endet, sodass eine Antwort auf dem Bildschirm bleibt, während sie erklärt wird.
  • Dynamische Eingaben (OTP-Codes, IDs aus einer früheren Runde): {{fn:NAME}} in einen type-Schritt einfügen und NAME(page, state) aus hooks.ts neben dem Szenario exportieren. state.lastJson enthält das letzte POST-JSON, das captureJsonFrom entspricht.
  • Selektoren: Buttons werden nach Rolle und Namens-Regex gematcht ("Tools used", "^Send$"). CSS wird nur für Eingaben und Auswahlen verwendet. Namen durch einen kurzen Screenshot vor dem Scripting finden.
  • Concat benötigt identische Kodierungen. Jedes Segment wird mit demselben Codec, derselben Rate und demselben Audio-Layout neu kodiert, dann mit -c copy zusammengefügt.
  • Bessere Stimme: ELEVENLABS_API_KEY=... build.py plan.json --eleven <voice_id> (Modell eleven_multilingual_v2; Clips werden nach Stimme+Text-Hash gecacht, sodass Wiederholungen keine Zeichen verbrauchen). Den Schlüssel in einer 0600-Datei aufbewahren, niemals im Plan, und nach Gebrauch löschen.
  • Einseitige Demo (kein A/B): Ein Szenario aufnehmen, cards.json ein Banner geben, und denselben Clip in mehrere Plan-Segmente aufteilen, eins pro Anspruch, mit spans, die die Wartezeiten beschleunigen (z. B. 5×). Gleicher Build, keine A-Seite.
  • Der Benutzer könnte nur <voice_id> <key> einfügen. Das bedeutet Neubuild mit --eleven <voice_id>. Eine langsamere Stimme dehnt das Video (72s mit say wurden 92s), da build.py das letzte Bild bis zum Ende der Stimme hält.
  • Wiederherstellen einer abgebauten Demo vor dem Filmen: Kurzlebige Authentifizierung (lokale JWTs, Tunnel-URLs, temporäre Cloud-Ressourcen) ist meist am nächsten Tag tot. Vor der Aufnahme mit einem API-Durchlauf neu verifizieren; ein 401 „JWT token expired“ hätte dort eine Runde gefilmt, deren Ergebnisse nie ankommen.
  • Verlorener Rohclip: Das Filmmaterial dieser Seite aus einem früheren Ausgabe-MP4 ausschneiden (seinen Span durch Abtasten der Bannereckenfarbe finden), als <dir>/a.webm mit -f mp4 und einem leeren marks.json speichern, und einen expliziten Span verwenden. Das banner weglassen, da es eingebrannt ist.
  • Audio: say -o schreibt nur Dateien. Niemals das Video oder Audio ohne ausdrückliches OK des Benutzers abspielen. Pausiert öffnen und übergeben.
  • Beweisen bevor gefilmt wird. Zuerst das A/B ausführen und das Ergebnis (API oder Log) bestätigen. Das Video zeigt ein bewiesenes Ergebnis; es ist nicht der Test.
  • Karten müssen zur Clip-Größe passen. build.py skaliert nicht. Aufnahme mit "viewport": [1440, 900] benötigt "size": [1440, 900] in cards.json, sonst hat der Concat gemischte Bildgrößen.
  • Asynchrone UIs benötigen Markierungen, keine festen Wartezeiten. waitText markiert, wenn ein Regex auftaucht (oder timeout:<mark>), probeEnabled mit waitMs pollt einen Button und protokolliert probes[] in marks.json, tryMs auf type/send/click markiert skipped:<step> statt abzubrechen, sodass eine „bleibt deaktiviert“-Seite den Clip dennoch beendet.
  • Das gleiche Element abfragen, das geklickt wird. Ein CSS-Probe (button[aria-label=...]) traf einen anderen passenden Button als den role-name send und las deaktiviert, während das Senden durchging; "role" in probeEnabled verwenden.
  • Dev-Mode-Overlays (Query DevTools, Error-Toasts) landen im Clip. {"clickIfPresent": "^Close .* devtools$"} nach dem ersten Warten einfügen.
  • Warten auf eine Antwort, die nie „stabil“ wird: Ein Live-verstrichene-Zeit-Badge ändert den Body-Text jede Sekunde. marks.json auf eine replied-Markierung prüfen, bevor der Build gestartet wird.
  • Prüfen, dass der Beweis in sichtbarem Text steht. Eingeklappte Tool-Karten werden möglicherweise nicht erweitert (expand klickt lautlos nichts). marks.json body auf den Anspruchstext prüfen. Fehlt er, die Eingabeaufforderung ändern oder den Beweis stattdessen auf einer Karte zeigen.
  • Parität vor dem Filmen eines „Basis scheitert“-Anspruchs beweisen. Wenn eine lokale Basis aus einem Grund (ein Flag, das lokal an, remote aus war) scheiterte, den die echte Umgebung nie trifft, und die Erzählung ihn behauptete. Zuerst die Flags der Remote-Umgebung angleichen, dann filmen.
  • Titel-Karte: Commits getestet und Flags auf jeder Seite. Ein Anspruch pro Clip-Segment. Mit einer Urteils-Karte enden.

Verwandt

  • narrated-screenshot: ein einzelnes annotiertes Standbild statt eines Videos.
  • pr-ab-evidence: die rot/grün A/B-Methode, deren Ergebnis dieses Skill filmt.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills