Communitygithub.com

product-video

Produza um vídeo narrado de apresentação, demonstração ou para investidores usando HyperFrames a partir de um aplicativo web ao vivo, um protótipo ou um arquivo Figma público. Abrange o roteiro com uma tabela de alegações, captura de ativos (telas, gravações de rolagem e interação, quadros Figma), TTS local ou narração fornecida, temporizações alinhadas ao roteiro, legendas em karaokê, um gerador de composição, validação e renderização.

O que é product-video?

Esta skill cria vídeos narrados de 60 a 120 segundos que apresentam produtos usando suas telas reais, gerando um projeto HyperFrames (um arquivo `index.html` mais ativos) e um MP4 renderizado. Ela é ideal para desenvolvedores e criadores que precisam de vídeos de demonstração, apresentação ou para investidores com qualidade profissional, sem depender de edição manual complexa. A skill suporta captura de aplicativos web ao vivo, protótipos e arquivos Figma públicos, além de integração com serviços de voz como ElevenLabs via MCP ou chave de API, narração fornecida pelo usuário ou modelos TTS locais. O fluxo de trabalho é organizado em fases (Fontes, Roteiro, Ativos, Voz, Composição, Verificação e Entrega), cada uma com verificações para garantir consistência, e inclui recursos como legendas em karaokê alinhadas ao texto do roteiro, temporizações precisas e geração de composições verticais para Stories/Reels. Uma tabela de armadilhas comuns (por exemplo, animações correspondendo a palavras erradas, legendas com erros de transcrição, narração com tom inconsistente) ajuda a evitar problemas já conhecidos, tornando o processo mais robusto.

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

Perguntar na sua IA favorita

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

Documentação

Product video (Vídeo de produto)

Construa um vídeo narrado de 60 a 120 segundos que apresente um produto usando suas telas reais. A saída é um projeto HyperFrames (um arquivo index.html gerado mais ativos) e um MP4 renderizado.

Escreva cada entrega (roteiro, texto na tela, README) no idioma do público. Este arquivo está em inglês apenas porque são instruções.

Layout de saída

Crie uma pasta por vídeo, fora de qualquer repositório de código, a menos que o usuário diga o contrário:

<Product>-video/
  ROTEIRO.md | SCRIPT.md     script, tabela de alegações, pontos a confirmar
  LEIA-ME.md | README.md     o que é real, o que foi reconstruído, limitações, como reexecutar
  01-.. 0N-..                ativos capturados, uma pasta por fonte
  voz/ | voice/              segmentos de narração (texto e áudio por cena)
  ferramentas/ | tools/      configurações e gen.js (o gerador de composição)
  hyperframes/
    index.html               GERADO. Nunca editar manualmente.
    assets/{img,video,audio,fonts}
    renders/

Fluxo de trabalho

Execute as fases em ordem. Cada uma termina com uma verificação; não inicie a próxima fase até que a verificação seja aprovada.

P1. Fontes

  1. Localize cada fonte que o usuário nomeou. Um caminho de outra máquina não existirá: procure pelo mesmo projeto nas pastas do usuário atual e diga qual você usou.
  2. Classifique como o produto pode ser mostrado:
    • Aplicativo ao vivo, acessível: capture-o (P3, scripts/site-capture.cjs, scripts/record-interaction.cjs).
    • Arquivo Figma público: capture quadros através da visualização de protótipo (P3, scripts/figma-frames.cjs). Nenhum token é necessário.
    • Atrás de um login sem acesso: peça capturas de tela ou uma conta de teste. Não reconstrua telas de memória.
  3. Extraia as próprias palavras do produto: texto da página de destino, nomes de recursos, números, FAQ, termos. Estas são as únicas fontes permitidas para alegações.

Verificação: você pode nomear o público, os módulos do produto e a fonte de cada fato que planeja usar.

P2. Roteiro

