Communitygithub.com

lyonsv/demo-video-skill

Grave vídeos de demonstração roteirizados e polidos de aplicações web (walkthroughs de produtos, animações de arquitetura antes→depois, segmentos de funcionalidades) como MP4s 1440×900 em formato consistente — cartões de título brancos, legendas em pill, ripples de clique, esperas aceleradas — usando Playwright para controlar o Chrome headless e ffmpeg para codificação. Use sempre que o usuário quiser um vídeo de demonstração, screencast, gravação de walkthrough, vídeo de produto, “grave o aplicativo”, “faça um vídeo desta funcionalidade”, “estenda / adicione ao vídeo de demonstração”, um diagrama de arquitetura animado, ou mostrar uma funcionalidade para stakeholders em vídeo, mesmo que não mencionem “skill” ou nomeiem um formato.

O que é demo-video-skill?

Esta skill produz vídeos de demonstração roteirizados e de alta qualidade para aplicações web, seguindo um formato consistente (1440×900, 30fps, legendas em pill, ripple de clique, aceleração de esperas) ideal para apresentações de produtos, animações de arquitetura e gravações de funcionalidades. Utiliza Playwright para controlar o Chrome headless e ffmpeg para codificar os vídeos em MP4 H.264 sem áudio, garantindo que segmentos possam ser combinados perfeitamente. A skill é especialmente útil para engenheiros de software, PMs e desenvolvedores que precisam criar vídeos de demonstração rápidos e padronizados para stakeholders, sem a necessidade de ferramentas de edição complexas. O fluxo de trabalho inclui storyboard, configuração de pasta no repositório de demos, gravação com script, aceleração de partes lentas, revisão com contact sheets e entrega do vídeo final, tudo automatizado via scripts Node.js. Suporta múltiplos segmentos (walkthroughs, páginas de cena, vídeos existentes) através de um manifesto `demo.json`, e inclui ferramentas para gravar, codificar, concatenar e revisar o resultado.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lyonsv/demo-video-skill/tree/HEAD

Perguntar na sua IA favorita

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

Documentação

Vídeos de demonstração

Walkthroughs roteirizados gravados a partir do aplicativo real em execução. O espectador vê o produto realizando trabalho real; partes lentas (respostas do modelo, tarefas) são aceleradas, e cada batida tem uma pequena legenda dizendo o que observar. O mesmo formato é usado sempre, para que segmentos possam ser unidos em um único vídeo.

O formato padrão

Mantenha estes exatos, para que novos segmentos correspondam aos anteriores:

  • Vídeo: 1440×900, 30fps, H.264 (libx264 -preset slow -crf 18), yuv420p, +faststart, sem áudio.
  • Cartões de título e fim: tela branca total, centralizado: uma linha opcional de marca pequena em maiúsculas cinza (defina brand em kit.start; nenhum por padrão), título em negrito 46px, subtítulo cinza 20px. Mantenha cerca de 2,8s, depois fade out. Segmentos abrem com um cartão de título; o último termina com um cartão de takeaway de uma linha (ex.: "Ideia → avaliação → teste ao vivo → envio" / "Nenhum deploy de app no meio").
  • Legendas: pill escuro (rgba(17,17,17,.88)), branco 17px seminegrito Lato, centro inferior. Uma ideia por legenda, cerca de 60 caracteres ou menos, sentença normal, sem ponto final, tempo presente, escrita do lado do espectador ("Resultados abrem como um artefato ao lado do chat"). Mude a legenda quando a batida mudar; mantenha cada uma por cerca de 2,5–4s.
  • Cliques: um ripple roxo (rgba(122,71,255,…)) aparece no alvo imediatamente antes de cada clique.
  • Digitação: visível, tecla por tecla (cerca de 25ms por tecla; 14ms para texto longo).
  • Esperas: qualquer coisa lenta executa dentro de ff(), que reproduz em cerca de 2s. Todo o resto é em tempo real.
  • Cenas de arquitetura: uma página branca fixa 1440×900 de cenas (título → antes → problema destacado → depois → contagem de métricas → lista de funcionalidades), Lato, tinta #111, acento roxo #6f43d6; tags "antes" em cinza, tags "depois" em roxo. assets/architecture-example.html é a referência: reutilize seu CSS e estrutura e altere o conteúdo.

