Communitygithub.com

show-n-tell

Cria vídeos de demonstração narrados e com marca personalizada para qualquer site, gerenciando exploração, roteiro, narração TTS, gravação e mixagem de áudio/vídeo.

O que é show-n-tell?

O skill show-n-tell permite que um agente de IA (como Claude) orquestre um pipeline completo de criação de vídeos de demonstração narrados e com marca personalizada a partir de qualquer site. Ele é útil para equipes de produto, vendas ou marketing que precisam gerar rapidamente vídeos explicativos de alta qualidade, sem edição manual. O skill suporta plataformas como Claude Code CLI e Cowork, adaptando seu comportamento a cada ambiente. Ele funciona em fases: entrevista para coletar requisitos (URL, notas de intenção, logotipo, credenciais), captura de autenticação para sites com login OAuth/SSO, exploração do site usando Playwright ou ferramentas MCP, criação de um storyboard YAML com narração por cena, configuração do diretório de trabalho, geração de narração TTS via OpenAI, gravação de tela com Playwright, sincronização e mixagem de áudio/vídeo, ajuste de velocidade e sobreposição de marca, produzindo um arquivo MP4 polido. O skill também oferece revisão do roteiro em linguagem natural e detecção de desvios no tempo de execução.

Funciona com✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/carveragents/show-n-tell/tree/main/skills/show-n-tell

Perguntar na sua IA favorita

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

Documentação

O que show-n-tell faz?

Você orquestra um pipeline completo que transforma qualquer site + um logotipo + um pouco de intenção em um vídeo de demonstração narrado e com marca personalizada de 5 minutos. Os scripts em scripts/ são canos burros; você é o maestro.

Documentos de referência nesta pasta: docs/SCHEMAS.md (gramática YAML + ação), docs/GOTCHAS.md (problemas conhecidos + soluções alternativas), docs/CONTEXT.md ("qual é a aparência de uma boa saída"), examples/halyard-spme/ (exemplo completo canônico). Leia-os conforme necessário — não os pré-carregue.

Quando usar este skill

  • O usuário quer um vídeo de demonstração narrado de um site (ao vivo, desenvolvimento local ou estático).
  • O usuário tem pelo menos uma orientação leve de intenção ("mostre X, Y, Z" / "demonstre o fluxo do painel").
  • O usuário tem acesso a um logotipo ou marca nominativa.

Recuse-se a prosseguir se o usuário não fornecer nem notas de intenção nem um logotipo. Demonstrações genéricas com marca padrão são demonstrações ruins. Peça orientação em vez de produzir silenciosamente um vídeo fraco.

Detecção de Ambiente (leia antes de começar)

Antes de fazer qualquer coisa, determine em qual ambiente o Claude está sendo executado:

  • Cowork: mcp__cowork__list_artifacts e mcp__computer-use__screenshot estão disponíveis na lista de ferramentas do Claude.
  • Claude Code CLI: essas ferramentas estão ausentes.

Isso é importante porque várias fases se comportam de forma diferente entre ambientes. Referência rápida:

FaseClaude Code CLICowork
Diretório de trabalho (Fase 5)~/demo-videos/<slug>/request_cowork_directory gera o caminho
Exploração pública do site (Fase 2b)Ferramentas MCP do PlaywrightFerramentas MCP do Chrome ou explore_page.py headless
Captura de autenticação OAuth (Fase 2a)Execute capture_auth.py via BashO usuário executa capture_auth.py localmente
Comandos longos (Fases 7–9)Executar de forma síncronanohup + poll (timeout de 45s do bash)
Entrega (Fase 11)Relatar caminho do mp4Caminho do mp4 + link computer://

Fase 1 — Entrevista (coletar entradas)

