VirtualPirate/criar-video-demonstracao-produto

Skill do Claude Code: grava um vídeo de demonstração de produto percorrendo um fluxo real do usuário no seu próprio web app — transcrito da interface real, gravado em mp4/gif com Playwright + ffmpeg.

O que é criar-video-demonstracao-produto?

Esta skill do Claude Code permite criar vídeos de demonstração (demo) de produtos web a partir de uma descrição textual de fluxo do usuário. Ela mapeia o fluxo descrito para rotas reais do aplicativo, lê o código-fonte de cada tela para transcrever fielmente a interface (layout, textos, componentes) e gera um vídeo mp4 (ou gif) usando Playwright para captura e ffmpeg para pós-produção. A skill suporta legendas personalizáveis (pill, lower-third, rail, coach), música de fundo opcional com fade automático, e inclui verificações rigorosas de qualidade: extração de frames para detectar bugs visuais e análise de áudio para garantir níveis adequados. O resultado é um vídeo que reflete exatamente o produto real, sem invenções ou impressões aproximadas, ideal para apresentações de marketing, documentação ou walkthroughs interativos.

Funciona com✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/VirtualPirate/create-product-demo-video-skill/tree/main/skills/create-product-demo-video

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Construa um vídeo de demonstração do fluxo descrito pelo usuário. O resultado é salvo em uma pasta nova demo/vN/.

A única regra que importa: cada tela é uma transcrição da interface real, não uma impressão dela. Uma demonstração que inventa layout, texto ou componentes é pior do que nenhuma demonstração — ela ensina os espectadores sobre um produto que não existe. Leia o código-fonte de cada tela antes de escrever qualquer marcação para ela.

Entradas

/create-product-demo-video <o que deve acontecer> — uma descrição do fluxo. Se for vaga ("mostrar o produto"), escolha o fluxo completo mais restrito que termina em valor visível, diga qual você selecionou em uma linha, e construa-o. Não pare para fazer perguntas.

