Communitygithub.com

Vídeo A/B Narrado

Crie um vídeo de prova A/B narrado de um PR ou funcionalidade: grave a execução do navegador de cada lado com Playwright (marcações de tempo, hooks para entrada dinâmica como códigos OTP), renderize cartões de título/evidência e banners de canto A/B, narre cada segmento com a voz do macOS say, acelere as esperas do modelo, congele o último quadro para ajustar à narração e concatene em um único mp4.

O que é B Narrado?

Este skill permite gerar vídeos narrativos A/B que demonstram visualmente a comparação entre uma versão base e uma versão com alterações de um pull request ou funcionalidade. Ele grava automaticamente a execução do navegador para cada lado usando Playwright, insere cartões de título e evidência, banners de canto identificando o lado A/B, e adiciona narração via síntese de voz (macOS `say` ou API ElevenLabs). A ferramenta otimiza o vídeo acelerando os períodos de espera do modelo (10x padrão) e congelando o último quadro até que a narração termine, garantindo que cada afirmação seja claramente explicada. Compatível com macOS Apple Silicon, mas pode ser usado em outros sistemas configurando `CHROMIUM_EXE` e usando `--eleven` para voz. Requer Bun, ffmpeg e Python 3. O skill lida com desafios comuns como ausência do ffmpeg do Playwright, falta do filtro drawtext no ffmpeg Homebrew (usando PNGs para banners), entrada dinâmica via hooks (códigos OTP, IDs), seletores robustos (role, regex), tentativas para elementos ausentes, e concatenação com codificação idêntica. Inclui validação pré-gravação e dicas para evitar problemas de tokens expirados, overlays de devtools e provas de paridade.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que B Narrado faz?

Mais gatilhos

apresentação em vídeo do PR, fazer uma gravação demo, narração demo, gravar ambas as stacks, vídeo explicativo, sem filtro drawtext, Playwright recordVideo, shell headless ausente

Um mp4 por conjunto de afirmações: cartão de título, clipe A, clipe B, cartão de evidência, cartão de veredito, cada um narrado.

Construído para macOS em Apple Silicon (say, cache do Playwright em ~/Library/Caches/ms-playwright, chrome-mac-arm64). Em outros sistemas, defina CHROMIUM_EXE e use --eleven para a voz. Precisa de Bun, ffmpeg e Python 3.

Faça isso

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                         # um cenário por lado (copie examples/scenario.json)
bun $S/record.ts b.json raw/b-run
bun $S/cards.ts cards.json cards                          # PNGs de título/evidência/veredito + banner-A/B.png
python3 $S/build.py plan.json                             # [--voice Samantha] [--rate 182]
abra -a "QuickTime Player" demo.mp4                       # abre pausado; nunca o reproduza você mesmo

Exemplos em examples/: scenario.json (passos: wait, select, click, clickIfPresent, type, send, waitStable, expand, fetchText, waitText, probeEnabled, reload; veja o cabeçalho de record.ts), cards.json, plan.json. Caminhos do plano são relativos ao arquivo do plano. Validado de ponta a ponta em um build de 4 segmentos, 40s a partir de dois clipes reais.