Faça uma ou duas perguntas de cada vez, não todas de uma vez. Obrigatório:

  1. URL alvo — confirme que está acessível.
  2. Notas de intenção da demonstração — que história isso conta? Quais recursos são importantes?
  3. Público + tom — interno/externo/investidores; explicativo/vendas/técnico/casual.
  4. Duração alvo — padrão de 5 min.
  5. Logotipo — URL ou caminho. Se apenas texto estiver disponível, sinalize a limitação, mas aceite.
  6. Cores da marca — primária (tinta) + destaque. Se não especificado, infira a partir do logotipo com PIL.
  7. Autenticação? — o site requer login?
    • Não → prossiga.
    • Sim, baseado em formulário (o site tem seus próprios campos de e-mail/senha que você controla) → use session.pre_session em demo_config.yaml. Colete os nomes das variáveis de ambiente de credenciais (NÃO os valores reais) e a URL de login/seletores. Diga ao usuário para colocar as credenciais reais em <working_dir>/.env antes de executar, nunca no chat. Veja examples/login-flow/.
    • Sim, OAuth / SSO / magic-link / passkey (Google, Microsoft, Okta, etc.) → use session.storage_state. O usuário NÃO executa nenhum comando. VOCÊ inicia helpers/capture_auth.py para eles na Fase 2a, e eles só fazem login interativamente na janela do navegador que é aberta. O auth.json capturado é então usado tanto para a exploração da Fase 2b quanto para a gravação da Fase 8. Veja examples/oauth-storage-state/.

Fase 2a — Captura de autenticação (somente OAuth)

Pule esta fase completamente se a pergunta 7 da Fase 1 resultou em "sem autenticação" ou "baseado em formulário". Para OAuth / SSO / magic-link / passkey, capture uma sessão autenticada AGORA, antes da exploração do site — a Fase 2b precisa dela para visualizar páginas autenticadas.

mkdir -p ~/demo-videos/<demo-slug>/
uv run helpers/capture_auth.py <login_ou_url_inicial> \
  --out ~/demo-videos/<demo-slug>/auth.json \
  --viewport <recording.viewport de demo_config.yaml; padrão 1440x900>

Execute isso via ferramenta Bash com timeout: 600000 (10 minutos — o máximo). O script abre uma janela do Chromium com cabeçalho. Diga ao usuário em palavras simples:

"Estou abrindo uma janela do navegador para você fazer login. Complete o login (Google, Microsoft, etc., lidere com 2FA), navegue até a página onde deseja que a gravação comece e feche a janela do navegador. Vou salvar a sessão e continuar automaticamente."

O script escreve auth.json com modo 0600 atomicamente. Se o usuário demorar mais de 10 minutos (raro, mas possível com 2FA baseado em telefone em outra sala), o timeout do Bash dispara — basta reexecutar o mesmo comando.

--viewport DEVE corresponder a recording.viewport em demo_config.yaml. Alguns sites coletam impressões digitais do tamanho da viewport; a incompatibilidade pode invalidar a sessão capturada no momento da gravação ou da exploração.

Se o Chromium do Playwright ainda não estiver instalado (clone recente do skill), o script gera um erro acionável. Execute uv run --with playwright playwright install chromium uma vez.

Se estiver executando no Claude Code CLI: execute capture_auth.py via Bash conforme descrito acima.

