explainer-video-pipeline (auto-gerado)
Quando usar
O usuário deseja um vídeo explicativo narrado de 1 a 3 minutos sobre um tópico (ciência, um produto, uma tecnologia), entregue como um único MP4 com narração, legendas, música e efeitos sonoros.
Parâmetros e padrões
Pergunte apenas pelo tópico; use todos os outros padrões, a menos que o usuário nomeie um valor. Diga em uma linha quais valores você usou.
| Parâmetro | Padrão | Outros valores |
|---|---|---|
topic | obrigatório | — |
storyboard_model | claude-opus-5.5 escreve o roteiro, a narração e o storyboard | qualquer id de modelo de kiro-cli chat --list-models |
video_engine | opus-5.5: claude-opus-5.5 escreve cada cena como código que desenha cada quadro | outro modelo de código, ex.: claude-sonnet-5.5; seedance (API BytePlus ModelArk, precisa de ARK_API_KEY); hybrid (clipes Seedance dentro de cenas desenhadas por código) |
renderer | remotion (React/SVG; Remotion controla Chromium headless quadro a quadro) | html (Canvas 2D / SVG / GSAP / p5.js, capturado com Playwright); manim (Cenas Manim Community; melhor para geometria, gráficos, vetores e derivações passo a passo) |
seedance_model | seedance-1-5-pro-251215 | qualquer modelo Seedance habilitado na conta ModelArk do usuário |
tts | polly, voz neural Zhiyu, cmn-CN, us-east-1 | gtts (grátis, sem chave, voz mais monótona); qualquer outra voz/idioma Polly |
captions | ligado: temporização de palavras Whisper, queimadas como legendas destacadas palavra por palavra | desligado |
whisper_model | small (CPU, int8; cerca de 5 s para 10 s de fala) | base (mais rápido), medium (temporização mais precisa) |
music | synth (trilha baseada em oscilador royalty-free feita com ffmpeg) | none; um caminho para um arquivo de música que o usuário possui |
sfx | ligado: eventos listados em scenes.json são sintetizados e colocados em seus quadros | desligado: deixe sfx fora de cada cena |
language | Narração em mandarim | qualquer idioma que Polly e Whisper suportem |
size, fps | 1920×1080, 30 fps | 1080×1920 para vertical |
"Feito com Opus 5.5" significa que Opus 5.5 é o autor: ele escreve o roteiro e o código de desenho, e um renderizador transforma esse código em pixels. Nenhum modelo de texto gera vídeo diretamente; apenas Seedance faz isso. Diga isso uma vez na primeira resposta.
Se a sessão já estiver rodando em claude-opus-5.5, faça a escrita você mesmo.
Caso contrário, inicie uma tarefa com model="claude-opus-5.5" e keep=true para o storyboard (passo 2) e continue a mesma execução com spawn_continue para o código da cena (passo 5), depois revise a saída você mesmo.
Configuração (uma vez por máquina)
Mantenha as ferramentas em um diretório de cache estável (ex.: ~/.cache/explainer-video/), nunca em $KIROCREW_SCRATCH, que é recuperado entre sessões.
- ffmpeg: uma compilação estática completa com
aevalsrc,anoisesrc,tremolo,sidechaincompresseass/libass. O ffmpeg agrupado do Remotion não os possui. AponteFFMPEG/FFPROBEpara ele. - Python venv (
boto3 gTTS playwright faster-whisper pillow numpy), em seguidapython -m playwright install chromium-headless-shella partir desse venv. O faster-whisper 1.2.x quebra com PyAV 19 (unexpected keyword argument 'metadata_errors'): fixeav==16.1.0. DefinaHF_HOMEpara o diretório de cache para que o modelo Whisper seja baixado uma vez. - Manim (apenas para
renderer=manim): pip não consegue compilá-lo em aarch64 (sem wheels para pycairo, manimpango, moderngl). Sem root, use micromamba:micromamba create -p <cache>/manim-env -c conda-forge python=3.12 manim.Text()com uma fonte CJK funciona.MathTex/Texprecisam de uma distribuição LaTeX maisdvisvgm;texlive-coredo conda-forge em aarch64 não temlatex.fmt, então fórmulas falham lá. Escreva fórmulas comText()(Unicode: F = m·a, x², √, →), ou instale um TeX Live de sistema onde o usuário puder.
Passos
Os helpers estão na pasta scripts/ desta skill.
- Projeto. Crie uma pasta de projeto em um repositório git sob o local de trabalho do usuário. Para
renderer=remotion, montepackage.json,tsconfig.json(resolveJsonModule: true),src/index.ts,src/Root.tsxmanualmente enpm i remotion @remotion/cli react react-dom. - Roteiro e storyboard (por
storyboard_model). Escrevascenes.json: um objeto por cena comid,narration(a linha falada),visual(o que está na tela),manimopcional (nome da classe da cena) esfxopcional:[{"at": FRAME_IN_SCENE, "kind": "whoosh|hiss|pop|rise|thud|PATH"}]. Use 6 a 10 cenas, uma ideia cada, com uma cena de título e um cartão final. Verifique fatos com pesquisa na web e cite as fontes no README. - Imagens de referência. Quando o vídeo mostrar um objeto real, peça ou encontre uma foto clara e mantenha-a em
ref/. Nunca desenhe a forma de um objeto real de memória: execute detecção de bordas na foto, meça pontos-chave e gere as formas a partir desses pontos com um pequeno script mantido no repositório. - Narração dita o tempo. Execute
narrate.py scenes.json . --tts polly. Ele escrevedurations.json(quadros por cena, a partir do comprimento real da voz mais preenchimento),narration.waveaudio/sNN.mp3. O código da cena lêdurations.json, então cada cena dura exatamente o tempo da sua linha. - Código da cena (por
video_engine).remotion: um componente React por cena, animado comuseCurrentFrameeinterpolate/springrelativo ao início da cena.html: umindex.htmlcomwindow.seek = async (frame) => {...}que desenha exatamente aquele quadro a partir do número do quadro e do arraydurations.json. SemrequestAnimationFrame, sem relógio de parede, semMath.randomsem semente. Cole o arraydurations.jsonna página como uma constante: uma página aberta comofile://não podefetch()um arquivo local, e a falha é silenciosa. GSAP: timeline pausada +tl.seek(frame / fps). p5.js:noLoop()+redraw()emseek.manim: umscenes.pycom uma classe de cena por cena. Leia o comprimento alvo deos.environ["SCENE_SECONDS"]e termine comself.wait(max(0.04, secs - self.renderer.time)); dimensione animações longas a partir desecstambém. Mantenha os 15% inferiores do quadro livres para legendas.seedance:seedance_clips.py scenes.json .comARK_API_KEYdefinida; ele baixaclips/<id>.mp4(URLs expiram após 24 h).
- Verifique stills antes da renderização completa. Renderize 4 a 6 quadros, um por cena chave, combine-os em uma folha de contato reduzida e olhe para essa única imagem. Para uma verificação independente, inicie um revisor novo apenas com a folha e
scenes.json. - Áudio. Se alguma cena tiver
sfx, executesfx.py scenes.json .. Em seguida,mix_bgm.py . --music <music>: ele abaixa o volume da música sob a voz, adicionasfx.wav, escrevenarration_bgm.wave imprime níveis RMS. A introdução apenas com música deve estar em torno de −20 a −30 dB; −55 dB ou inferior significa que está inaudível. - Legendas.
captions.py scenes.json . --size <WxH>transcreve cada linha com timestamps de palavras do faster-whisper e os mapeia para os próprios caracteres do roteiro, porque o Whisper ouve mal homófonos (ouviu 气体 como 漆体). Ele escrevecaptions.ass(cada caractere destaca quando é falado) ewords.json(tempos por caractere, utilizáveis para ênfase na tela no passo 5). - Renderize (imagem silenciosa).
remotion:npx remotion render src/index.ts <Comp> out/silent.mp4.html:capture_html.py index.html out/silent.mp4 --frames <soma de durations.json>.manim:manim_scenes.py scenes.py . --manim <manim-env>/bin/manim --quality h. Ele renderiza cada classe e preenche ou corta até exatamente sua contagem de quadros.
- Componha com FFmpeg. Com legendas:
ffmpeg -i silent.mp4 -i narration_bgm.wav -vf "ass=captions.ass" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 192k -shortest final.mp4(sem legendas, use-c:v copye remova-vf). Verifique se as durações do vídeo e do áudio correspondem dentro de cerca de 0,1 s, então extraia 4 a 5 quadros do MP4 final e olhe para eles, incluindo um no meio de uma frase para ver o destaque da legenda. - Entregue. Faça commit em um branch de funcionalidade, abra um PR e, após o merge, confirme com
gh api repos/<o>/<r>/git/trees/<base>?recursive=1que os arquivos foram parar lá.
Armadilhas
- Nunca coloque comentários
/* */dentro de uma string de caminho SVGd=; o Chromium para de analisar na/. Use cores hexadecimais de 6 dígitos. - Código com números de quadro absolutos codificados pode colocar um clímax após o fim de sua cena.
- No Manim, posicione rótulos e setas após o objeto ter se movido (ou anexe-os com
always_redraw/add_updater), caso contrário, eles permanecem no lugar antigo.DashedVMobjectnão tem pontos próprios: pegue posições de uma forma simples. - Um Playwright instalado via pip pode querer uma compilação Chromium mais nova do que a em cache.
- Não edite um arquivo com várias chamadas
strReplaceparalelas; as edições são perdidas. Não escreva código através de heredocs do shell; barreiras de proteção podem bloqueá-los. - Modelos Seedance 2.x precisam de ativação de conta e rejeitam imagens de referência com rostos humanos reais. Clipes Seedance 1.5 pro têm 4 a 12 s.
- Licença Remotion: gratuita para indivíduos e empresas de até 3 pessoas; empresas maiores precisam de uma Licença Empresarial paga.
htmlemanimevitam isso.