Por que foi construído assim (atritos minerados)

  • O shell headless fixo do Playwright muitas vezes não está baixado. record.ts e cards.ts lançam o build completo chromium-* mais recente em cache (ou $CHROMIUM_EXE) em vez de falhar.
  • recordVideo precisa do próprio ffmpeg do Playwright. A falta impede a geração de webm. O preflight lê a revisão de browsers.json e executa bunx playwright install ffmpeg.
  • O ffmpeg do Homebrew pode não ter drawtext. Os banners são PNGs transparentes do cards.ts, sobrepostos no build.py. Sem caça a fontes ou filtros.
  • As respostas do modelo levam de 10 a 60 segundos de silêncio. send marca "enviado" e waitStable marca "respondeu". O build.py reproduz esse intervalo em speed (padrão 10x) e o resto em 1x.
  • A narração geralmente é mais longa que o clipe. O build.py segura o último quadro (tpad stop_mode=clone) até a voz terminar, então uma resposta permanece na tela enquanto é explicada.
  • Entrada dinâmica (códigos OTP, ids de uma rodada anterior): coloque {{fn:NOME}} em um passo type e exporte NOME(page, state) de hooks.ts ao lado do cenário. state.lastJson contém o último JSON POST que corresponde a captureJsonFrom.
  • Seletores: botões são correspondidos por role e regex de nome ("Ferramentas usadas", "^Enviar$"). CSS é usado apenas para inputs e selects. Encontre nomes com uma captura de tela rápida antes de scriptar.
  • Concatenação precisa de codificações idênticas. Cada segmento é recodificado com o mesmo codec, taxa e layout de áudio, depois unido com -c copy.
  • Voz melhor: ELEVENLABS_API_KEY=... build.py plan.json --eleven <voice_id> (modelo eleven_multilingual_v2; clipes em cache por hash de voz+texto, então reexecuções não gastam caracteres). Mantenha a chave em um arquivo 0600, nunca no plano, e delete após o uso.
  • Demo de um lado (sem A/B): grave um cenário, dê a cards.json um banner, e corte o mesmo clipe em vários segmentos do plano, uma afirmação cada, com spans acelerando as esperas (ex.: 5x). Mesmo build, sem lado A.
  • O usuário pode colar apenas <voice_id> <key>. Isso significa reconstruir com --eleven <voice_id>. Uma voz mais lenta estica o vídeo (72s com say viraram 92s), já que o build.py segura o último quadro até a voz terminar.
  • Restaurar uma demo desmontada antes de filmar: autenticação de curta duração (JWTs locais, URLs de túnel, recursos cloud temporários) geralmente expira no dia seguinte. Re-verifique com uma execução de API antes de gravar; um 401 "JWT token expirado" teria filmado uma rodada cujos resultados nunca chegam.
  • Clipe raw perdido: corte a filmagem desse lado de um mp4 de saída anterior (encontre seu span amostrando a cor do canto do banner), salve como <dir>/a.webm com -f mp4 e um marks.json vazio, e use um span explícito. Remova o banner pois já está embutido.
  • Áudio: say -o escreve arquivos apenas. Nunca reproduza o vídeo ou qualquer áudio sem a autorização explícita do usuário. Abra pausado e entregue.
  • Prove antes de filmar. Execute o A/B e verifique o resultado (API ou log) primeiro. O vídeo mostra um resultado comprovado; não é o teste.
  • Cartões devem corresponder ao tamanho do clipe. O build.py não escala. Gravar com "viewport": [1440, 900] requer "size": [1440, 900] no cards.json, ou a concatenação terá tamanhos de quadro mistos.
  • UIs assíncronas precisam de marcas, não esperas fixas. waitText marca quando um regex aparece (ou timeout:<mark>), probeEnabled com waitMs consulta um botão e registra probes[] no marks.json, tryMs em type/send/click marca skipped:<step> em vez de abortar, então um lado "permanece desabilitado" ainda finaliza o clipe.
  • Consulte o mesmo elemento que você clica. Uma consulta CSS (button[aria-label=...]) encontrou um botão diferente do role-name send e leu desabilitado enquanto o send passava; use "role" em probeEnabled.
  • Overlays de modo dev (consulta devtools, toasts de erro) aparecem no clipe. Adicione {"clickIfPresent": "^Fechar .* devtools$"} após a primeira espera.
  • Esperando uma resposta que nunca "estabiliza": um badge de tempo decorrido ao vivo muda o texto do corpo a cada segundo. Verifique marks.json por uma marca replied antes de construir.
  • Verifique se a prova está em texto visível. Cartões de ferramenta recolhidos podem não expandir (expand silenciosamente não clica em nada). Leia o body do marks.json para a string de afirmação. Se estiver faltando, mude o prompt ou prove em um cartão.
  • Prove a paridade antes de filmar uma afirmação de "base falha". Uma vez uma base local falhou por um motivo (uma flag que estava ativa localmente, desligada remotamente) que o ambiente real nunca encontra, e a narração afirmou. Corresponda as flags remotas primeiro, então filme.
  • Cartão de título: commits testados e flags de cada lado. Uma afirmação por segmento de clipe. Termine com um cartão de veredito.

Relacionados

  • narrated-screenshot: um único still anotado em vez de um vídeo.
  • pr-ab-evidence: o método A/B vermelho/verde cujo resultado este vídeo filma.

Individual skills in this repo

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

Habilidades Relacionadas