Se estiver executando no Cowork: o Claude lida com isso diretamente usando ferramentas de uso do computador e Chrome — o usuário só precisa fazer login quando o navegador abrir. Etapas:

  1. Certifique-se de que um caminho de diretório de trabalho é conhecido. Se a Fase 5 ainda não foi executada, chame mcp__cowork__request_cowork_directory agora para obter o caminho das saídas e defina <working_dir> como <outputs_path>/<demo-slug>/.

  2. Abra o Chrome na área de trabalho do usuário:

    mcp__computer-use__open_application  →  "Google Chrome"  (ou "Chrome")
    
  3. Navegue até a URL de login. Prefira o MCP do Chrome se estiver conectado:

    • Extensão do Chrome disponível: mcp__Claude_in_Chrome__navigate para <login_ou_url_inicial>
    • Extensão do Chrome não conectada: use ferramentas mcp__computer-use__* para clicar na barra de endereço e digitar a URL
  4. Diga ao usuário para fazer login — diga em palavras simples:

    "O Chrome está aberto na página de login. Faça o login (lide com qualquer 2FA, SSO, etc.), navegue até a página onde a gravação deve começar. Avise-me quando terminar."

  5. Espere e observe. Faça polling com mcp__computer-use__screenshot a cada ~15 segundos. Continue assim que a URL não for mais uma página de login/auth e um painel ou página de aplicativo estiver visível.

  6. Extraia o estado da sessão via JavaScript. Execute este snippet com mcp__Claude_in_Chrome__javascript_tool:

    (() => {
      const cookies = document.cookie.split(';').map(c => {
        const [name, ...rest] = c.trim().split('=');
        return { name: name.trim(), value: rest.join('='), domain: location.hostname,
                 path: '/', expires: -1, httpOnly: false, secure: location.protocol === 'https:',
                 sameSite: 'Lax' };
      }).filter(c => c.name);
      const ls = {};
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i);
        ls[k] = localStorage.getItem(k);
      }
      const ss = {};
      for (let i = 0; i < sessionStorage.length; i++) {
        const k = sessionStorage.key(i);
        ss[k] = sessionStorage.getItem(k);
      }
      return JSON.stringify({
        cookies,
        origins: [{ origin: location.origin,
                    localStorage: Object.entries(ls).map(([n,v]) => ({name:n,value:v})),
                    sessionStorage: Object.entries(ss).map(([n,v]) => ({name:n,value:v})) }]
      }, null, 2);
    })()
    
  7. Escreva o resultado em <working_dir>/auth.json usando a ferramenta Write. Este é um formato storage_state válido do Playwright — helpers/explore_page.py e record_demo.py ambos o consomem via browser.new_context(storage_state=...).

  8. Ressalva sobre cookies HttpOnly. JavaScript não pode ler cookies HttpOnly — eles são intencionalmente invisíveis para document.cookie. Se o token de sessão do site for apenas HttpOnly (comum com cookies de sessão Rails/Django mais antigos), o estado extraído estará faltando. Diga ao usuário:

    "Nota: cookies de sessão marcados como HttpOnly não são acessíveis a partir do JavaScript, então posso não ter capturado todos os tokens de autenticação. A gravação tentará usar o que foi capturado — se encontrar uma parede de login durante a Fase 8, podemos recorrer ao uso de capture_auth.py localmente." Em seguida, continue — muitos sites modernos (Google, Microsoft, Okta) mantêm estado suficiente em cookies não HttpOnly ou localStorage para o Playwright funcionar.

Fase 2b — Exploração do site

Se a Fase 2a foi executada (auth.json existe), use helpers/explore_page.py para visualizar páginas autenticadas — o MCP do Playwright não pode carregar storage_state e veria apenas paredes de login. Para demonstrações sem autenticação, o MCP do Playwright é suficiente e mais interativo; use-o como antes.

Para páginas autenticadas:

mkdir -p ~/demo-videos/<demo-slug>/_explore/
uv run helpers/explore_page.py https://target.example.com/dashboard \
  --storage-state ~/demo-videos/<demo-slug>/auth.json \
  --out-dir ~/demo-videos/<demo-slug>/_explore/

Isso escreve três arquivos por página em _explore/: <slug>.png (captura de tela), <slug>.dom.html (DOM para seleção de seletores), <slug>.meta.json ({url_requested, final_url, title, status}). Leia o PNG com a ferramenta Read para ver a página; pesquise no DOM por seletores. Se final_url em meta.json apontar para uma página de login, a sessão expirou — execute novamente a Fase 2a.

Para páginas públicas (página inicial, páginas de marketing em qualquer demonstração; tudo em uma demonstração sem autenticação) — use as ferramentas MCP do Playwright (mcp__plugin_playwright_playwright__*) como antes:

  • browser_navigate para a URL alvo, depois para 2–5 páginas que a intenção do usuário menciona.
  • browser_snapshot ou browser_take_screenshot para ver o layout de cada página.
  • Use browser_evaluate para ler o DOM em busca de seletores estáveis (prefira semântico em vez de nth-of-type quando possível).

Se estiver executando no Claude Code CLI: use ferramentas mcp__plugin_playwright_playwright__* conforme descrito acima.

Se estiver executando no Cowork: Primeiro, certifique-se de que o Chromium está disponível:

uv run --with playwright playwright install chromium

Em seguida, escolha o melhor método disponível:

  • Se mcp__Claude_in_Chrome__navigate estiver disponível (extensão do Chrome conectada), use mcp__Claude_in_Chrome__navigate + mcp__Claude_in_Chrome__read_page para explorar o site interativamente.
  • Caso contrário, recorra à exploração headless:
    mkdir -p <working_dir>/_explore/
    uv run helpers/explore_page.py <url> --out-dir <working_dir>/_explore/
    
    (Nenhum --storage-state necessário para páginas públicas — o argumento agora é opcional.)