Leia references/script.md e escreva o arquivo de roteiro a partir do seu modelo. As regras mais importantes:

  • Orçamento de 2,3 a 2,6 palavras faladas por segundo. 250 palavras equivalem a cerca de 100 segundos.
  • Uma ideia por cena, 8 a 16 segundos por cena, 6 a 9 cenas.
  • Cada alegação na narração tem uma linha na tabela de alegações com sua fonte. Deixe de fora qualquer coisa que as fontes não possam respaldar.
  • Escreva para a voz: nomes de marcas como são pronunciados, números por extenso, sem abreviações que a voz soletraria letra por letra.

Verificação: a tabela de alegações não tem células de fonte vazias, e a lista "pontos a confirmar" nomeia cada número que veio do texto de marketing.

P3. Ativos

Leia references/capture.md para exemplos de configuração.

FonteScriptSaída
Aplicativo web ao vivo, estáticoscripts/site-capture.cjsprimeira dobra, página completa, capturas de tela por etapa, vídeos de rolagem, recortes
Aplicativo web ao vivo, fluxosscripts/record-interaction.cjsclipes de interação com cursor ou overlay de toque
Arquivo Figma públicoscripts/figma-frames.cjsum PNG por quadro, recortado no quadro

Também colete a marca: logotipo (vetorial se existir), os arquivos de fonte da marca com sua licença e os tokens de cor do CSS do produto. Leia os estilos que as próprias páginas do produto usam com scripts/page-styles.cjs <url>: família do título, peso, altura da linha e espaçamento entre letras, estilos de botão e qualquer superfície de vidro fosco. O vídeo os copia em vez de adivinhar.

Verificação: abra algumas capturas e olhe para elas. Uma captura que mostra uma tela de login, um banner de cookies ou um overlay de desenvolvimento é uma captura falha.

P4. Voz

Leia references/voice.md. Pergunte qual voz o usuário tem antes de gerar qualquer coisa: um serviço pago acessado via MCP ou chave de API vem primeiro, uma narração fornecida em segundo. Um modelo local gratuito é apenas para um usuário que solicite um, pois instala um modelo na máquina dele.

  • Serviço de voz via MCP: gere toda a narração como uma única tomada contínua (um parágrafo por cena, uma tag de entrega no início). Alinhe com scripts/voice.py --existing, corte nas pausas com scripts/split-take.py --level, depois junte os arquivos de cena com scripts/voice.py --parts "voz/cena-{id}.wav". Os limites das cenas são exatos e o tom permanece o mesmo desde a primeira até a última cena. Uma narração solicitada cena por cena muda o humor entre as solicitações.
  • Serviço de voz via chave de API: scripts/voice.py --provider elevenlabs --el-voice <id> gera e junta. scripts/elevenlabs.py verifica a conexão, classifica vozes e compõe música.
  • Narração fornecida: passe --existing. Os limites das cenas vêm do alinhamento da transcrição ao roteiro.

Com um modelo expressivo, defina a entrega com uma [tag de áudio] no início da tomada. Cada cena carrega text (limpo, para legendas) e pode carregar tts (o que a voz recebe, quando difere).

Em todos os modos, as temporizações das palavras são alinhadas ao texto do roteiro, então as legendas nunca mostram um erro de transcrição. Leia a lista de misheard que imprime: qualquer coisa além de números por extenso e homófonos é um problema de pronúncia. Corrija o texto do roteiro e regenere.

Normalize a narração para aproximadamente −18 LUFS antes de compor.

Verificação: voiceover.json existe, a duração total está dentro de 10% do alvo, misheard está explicado e scripts/voice-tone.py --scenes relata uma dispersão da mediana do tom entre as cenas de cerca de 3 semitons ou menos.

P5. Composição