Onde os vídeos ficam: o repositório de demos

Cada vídeo tem uma pasta no repositório de demos da equipe (padrão ~/src/demos, ou $DEMOS_REPO), contendo seus scripts de gravação e um manifesto demo.json. Os repositórios de produto permanecem livres de código de demonstração. As gravações nunca são commitadas; o output do manifesto diz onde o MP4 vai.

~/src/demos/
  package.json            playwright-core + ffmpeg-static (npm install uma vez)
  <video>/
    demo.json             manifesto
    architecture.html     segmento "scenes" (opcional)
    record-<part>.js      segmentos "walkthrough", escritos no kit de demonstração
    .build/               MP4s e frames por segmento (gitignorado)

Manifesto (demo.json):

{
  "name": "<nome-do-video>",
  "title": "Uma linha: o que o vídeo mostra",
  "description": "Para quem é e o ponto que faz",
  "owner": "email",
  "repos": ["repositórios onde as funcionalidades gravadas estão, com branches"],
  "needs": [{ "what": "serviço", "check": "URL que responde 2xx/3xx quando estiver no ar", "start": "como iniciá-lo" }],
  "reset": "como obter uma gravação limpa, e o que a gravação deixa para trás",
  "segments": [
    { "name": "architecture", "kind": "scenes", "page": "architecture.html", "timeline": "0:3000,1:4500" },
    { "name": "walkthrough", "kind": "walkthrough", "script": "record-walkthrough.js" },
    { "name": "intro", "kind": "video", "file": "~/path/to/existing.mp4" }
  ],
  "output": "~/Downloads/<nome>.mp4"
}

A pasta examples/sift/ desta skill é uma pasta de referência: um vídeo de dois segmentos (uma página de cena e um walkthrough real) de um pequeno aplicativo de exemplo que está na mesma pasta.

Se o repositório de demos ainda não foi clonado, crie-o (git init, o package.json acima, e um .gitignore cobrindo node_modules/, .build/, *.mp4, *.jpg, *.png, *-frames/ e *-timeline.json) e informe ao usuário que ele ainda não tem um remote.

Ferramentas (em scripts/, relativo a esta skill)

ScriptO que faz
find-demos.jsnode find-demos.js [root…] [--json]: lista cada vídeo no repositório de demos, com segmentos, repositórios, saída, e quando foi gravado e commitado pela última vez.
record.jsnode record.js <video-dir> [--only <segment>]: verifica needs, grava e codifica cada segmento em .build/, junta-os em output (o vídeo antigo é mantido como *.previous.mp4). Execute-o a partir da raiz do repositório de demos.
demo-kit.jsBiblioteca para scripts de walkthrough: kit.start() fornece page, title/untitle, caption, tap, type, ff, scroll/scrollTop, ripple, navigate, startCast, finish. Frames são transmitidos para o disco.
encode.jsnode encode.js <frames-dir> <timeline.json> <out.mp4>: constrói o MP4, comprimindo janelas ff().
record-scenes.jsnode record-scenes.js <page.html> <out.mp4> "0:3000,1:4500,…": grava uma página de cena que define window.step(n).
concat.jsnode concat.js <out.mp4> <a.mp4> <b.mp4> …: junta segmentos, re-codificando para o formato padrão.
review.jsnode review.js <video.mp4> <out-dir> [stills] [at=s,s,…]: contact sheets 2×2 de stills para ler de volta.

assets/example-walkthrough.js é um exemplo completo trabalhado no kit (e examples/sift/record-walkthrough.js é um real). Leia-o antes de escrever um novo walkthrough; ele mostra a estrutura, incluindo troca de aplicativos no meio do vídeo, tarefas aceleradas e um cartão final.