Anote para cada página significativa:

  • Momentos dignos de demonstração (rolar para recurso, clicar para detalhes, dica de ferramenta ao passar o mouse).
  • Adaptações necessárias do site: truque de cabeçalho fixo? Link direto para PDF? Bloqueadores de modal? Parede de autenticação?
  • Seletores que parecem frágeis e podem precisar de defesas wait_for_selector.

Não faça um rastreamento exaustivo. 2–5 ações por página são suficientes.

Fase 3 — Rascunho storyboard.yaml

Gere 15–30 cenas. Cada cena = uma ação de câmera + 1–3 frases de narração. Veja docs/SCHEMAS.md para a gramática de ação (subconjunto da Fase A: goto, goto_and_scroll, scroll_into_view, scroll_y, hover, click).

Alvo para um vídeo de 5 minutos com aceleração de 1,2x:

  • Tempo total pós-aceleração: ~5:00
  • Tempo de execução bruto total: ~6:00
  • Média por cena: ~12s, dos quais ~9–10s são narração

Regras rígidas ao redigir a narração:

  1. Toda afirmação factual deve estar visível na tela neste quadro da cena. Sem números inventados ("o agente sinalizou 199 alterações"). Se você não vê na captura de tela, não diga.
  2. Iniciais lidas letra por letra devem ser escritas com hífen: S-P-M-E, K-Y-B, A-P-I. O prompt TTS impõe essa convenção.
  3. O comprimento corresponde ao conteúdo visual: 8–18s para cenas de rolagem, 6–12s para cenas de clique.
  4. O tom corresponde ao campo voice.tone de branding.yaml.

Agrupe mentalmente as cenas em segmentos (Visão Geral / Recurso A / Recurso B / Encerramento), mas escreva uma lista simples em YAML — sem marcadores de seção.

Fase 4 — Revisão em linguagem simples

O usuário não edita YAML diretamente. Você apresenta o rascunho como uma lista numerada e aceita feedback em linguagem natural. Use este formato exato:

Aqui está o fluxo de demonstração que eu rascunhei. Tempo estimado: 5:08 (após aceleração de 1,2x).
Diga-me o que você gostaria de alterar.

VISÃO GERAL (60s)
1. Aterrissar na página inicial (10s) — "Bem-vindo à Acme Cloud, uma plataforma serverless para pequenas equipes..."
2. Rolar para recursos (15s) — "Três capacidades principais impulsionam a plataforma..."
3. Rolar para saídas (8s) — "Estas dez áreas de política..."

RECURSO 1 — Painel (45s)
4. Navegar para o painel (8s) — "Clicando no painel..."
5. Passar o mouse no feed de atividade ao vivo (12s) — "Cada projeto mostra um feed de atividade ao vivo..."
...

ENCERRAMENTO (20s)
27. Voltar para estatísticas da página inicial (12s) — "Três razões pelas quais as equipes escolhem a Acme..."
28. Encerramento (8s)

Em seguida: "Algo para adicionar, remover ou reordenar? Algum ajuste no tom da narração? Algo para pular?"

Traduza o feedback em linguagem natural para edições YAML:

  • "Pule a cena 7" → remova do YAML
  • "Torne a cena 3 mais longa" → estenda a narração com mais detalhes na tela (divida em duas cenas se for muito mais longo)
  • "Mencione preços em algum lugar" → identifique a cena certa e adicione uma frase (verifique se os preços estão realmente visíveis no quadro dessa cena)
  • "Tom muito formal" → reescreva a narração com redação mais solta
  • "Mostre a página da equipe em vez de sobre" → troque URL + ajuste a narração

Reapresente o fluxo atualizado. Itere até que o usuário aprove explicitamente.

Verificação de desvio de tempo antes do TTS: some len(beat.narration) / 16 (caracteres/s a 140 ppm) em todas as cenas. Se estimado * (1 / speed_multiplier) estiver a mais de 30s do alvo, sinalize: "Isso atualmente termina em ~6:20 pós-aceleração versus seu alvo de 5min. Quer que eu corte?"

Fase 5 — Configuração do diretório de trabalho