Passos

  1. Mapeie o fluxo para rotas. Transforme o prompt em uma lista ordenada de rotas reais pelas quais o usuário passaria. Encontre o roteador primeiro — um diretório routes/, uma árvore app/, um bloco <Routes>, um manifesto de rotas — e liste apenas os caminhos que existem. Se o fluxo precisar de uma entidade que deve ser criada antes que uma tela posterior possa existir (um projeto antes de um relatório com escopo de projeto), inclua essa tela ou escolha um escopo que não precise dela — não pule uma etapa necessária silenciosamente.

  2. Leia o código-fonte de cada tela. Para cada rota: o arquivo de rota, os componentes que ela renderiza, os componentes de layout compartilhados do aplicativo (shell, cabeçalho de página, estado vazio) e seus primitivos do sistema de design (components/ui/ ou onde estiverem). Leia também qualquer coisa que gere strings que a demonstração exibe — helpers de pré-visualização, nomes derivados, serviços de renderização/modelo do backend. Copie strings literalmente; não parafraseie o texto do produto.

  3. Estrutura inicial. mkdir -p demo/vN (próximo N não utilizado — nunca sobrescreva um vN existente), depois copie assets/skeleton.html → demo/vN/index.html e assets/record.mjs → demo/vN/record.mjs. assets/ fica ao lado deste SKILL.md, onde quer que a skill esteja instalada — um diretório de cache de plugins, ~/.claude/skills/, ou .claude/skills/ de um projeto. Resolva-o a partir do próprio diretório da skill, nunca do repositório que está sendo demonstrado. O esqueleto carrega um shell placeholder, uma escala de token e o mecanismo de reprodução. Para uma demonstração com trilha sonora, copie também a faixa escolhida de assets/music/ → demo/vN/music.mp3 — veja Música. Copiá-la (em vez de referenciar a pasta da skill) é o que permite regravar vN/ depois, pela mesma razão que record.mjs é copiado por versão.

  4. Adapte o esqueleto a este produto. Tudo marcado como REPLACE: é um placeholder que deve ser substituído antes que qualquer cena seja escrita, porque cada tela o herda:

    Em index.htmlSubstitua por
    PRODUCTO nome do aplicativo, o host que sua barra de endereço mostra e seu logotipo svg real
    NAVA barra lateral transcrita da navegação real — mesmas seções, mesma ordem, mesmos rótulos
    TOPBARA barra superior real; remova controles que o aplicativo não possui
    Tokens :rootO bloco :root da folha de estilo do aplicativo, para que cor/raio/tipo correspondam
    ICONSDados de caminho do conjunto de ícones que o aplicativo realmente usa
    Remova os blocos CSS opcionais (tela de terceiros, painéis de entrega) que o fluxo não usa.
  5. Escreva as cenas. Uma <section class="scene" data-scene="N"> por tela, em ordem. Reutilize as classes CSS do esqueleto (.pagehead, .card, .btn, .seg, .opt, .chip, .scopeid, .statusbadge, .empty, .input, .pillbar, .toast) — elas são moldadas como a saída de um sistema estilo Tailwind/shadcn, então verifique cada uma em relação às classes reais do componente e ajuste em vez de presumir. Adicione novo CSS apenas para um componente que o esqueleto não possui, e derive-o das classes reais desse componente.

  6. Escreva play(). Cartão de título → telas → encerramento. Use legendas para nomear cada etapa e defina CAPTIONS no topo do script — o estilo e steps = quantas chamadas say() a execução faz. As interações passam pelos helpers do ponteiro para que o espectador possa acompanhar o que está sendo clicado.

  7. Grave. node demo/vN/record.mjs → demo/vN/out/product-demo.mp4. Adicione --gif para um gif de 900px. Um arquivo demo/vN/music.* é detectado automaticamente; --music <caminho> aponta para um em outro lugar, --music-db <n> desloca o nível, --no-music força silêncio.

  8. Verifique olhando. Extraia quadros e leia as imagens — isso não é opcional, é como bugs de layout são detectados:

    for t in 5 12 20 28 36 44; do ffmpeg -y -loglevel error -ss $t \
      -i demo/vN/out/product-demo.mp4 -frames:v 1 /tmp/f$t.png; done
    

    Verifique: sem ícones superdimensionados, nada cortado na dobra, o ponteiro pousa no elemento que afirma clicar, o texto não está colapsado em uma linha. Corrija e regrave até ficar limpo.

    Os quadros não mostram o áudio. Em uma demonstração com trilha sonora, verifique também o fluxo e as rampas — volumedetect registra em nível de informação, então -v error engoliria sua saída:

    ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,duration \
      -of default=nw=1 demo/vN/out/product-demo.mp4
    for w in "-ss 0 -t 0.25" "-ss 12 -t 0.5" "-sseof -0.25"; do \
      ffmpeg -hide_banner -nostats $w -i demo/vN/out/product-demo.mp4 \
        -af volumedetect -f null - 2>&1 | grep mean_volume; done
    

    Espere um fluxo aac dentro de ~0,05s da duração do vídeo, max_volume abaixo de 0 dB, e as médias do início e fim bem abaixo da média do meio — isso é o fade provando que funcionou.

  9. Escreva demo/vN/README.md — tabela de cenas com rotas, o mapeamento de arquivos-fonte, duração, o estilo CAPTIONS e a faixa de música com a qual a versão foi gravada, e o que o fluxo deliberadamente pula. Atualize demo/README.md para listar a nova versão.

Relate o caminho, duração e tamanho, depois abra o mp4 para que o usuário possa assisti-lo — open no macOS, xdg-open no Linux, start no Windows.

API do Mecanismo

Disponível dentro de play():

