Novo vídeo: da tomada ao master
Antes de começar: harness.config.json → configured: true (caso contrário — skill setup), bash video/scripts/doctor.sh sem MISSING. Leia brand-kit.md, editing-taste.md, “Perfil de gosto” em exemplars.md, anti-patterns.md, delivery-specs.md. O estilo do vídeo é apenas o do perfil do usuário: há pôster, cards, stickers, b-roll, som, quanta gráfica, qual ritmo. O que não estiver no perfil — pergunte, não decida sozinho. O ponto de partida do código é o diretório video/src/ atual.
Se video/public/footage.mp4 já existir de um vídeo anterior e não estiver arquivado em edits/ — primeiro arquive (passo 11), depois comece.
1. Inspeção da tomada
ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate:stream_side_data=rotation -of default=nw=1 takes/1.MOV
Veja a orientação pela rotation, não pela width (o iPhone grava vertical como 1920x1080 + flag). Visualize 3–4 frames (ffmpeg -ss N -i … -frames:v 1 out/peek-N.jpg). Não estabilize, se filmado com tripé — vidstab adicionará tremor. Apenas se claramente na mão: estabilize o ARQUIVO ORIGINAL (vidstabdetect=shakiness=6:accuracy=15 → vidstabtransform=smoothing=25:optzoom=1:interpol=bicubic, -c:a copy; precisa de ffmpeg com libvidstab) e trabalhe com ele em diante.
2. Takes e falsos inícios — ANTES do corte
cd video && python3 scripts/chunks.py ../takes/1.MOV
Uma transcrição contínua esconde repetições, mas o espectador as percebe imediatamente. Encontre: trechos vizinhos com a mesma frase (take — mantenha o ÚLTIMO), trechos de 1–2 palavras que o trecho seguinte recomeça (falso início). Mostre ao usuário a lista do que será cortado, com timestamps — e obtenha um “sim”. Os limites devem estar dentro das pausas.
3. Corte
cp public/captions.json out/captions.backup.json 2>/dev/null # cut.py sobrescreve a transcrição
DROP="12.40-15.80" python3 scripts/cut.py ../takes/1.MOV
O ritmo é definido pelo cut no perfil (ajustado conforme referências). O script imprime DURATION, os frames das emendas e uma verificação de “emenda sobre fala”. Se houver poucas emendas para o ritmo desejado pelo usuário, passe argumentos abaixo do perfil, por exemplo … 0.4 0.2 (pausa média ~0.35 / 0.2); se muitas, acima. Nenhuma emenda — sala ruidosa: QUIET=-46. Falante rápido/ritmo lento — SPEED=1.1. Emenda sobre fala — ajuste DROP ou parâmetros, não deixe.
4. Matte — execute IMEDIATAMENTE (se style.poster.enabled)
TITLE_OUT = primeira emenda da saída do cut.py (o pôster sai nela), geralmente 4–7 s. Matte é a parte mais demorada (~8 s/frame em CPU, 2 workers ≈ 6 frames/min), execute em background e escreva código enquanto ele roda:
python3 scripts/matte.py <TITLE_OUT> 2 > out/matte.log 2>&1 # em background (run_in_background)
Não renderize stills enquanto ele roda — eles o sufocam. Para aguardar o término: use ps -axo command | grep "[m]atte.py", não pgrep. O script pula frames já prontos — após reinicialização, apenas execute novamente.
5. Transcrição
Abra public/captions.json (w, s, e em segundos, em):
- corrija erros de audição: nomes, marcas, termos, anglicismos; acrônimos como são escritos ("AI", "ROI"); whisper adora “Obrigado por assistir” / “Thank you.” no silêncio do final — remova;
em: 2(sestyle.captions.highlightforsizeouboth) e"accent": 1(secolorouboth) — por SENTIDO, na quantidade e nas palavras descritas no perfil (brand-kit.md§2, §4). Se não descrito — pergunte quais palavras destacar.
6. Bit-list
Você mesmo ou pelo subagente script-beats (para vídeos longos) escreva video/SCRIPT.md:
- pôster — apenas se
style.poster.enabled: linhas com palavras e tom do usuário, acento e kicker conforme o perfil; - cards — se
style.cardsnão fornone, com densidade deediting-taste.md§3 (número →count; passo →num+head; enumeração →head+linesourowcom ícones nas palavras);from= primeira palavra da frase + 4 frames; - stickers
FLOATS— apenas sestyle.stickers: legenda de uma palavra, pictograma compacto (ART_NAMES); - card
pain: true— apenas se o usuário quiser “não faça assim”.
Antes do código, mostre ao usuário o bit-list resumidamente (o que e onde aparecerá) — é o vídeo dele, as decisões são dele.
7. Código
src/Composition.tsx:DURATION,TITLE_OUT,KICKER,TITLE,BEATS,FLOATS;Captions from= início da segunda frase, se houver pôster, senão 0.src/ui/Footage.tsx: tabelaBEATSestritamente pelas emendas do cut.py, com força total (close-up 1.16–1.21×, normal 1.06–1.09×) —style.motion.punchenfraquecerá ou desligará. Onde colocar close-up: conformeediting-taste.md§4; após close-up — volte a abrir, senão o close-up “gruda”; se houver pôster, na primeira emenda.- Novo componente — apenas se nem card, nem sticker, nem
Photo/Clip/Tagpuderem expressá-lo (neste caso —scene-builder). - B-roll do Higgsfield — se estiver conectado e o perfil desejar (
brand-kit.md§5): exiba via<Clip>(corte e mude antecipadamente comffmpeg -an -t <seg>), verifique texto/rostos/mãos nos frames da geração antes de inserir. Primeiro pergunte ao usuário e informe o preço. - Som — apenas se
style.sfx: sons faltantes (card,count,end) — pelo subagenteaudio-agentconforme descrição do perfil. npm run lint— limpo.
8. Frames para aprovação (após o matting)
Renderize um still de cada card e sticker no momento completamente montado, o pôster no meio de sua vida (a última linha é lida acima do cabelo), algumas frases de legendas, o ÚLTIMO frame:
npx remotion still MyComp out/key/f<N>.png --frame=<N> --scale=0.5 --timeout=120000
Monte em uma folha de 4 por linha com legendas numeradas (PIL; fonte com cirílico, ex.: /System/Library/Fonts/Supplemental/Arial Bold.ttf), mostre ao usuário (SendUserFile). O master — apenas após seu “ok” A folha leva minutos, o master 10–20 minutos.
Verifique você mesmo antes de exibir: texto-chave fora dos 15% inferiores / 8% superiores; nada sobreposto; sticker não intersecta card; último frame não vazio nem cortado; tudo conforme o perfil do usuário e nada além.
9. Master
npm run master # em background; aguarde o processo, não o surgimento do arquivo
O script verifica os cortes, conta frames e gera out/preview.mp4. Verifique o volume: ffmpeg -i out/final-master.mp4 -af ebur128 -f null - 2>&1 | grep -A3 Summary ≈ alvo de audio.lufs. Envie a prévia ao usuário.
Edição após o master (“corte esta frase”) — corte o próprio master (ffmpeg trim+concat em silêncios), não recorte a tomada nem re-renderize tudo; informe o ETA antecipadamente. Verifique a emenda: corte 6 s ao redor e rode whisper — devem coincidir exatamente as duas frases desejadas.
10. Capa
Pergunte qual capa é necessária, se não estiver no perfil: frame com título (Cover), pôster do vídeo (PosterCover) ou própria. Escolha o frame junto com o usuário: ofereça 3–4 frames nítidos com olhos abertos (ffmpeg -ss <seg> -i takes/1.MOV -frames:v 1 -q:v 2 out/cover-N.jpg).
- Frame escolhido →
public/cover-bg.jpg. rembg i -m birefnet-portrait public/cover-bg.jpg out/cover-matte.pngpython3 scripts/cover-sticker.py public/cover-bg.jpg out/cover-matte.png public/cover-cutout.png 20- Em
Root.tsx→CoverdefaultProps.lines: título com palavras do usuário,accent/em— como ele desejar. Os tamanhos são ajustados automaticamente — não altere os tamanhos de ponto. npx remotion still Cover out/cover.png --timeout=120000— mostre.
Alternativa: PosterCover — pôster do vídeo como capa (frame + seu recorte em poster-bg.jpg / poster-cutout.png).
11. Arquivo
edits/<N>/ (na raiz, não em video/): Composition.tsx, Footage.tsx, captions.json, SCRIPT.md, cover.png, final-master.mp4, preview.mp4. Se o usuário desejar — prossiga com o skill publish.