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.tsundcards.tsstarten den neuesten gecachtenchromium-*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.jsonund führtbunx playwright install ffmpegaus. - Homebrew ffmpeg könnte
drawtextfehlen. Banner sind transparente PNGs auscards.ts, in build.py überlagert. Keine Schriftarten- oder Filtersuche. - Modellantworten dauern 10 bis 60 Sekunden tote Luft.
sendmarkiert „gesendet“ undwaitStablemarkiert „geantwortet“. build.py spielt diesen Bereich mitspeed(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 einentype-Schritt einfügen undNAME(page, state)aushooks.tsneben dem Szenario exportieren.state.lastJsonenthält das letzte POST-JSON, dascaptureJsonFromentspricht. - 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 copyzusammengefü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.jsonein Banner geben, und denselben Clip in mehrere Plan-Segmente aufteilen, eins pro Anspruch, mitspans, 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 mitsaywurden 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.webmmit-f mp4und einem leeren marks.json speichern, und einen expliziten Span verwenden. Dasbannerweglassen, da es eingebrannt ist. - Audio:
say -oschreibt 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.
waitTextmarkiert, wenn ein Regex auftaucht (odertimeout:<mark>),probeEnabledmitwaitMspollt einen Button und protokolliertprobes[]in marks.json,tryMsauf type/send/click markiertskipped:<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-namesendund las deaktiviert, während das Senden durchging;"role"inprobeEnabledverwenden. - 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.jsonauf einereplied-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 (
expandklickt lautlos nichts).marks.jsonbodyauf 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.