Produtor Automático de Demonstrações
Produza demonstrações em vídeo narradas e profissionais de QUALQUER aplicação web — automaticamente.
Visão Geral do Pipeline
Contexto do usuário → Roteiro da demonstração → Slides → Narração TTS → Gravação do navegador → MP4 final
Três fases, totalmente automatizadas:
- Narração — edge-tts (Microsoft Neural TTS gratuita) gera áudio por cena
- Gravação — Playwright controla Chromium sem cabeça com captura de vídeo
- Montagem — ffmpeg mescla vídeo + áudio em MP4 polido
Quando Ativar
- O usuário pede para "criar uma demo", "gravar um tutorial" ou "fazer um vídeo de demonstração"
- O usuário fornece uma URL + descrição do que mostrar
- O usuário quer uma gravação de tela automatizada com narração
Fluxo de Trabalho Passo a Passo
Passo 1: Coletar Contexto
Pergunte ao usuário:
- URL de destino — o aplicativo web a ser demonstrado (ex.:
https://meuapp.azurewebsites.net) - O que mostrar — principais recursos, fluxos de usuário ou cenários
- Público-alvo — quem vai assistir? (executivos, desenvolvedores, clientes)
- Duração desejada — quanto tempo a demo deve ter? (1-5 min típico)
- Preferência de voz — idioma e gênero (padrão:
en-US-JennyNeural) - Marca — nome do produto, subtítulo, organização, cor de destaque para intro/outro
Passo 2: Criar Roteiro da Demonstração
Gere um arquivo demo_script.md usando este formato:
# Demo: {Nome do Produto}
## intro | 5
> slide intro
Bem-vindo a esta demonstração do Nome do Produto. Hoje vamos percorrer os principais recursos.
## login | 8
> goto {base_url}
> fill Nome de usuário [email protected]
> fill Senha ****
> click button Entrar
Aqui fazemos login no aplicativo usando nossas credenciais de demonstração.
## dashboard | 10
> wait 2
> scroll down 300
O painel mostra uma visão geral em tempo real de todos os itens ativos.
## feature_one | 12
> click link Recurso Um
> wait 1
> scroll down 200
Vamos explorar o Recurso Um, que permite criar e gerenciar fluxos de trabalho.
## outro | 5
> slide outro
Obrigado por assistir! Visite-nos em contoso.com para mais informações.
Regras de formato do roteiro:
## id_da_cena | duração_mínima_em_segundos— cabeçalho da cena> ação argumentos...— ações do Playwright (consulte a Referência de Ações abaixo)- Linhas de texto simples = narração (falada pela voz TTS)
- A narração determina a duração real da cena (preenchida para corresponder ao comprimento do áudio)
Passo 3: Gerar Slides
Execute o gerador de slides para criar arquivos HTML de intro/outro:
python generate_slides.py `
--title "Nome do Produto" `
--subtitle "Seu slogan aqui" `
--org "Contoso" `
--badge "Desenvolvido pela Azure" `
--accent "#60a5fa" `
--out-dir ./slides
Passo 4: Instalar Dependências
pip install edge-tts playwright
playwright install chromium
# Certifique-se de que ffmpeg está disponível:
# Windows: winget install Gyan.FFmpeg
# macOS: brew install ffmpeg
# Linux: sudo apt install ffmpeg
Passo 5: Executar o Gravador
python record_demo.py `
--script demo_script.md `
--base-url "https://meuapp.azurewebsites.net" `
--voice en-US-JennyNeural `
--slides-dir ./slides `
--output demo_final.mp4
Opções adicionais:
--resolution 1280x720para tamanho de arquivo menor--var project_id=abc123para variáveis personalizadas no script--var [email protected]para fluxos parametrizados
Passo 6: Revisar e Iterar
Após a gravação, revise o vídeo de saída. Ajustes comuns:
- Muito rápido? Aumente
min_durationnos cabeçalhos das cenas - Tempo errado? Adicione ações
> wait Nentre as etapas - Etapas ausentes? Adicione mais cenas ao roteiro
- Voz errada? Tente uma voz diferente do edge-tts
Referência de Ações
| Ação | Sintaxe | Descrição |
|---|---|---|
goto | > goto https://url.com | Navegar para URL |
slide | > slide intro | Mostrar slide HTML do diretório de slides |
click | > click link Texto do Link | Clicar em um link pelo texto |
click | > click button Texto do Botão | Clicar em um botão pelo texto |
click | > click text Qualquer Texto | Clicar em qualquer elemento pelo texto |
fill | > fill Rótulo valor | Preencher uma caixa de texto de formulário |
type | > type #seletor valor | Digitar em elemento pelo seletor CSS |
hover | > hover Texto do Elemento | Passar o mouse sobre o elemento |
select | > select Rótulo Opção | Selecionar opção de lista suspensa |
scroll | > scroll down 300 | Rolar para baixo por pixels |
scroll | > scroll up 200 | Rolar para cima por pixels |
wait | > wait 2 | Pausar por N segundos |
screenshot | > screenshot nome.png | Salvar captura de tela |
Seleção de Voz
Vozes populares do edge-tts (todas gratuitas, sem necessidade de chave de API):
| Voz | Idioma | Estilo |
|---|---|---|
en-US-JennyNeural | Inglês (EUA) | Calorosa, conversacional |
en-US-GuyNeural | Inglês (EUA) | Profissional, clara |
en-US-AriaNeural | Inglês (EUA) | Natural, versátil |
en-GB-SoniaNeural | Inglês (Reino Unido) | Polida, profissional |
it-IT-IsabellaNeural | Italiano | Natural, clara |
de-DE-KatjaNeural | Alemão | Profissional |
fr-FR-DeniseNeural | Francês | Elegante |
es-ES-ElviraNeural | Espanhol | Clara |
ja-JP-NanamiNeural | Japonês | Natural |
zh-CN-XiaoxiaoNeural | Chinês | Versátil |
Lista completa: edge-tts --list-voices
Variáveis
Use {nome_da_variável} nos scripts. Integradas:
{base_url}— definida via argumento--base-url
Variáveis personalizadas via --var chave=valor:
> goto {base_url}/projects/{project_id}
> fill Pesquisar {search_term}
Saída
A skill produz:
demo_final.mp4— vídeo H.264, áudio AAC, otimizado para web (faststart)- Resolução: 1920×1080 (padrão) ou personalizada
- Qualidade: CRF 18 (alta qualidade), AAC 192kbps
Dicas para Demonstrações Incríveis
- Roteiro primeiro — Escreva a narração antes das ações. A história dita o ritmo.
- Cenas curtas — 8-15 segundos por cena. Mantenha o ritmo.
- Esperas generosas — Adicione
> wait 1-2após navegações para dar espaço visual. - Combine narração com ação — Descreva o que está acontecendo na tela enquanto acontece.
- Slides de intro/outro — Sempre use-os para um acabamento profissional.
- Teste incrementalmente — Grave uma cena primeiro para verificar o tempo e depois adicione mais.
- Consistência de marca — As cores dos slides de intro/outro DEVEM corresponder à paleta da marca do PoC (do
threadlight-designpadrão transversal 1). Não use gradientes azul/roxo padrão para um cliente com marca vermelha. Copie as propriedades personalizadas CSS dodemo-deck.htmldo PoC para os arquivos HTML dos slides. - Legendas — Gere um arquivo WebVTT a partir do texto da narração. NÃO use
<track src="arquivo.vtt">externo — o Edge bloqueia CORS no protocolofile://. Em vez disso, incorpore o VTT inline como uma URL blob JS:var blob = new Blob([vttData], {type:'text/vtt'}); track.src = URL.createObjectURL(blob);e anexe dinamicamente o elemento<track>. Os carimbos de data/hora DEVEM usar o formatoHH:MM:SS.mmm(nãoMM:SS.mm— o Edge rejeita). - Incorporar no deck — Se o PoC enviar um
demo-deck.html, incorpore o vídeo como fallback no cartão de demonstração ao vivo. Ative uma alternância com a teclaV: pressione V para reproduzir o vídeo inline no slide.is-cue, pressione V novamente para parar. Adicione uma barra de controle visível (botão play/pause + barra de progresso clicável + exibição de tempo) para que o apresentador não dependa apenas de atalhos de teclado. Pare automaticamente no eventoended. A dica de fallback ("Pressione V para fallback pré-gravado") aparece abaixo do texto da deixa com baixa opacidade.
Gravação de Demonstrações de Agentes (padrão testado em batalha)
Esta seção foi extraída de 6 tentativas de gravação fracassadas em um PoC de agente hospedado no Foundry. Os padrões abaixo são a única abordagem que produz de forma confiável um vídeo assistível quando o tempo de resposta do agente é imprevisível (10–50 segundos).
O problema
Demonstrações de agentes de IA não são graváveis em tempo real. O agente leva 10–50 segundos para responder. Se você gravar o navegador continuamente e sobrepor o áudio de narração pré-gerado, a voz descreve a resposta enquanto a tela ainda mostra "Trabalhando...". Nenhuma quantidade de aceleração ou deslocamento de áudio na pós-produção corrige isso de forma confiável — as duas linhas do tempo estão fundamentalmente dessincronizadas.
A solução: cortes de salto por captura de tela por cena
Nunca mostre "Trabalhando..." no vídeo. Faça um corte de salto de "pergunta digitada" diretamente para "resposta renderizada". A espera do agente acontece fora da câmera entre as capturas de tela.
Fluxo de trabalho por cena:
- Digite o prompt → capture a tela do estado digitado (o narrador apresenta a pergunta sobre este quadro)
- Clique em "Perguntar" → faça polling até que a resposta seja totalmente renderizada (fora da câmera — sem gravação)
- Capture a tela da resposta concluída (o narrador descreve a resposta sobre este quadro)
- Construa o segmento: imagem estática + clipe de áudio de narração correspondente (duração exata)
- Concatene todos os segmentos: intro → K1digitado → K1pronto → K2digitado → K2pronto → … → outro
Espera inteligente — polling de aparecimento → desaparecimento:
# Fase 1: aguarde o indicador de carregamento APARECER (confirma que a chamada à API foi iniciada)
for _ in range(30):
if await page.evaluate("() => !!document.body.innerText.match(/Working/)"):
break
await page.wait_for_timeout(500)
# Fase 2: aguarde o indicador de carregamento DESAPARECER (confirma que a resposta foi renderizada)
for _ in range(120):
if not await page.evaluate("() => !!document.body.innerText.match(/Working/)"):
break
await page.wait_for_timeout(1000)
await page.wait_for_timeout(2000) # deixe o DOM estabilizar
Adapte a regex (/Working/) para corresponder a qualquer indicador de carregamento que o
ambiente de trabalho use. O padrão de 2 fases evita o bug comum onde o
script verifica antes que "Trabalhando..." apareça e prossegue imediatamente.
Construindo um segmento a partir de uma imagem estática + áudio:
def make_segment(image_path, audio_path, output_path):
audio_dur = ffprobe_duration(audio_path)
subprocess.run([
"ffmpeg", "-y",
"-loop", "1", "-i", str(image_path),
"-i", str(audio_path),
"-c:v", "libx264", "-preset", "fast", "-crf", "18",
"-c:a", "aac", "-b:a", "192k",
"-t", str(audio_dur),
"-pix_fmt", "yuv420p",
"-movflags", "+faststart", str(output_path),
], check=True)
A duração de cada segmento é igual ao seu áudio de narração — o narrador sempre descreve o que está na tela.
Antipadrões (de 6 tentativas de gravação fracassadas em um PoC de agente hospedado no Foundry)
| ❌ Abordagem | Por que falha |
|---|---|
| Gravar continuamente + sobrepor áudio depois | As linhas do tempo de áudio e vídeo nunca se alinham — o narrador fala sobre citações enquanto a tela mostra "Trabalhando..." |
Acelerar partes do vídeo "Trabalhando..." com setpts | Parece instável; o fator de aceleração depende do tempo de resposta imprevisível do agente |
Temporizadores fixos > wait 35 no script | O tempo de resposta do agente é de 10 a 50s; temporizadores fixos cortam as respostas ou desperdiçam 30s mostrando nada |
| Gravar vídeo + áudio simultaneamente em tempo real | O Playwright não consegue capturar áudio do sistema; o Chromium sem cabeça não tem dispositivo de áudio |
| Pós-processar com detecção de deslocamento de áudio | Muito frágil; o texto "Trabalhando..." aparece no DOM, mas os spinners de carregamento visual variam por ambiente de trabalho |
Seleção de voz para demonstrações de agentes
Use uma voz britânica (en-GB-SoniaNeural) para PoCs com público do Reino Unido —
elas leem naturalmente no ritmo de demonstração e correspondem ao registro profissional.
Evite vozes casuais dos EUA para demonstrações em setores regulamentados (FSI, telecom, saúde).
Locais dos Arquivos
Quando ativada como uma skill global do CLI do Copilot, os scripts estão em:
~/.copilot/skills/auto-demo-producer/scripts/record_demo.py~/.copilot/skills/auto-demo-producer/scripts/generate_slides.py
Copie-os para o diretório do seu projeto antes de executar, ou referencie-os diretamente.
Pré-requisitos
- Python 3.10+ com
pip - edge-tts —
pip install edge-tts(Microsoft Neural TTS gratuita) - Playwright —
pip install playwright && playwright install chromium - ffmpeg — binário do sistema (consulte os comandos de instalação acima)