Leia references/hyperframes.md (as regras que o renderizador aplica) e comece a partir de assets/gen-template.js.

  • Gere index.html a partir de um script. Mudanças de tempo acontecem sempre que a voz muda; um gerador absorve isso, edições manuais não.
  • Ancore cada animação a uma frase da narração (at(3, 'No painel')), nunca a uma única palavra curta. "no", "e" e "um" ocorrem várias vezes por cena e a primeira correspondência é a errada.
  • Reserve os 17% inferiores do quadro para legendas. Nada mais entra nessa faixa.
  • Mostre telas reais dentro de um mockup de janela de navegador ou dispositivo. Coloque a explicação ao lado, não em cima dela.
  • Prefira um destaque claro por frase (um anel, um zoom, um movimento do cursor) em vez de muitos pequenos.
  • Os títulos usam o próprio estilo de título do produto e as tags usam a linguagem de superfície dele, ambos lidos em P3. Não use o peso mais pesado por padrão.
  • Para Stories, Reels ou Shorts, leia references/vertical.md e construa uma segunda composição vertical a partir da mesma narração, começando de assets/gen-vertical-template.js. Nunca recorte a composição 16:9.

Verificação: npx hyperframes lint tem 0 erros.

P6. Verificar

  1. npx hyperframes check deve terminar com "Check passed" (lint, runtime, layout, motion, contraste).
  2. npx hyperframes snapshot --no-end --at <um horário por cena, mais cada destaque> e olhe para cada quadro. Monte folhas de revisão 2×2 com ffmpeg para revisar mais rápido.
  3. Compare cada quadro com o que a narração diz naquele segundo. Os defeitos comuns: tela errada para a frase, destaque no elemento errado, quebra de texto, um elemento dentro da faixa de legendas.
  4. Renderize um rascunho (render -q draft), depois verifique o próprio MP4: ffprobe para duração e streams, loudnorm para volume (alvo −16 a −17 LUFS com música) e quadros extraídos com ffmpeg.

Verificação: você olhou um quadro de cada cena retirado do MP4, não apenas das capturas instantâneas.

P7. Entrega

Escreva o README com: o que é real (capturado), o que foi reconstruído em HTML com dados reais, o que é conceitual, limitações conhecidas, os comandos para pré-visualizar, verificar e renderizar, e como trocar a voz. Depois informe ao usuário: o que foi feito, o que foi verificado e o que ainda precisa de uma decisão humana (números não confirmados, música, qualidade da voz).

Armadilhas já pagas

