O que Motion Ad Studio (auto-aprimorável) faz?
Faça um anúncio vertical de motion graphics de 20 a 40 segundos que um motion designer sênior aprovaria: o quadro 0 já está em movimento, um objeto condutor atravessa o filme, as transições cortam no meio do movimento com velocidade combinada, e cada clique, pouso, queda e whoosh está travado em uma palavra falada ou em um beat musical. O filme é uma única página HTML (timeline GSAP + funções puras do tempo). Ele renderiza frame-perfeitamente para MP4, e scripts o verificam antes que alguém o assista. Os efeitos sonoros são posicionados a partir da própria lista de eventos do filme, portanto a sincronia de áudio é mantida por construção, e não de ouvido.
Toda execução: leia references/lessons.md e references/runs.md PRIMEIRO. Finalize com a Retrospectiva (passo 13).
A skill só melhora se você escrever as lições de volta.
0. Pré-verificação (sempre)
python scripts/preflight.py [--elevenlabs-mcp yes] # passe yes se você tiver ferramentas ElevenLabs conectadas
Caminhos usados abaixo: scripts/..., references/... e templates/... são relativos à pasta desta skill
($SKILLS/motion-ad-studio). $MOTIONMAXXING é a pasta do motor ($SKILLS/motionmaxxing; o preflight a exibe), e
$SEAM_GATE é o script opcional de seam gate que o preflight encontra (ou passe --seam-gate FILE).
| Necessidade | Por quê | Se faltar |
|---|---|---|
| motor motionmaxxing (Apache-2.0) | render.mjs (quadros → MP4), look.py gates, lint.mjs lint de design, runtime/vendor/gsap.min.js | git clone https://github.com/Tejashmakwana/motionmaxxing ao lado desta skill, ou defina MOTIONMAXXING |
| ffmpeg + ffprobe, Node 18+, Chrome/Chromium/Edge | render, probe, mix | instale; defina CHROME_PATH se o Chrome não for encontrado automaticamente |
| Python 3.9+ com numpy + Pillow | beats, synth bed, mix, sheets | pip install numpy pillow |
| faster-whisper (opcional) | timestamps de palavras para temporização travada em palavras | pip install faster-whisper, ou qualquer alinhador que forneça tempos de início/fim de palavras |
| seam gate (opcional) | prova que cada transição tem velocidade combinada | HyperFrames motion-doctrine + patches/seam-gate-camera-overlap.patch |
| ElevenLabs (opcional, recomendado) | locução expressiva, música composta, SFX personalizados | veja a próxima seção |
ElevenLabs é opcional: notifique o usuário uma vez, nunca bloqueie
Se o preflight exibir o AVISO (sem chave de API e você não tem ferramentas ElevenLabs), repasse-o ao usuário em seu idioma antes da etapa de áudio, em uma mensagem curta, e deixe-o escolher:
- conectar: ele adiciona uma
ELEVENLABS_API_KEYou conecta o servidor MCP do ElevenLabs. Execute o preflight novamente. - continuar: construa o filme completo com o caminho sem chave abaixo. Diga uma vez na nota de entrega que o ElevenLabs elevaria a qualidade da locução e da música. Não pergunte novamente no mesmo projeto. Se você não puder perguntar (execução em lote ou não interativa), continue sem ele e coloque a recomendação em NOTE.md.
| Camada | Com ElevenLabs | Sem ele (ainda funciona) |
|---|---|---|
| Locução | TTS com tags de emoção, 2 takes, escolha um | a própria gravação do usuário (melhor), ou uma voz guia TTS local/do SO; ou um filme guiado por música sem locução |
| Música | música gerada para a duração do filme, drop no payoff | scripts/synth_bed.py (procedural, grade de beats exata), ou uma faixa para a qual o usuário tenha os direitos |
| SFX | 1-3 samples principais (chicote, whoosh, digitação) | scripts/mix_events.py sintetiza cada SFX localmente |
| Tempos de palavras | fala para texto com timestamps (ou timestamps do TTS) | scripts/words.py (faster-whisper local) |
Detalhes, prompts, custos de créditos e regras de licença: references/audio-providers.md.
Pipeline
-
Espaço de trabalho.
python scripts/new_film.py <projeto>copia o kit de take único, o runtime GSAP e as fontes locais. Renderize um still do demo intocado para provar a toolchain:node $MOTIONMAXXING/scripts/render.mjs <projeto>/film/index.html --still 1.2,16.4 <projeto>/stills. -
Kit da marca. Obtenha os arquivos oficiais do logotipo do usuário e corte cada um em sua bbox alfa. Se um condutor for atracar no logotipo, meça os retângulos dos subglifos. Pegue as cores contando
#hexno CSS do site e fontes como woff2 local (scripts/fetch_fonts.py). Use o canal de CTA que a marca realmente usa. Nunca redesenhe ou aproxime um logotipo: peça-o. -
Uma ideia + um novo estilo. Escreva uma ideia que só esta marca poderia filmar. O teste de cobrir o logotipo: esconda o logotipo e o filme ainda deve apontar para esta marca. Escreva três direções, mate duas e escolha um estilo DIFERENTE da última linha de
references/runs.md. -
Gancho. Escreva 3 variantes com menos de 12 palavras (pergunta, negação, especificidade, história) e escolha uma. O quadro 0 já está ocupado e em movimento, o gancho está na tela até o quadro 1, e nada aparece gradualmente a partir do preto.
-
Locução. Escreva cerca de 2,5 palavras/s (30 s ≈ 70-75 palavras). Se o TTS suportar tags de emoção, marque cada linha ([curioso] [confiante] [energético] [brincalhão] [caloroso]). Gere ou grave, corte pausas longas, ajuste a duração com
atempo≤ 1,1, então obtenha os tempos das palavras:python scripts/words.py audio audio/vo.wav --lang <código>. O Whisper fornece apenas TEMPOS. O texto da legenda sempre vem do roteiro aprovado. -
Música. Gere (duração + BPM + "drop em "), licencie uma faixa ou execute
python scripts/synth_bed.py --bpm 120 --dur 32 --drop 15.8 --out audio/bed.wav. Obtenha a grade compython scripts/beats.py audio/music.mp3 audio/beats.json(synth_bed escreve um.beats.jsonexato). Corte o início da música para que o drop coincida com a palavra do payoff da locução: beat do filme k = primeiro_beat - corte + k·período. -
STORYBOARD.md + ledger.json (
templates/one-take/tem um exemplo preenchido). Inclua:- a especificação da página, a ideia e as três direções;
- uma folha de ritmo (alongamento / t / energia 0-10 / rota / música);
- um mapa de temporização: cada evento com a palavra
w(i)ou beatbeat(k)ao qual está travado; - a locução e a lista de dados ilustrativos;
- o ledger: uma linha por costura (eixo de saída/entrada + direção, tempo de corte).
-
Construção. Copie padrões do kit (
references/one-take-kit.md):- relógios
w(i)/we(i)/beat(k); - ordem por quadro
tl.seek → PRE (câmeras, âncoras móveis) → cursores (leem rects ao vivo) → UP (UI que segue); - câmera 3D com keyframes e um mecanismo de cursor que mira em rects do DOM ao vivo;
- atualizadores de digitação/texto/classe como funções puras de t;
- eventos
sfx()e whooshes derivados da câmera.
Contrato que o renderizador precisa:
#maincarregadata-composition-id="main" data-width data-height data-duration.window.__seek / __duration / __timelines / __events / __player / __ready / __playerReady / __renderReady. Filmes estilo montagem (cenas em camadas, UI plana, condutor do logotipo):references/montage-kit.md. - relógios
-
Olhe para ele. Renderize 15-20 stills (
node $MOTIONMAXXING/scripts/render.mjs ... --still t1,t2,... stills), organize em uma sheet (python scripts/sheet.py stills sheet.jpg 6 220) e execute uma passada de visão: uma linha por quadro, depois uma lista de defeitos. Corrija e repita 2-3 passadas.- A verdade geométrica (o que está onde, visível, sua opacidade) vem de
node scripts/probe.mjs index.html "t1,t2" "#a,#b". - A verdade do texto vem de um recorte em resolução total: a visão lê mal árabe e CJK reduzidos como "erros de digitação" que não existem.
- A verdade geométrica (o que está onde, visível, sua opacidade) vem de
-
Seam gate (recomendado). Sirva a pasta do filme em localhost, então execute
node "$SEAM_GATE" verify --ledger ledger.json --url http://127.0.0.1:<porta> --comp-url http://127.0.0.1:<porta>/index.html. O alvo é 0 FALHA. Linhas onde um movimento de câmera de take único mantém ambas as janelas na tela precisam de"overlap": "camera"mais o patch empatches/. Pare o servidor depois. Vejareferences/qa-gates.md. -
Mixagem. Cada SFX vive em
window.__events({t, type:'sfx', name, gain, dur?, speed?}).- Despeje-os com
node $MOTIONMAXXING/scripts/render.mjs index.html --still <t> ev, que escreveev/events.json. - Mix:
python scripts/mix_events.py --events ev/events.json [--vo vo.wav --vo-at 0.10] [--music bed.wav --music-trim s] --dur <s> --out audio/mix.wav [--music-db -24] [--tp -2.5] [--whip/--whoosh/--typing samples] [--lift t0:t1:dB] [--fade t]. - Níveis: locução a -18 dBFS RMS, música a -30 com ducking sob a locução, whooshes alinhados ao pico do quadro mais rápido da câmera, loudnorm de duas passadas para -14 LUFS / TP ≤ -1.
- Despeje-os com
-
Render + gates + entrega.
- Render:
node $MOTIONMAXXING/scripts/render.mjs index.html <NOVO-nome>.mp4 --audio ../audio/mix.wav --crf 17 --grain 0.03. Use um novo nome de saída para cada tentativa: duas renderizações no mesmo arquivo o corrompem. ffmpeg -v error -i x.mp4 -f null -não deve imprimir nada. Então executepython $MOTIONMAXXING/scripts/look.py x.mp4 --out look --expect <dur> --expect-audio(G0/G2/G3/G5 PASS) enode $MOTIONMAXXING/scripts/lint.mjs index.html.- Entregue: o mestre 9:16, um crop 4:5 (
crop=1080:1350:0:200após verificar o layout), 2-3 PNGs de capa, NOTE.md (ideia, mapa de temporização, dados reais vs ilustrativos, fontes de áudio + licenças, números dos gates, o que melhorar) e uma pastaproject/(filme + áudio + scripts). - Limpeza: pare servidores e Chrome headless órfão.
- Render:
-
Retrospectiva (OBRIGATÓRIA, antes de sua resposta final). Acrescente regra datada + por quê às lições em
references/lessons.md. Adicione uma linha areferences/runs.md(data, tipo de produto, estilo, duração, números dos gates, veredito quando conhecido). Aplique patch neste arquivo, em um script ou no kit se uma etapa mudou. Quando o usuário reagir depois, registre o veredito. As lições contêm apenas método, nunca nomes de clientes ou dados privados.
Barra de qualidade
- Gancho: frase real do cliente ou uma lacuna de curiosidade. Quadro 0 em movimento, o gancho legível até o quadro 1, sem fade do preto.
- Continuidade: um condutor através do filme (cursor, chip, marca do logotipo), sem crossfades, e 2-3 tipos de transição repetidos. Cortes acontecem no meio do movimento e com velocidade combinada. Mantenha uma direção atual: para "próximo", filmes RTL viajam conteúdo esquerda→direita e filmes LTR direita→esquerda. Vetores reservados são gastos em significado.
- Travamento de temporização: cada clique, queda e pouso está em
w(i)oubeat(k), e o drop musical está em uma palavra da locução. Whooshes derivam da velocidade da câmera. O mapa de temporização lista cada evento e a que ele está travado. - Sem oscilação ociosa: cada pausa tem um movimento de câmera com intenção, uma revelação em etapas ou UI ao vivo. A quietude pertence apenas antes de um payoff.
- Zonas seguras (1080×1920):
- Posicionamentos pagos Meta: texto legível em y 270-1250 e x 60-960 (os 120 px da direita são botões);
- Reels/TikTok orgânicos: mantenha os 320-370 px inferiores livres;
- coloque o trilho de legenda sob os painéis de UI, nunca sobre um compositor;
- o trilho de drop mostra palavras que a imagem já exibe.
- Fim: marca registrada mais um CTA no canal real da marca. Segure o fim 0,6-1,4 s e mantenha o take final ≤ 25 % do filme.
- Honestidade: declare dados ilustrativos em NOTE.md. Nunca invente alegações de desempenho, preços ou depoimentos.
- Metas: look.py G0/G2/G3/G5 PASS, energia de movimento ≥ 5/255 de mudança média de luma (filmes UI escuros ficam perto de 2), sincronia de corte ≥ 35 % (o benchmark profissional medido), -14 LUFS ± 0,5 com pico verdadeiro ≤ -1 dBTP, 0 erros de decodificação.
Notas de plataforma
- Trabalhos em segundo plano no Windows git-bash: chame
node.exe, não o aliasnodewinpty ("stdin is not a tty"). - Um import ESM de um caminho absoluto do Windows precisa de
file:///C:/.... - Chrome headless vaza de execuções interrompidas. No final, liste navegadores iniciados com
--headless=newe--remote-debugging-port=0cujo pai se foi, e mate a raiz com sua árvore. - Velocidade de render: UI plana ≈ 4 min por 35 s a 1080×1920. Um mundo 3D ≈ 4-5 min a ~4 fps, mas apenas se a contagem de camadas 3D permanecer pequena.
Arquivos
scripts/:preflight.py: dependências e aviso ElevenLabs;new_film.py: scaffold de um projeto;fetch_fonts.py: woff2 local;words.py: tempos de palavras;beats.py: grade de beats e drop;synth_bed.py: música sem chave;mix_events.py: mixagem orientada a eventos;sheet.py: folha de contato;probe.mjs: geometria ao vivo.
templates/one-take/: o filme completo de câmera 3D take único como um demo executável (produto fictício, cópia RTL em árabe), com STORYBOARD.md e ledger.json.references/:research.md: pesquisa de cenário, skills upstream, notas de segurança, especificações de plataforma;lessons.md,runs.md: a memória de auto-aprendizado;audio-providers.md,one-take-kit.md,montage-kit.md,qa-gates.md.
patches/seam-gate-camera-overlap.patch: regra opt-in de seam gate para filmes de câmera take único.