ChamadaEfeito
scene(n)Transição para cena n, atualiza a barra de endereço de URLS
tap(sel, ms)Move o ponteiro até o elemento e clica (ondulação + pressão)
moveTo(sel, ms) / click(sel)As duas metades, quando você precisa de mudanças de estado entre elas
hideCursor() / place(x, y, 0)Redefine o ponteiro ao entrar em uma cena
say(texto, opts?) / hush()Legenda entra/sai. { at: sel } ancora uma legenda coach; { step: n } força o índice
type(el, texto, ms)Digitação caractere por caractere em um <span>
wait(ms)Pausa
reveal(el)Chamado automaticamente por moveTo — rolagem suave de .main para que alvos fora da dobra fiquem visíveis

Defina window.__demoDone = true no final (o esqueleto já faz isso) — o gravador espera por ele.

Design de legendas

const CAPTIONS = { style: 'pill', steps: 6 } fica com URLS no topo do mecanismo. Todos os quatro estilos estão incluídos no esqueleto; say() é a mesma chamada independentemente de qual esteja ativo. Escolha por vídeo:

styleO que éEscolha quando
pill (padrão)Cápsula de tinta, centro inferiorQualquer coisa curta e voltada ao marketing. Menos oclusão, ~10 palavras por legenda
lower-thirdBloco ancorado à esquerda com índice de etapa + barra de progressoFluxos mais longos onde o espectador deve sentir a sequência; mais legível em um gif
railFaixa de 68px sob a janela, pontos de capítuloDocumentação e clipes de suporte onde nada pode ser coberto. Custa altura do app — veja abaixo
coachChamada ancorada ao elemento em ação, resto escurecidoWalkthroughs de acompanhamento. Cada legenda precisa de { at: sel }; as sem ele recaem em pill

steps controla o índice, a barra de progresso e os pontos da faixa — conte as chamadas say() e defina-o, ou a execução termina mostrando 05 / 06. Não sabe qual estilo? Abra index.html em um navegador e alterne CAPTIONS.style — a página repete com R, então todos os quatro podem ser comparados sem gravação.

Música

Opcional, e desligada a menos que uma faixa esteja presente. A base é multiplexada no momento da codificação — o Playwright não captura áudio algum, então nada disso toca na página de demonstração ou no mecanismo.

node demo/vN/record.mjs                      # usa demo/vN/music.* se presente, silencioso se não
node demo/vN/record.mjs --music ~/beds/x.mp3  # caminho explícito vence o irmão
node demo/vN/record.mjs --music-db -4        # base mais silenciosa
node demo/vN/record.mjs --no-music           # silencioso mesmo com uma faixa irmã
  • Faixas incluídas ficam em assets/music/, uma linha por arquivo em seu LICENSES.md. Nenhuma faixa é distribuída sem uma linha CC0/CC-BY verificável — um mp3 sem licença é um problema para todos que instalam isso, não só seu. Em dúvida? Mantenha fora do repositório e passe --music <caminho>.
  • Nível é normalizado, não definido. Cada faixa é ajustada para −18 LUFS com um teto de pico verdadeiro de −1,5 dB, para que bases trocadas entre versões correspondam sem ajuste manual. --music-db desloca esse alvo; não adiciona ganho adicional.
  • Fades são automáticos — 1,5s de entrada, 2,5s de saída, a saída cronometrada pela duração real do vídeo.
  • Escolha uma faixa mais longa que o vídeo. Qualquer coisa mais curta é repetida e a emenda é audível; o gravador avisa quando precisa fazer isso. 60s+ cobre uma demonstração normal de 40–60s.
  • Sem vocais, sem quedas bruscas. O espectador está lendo legendas e texto da interface ao mesmo tempo.
  • Áudio vai apenas no mp4. O webm é a captura silenciosa bruta, e um gif não tem faixa de áudio alguma — uma mudança apenas na música é invisível na saída --gif.

Convenções

  • O palco é um navegador simulado fixo de 1280×800; 44px disso são o chrome do navegador, deixando 1280×756 para o aplicativo. O esqueleto fornece um

Habilidades Relacionadas