CódigoSintomaCausa e correção
X1As telas mudam um segundo antesat() correspondeu ao primeiro "no" ou "e". Âncore em frases.
X2Um elemento permanece oculto por cenas inteirasDois fromTo tweens no mesmo elemento; o posterior renderiza seu estado "from" imediatamente. Use um elemento por aparição, ou to() a partir de um estado CSS inicial.
X3O site responde 403 ao script, mas abre no navegadorUser agent headless. Use lib/browser.cjs, que envia um UA de desktop.
X4"Executable doesn't exist" na inicializaçãoA versão do navegador instalado difere da versão do Playwright. lib/browser.cjs recai para o Chromium local mais recente, depois Chrome.
X5Captura de página inteira é cortada em uma dobraO aplicativo rola um contêiner interno. Encontre o maior elemento rolável e aumente a janela de visualização para sua altura.
X6Gravação de rolagem gaguejaA taxa de quadros da screencast é variável. Renderize rolagens quadro a quadro.
X7Você continua verificando um arquivo que nunca mudaO gravador escreve em uma pasta diferente da que você inspeciona. Imprima e verifique o caminho de saída.
X8Um contador renderiza minúsculo ao lado de um enorme "%"Um seletor descendente (.num span) também correspondeu ao span do contador interno. Use seletores filhos para rótulos.
X9As legendas mostram uma palavra erradaAs legendas vieram da transcrição bruta. Alinhe as temporizações ao texto do roteiro (voice.py faz isso).
X10A voz pronuncia mal a marca ou um termoEscreva como falado (uma marca escrita como uma palavra é narrada como duas, um termo estrangeiro recebe uma frase nativa), escreva números por extenso, expanda abreviações.
X11Uma segunda execução de captura apagou o índice da primeiraMescle arquivos de índice entre execuções em vez de sobrescrever.
X12Vídeo dentro de um wrapper cronometrado falha na verificaçãoA mídia cronometrada carrega class="clip" ela mesma; seu contêiner não tem temporização.
X13A captura de protótipo inclui um toast ou barra de cookiesFeche e oculte overlays antes da captura de tela, depois recorte no quadro.
X14A gravação mostra botões apenas de protótipoOculte controles de teste e desenvolvimento por seletor ou prefixo de texto antes de gravar.
X15Alegações que o produto não pode provar"Primeiro", "total", "garantido" precisam de uma fonte. Deixe-as de fora ou mova para "pontos a confirmar".
X16Um número de marketing não tem baseVerifique de onde veio antes de usá-lo: pesquise nos documentos e no histórico git da página (git log -S'<número>'). Um número levantado manualmente em uma edição de texto não é evidência. Remova-o.
X17Corte vertical é ilegívelUma tela de desktop em 9:16 tem texto de 9 px, e um recorte dela ainda parece desktop. Mostre um elemento adaptado por vez em um painel, como a página móvel do produto faz (references/vertical.md).
X18Narração soa dramática ou eufóricaTags não verbais ([suspira]), [animado] e [sério] exageram em um vídeo de produto. Use [calmo] e [caloroso], regenere apenas as cenas nomeadas e compare as tomadas com scripts/voice-tone.py.
X19Layout parece uma página webColuna alinhada à esquerda, rótulos de seção acima dos títulos, logotipo pequeno no canto. Em vídeo vertical: centralize tudo, remova os rótulos, torne o logotipo maior e centralizado.
X20Tagline fica longe do logotipoA exportação do logotipo tem preenchimento transparente. Apare o arquivo e posicione contra a marca real.
X21Narração é plana em algumas cenas e animada em outrasCada cena foi uma solicitação separada com sua própria tag, então cada uma foi uma performance separada. Gere uma única tomada contínua com uma tag, corte nas pausas com scripts/split-take.py e meça com scripts/voice-tone.py --scenes. Uma dispersão de 5 semitons entre cenas foi ouvida como oscilações de humor, 2 como uniforme.
X22Títulos parecem pesados e diferentes do produtoO peso foi assumido (800). Leia o estilo de título do produto com scripts/page-styles.cjs e copie família, peso, altura da linha e espaçamento entre letras.
X23Palavras se juntam em um títuloO espaçamento apertado entre letras copiado de uma página web fecha os espaços entre as palavras em tamanhos de vídeo. Adicione word-spacing: .07em.
X24Uma tag de vidro parece branco sólido, ou seu desfoque aparece após o fadeO fundo é muito opaco (mantenha a parte inferior perto de 0,6), ou o fade está em um pai: opacidade abaixo de 1 em um ancestral corta o elemento do que está atrás dele. Anime o elemento que tem backdrop-filter.
X25A verificação de contraste falha em texto que parece bomA verificação amostrou um quadro no meio de um fade. Tire uma captura instantânea no horário relatado. Se o elemento está entrando no meio, mova a entrada alguns quadros e execute a verificação novamente. Composições muito curtas sofrem mais com isso.

Arquivos nesta skill

  • references/script.md: modelo de roteiro, ritmo, tabela de alegações, tabela de pronúncia.
  • references/capture.md: configurações para os três scripts de captura, especificações de captura, ativos da marca.
  • references/voice.md: configuração de TTS, vozes, alinhamento, volume, música, troca da narração.
  • references/hyperframes.md: regras de composição, comandos CLI, zonas de layout.
  • references/vertical.md: versão 9:16 para Stories: área segura, câmera na tela, legendas, divisão em partes.
  • assets/gen-template.js: gerador de composição 16:9 para copiar para a pasta de ferramentas do projeto.
  • assets/gen-vertical-template.js: gerador vertical com uma edição completa e uma curta.
  • scripts/lib/browser.cjs, scripts/site-capture.cjs, scripts/record-interaction.cjs, scripts/figma-frames.cjs, scripts/element-shots.cjs, scripts/page-styles.cjs, scripts/voice.py, scripts/split-take.py, scripts/voice-tone.py, scripts/elevenlabs.py, scripts/lib/eleven.py.

O código da API ElevenLabs (--provider elevenlabs, elevenlabs.py) foi escrito sem uma chave para testar. Sua primeira execução real pode precisar de uma correção; a rota --parts e a rota local são testadas.

Habilidades Relacionadas