Fluxo de trabalho

0. Encontre o que já existe

Execute find-demos.js primeiro. Se o usuário quiser regravar ou estender um vídeo que já tem uma pasta, trabalhe nessa pasta: regrave com record.js <folder> (ou --only <segment> após uma mudança de UI), ou adicione um segmento ao seu manifesto. Não comece uma segunda pasta para o mesmo vídeo. Crie uma nova pasta apenas para um vídeo genuinamente novo, nomeada após ele (kebab-case).

1. Storyboard primeiro

Antes de qualquer código, escreva o storyboard como uma lista numerada de seções, cada uma com suas batidas: o que acontece na tela e a legenda. Decida antecipadamente:

  • O que deve ser real, e o que pode ser simulado. Prefira real (chamadas de modelo reais, buscas reais). Se os dados precisarem ser simulados (ex.: semanas de tráfego ao vivo), diga isso na tela, tanto em uma legenda quanto no próprio aplicativo, se puder rotular. Os espectadores aceitam uma demonstração pelo valor de face, portanto um resultado simulado apresentado como real é enganoso.
  • O que não deve ser clicado. Qualquer coisa que escreva em ambientes compartilhados (salvar quadros, enviar e-mail, compras). Mostre o botão; não pressione.
  • Duração: cerca de 60–90s por segmento. Um vídeo montado de 3 minutos é aceitável; cada segmento deve fazer um ponto.

Se o objetivo do usuário estiver claro pela conversa, vá em frente e compartilhe o storyboard em sua atualização enquanto trabalha. Pergunte apenas quando o objetivo do vídeo não estiver claro.

2. Configure a pasta do vídeo

Crie <demos repo>/<video>/ com um demo.json (preencha needs com uma URL check para cada serviço que o vídeo tocar, e anote reset). Execute npm install na raiz do repositório de demos se node_modules estiver faltando. O kit e os scripts resolvem playwright-core e ffmpeg-static a partir do diretório de trabalho, então execute tudo a partir da raiz do repositório. O Chrome dever estar instalado (channel: 'chrome'; nenhum download de navegador Playwright é necessário).

3. Pré-voo do aplicativo

  • Confirme que cada serviço que o vídeo toca está no ar (curl cada URL), e que o HTTPS local funciona (o kit ignora certificados autoassinados).
  • Redefina o estado para que a gravação comece limpa (novo banco de dados, localStorage limpo), e faça o script lançar um erro imediatamente se o estado estiver sujo. Uma gravação que falha 3 minutos depois custa chamadas de modelo reais e tempo.
  • Cronometre os endpoints lentos que o vídeo consulta. Uma consulta de resultados de 4 segundos mostra um esqueleto de carregamento na câmera; corrija a consulta ou espere por ela.
  • Capture a tela de cada estado-chave com um pequeno script Playwright e observe: layout, quebra de linha, imagens quebradas, o que está acima da dobra em 1440×900. Isso é mais barato que gravar.

4. Escreva o script de gravação

Copie a estrutura de assets/example-walkthrough.js:

const kit = require(process.env.DEMO_KIT || `${process.env.HOME}/.claude/skills/demo-video/scripts/demo-kit`);
const demo = await kit.start();                             // record.js fornece os caminhos de frame e timeline
await demo.page.goto(URL, { waitUntil: 'networkidle' });
await demo.title('Nome da funcionalidade', 'O que ela permite fazer');
await demo.startCast();                                     // inicia após o título cobrir a página
await demo.sleep(2800); await demo.untitle(); await demo.sleep(900);
await demo.caption('…'); await demo.tap(locator); await demo.type(locator, 'text');
await demo.ff(() => page.waitForFunction(() => /* resposta terminada */ true, null, { timeout: 180000 }));
await demo.finish();
  • Use seletores estáveis (aria-label, ids, data-*) e verifique-os contra o DOM real.
  • Aguarde condições reais de conclusão dentro de ff(), não sleeps fixos, com timeouts generosos.
  • Quando uma legenda falar sobre algo, role-o para a tela primeiro (demo.scroll(px, 'main') para aplicativos cujo conteúdo rola dentro de um elemento).
  • demo.navigate(url) troca de páginas ou aplicativos; ele reinicia o screencast na nova página.
  • Para um segmento de arquitetura, construa a página de cena a partir do exemplo e grave-a com record-scenes.js. Também dê a ela navegação por teclas de seta e espaço (o exemplo tem), para que a mesma página funcione ao apresentar ao vivo.

