O que thought-to-motion faz?
A ideia é o produto; todo o resto é apenas uma camada. Este skill pega uma gravação (um vídeo de cabeça falante ou apenas uma nota de voz), encontra os momentos importantes no que foi dito e projeta movimento ao redor deles: legendas no idioma falado, cartões nas palavras-chave, uma revelação na reviravolta, uma pergunta de fechamento.
Três modos:
- cabeça-falante: a gravação permanece; cartões, legendas e zoom ficam sobre ela.
- voz: nenhuma gravação é necessária (um arquivo de áudio, ou o áudio extraído de um vídeo); uma tela de marca em tela cheia com cenas, legendas cinéticas e uma forma de onda ao vivo.
- texto: nenhuma gravação; o texto simples se transforma em legendas cinéticas temporizadas e cenas na tela de marca, geralmente com música de fundo.
Dois formatos: 9:16 (padrão; Reels, TikTok, Shorts) e 16:9 ("aspecto": "16:9"; YouTube, LinkedIn, web). O mesmo plano é renderizado em ambos: em 16:9 o layout 9:16 é colocado em um palco amplo (cabeça-falante: o apresentador emoldurado à direita, motion design à esquerda).
Tudo roda nesta máquina. Nenhuma gravação, áudio ou texto é enviado para lugar nenhum.
0. Configuração (uma vez por máquina)
A partir da pasta do skill:
bash scripts/setup.sh # venv + pacotes fixados + engine/node_modules a partir do lockfile + kit de som local
Requer ffmpeg, Node 18+, Python 3.10+. A primeira transcrição baixa modelos do huggingface.co (mais seu CDN *.hf.co) para .cache/hf. Se o acesso à rede for restrito a uma lista de permissões, esses hosts devem estar permitidos. Se um headless shell Chrome/Chromium já existir, defina BROWSER_EXECUTABLE=/caminho/para/headless_shell; caso contrário, o Remotion baixará o seu próprio em engine/node_modules na primeira renderização. Execute scripts Python com .venv/bin/python.
Sua marca (uma vez)
Copie brand.example.json para brand.json e preencha: wordmark (seu nome ou marca), rótulo da série, identificador, linha da marca, tema (warm, cinematic ou tech, veja engine/src/lib/theme.js; adicione suas próprias cores e fontes lá). Os campos brand, theme e bumpers de cada plano vêm dele. Sem brand.json -> sem cabeçalho, sem introdução ou encerramento.
1. Entrada (pergunte apenas o que não pode inferir)
- A fonte. Vídeo com uma pessoa falando -> cabeça-falante; apenas áudio, ou um vídeo onde só a voz importa -> voz (a preparação extrai o áudio); texto simples -> modo texto.
- Formato: 9:16, 16:9, ou ambos (duas renderizações do mesmo plano com
aspectodiferente). - Música: ligada ou desligada. Apenas as bases geradas integradas estão incorporadas (calma / quente / pulsante, sem direitos autorais, nada a ser reivindicado). Se o usuário quiser uma música específica, deixe a música desligada; ele a adiciona no aplicativo.
- Idioma(s) da legenda: padrão = o idioma falado. Duas opções para um segundo idioma: bilíngue (um vídeo, o idioma falado em cima e uma tradução menor embaixo:
lang2+text2) ou uma renderização separada. - Tema (
warmquente /cinematicescuro /techmarinho, veja engine/src/lib/theme.js), wordmark da marca + rótulo da série (ou nenhum) e a pergunta final / CTA se tiverem. - Modo voz: quaisquer fotos próprias para usar (coloque-as em
<job>/public/).
2. Preparação
Modo texto (sem gravação):
.venv/bin/python scripts/prep_text.py <texto.txt | "texto inline"> <job> [--lang he|en] [--wpm 150] [--aspect 9:16|16:9]
Divide o texto em linhas do tamanho de legenda nos limites de frases, temporiza-as a um ritmo de leitura confortável e escreve plan.draft.json (modo "texto", música calma, movimento calmo). Não reescreva as palavras do usuário; apenas divida e temporize. Em seguida, desenhe as cenas (seção 4) como no modo voz. Pule para a seção 4.
Vídeo ou áudio:
.venv/bin/python scripts/prep.py <mídia> <job> [--mode voice] [--lang he|en|auto] [--no-cut]
Normaliza para 1080x1920 30fps (ou áudio), corta pausas > 0,45s, limpa a fala (remoção de ruído DeepFilterNet3 + EQ, de-ess, compressão, -14 LUFS; --clean gentle por padrão, full para clipes externos muito ruidosos, off para gravações de estúdio), copia o kit de som e transcreve a linha do tempo CORTADA com temporizações de palavras -> <job>/transcript.json. O Hebraico usa o modelo ivrit.ai automaticamente. O script imprime palavras de baixa confiança: verifique-as primeiro.
Opcional: substituir o fundo (cabeça-falante)
Melhores resultados - filme um plano limpo. Antes de se sentar, filme 3-5 segundos da sala vazia, depois entre e comece. Prenda o telefone em um tripé e trave a exposição e o foco (no iPhone: pressione longamente a tela até "AE/AF LOCK"), para que a sala não clareie ou escureça quando você entrar. Não aplique zoom ou mova a câmera. O prep.py detecta a abertura vazia automaticamente, salva-a como a referência exata de fundo (work/clean_plate.png) e a corta (e a entrada) do vídeo. Sem um plano limpo, o motor tem que adivinhar a sala atrás da cabeça e do tronco. A sala vazia também pode ser um clipe separado filmado da mesma posição de câmera travada (antes ou depois da fala):
.venv/bin/python scripts/plate_from_clip.py <job> <clipe_sala_vazia>
Ele usa apenas a abertura parada e vazia daquele clipe (para quando alguém entra), alinha-a ao fundo da própria fala (ECC, afim) e combina exposição e cor por canal. Verifique work/plate_check.jpg (fala | placa | diferença) e os números de correspondência impressos antes de processar.
.venv/bin/python scripts/background.py <job> <placa.jpg> --draft [--reveal SEGUNDOS] # rascunho: meia resolução, ~4x mais rápido
.venv/bin/python scripts/background.py <job> <placa.jpg> [--reveal SEGUNDOS] # final: resolução total
# opções: [--match 0.65] [--wrap 0.35] [--preview SEGUNDOS]
Mascara de retrato local (MODNet) combinada com uma máscara de diferença de sala limpa: com uma câmera estática, a mediana do clipe é a sala vazia, e qualquer coisa que difira dela (mãos rápidas, cabelo, braços) é mantida como a pessoa. A sala vazia é aprendida apenas a partir de quadros onde cada ponto está realmente vazio (a pessoa é mascarada primeiro), para que a parede real ao lado da cabeça nunca seja confundida com a pessoa. Bordas semitransparentes (cabelo) são descontaminadas contra essa sala vazia, para que nenhum resquício da parede antiga apareça. Tudo abaixo da linha da mesa (--desk auto: cerca de 1,2 alturas de rosto abaixo do queixo; ou uma fração como 0.9; off para tomadas em pé) está na frente da pessoa - a mesa e antebraços apoiados - e é mantido como filmado, re-iluminado para combinar. Use --moving-camera para filmagens com câmera na mão (apenas modelo). Uma parede lisa ou verde atrás do apresentador dá o resultado mais limpo. Em seguida, a pessoa é re-iluminada para o brilho e cor da placa, a luz da placa envolve suas bordas, e um vinheta + granulação é aplicada em ambos para que compartilhem uma câmera. --reveal mantém a sala real até aquele momento e faz a transição para a nova (ótimo quando o apresentador pede isso na câmera). Sempre execute --preview em 1-2 quadros e mostre ao usuário antes de processar o clipe inteiro. Após o processamento, execute scripts/bg_qa.py <job>: ele compara o vídeo original e o novo a cada dois quadros e relata onde a pessoa foi perdida (vermelho) ou a sala antiga vazou (amarelo), por segundo, com uma folha dos piores quadros (work/bg_qa_sheet.jpg). Corrija ou sinalize cada segundo com falha antes que o usuário veja o vídeo. Falso positivo conhecido: um objeto que se moveu entre o plano limpo e a tomada (uma cadeira, uma porta) é contado como "pessoa"; olhe a folha antes de agir nesses segundos. A placa deve corresponder à cena: interno/externo, hora do dia, luz quente/fria, altura da câmera. Escreve public/source_bg.mp4.
3. Leia a transcrição, corrija-a, escreva as legendas
- Corrija erros óbvios de reconhecimento (nomes, gírias, palavras em idioma misto). Liste cada correção para o usuário; nunca mude o significado silenciosamente. Se não tiver certeza do que foi dito, pergunte.
- Remova vícios de linguagem ("hum", "אה"). Legendas: uma ideia por sinal, <= ~42 caracteres, no máximo 2 linhas, velocidade legível (<= ~20 caracteres/s), tempos de sinal a partir dos carimbos de data/hora das palavras.
- Segundo idioma: traduza você mesmo os sinais, mantendo a voz do apresentador e os mesmos tempos (como
text2para legendas bilíngues; mantenha a tradução curta o suficiente para uma linha). - Em legendas RTL, mantenha o Inglês citado como uma execução contínua ("כי אני זוכר Is that cheese") - o motor isola isso.
4. Plano de movimento -> PORTA 1 (aprovação)
Leia primeiro references/motion-rules.md. Em seguida, execute os prompts de estágio em references/prompts/ em ordem, como suas próprias etapas de trabalho (eles produzem material para as portas; nunca as substituem):
- Editor de história e gancho (1-story-hook-editor.md): candidatos a gancho, a pergunta aberta e onde ela fecha, o arco, uma lista de cortes. Apenas spans literais. Modo texto: use 6-text-to-video-writer.md.
- Designer de legendas (3-caption-designer.md): divisão em blocos, velocidade de leitura, palavras de ênfase, RTL.
- Diretor de movimento (2-motion-director.md): um elemento por batida, pousando em sua palavra, um ponto focal por vez, transforme em vez de substitua.
- Designer de som (4-sound-designer.md): sons esparsos nos pousos, estilo musical, uma batida de silêncio.
Encontre as batidas (veja references/design-rules.md): gancho, referências nomeadas (programas, pessoas, lugares, produtos), o conceito-chave, contrastes ou escolhas, listas, números que o apresentador realmente disse, a reviravolta/revelação, a pergunta/CTA. Mapeie cada batida para um elemento (references/plan-schema.md). Apresente uma tabela ao usuário:
| # | tempo | o que é dito | elemento | por quê | ensina | verificar |
|---|
Proponha também a frase de efeito do vídeo (a ideia principal do vídeo, uma linha que o apresentador realmente diz, cerca de 2-3 s) para a abertura. Liste também: correções de legendas, quaisquer fatos na tela que você adicionou (por exemplo, os anos de um programa) com uma fonte, tema, sons. Pare e aguarde aprovação. Nada é renderizado antes disso.
5. Escreva e valide o plano
Escreva <job>/plan.json (esquema em references/plan-schema.md, exemplo em examples/). Em seguida:
.venv/bin/python scripts/validate_plan.py <job>/plan.json
Corrija todo ERRO. Leia os AVISOS e corrija o que importa. Além do esquema, ele verifica as regras de movimento: conteúdo a partir de 0,5 s, nenhuma lacuna superior a 6 s sem um evento visual, no máximo 2 gráficos de uma vez, velocidade de leitura (máx. 20 caracteres/s), duração da legenda, limites de zoom, segurança contra vazamento de luz, espaçamento de efeitos sonoros, batidas de silêncio. Quebre uma regra apenas intencionalmente e diga o motivo na Porta 2.
O validador também impõe a área segura (x 60-900, y 220-1420: as partes do quadro que nenhuma interface de aplicativo cobre) e mantém todo cartão e painel fora do rosto do apresentador (rastreado em faces.json). Adicione --fix para mover cartões automaticamente. Veja references/safe-zones.md.
Câmeras virtuais (cabeça-falante, automáticas)
.venv/bin/python scripts/shots.py <job> [--plan plan.json]
Transforma uma única tomada fixa em uma edição multicâmera: câmera A (aberta, o enquadramento original), B (média, ~1,2x) e C (fechada, ~1,4x; até 1,7x em 16:9), cortadas do mesmo quadro e ancoradas no rosto rastreado. As mudanças de câmera pousam nos cortes de pausa que a preparação fez (escondendo o salto), caso contrário, nos finais de frase; as tomadas duram 3-8 s; nunca a mesma câmera duas vezes; aberta enquanto os cartões precisam de espaço, fechada em zooms e revelações; cada tomada com zoom empurra ~1,5% (calmo). Cada câmera é testada contra os cartões e legendas para que o rosto permaneça claro. Selfies em close-up (rosto mais alto que um terço do quadro) não recebem câmeras virtuais em 9:16 - não há espaço para se aproximar. Sem ângulos gerados por IA: a gravação permanece real e local. Adicione uma coluna "câmera" (A/B/C) à tabela da Porta 1.
6. Imagens estáticas -> PORTA 2 (aprovação)
.venv/bin/python scripts/render.py stills <job> # momentos-chave -> <job>/stills/sheet.jpg
A folha mostra guias: zonas não seguras em vermelho, o rosto rastreado em verde. Olhe para ela primeiro: tudo dentro da área segura, nada cobrindo o rosto/boca, ordem Hebraico/Inglês correta, fontes carregadas (sem fallback tipo Times), sem sobreposições. Em seguida, execute o revisor independente (references/prompts/5-reviewer.md) como um agente separado que não viu seu raciocínio: dê a ele apenas as imagens estáticas, plan.json e transcrição. Corrija seus bloqueadores e mostre seu veredito ao usuário com as imagens estáticas. Pare e aguarde aprovação. O revisor nunca aprova em nome do usuário.
7. Renderizar, verificar, entregar
.venv/bin/python scripts/render.py video <job> --name <NOME> # rascunho 540x960 (padrão, rápido) para revisão
.venv/bin/python scripts/render.py video <job> --name <NOME> --final # total 1080x1920, máxima qualidade
Cada renderização de revisão é um rascunho de meia resolução (540x960). Renderize --final apenas para a versão final aprovada. Uma renderização por idioma de legenda (altere lang + captions no plano). Após a renderização, verifique: duração corresponde, áudio presente, alguns quadros parecem corretos. Entregue os MP4s (1080x1920 ou 1920x1080 H.264 perfil alto, faststart; adequado para Reels, TikTok, Shorts, YouTube, LinkedIn) e os arquivos de legenda .srt escritos ao lado deles (um por idioma de legenda). Com "music" no plano, a base é mixada no momento da renderização e abaixa automaticamente sob a voz. A renderização leva alguns minutos por minuto de vídeo em 2 CPUs.
--final também escreve <NOME>_social.mp4: a mesma imagem a cerca de 10 Mbps (pequeno o suficiente para APIs de agendamento, por exemplo, o limite de ~300 MB do Instagram) com o áudio remensurado e normalizado para -14 LUFS / -1 dBTP no arquivo final. Entregue essa cópia para postagem e mantenha o master de alta taxa de bits como arquivo. Meça o arquivo entregue (ffmpeg -i <arquivo> -af ebur128=peak=true -f null -) e relate sua sonoridade. O vídeo termina cerca de 0,8 s após a última palavra falada (a preparação mantém essa cauda), para que a última palavra nunca seja cortada. Com "bumpers" no plano, render.py junta abertura -> introdução -> vídeo -> encerramento (scripts/bumpers.py), desloca os arquivos .srt pelo comprimento da abertura + introdução, e para se o som e a imagem estiverem fora de sincronia (veja Abertura, introdução e encerramento).
Regras (não negociáveis)
- Nunca invente fatos, números, citações ou histórias. Fatos na tela além da transcrição (datas, títulos) devem ser verificados e mostrados ao usuário na Porta 1.
- Não desenhe personagens reconhecíveis, logotipos ou obras de arte protegidas por direitos autorais; use tipografia e os ícones genéricos integrados. Exceção: o elemento
logo
... [truncado para tradução]