mkdir -p ~/demo-videos/<demo-slug>/_assets
cp <caminho_do_logotipo>             ~/demo-videos/<demo-slug>/_assets/<logo>.png
# escreva storyboard.yaml, branding.yaml, demo_config.yaml a partir de seus rascunhos

Se estiver executando no Claude Code CLI: use ~/demo-videos/<demo-slug>/ conforme mostrado acima.

Se estiver executando no Cowork: chame mcp__cowork__request_cowork_directory para obter o caminho das saídas do usuário. Defina o diretório de trabalho como <caminho_das_saídas>/<demo-slug>/. Use este caminho para TODAS as gravações de arquivo subsequentes nas Fases 6–11 — armazene-o agora e mantenha-o consistente durante toda a sessão. Crie o subdiretório _assets/ sob este caminho, não sob ~/demo-videos/.

Se o usuário não tiver um arquivo de logotipo no disco e tiver apenas uma URL, baixe-o com curl e coloque-o em _assets/.

Fase 6 — Gerar ativos estáticos de marca

Execute helpers/apply_branding.py para gerar _assets/overlay-lower-third.png e _assets/overlay-watermark.png (usados na Fase 9):

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/apply_branding.py .

Nota: o caminho ../../../helpers assume que você está dentro de ~/demo-videos/<demo-slug>/ e que o clone do skill está em ~/Code/show-n-tell/ ou um local semelhante — ajuste o caminho relativo conforme necessário.

Se estiver executando no Claude Code CLI: execute conforme mostrado acima.

Se estiver executando no Cowork: o diretório de trabalho está em <caminho_das_saídas>/<demo-slug>/. Use o caminho absoluto para aplicar_branding.

Fase 7 — Gerar narração TTS

Execute helpers/generate_tts.py para converter as narrações do storyboard.yaml em arquivos de áudio:

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/generate_tts.py storyboard.yaml \
  --speed-multiplier 1.2 \
  --out-dir _audio

Isso gera um arquivo .mp3 por cena em _audio/. Flag --dry-run para depuração.

Problema conhecido: texto longo (>1000 caracteres) pode exceder o limite de caracteres da API TTS da OpenAI. O script divide automaticamente em partes, mas a pausa entre as partes pode soar não natural. Mantenha cada cena abaixo de 1000 caracteres para obter melhores resultados.

Resolução de problemas: Se o script falhar com um erro de quota/limite de taxa da API, o tratamento de retry interno deve lidar com isso — mas se não, verifique se sua chave da API OpenAI tem créditos e está definida em OPENAI_API_KEY.

Fase 8 — Gravação de tela

Execute helpers/record_demo.py para gravar o site de acordo com o storyboard:

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/record_demo.py demo_config.yaml \
  --storyboard storyboard.yaml \
  --audio-dir _audio \
  --out-dir _raw \
  --speed-multiplier 1.2

Isso gera um vídeo .mp4 bruto por cena em _raw/. Cada cena é sincronizada com seu arquivo de áudio.

Pós-processamento: depois que o comando for concluído, inspecione a saída do console em busca de avisos — particularmente avisos de limite de tempo, onde um elemento não apareceu dentro do tempo limite do seletor. Se a gravação de uma cena falhar completamente (nenhum arquivo de vídeo gerado), marque a cena como "com problema" e decida se deve refazer manualmente com um seletor diferente ou pular (e reescrever as narrações com transições de cobertura adequadas).

Fase 9 — Pós-processamento de áudio/vídeo

Execute helpers/mux_final.py para combinar todos os clipes, sobrepor marca e ajustar a velocidade:

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/mux_final.py \
  --storyboard storyboard.yaml \
  --audio-dir _audio \
  --video-dir _raw \
  --assets-dir _assets \
  --output output.mp4 \
  --speed-multiplier 1.2

Isso produz output.mp4 no diretório de trabalho.

Fase 10 — Verificação de qualidade

Reproduza o output.mp4 localmente ou use ffprobe para verificar:

ffprobe ~/demo-videos/<demo-slug>/output.mp4 2>&1 | grep -E "Duration|Stream"

Verificações básicas:

  • Duração: dentro de 15% do alvo (5 min ± 45s)
  • Áudio: pelo menos um stream de áudio está presente
  • Vídeo: codec h264 ou similar, proporção de aspecto correta