5. Grave

A partir da raiz do repositório de demos, execute o vídeo inteiro (ou um segmento) em primeiro plano com um timeout longo, registrando a saída:

set -o pipefail; node ~/.claude/skills/demo-video/scripts/record.js <video> [--only <segment>] 2>&1 | tee <video>/.build/record.log

Não redirecione para tail: ele esconde o código de saída do gravador, e uma gravação com falha parece sucesso. Se precisar colocá-lo em segundo plano, espere pelo PID real (while kill -0 $PID; do sleep 5; done) em vez de confiar em uma notificação "concluído", que pode chegar antes do processo terminar.

6. Revise

record.js já codificou e juntou tudo; ele imprime o comando de revisão:

node ~/.claude/skills/demo-video/scripts/review.js <output.mp4> <video>/.build/review 16

Para olhar um segmento, revise <video>/.build/<segment>.mp4.

Leia cada contact sheet antes de considerar o vídeo pronto. Verifique que:

  • cada legenda corresponde ao que está na tela naquele momento;
  • a coisa a que a legenda se refere está visível, não abaixo da dobra;
  • não há imagens quebradas ou texto alternativo, esqueletos travados, toasts de erro, cabeçalhos quebrados ou cortados, ou interface de depuração;
  • esperas aceleradas parecem um rápido borrão de progresso, não um quadro congelado;
  • cartões de título e fim estão lá.

Corrija o script ou o aplicativo (ex.: um placeholder para imagens que falham ao carregar, uma consulta mais rápida), redefina o estado, e regrave. Espere duas ou três tentativas.

7. Entregue

  • Revise os pontos de junção: review.js <output> <dir> 0 at=<t-1>,<t+1> em cada limite de segmento.
  • record.js mantém a versão anterior como *.previous.mp4. Nunca sobrescreva vídeos que não são o próprio output desta pasta: para adicionar ao vídeo de outra pessoa, adicione-o como um segmento video de uma nova pasta.
  • Informe ao usuário que a pasta do vídeo está pronta para commit no repositório de demos. Faça commit apenas se ele pedir.
  • Relate ao usuário: os caminhos de arquivo e durações, o que cada segmento mostra, o que era real e o que foi simulado, e qualquer estado que a gravação deixou para trás (serviços em execução, registros que criou, qualquer coisa ainda ligada) com como desfazer.

Armadilhas encontradas antes

  • Memória: um screencast CDP envia até 60 quadros por segundo enquanto algo anima. Armazenar frames em buffer na memória para uma gravação de vários minutos faz o gravador ser morto sem saída. O kit transmite frames para o disco e os reduz durante ff(); mantenha isso assim.
  • Relógio: janelas ff() e timestamps de quadro usam segundos de relógio de parede, então cronometre a espera inteira (incluindo polling) dentro de uma única chamada ff().
  • Trabalho bloqueante (ex.: execFileSync para um script de dados) dentro de ff() é aceitável: frames retomam depois e a janela é comprimida de qualquer forma.
  • Portas: verifique se uma porta está livre antes de iniciar um serviço para a demonstração; não mate processos que você não iniciou.
  • Estado residual: uma demonstração que termina enviando ou habilitando algo deixa isso ligado. Desligue depois ou informe o usuário.

Habilidades Relacionadas