O que Histórias Curtas Animadas em Cartoon-3D (three.js + Remotion) faz?
O que produz: um vídeo curto de 1080x1920, 30 fps, 45-65 s. Uma história real original contada no estilo de referência: um gancho absurdo no passado, pessoas rindo, "Viu só?", e uma recompensa de uma linha. Cartões planos de cartoon estão em um mundo 3D pintado com contornos a tinta, luz quente direcionada contra sombra fria, desfoque de lente e uma câmera que nunca corta. Um narrador rápido (~3,7 palavras/s), legendas de uma palavra, uma trilha sonora original e efeitos sonoros sintetizados, masterizados a -14 LUFS.
Exemplo prático: Os Falsos Compradores (1937, Sylvan Goldman paga atores para empurrar seus novos carrinhos de compras), que está em project/src/videos/fake-shoppers/ e project/stories/fake-shoppers/.
Regras básicas (sempre)
- História, personagens, voz e música são nossos. Use a referência para o visual e a fórmula, nunca seus roteiros, personagens ou cenas. Nunca diga o nome do canal em um vídeo, título ou descrição. Os vídeos de referência são material de estudo particular: nunca os envie ou compartilhe.
- Os fatos são pesquisados e com fontes no topo do SCRIPT.md da história. Piadas são hipérboles ou fatos reais, nunca história inventada apresentada como fato.
- Apenas ferramentas gratuitas e locais. Use edge-tts ou a própria voz do usuário; nenhum gerador pago. Pergunte antes de usar créditos em qualquer conector.
- Sem pausas na voz (corte as lacunas para 0,07 s, ou 0,2 s no final das frases). As legendas estão ativas (estilo de referência). O vídeo termina ≤0,5 s após a última palavra, sem encerramento ou CTA.
- Verifique
references/TOPICS_DONE.mdantes de escolher um tópico. - Duas portas de aprovação, depois "apenas faça" (mantido da skill original):
- Roteiro: mostre o roteiro (com suas fontes) e aguarde o OK do usuário antes da voz e do plano de cenas. Depois disso, trabalhe sem perguntar até a porta 2.
- Quadro de revisão: antes da renderização completa, o usuário assiste a um rascunho com metade da resolução no quadro de revisão, fixa anotações em momentos ou cenas e pressiona "Looks good" (etapa 8). As rodadas se repetem até lá; nenhuma renderização completa antes disso.
- O gosto do usuário e verificações aprendidas (de quadros de revisão anteriores). Leia ambos os arquivos PREFERENCES antes de escrever o roteiro (etapa 2), o plano de cenas (etapa 4), os cenários (etapa 5) e o elenco (etapa 6). Percorra ambos os arquivos CHECKS na etapa 8, juntamente com as Armadilhas de legibilidade:
- compartilhado por toda skill de vídeo:
~/video-editor/review-board/PREFERENCES.md,~/video-editor/review-board/CHECKS.md; - apenas para este estilo:
references/PREFERENCES.md,references/CHECKS.md.
- compartilhado por toda skill de vídeo:
- Retomando uma história existente: execute
node ~/video-editor/review-board/cli.mjs show stories/<name>/reviewprimeiro. As anotações que o usuário enviou enquanto nenhuma sessão estava em execução são tratadas antes de qualquer outra coisa (etapa 8.5). - Uma renderização completa. Inicie-a em segundo plano, informe ao usuário o ETA (~4 fps em 1080, ~10 min para 60 s em 2K), e não faça polling: o trabalho avisa quando termina. As prévias em
--scale 0.5são gratuitas para repetir.
Este Mac (configurado e testado em 2026-11-07)
- Projeto de trabalho:
~/video-editor/toon3d-shorts/, criado porsetup.sh. Ele contémsrc/engine(genérico),src/videos/<name>/(uma pasta por vídeo),stories/<name>/(roteiro, voz, dicas de cena, partitura),audio/(kit de sintetizador + mixer),tools/measure.py,scripts/epublic/. Uma cópia nova está na pastaproject/desta skill. Recrie-a em qualquer lugar combash ~/.claude/skills/toon3d-story-shorts/setup.sh <dir>, que executa npm install (versões fixadas) epip install --user scipy. - Node 24 + Remotion 4.0.539: GPU via ANGLE/Metal. Stills levam ~1,3 s cada após um bundle de ~20 s; uma prévia completa de 60 s renderiza em ~45 s com
--scale 0.5. - Python 3.9: numpy, PIL, scipy. ffmpeg-full. whisper-cli com
~/video-editor/models/ggml-large-v3-turbo-q5_0.bin. edge-tts (python3 -m edge_tts). - Estudo de referência (seu para construir, não incluído):
~/video-editor/reference-study/, feito a partir dos vídeos de referência que você estuda (baixe-os você mesmo em~/Downloads/reference-shorts/; eles são material de estudo, nunca os compartilhe). O estudo do autor mediu 19 vídeos; os números emreferences/vêm dele:STYLE_BIBLE.mdeSCRIPTS_ANNOTATED.mdmeasure/(estatísticas por quadro, transcrições, folhas de contato de 2 s / 60 quadros, quadros de 1 fps, summary.json), que é a linha de base paratools/measure.py ours ... --refsframes/esheets/(visualizações de 1 fps / 2 s usadas para comparações lado a lado)
- Defina
TMPDIR/REMOTION_TMPpara~/video-editor/remotion-tmp(stills.mjs faz isso). Os bundles do Remotion se acumulam lá. Exclua pastas antigasremotion-webpack-bundle-*somente quando o usuário concordar.
Pipeline
-
Ideias → tópico → fatos. Quando o usuário não tem tópico, ou pede ideias, execute uma rodada de ideias (
references/VIRAL_IDEAS.mdtem os dados, fontes, rubrica e regras de fatos):-
O que vence agora (algumas chamadas de pesquisa no YouTube; pergunte primeiro se o conector cobra créditos):
- Os vídeos mais populares do canal de referência:
youtube_channel_shortscom channel_id<REFERENCE_CHANNEL_ID>(o canal cujos vídeos você estuda) e sort_bypopular. Adicione quaisquer novos títulos aTOPICS_DONE.md. - Destaques de nicho:
faceless_outliers_videoscom umaquerysemântica por tipo vencedor (por exemplo, "animated short revealing the hidden reason behind a strange historical invention, trick or law, with a twist ending"), videoTypeshorts, languages["english"], minOutlierScore 3. Ignore acertos fora do nicho (jogos, gadgets). Anote os padrões de título e adicione histórias já usadas aTOPICS_DONE.md.
- Os vídeos mais populares do canal de referência:
-
Candidatos: colete ~30 histórias verdadeiras da lista de fontes, com WebSearch/WebFetch. Mapeie cada uma para um tipo vencedor: razão oculta por trás de um objeto ou prática antiga, sistema estrangeiro ou brecha, psicologia do cérebro, truque ou golpe de dinheiro, fábula ou paradoxo.
-
Pontue cada uma com a rubrica de 10 testes (de 20). Para as 10 melhores, verifique a novidade com
youtube_search(tiposhorts): descarte uma história já feita acima de 1 milhão de visualizações nos últimos 12 meses, ou encontre um ângulo novo. -
Apresente 5 a 8 ideias com: um título de trabalho em um padrão vencedor, o gancho de uma linha, o objeto, o mecanismo + analogia, a divisão da pontuação, por que pode viralizar (números de referência do seu tipo) e 2 a 3 fontes. Salve todas em
references/IDEAS_BANK.md. O usuário escolhe uma. -
Pesquise a escolha:
- ≥2 fontes sólidas independentes para cada número, data, nome e afirmação;
- lenda contada como lenda; provocações dramatizadas marcadas como tal;
- um bloco de fatos (afirmação → links → confiança) no topo de
stories/<name>/SCRIPT.md.
Para um tópico grande, a skill de pesquisa aprofundada pode fazer esta passagem.
Um bom tópico é uma história verdadeira surpreendente com um único objeto central e um mecanismo oculto que o espectador pode visualizar, além de uma analogia cotidiana que o explique (tigela de sopa, telefone escorregando de uma mesa, botões de elevador).
-
-
Roteiro (160-240 palavras, 45-65 s). A fórmula medida do canal (
references/STYLE_BIBLE.md§2,SCRIPTS_ANNOTATED.md):- Gancho (feito em ~5 s, 9-20 palavras): uma ação absurda declarada como fato, no passado ("Ele pagou estranhos para fingir que faziam compras em seu próprio supermercado."). Alternativas: uma afirmação paradoxal ("X é ilegal, mas...") ou uma promessa condicional ("Se você alguma vez..."). Nunca uma pergunta.
- Cenário: 1-2 linhas no presente, com números concretos e o ano.
- Céticos: alguém ri ou zomba, com uma provocação citada em caráter. Use 1-2 provocações por vídeo.
- Pergunta do espectador: "Espera, ...?" / "Mas como?" (cerca de uma por vídeo).
- Escala: saltos no tempo e repetição ("Semana após semana", "Em julho..."), além de uma piada de hipérbole a cada 10-15 s ("tão X que Y", uma comparação que esvazia).
- Virada: "Então, uma noite/manhã...".
- Revelação: "Viu só," em ~65-87 % do tempo de execução, dando o mecanismo real em 1-3 frases simples, idealmente através da analogia cotidiana. ("Viu só," logo após o gancho também funciona como uma mudança de contexto.)
- Recompensa: uma linha declarativa curta que recontextualiza tudo (os céticos provados errados). Corte nela. Bônus: escreva a última linha para que ela flua de volta para a primeira, para um loop perfeito.
- Estilo: gancho no passado, depois presente; palavras faladas com contrações; ~14 palavras por frase; as conjunções são "então / mas / daí", nunca "e então". Segunda pessoa ("Imagine você...") é um modo válido.
- Nunca narre o que o espectador já pode ver (mantido da skill original). A voz adiciona o que a imagem não pode: a causa, o número, a piada, os riscos. A imagem mostra a ação.
- Título: uma lacuna de curiosidade em torno do objeto, 4-8 palavras, em um padrão vencedor ("O [objeto] Que [resultado absurdo]", "Por que [grupo] [fez algo estranho]", "Como um [coisa pequena] [fez coisa grande]", "O Que [objeto] Realmente Significou", "O [pessoa] Que [paradoxo]"). Ofereça 3 opções com o roteiro.
- Teste do gancho: leia a primeira frase em voz alta. Ela deve impactar em menos de ~3 s e soar errada ou impossível. Se precisar de contexto, reescreva-a.
- Entregue para a porta 1: o roteiro, os 3 títulos e o bloco de fatos com fontes.
-
Voz em
stories/<name>/voice/:- Gere:
python3 -m edge_tts --voice en-US-AndrewNeural --rate=+14% --text "$(cat ../script.txt)" --write-media raw.mp3, ou use a gravação do usuário. - Aperte:
python3 scripts/tighten_voice.py raw.mp3 voice.wav --sentence-gap 0.12corta lacunas para 0,07 s, ou 0,12 s no final das frases (a referência tem ~1 pausa acima de 0,25 s por vídeo), e gera 48 kHz mono. - Tempos das palavras: whisper-cli
-l en -ml 1 -sow -ojem uma cópia de 16 kHz, depois converta parawords.json([{w, a, b}]em segundos). Use a grafia do roteiro, não a do whisper. Copie-o também parawords_authored.json: a linha do tempo contra a qual o plano de cenas é escrito (story.ts constróiRETIMEa partir do par; arquivos idênticos = nenhuma alteração). - A própria gravação do usuário: compare suas palavras com o roteiro e meça seu ritmo (palavras/s, pausas acima de 0,25 s). Apertar ajuda pouco uma leitura que já é apertada; se for mais lenta que os alvos abaixo, faça uma versão com preservação de tom
--tempo 1.1e deixe o usuário ouvir ambas antes de escolher. - Substituindo a voz após o plano de cenas (mesmas palavras, nova gravação; feito para Os Falsos Compradores em 2026-11-08): não reajuste o tempo de nada manualmente.
- Mantenha os tempos antigos como
words_authored.jsone coloque os novos emwords.json(grafia do roteiro, mesma contagem de palavras). Palavras diferentes significam um novo plano de cenas. RETIME = makeRetime(authored, spoken, FPS)(engine/retime.ts) mapeia cada quadro de saída para a linha do tempo do autor, seguindo a nova voz palavra por palavra com suavização de ±2 palavras (erro médio de início ~1 q). index.tsx usatotal: RETIME.total, retime: RETIME; cast.ts lip-sync continua importandowords_authored.json.- Verifique alguns quadros de palavras-chave em stills e depois publique o novo rascunho no quadro de revisão com cada cena listada em
--changed. - O som se move com ele, sem nada reposicionado manualmente:
node scripts/retime_cues.mjs <name>mantémcues_authored.jsonuma vez e escrevecues.jsonno tempo de saída (eventos, argumentosdur, bases, whooshes) maistimemap.json.python3 score.py music.wav <RETIME.total> timemap.json: os acentos seguem a imagem, a grade de batida segue seção por seção. Sem um mapa, a partitura fica inalterada (verificada amostra por amostra).python3 audio/mix.py stories/<name>/cues.json public/<name>/mix.wav, depois transcreva a mixagem para confirmar que cada palavra é ouvida.
- Mantenha os tempos antigos como
- Alvos: 3,6-3,9 palavras/s, gancho termina ≤6 s. TOTAL = ceil(último fim de palavra × 30) + 6 quadros.
- Aperte antes do plano de cenas, nunca depois. Cada quadro de cena é construído sobre o
words.jsonapertado, então reapertar depois significa reajustar o tempo do vídeo inteiro. (O exemplo pulou isso e manteve 10 pausas acima de 0,25 s, contra ~1 da referência.)
- Gere:
-
Plano de cenas em
src/videos/<name>/story.ts(copie o exemplo):SHOTS:{id, a, b, light, set}em quadros. Um novo visual a cada ~2,2 s (cerca de cada 8 palavras). A ação cai na palavra-chave, 0-3 q antes de seu início.TRANSITIONS: como uma cena aparece:dissolve(4-8 q) em mudanças de lugar ou tempoiris(12-16 q,cx/cy) através de vigias, olhos mágicos, lentes ou relógiosdust(20-26 q) quando uma baforada ou nuvem preenche o quadroflash(4 q) apenas após o gancho Cenas no mesmo cenário sem transição são automaticamente unidas por um deslizamento de câmera encadeado centrado no limite (makeCamAt;chain= 18 q, ou um registro por cena recebida dimensionado pelo percurso), então a troca de palco ocorre no meio do movimento. Nunca corte seco. Um limite encadeado que percorreria > ~1100 px ou giraria > 90° recebe um dissolve em vez disso.
CAMS: chaves por cena{f, dur?, dissolve?, s: f => dolly(pos, look, pushK(f, f0, rate, punch?), {fov, roll})}. Regras da câmera (references/studies/camera.md, 12 vídeos a 30 fps):- Orçamento de quadros: 15-20 % parada, ~45 % rastejamento, ~33 % deslizamento (3-30 px/q a 540 de largura), ≤3 % rápida.
- Um novo enquadramento a cada ~1,4 s. A maioria são pequenos reenquadramentos: envolva as chaves como
withReframes(CAMS, ENDS)e cada longa retenção recebe um movimento lateral de 14 q de ±5 % da distância do sujeito a cada 42 q, mantendo o próprio empurrão daquela chave. Marque retenções paradas deliberadashold: true. Cerca de 4 movimentos rápidos por minuto: pico de 35-55 px/q (limite 70), 20-34 q. - Autor ~7 movimentos a cada 10 s, a maioria deles movimentos pequenos e lentos (pico ~10 px/q, 80-150 px de percurso). Use
withNudges(CAMS, [[shot, baseKeyF, at, dur, ±0.05-0.07], ...])para pequenos reenquadramentos laterais dentro de longas retenções (eles mantêm o empurrão daquela chave), entãowithReframespreenche o que resta. A câmera do exemplo após esta re-chave mede dentro da referência em cada classe (parada 19,5 / rastejamento 49,9 / deslizamento 27,1 / rápida 3,5 %, 7,4 movimentos a cada 10 s; studies/camera.md). - Verifique a direção de cada ajuste em um still. Mova em direção ao...
[truncado para tradução]