O que saas-demo-maker faz?
Visão Geral
Este skill captura screenshots de qualquer aplicação web ou local e renderiza um vídeo de demonstração SaaS polido e silencioso (MP4). Ele é modelado no pipeline Castify comprovado em ~/SaaS/castify/generate_castify_demo.py e generalizado para qualquer projeto Aperone.
Quando invocado, você DEVE produzir um MP4 até o final da sessão. Não pare com "aqui está um plano" — execute-o.
Quando Usar
Use este skill sempre que um dos seguintes se aplicar (incluindo correspondência parcial ou paráfrase).
Gatilhos em Japonês
- デモ動画 / デモMP4 / デモ動画を作って / デモ動画を生成して
- プロモ動画 / 紹介動画 / サービス紹介動画
- スクショ撮って動画にして / スクリーンショットを動画にして
- 動画を作って(SaaSやアプリの文脈)
- 既存のスクショから動画を作って
- 画面録画(伝える代わりに静止画合成を使用)
Gatilhos em Inglês
- demo video / demo MP4 / product demo
- promotional video / promo video / intro video
- screenshot to video / capture and render
- make a video from screenshots
Comando Direto /saas-demo-maker
Casos Duvidosos (Pode Ativar)
- Contém "vídeo", "MP4", "screenshot" e tem contexto de aplicativo, SaaS ou ferramenta
- Menção a um aplicativo local ou URL pública
- Pedido como "faça um vídeo a partir de imagens existentes"
Entradas
Extraia da mensagem do usuário:
| Entrada | Padrão | Notas |
|---|---|---|
url | — | URL completa ou http://localhost:3000 |
product_name | inferido do projeto | Usado no pill e na configuração |
brand_color | #7c3aed | Substitui a constante VIOLET |
screens | 5 | Número de screenshots a capturar |
output_path | output/saas_demo.mp4 | Relativo à raiz do projeto |
mode | full | full / capture / render |
locale | ja se mensagem em japonês, senão en | Afeta o texto dos passos |
steps | predefinição de templates.md | Texto fornecido pelo usuário tem prioridade |
assets_dir | output/screenshots | Imagens de origem para o modo render |
Modos
Modo full (completo)
Captura screenshots de uma URL ativa ou aplicativo local e renderiza o vídeo.
Exemplos de gatilho:
/saas-demo-maker https://castify.aperone.com からサービスカード用デモ動画を作って。5画面、20秒以内、ブランドカラーは#7c3aed、出力はoutput/castify_demo.mp4
/saas-demo-maker http://localhost:3000 のLP、ログイン、ダッシュボード、入力、結果画面を撮って、無音ループ用のSaaSデモMP4を作って
Modo capture (captura)
Apenas captura de screenshots — sem renderização de vídeo.
Exemplos de gatilho:
/saas-demo-maker スクショだけ撮って。LP、ログイン、ダッシュボード、入力、結果の5枚
Modo render (renderização)
Renderiza vídeo a partir de screenshots existentes — sem etapa de captura.
Exemplos de gatilho:
/saas-demo-maker assetsの既存スクショ5枚から動画だけ作って。プロダクト名はAperone Academy、ブランドカラーは#7c3aed
/saas-demo-maker assetsの5枚から動画だけ作って。プロダクト名はCastify、出力はoutput/castify_demo.mp4
Fluxo de Trabalho
Etapa 0 — Pré-voo
- Leia
demo_config.jsonse existir no projeto atual. - Verifique screenshots existentes em
output/screenshots/ouassets/. - Detecte o modo a partir da mensagem do usuário (padrão:
full). - Confirme se o diretório
output/existe ou crie-o.
Etapa 1 — Gerar configuração
Escreva demo_config.json na raiz do projeto:
- Use valores extraídos da mensagem do usuário.
- Escolha textos de passos da predefinição
templates.mdcorrespondentes aproduct_name, ou modelo genérico para o número de telas, ou texto fornecido pelo usuário. - Escreva o arquivo agora, antes de qualquer geração de script.
Etapa 2 — Escrever scripts (modo full ou capture)
Escreva capture_screenshots.py na raiz do projeto.
Escreva generate_saas_demo.py na raiz do projeto.
Escreva README_demo_video.md na raiz do projeto (apenas na primeira vez; pule se existir).
Para o modo render, pule capture_screenshots.py.
Etapa 3 — Instalar dependências (se ausentes)
Verifique e instale conforme necessário (veja reference.md para comandos):
ffmpeg—which ffmpeg || brew install ffmpegpillow—python3 -c "import PIL" || python3 -m pip install pillow- Para captura TypeScript: verifique se
node_modules/playwrightexiste
Etapa 4 — Capturar (modo full ou capture)
Execute o script de captura:
python3 capture_screenshots.py
Ou se o projeto possui um script de captura Playwright TypeScript existente (por exemplo, scripts/demo-screenshots.ts), prefira esse:
npx tsx scripts/demo-screenshots.ts
Verifique se output/screenshots/ contém pelo menos 2 arquivos PNG após a captura.
Se a captura falhar, leia o erro, corrija capture_screenshots.py e tente novamente.
Etapa 5 — Renderizar (modo full ou render)
Execute:
python3 generate_saas_demo.py
Observe os erros. Se o script travar, leia o traceback, corrija o script e execute novamente. Não pergunte ao usuário — auto-cure até 3 tentativas.
Etapa 6 — Verificação de qualidade
Execute ffprobe para verificar:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,duration,codec_name,pix_fmt \
-of default output/saas_demo.mp4
Verifique todos os 10 itens da lista de verificação de qualidade em reference.md.
Se algum item falhar, corrija e renderize novamente.
Etapa 7 — Relatório
Produza a resposta final (veja "Formato da resposta final" abaixo).
Especificação de Captura de Screenshot
Resolução
1280 × 720 (viewport do Chromium)
Navegador
Playwright Chromium, headless.
Estratégia de Espera
await page.goto(url, wait_until="networkidle")
await page.wait_for_timeout(800) # tempo extra de estabilização
URLs Locais Candidatas (tentar em ordem)
http://localhost:3000
http://localhost:5173
http://localhost:8000
http://localhost:8080
Diretório de Saída
output/screenshots/ relativo à raiz do projeto.
Nomes de Arquivo Padrão
01-landing.png
02-login.png
03-dashboard.png
04-input.png
05-result.png
06-options.png (se 6+ telas)
07-processing.png (se 7 telas)
Inicialização do Aplicativo Local
- Leia
package.jsonpara encontrar o script de desenvolvimento (dev,start, etc.). - Inicie o servidor de desenvolvimento em segundo plano.
- Aguarde até que a URL candidata responda (máx. 30 s).
- Capture screenshots.
- Pare o servidor de desenvolvimento.
Tratamento de Autenticação
- Se
.envcontiver credenciais de teste e uma flag de bypass de desenvolvimento (por exemplo,DEV_BYPASS_AUTH=true), defina-a no ambiente antes de iniciar. - Para telas de login: preencha um email de demonstração (
demo@<product>.io) sem enviar — capture o estado preenchido como a tela de login. - Não tente bypass real de autenticação ou brute-force de login.
- Se uma página redirecionar para login e o bypass não estiver disponível, use a tela de login como uma das telas de demonstração (parece credível).
Artefatos do Modo de Desenvolvimento
Banner do modo de desenvolvimento do Clerk, indicador de desenvolvimento do Next.js, sobreposições de depuração — NÃO tente removê-los no navegador. Em vez disso, cubra-os na etapa de renderização com uma sobreposição gradiente ou um painel escuro na parte inferior do cartão.
Especificação de Renderização
Arquitetura
Gere todos os quadros como arquivos PNG em output/frames/, depois codifique com ffmpeg.
NÃO use moviepy para codificação — use subprocess ffmpeg diretamente.
Redimensionamento de Imagem
card = ImageOps.fit(image.convert("RGBA"), (card_w, card_h),
method=Image.Resampling.LANCZOS)
Este é o ÚNICO método de redimensionamento de imagem permitido. O screenshot deve estar completamente estático dentro de cada cena — sem zoom, sem panorâmica, sem Ken Burns.
Ken Burns — PROIBIDO
Não aplique qualquer fator de escala por quadro ou deslocamento de posição ao screenshot. O conteúdo de pixel do screenshot não deve mudar entre o quadro 0 e o quadro 98 de uma cena. Apenas sobreposições (legenda, pill, barra de progresso, glow) podem animar.
Animação de Legenda (permitida)
O painel de legenda pode aparecer gradualmente e transladar 8 px para cima nos primeiros 20% de uma cena (scene_t < 0.2). Esta é a única animação permitida na camada de imagem.
Temporização
SCENE_SECONDS = 3.3 # fixo — não altere
TRANSITION_SECS = 0.4 # fixo — não altere
FPS = 30
SCENE_FRAMES = 99
TRANSITION_FRAMES = 12
Transição
Deslize horizontal: o quadro de saída sai pela esquerda, o quadro de entrada entra pela direita.
Use ease_in_out_cubic. Adicione um véu estreito de suavização de costura no limite do corte.
Veja reference.md para o algoritmo completo.
Comando ffmpeg
Use o comando exato de reference.md. Flags principais:
-c:v libx264 -pix_fmt yuv420p -movflags +faststart -an -crf 18
Regras de Design Visual
Fundo
#020617 (BG) — preenche atrás do cartão
Layout do Cartão
card_box = (34, 22, WIDTH-34, HEIGHT-22)
radius = 30
Linha de destaque cromada no topo em card_box[1] + 48.
Borda do cartão: 1 px CARD_EDGE.
Sobreposições (todas obrigatórias)
- Barra de progresso — segmentada, topo do cartão, preenchimento violeta para etapas concluídas
- Painel de legenda — canto inferior esquerdo, painel escuro vítreo, ETAPA N / nome / corpo
- Pill do produto — canto inferior direito, ponto da cor da marca + nome do produto
- Glow de foco — brilho violeta ao redor do elemento de UI chave (veja reference.md para inferência)
- Vinheta — borda escura sutil arredondada no quadro completo
- Gradiente inferior — cobre artefatos do modo de desenvolvimento na área inferior do cartão quando necessário
Elementos de Design Proibidos
- Texto branco em caixa preta lisa (sem efeito vítreo)
- Brilho excessivo / glow supersaturado
- Transformações 3D ou deformações de perspectiva
- Qualquer distorção da UI do screenshot
- Editar ou substituir texto visível no screenshot
Regras de Configuração
Escreva demo_config.json antes de executar qualquer script.
Ao re-executar no modo render, leia a configuração existente primeiro e mescle as substituições do usuário em vez de sobrescrever.
Esquema:
{
"product_name": "string",
"brand_color": "#7c3aed",
"output_path": "output/saas_demo.mp4",
"screenshots": ["output/screenshots/01-landing.png"],
"steps": [{ "step": 1, "name": "...", "body": "...", "focus": null }],
"fps": 30,
"resolution": [1280, 720],
"mode": "full",
"locale": "ja"
}
Requisitos de Implementação
Responsabilidades de capture_screenshots.py:
- Iniciar Playwright Chromium headless
- Definir viewport 1280 × 720
- Navegar para cada URL alvo, aguardar networkidle + 800 ms de estabilização
- Salvar PNGs em
output/screenshots/com nomes de arquivo padrão - Mover o mouse para fora da tela antes de cada screenshot (
page.mouse.move(1400, 800)) - Imprimir sucesso/falha por screenshot
- Código de saída 0 em sucesso, 1 em falha
generate_saas_demo.py deve conter todas as funções listadas em reference.md.
Invariantes principais:
SCENE_SECONDS = 3.3— codificado, sem substituição por configuraçãoTRANSITION_SECONDS = 0.4— codificado, sem substituição por configuraçãofit_cover()chamaImageOps.fit()— sem aritmética de zoomrender_scene()NÃO modifica escala por quadroencode_video()chama subprocess ffmpeg com flag-an
Lista de Verificação de Qualidade
Após encode_video() ser bem-sucedido, verifique TODOS os seguintes antes de relatar conclusão:
output/saas_demo.mp4existe, tamanho > 100 KB- Duração dentro de ±2 s de (quantidade_de_telas × 3.3 s)
- Largura=1280, Altura=720 (confirmado por ffprobe)
- Nenhum fluxo de áudio
- codec_name = h264
- pix_fmt = yuv420p
- Todos os screenshots aparecem na ordem correta
- Nenhum banner de modo de desenvolvimento visível flagrante (coberto por sobreposição se necessário)
- Tela de resultado/saída comunica claramente o valor do produto
- Texto da legenda é legível em todas as cenas
Execute esta verificação:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,duration,codec_name,pix_fmt \
-of default output/saas_demo.mp4
Recuperação de Falhas
| Falha | Recuperação |
|---|---|
ffmpeg não encontrado | brew install ffmpeg, depois tente novamente |
PIL não encontrado | python3 -m pip install pillow, depois tente novamente |
| Captura retorna 0 imagens | Verifique a URL, verifique se o servidor está ativo, corrija o script e tente novamente |
| Falha na renderização | Leia o traceback, corrija generate_saas_demo.py e tente novamente (até 3 tentativas) |
| Falha na verificação de qualidade | Corrija o problema específico e renderize novamente |
| Playwright não instalado | npm install playwright ou npx playwright install chromium |