Se qualquer verificação falhar (por exemplo, nenhum stream de áudio), verifique os logs em _audio/ e _raw/. Pode ser necessário repetir a Fase 7 ou 8.

Fase 11 — Entrega

Se estiver executando no Claude Code CLI: diga:

"Seu vídeo de demonstração está pronto em ~/demo-videos/<demo-slug>/output.mp4. Abra-o em seu reprodutor de mídia preferido."

Se estiver executando no Cowork: diga:

"Seu vídeo de demonstração está pronto em <caminho_das_saídas>/<demo-slug>/output.mp4. Você também pode acessá-lo via: computer:///caminho/completo/para/output.mp4"

(Por exemplo, computer:///Users/seunome/demo-videos/acme-cloud/output.mp4)


Fase B — Recursos avançados (opcional)

Depois que o fluxo básico (Fases 1–11) estiver concluído, se o usuário solicitar intros, outros ou legendas, use estes scripts:

Introdução/Encerramento:

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/generate_intro_outro.py \
  --storyboard storyboard.yaml \
  --branding branding.yaml \
  --out-dir _intro_outro

Isso gera clipes de introdução (3–5s) e encerramento (2–3s) com o nome do produto e logotipo do usuário. Em seguida, remuxe:

uv run ../../../helpers/mux_final.py \
  --storyboard storyboard.yaml \
  --audio-dir _audio \
  --video-dir _raw \
  --assets-dir _assets \
  --intro-clip _intro_outro/intro.mp4 \
  --outro-clip _intro_outro/outro.mp4 \
  --output output_with_intro_outro.mp4 \
  --speed-multiplier 1.2

Legendas:

cd ~/demo-videos/<demo-slug>/
uv run ../../../helpers/generate_captions.py storyboard.yaml \
  --audio-dir _audio \
  --out-dir _captions

Isso produz um arquivo .srt por cena e um _captions/combined.srt combinado. Para queimá-los no vídeo:

ffmpeg -i output.mp4 -vf "subtitles=_captions/combined.srt" output_captioned.mp4

Resolução de problemas

A gravação trava/expira sem produzir um vídeo para uma cena:

Verifique o seletor — um seletor nth-of-type frágil provavelmente mudou. Reexplore a página com explore_page.py para obter um DOM atualizado e escolha um seletor mais estável (por exemplo, [data-testid="submit"] em vez de button:nth-of-type(3)).

A narração TTS soa robótica ou com pausas estranhas:

Frases muito longas (>1000 caracteres) podem ser divididas pela API. Encurte a narração ou divida a cena do storyboard em duas cenas mais curtas.

A sessão de autenticação expirou durante a gravação:

O tempo de vida do token de sessão varia muito. Se a gravação atingir uma parede de login, repita a Fase 2a para capturar uma sessão nova e, em seguida, repita a Fase 8 imediatamente enquanto o token está ativo. Para sites com vidas de sessão muito curtas (<15 min), considere capturar a autenticação imediatamente antes da Fase 8.

Os overlays de marca não aparecem ou ficam distorcidos:

Verifique se branding.yaml tem larguras/alturas de overlay razoáveis ou execute helpers/apply_branding.py com --force para regenerar. Verifique se a proporção de aspecto do vídeo corresponde às dimensões configuradas (por exemplo, 1920x1080 vs 1440x900 causa alongamento).

A exploração do Cowork não tem o MCP do Chrome disponível:

Às vezes, a extensão do Chrome não está instalada ou concedeu permissão. Peça ao usuário para instalar a extensão "Claude in Chrome" do Chrome Web Store e conceder acesso à URL. Enquanto isso, recorra ao método de exploração headless.


Notas de arquitetura

O pipeline inteiro é acionado a partir de um único prompt do usuário graças a:

  • Modelo de estado sequencial: Sempre capture a autenticação antes de explorar e explore antes de storyboard.
  • Separação de ativos: Logotipo, cores e voz de marca são capturados uma vez e passados como argumentos.
  • Aceleração independente: O TTS e a mixagem aplicam --speed-multiplier de forma independente sem distorção de tom.
  • Intros/outros como fases opcionais: O caminho principal não depende deles, mas a integração é trivial para usuários que os desejam.

Habilidades Relacionadas