Communitygithub.com

vincesector/pipeline-cabeça-falante

Cria uma edição dinâmica de cabeça falante no Remotion a partir de gravações pré-cortadas, com zooms baseados na transcrição, layout lateral com cartões de conteúdo, tela com picture-in-picture da câmera, profundidade rotoscopada (palavras-herói e objetos passando atrás do apresentador), tipografia 3D com traçado de caminho e logotipos 3D, legendas fixas com ênfase em frases, efeitos sonoros sutis e ajuste de sincronia de áudio.

O que é pipeline-cabeça-falante?

Este skill do agente IA constrói edições avançadas de cabeça falante no Remotion, transformando gravações simples em vídeos dinâmicos e profissionais. Ele é acionado quando o usuário pede para tornar um vídeo de cabeça falante "mais dinâmico", adicionar zooms, gráficos, demonstrações de tela, ou "editar como um profissional". O pipeline começa com um plano detalhado que o humano deve aprovar. A partir da transcrição, o agente identifica os pontos narrativos (gancho, afirmação, número, reviravolta, etc.) e escolhe um efeito adequado para cada um: zoom no rosto (punch-in), layout lateral com cartões de conteúdo, cena de tela com picture-in-picture, profundidade rotoscopada (palavras e objetos passando atrás do apresentador), tipografia 3D animada, logotipos 3D, legendas com ênfase em frases e efeitos sonoros sutis. Após aprovação, o agente executa as operações necessárias (rotoscopia, render 3D, geração de legendas) e renderiza o vídeo final com controle de qualidade. Projetado para ambientes de desenvolvimento com Python 3.11, Node.js, pnpm, Remotion e ferramentas como MediaPipe e OpenCV. Ele exige gravações pré-cortadas (sem silêncio ou falhas) e cria um plano antes de qualquer renderização cara, evitando desperdício de recursos computacionais. Suporta múltiplas plataformas de agente IA (Claude Code, Cursor, Codex, etc.) e é ideal para criadores de conteúdo que desejam edições profissionais sem configurar manualmente cada efeito.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vincesector/talking-head-pipeline/tree/HEAD/skills/dynamic-edit

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

/dynamic-edit

Uma cabeça falante que nunca se mexe está morta na chegada; uma que se mexe sem motivo é pior. Este pipeline decide qual efeito merece seu lugar em qual palavra, escreve isso como um plano que o humano pode vetar, e só então gasta processamento.

Raiz do repositório:

THP_HOME=${THP_HOME:-$(cat ~/.config/talking-head-pipeline/root)}

Leia antes de planejar: $THP_HOME/docs/STYLE_RULES.md (as regras de estilo), $THP_HOME/docs/LAYOUTS.md (geometria e zonas seguras de legendas), references/plan-format.md (o esquema), references/qa.md (as validações). 3D: $THP_HOME/docs/3D.md.

Contrato de entrada: a gravação já está cortada. Sem remoção de silêncio, sem filtro de hesitações aqui. Uma gravação crua vai para /autocut primeiro; volte com seu clean.mp4 e seu workdir (para palavras literais).

Nunca pule a etapa do plano. Rotoscopia custa cerca de 12 minutos por minuto de gravação e uma renderização completa dezenas de minutos. Um palpite errado capturado em um plano de texto não custa nada.

Fluxo de trabalho

1. Estruturar o projeto

P=<diretório de projetos>/<slug>                 # pergunte onde o humano guarda projetos de vídeo; nunca a Área de Trabalho
cp -R "$THP_HOME/template" "$P"
cd "$P"
uv venv --python 3.11 .venv            # mediapipe não tem wheels para depois de 3.12
uv pip install --python .venv/bin/python "mediapipe==0.10.21" opencv-python backgroundremover numpy pillow
scripts/download_models.sh             # Detector facial MediaPipe (não incluso no repositório)
(cd remotion && pnpm install)          # ou npm install
cp "<autocut workdir>/clean.mp4" remotion/public/raw.mp4
python3 "$THP_HOME/scripts/autocut/verbatim_cut_words.py" "<autocut workdir>" -o remotion/public/words.json

Reel vertical a partir de uma gravação 16:9: scripts/prep_vertical.sh "<autocut workdir>" "$P" em vez das duas últimas linhas (corte estático 9:16 na mediana x da cabeça, nunca corte com acompanhamento).

2. Inventário, cortes, rastreamento

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,nb_frames \
  -show_entries format=duration -of default=nw=1 remotion/public/raw.mp4
.venv/bin/python scripts/detect_cuts.py remotion/public/raw.mp4 --out remotion/public/cuts.json
.venv/bin/python scripts/track_head.py remotion/public/raw.mp4 --out remotion/public/track.json --cuts remotion/public/cuts.json
  • Folga de zoom = largura da fonte / largura da linha do tempo (2560 em 1920 = 1.33x grátis). Além disso você aumenta a resolução.
  • A proporção é detectada automaticamente a partir da largura/altura do plano (perfis lib/layouts.ts). Um mecanismo, nunca uma ramificação.
  • Leia detectionRate em track.json. Abaixo de ~0.9, movimentos ancorados no rosto não são confiáveis; diga isso.
  • A detecção de corte perde mudanças graduais (uma troca animada para um compartilhamento de tela). Amostre um quadro por segmento e adicione limites ausentes a cuts.json manualmente. Segmentos de compartilhamento de tela não recebem zooms, nem legendas desenhadas sobre eles, nem cartões (defina captions.silence para esses intervalos).

3. Revisar as palavras

Pesquise em words.json por cada nome próprio, marca, ticker e pessoa que o script nomeia. Modelos da família Whisper os distorcem e a frase ainda soa fluente, então a revisão nunca percebe. Corrija o arquivo de palavras (mesclar dois tokens em um é aceitável), nunca a renderização. Números como dígitos.

4. Escrever o plano, depois PARE

  1. Leia a transcrição inteira primeiro. Encontre os momentos que a narrativa realmente tem: gancho, afirmação, número, reviravolta, revelação, recompensa, o momento melhor mostrado do que dito.
  2. Escolha uma ferramenta por momento em Escolhendo efeitos abaixo. Muitos momentos não recebem nada.
  3. Copie scripts/build_plan.example.py para scripts/build_plan.py e escreva os momentos lá com âncoras de palavra ("frase@segundos"). Ele escreve remotion/plan.json e as legendas. Ele recusa eventos sem motivo, sem âncoras de palavra para entrada E saída, ou zooms muito próximos.
  4. Mostre ao humano uma tabela, uma linha por evento: tempo, efeito, "chega em X, sai depois de Y, porque Z". Além disso: segundos de roto (e o tempo de matting que isso implica), qualquer reenquadramento além da folga de zoom, qualquer trecho sem evento por mais de ~12 s, e as renderizações 3D necessárias.
  5. Aguarde aprovação. Em seguida, releia plan.json do disco; o humano pode tê-lo editado.

Se o humano nomeou um efeito específico em um momento específico, esse é o plano para aquele momento.

5. Construa apenas o que o plano precisa, nada mais

  • Janelas de roto: scripts/render_and_qa.sh cria os mattes delas; ou scripts/matte_frames.py por janela.
  • Tipografia 3D / ativos 3D: tools/render3d (veja docs/3D.md). Ainda (--stills) primeiro, veja eles, depois --clip --dir=remotion/public/<nome>. Coloque os mesmos quadros de entrada/saída no plano que o at/until do evento do plano.
  • Cartões laterais: tipos em remotion/src/layouts/cards.tsx; adicione um tipo lá quando necessário.
  • Páginas de cena de tela: remotion/src/screen/pages.tsx. Reconstrua a interface em código para qualquer coisa em que você dê zoom; uma captura de tela fica desfocada com 2x.
  • Cenas em tela cheia: scenes/fullscreen/registry.ts (depth, clip, stage).
  • Efeitos sonoros: depois que o plano estiver final, scripts/add_sfx.py "$P" sfx_map.json --library <dir>.

6. Verifique com imagens estáticas, depois renderize

Imagens estáticas custam segundos; uma renderização custa a tarde:

cd remotion && npx remotion still src/index.ts Edit ../qa/landing.png --frame=<N>

Verifique cada chegada de herói (e chegada + 25), cada entrada de layout, cada transição, cada chegada 3D. Depois:

scripts/render_and_qa.sh "$P" <nome>        # cria mattes de janelas roto, renderiza, escreve folhas de QA

Renderizações: --concurrency 4-6, nice o processo, e mantenha Config.setChromiumOpenGlRenderer('angle') (já em remotion.config.ts) ou cenas WebGL falham headless. Entregue yuv420p bt709; um arquivo yuvj420p reproduz em branco no QuickTime.

7. QA (references/qa.md), depois ajuste de sincronia

Execute todas as validações em references/qa.md antes que alguém veja. Em seguida, meça e corte o atraso de áudio da renderização em relação à fonte (renderizações do Remotion atrasam algumas dezenas de ms; medido, nunca presumido):

"$THP_HOME/scripts/master/sync_trim.sh" renders/<nome>.mp4 remotion/public/raw.mp4 renders/<nome>_final.mp4 [--loudnorm -14]

Alvo |sincronia final| abaixo de 5 ms. Normalização de volume apenas se o humano quiser (padrão social -14 LUFS). Abra o final para o humano.

8. Correções após entrega: corrija o intervalo, nunca re-renderize o vídeo

scripts/patch_render.sh --base renders/anterior.mp4 --replace 0-1049 --render 0-887 --out renders/proximo.mp4

--replace é o intervalo da renderização antiga a ser descartado, --render o intervalo do plano atual que o substitui (eles diferem quando a fonte foi recortada novamente). Apenas o patch é codificado; cabeça e cauda são copiadas por stream nos keyframes; a contagem de quadros é verificada. Quando uma gagueira precisa sair da fonte depois que o plano existe, reconstrua o plano a partir das âncoras (build_plan.py) para que cada efeito se mova com sua palavra.

9. Limpeza, apenas quando o humano disser que o vídeo está pronto

Pergunte primeiro. scripts/cleanup.sh exclui PNGs de matte, dumps de quadros, folhas de QA, rascunhos, o venv e node_modules; mantém o plano, fonte, rastreamento, legendas e renderização final. Regenerar um matte custa ~12 min por minuto de gravação, então nunca execute sem permissão.

Escolhendo efeitos (uma caixa de ferramentas, não uma ordem de execução)

Não há fórmula. Um vídeo sem palavra-herói, sem roto, sem 3D é um plano válido. Um vídeo direto para a câmera pode ser apenas zooms e legendas. Cada efeito é conquistado por algo no script, e cada evento nomeia por quê (seu trabalho narrativo), em que (a palavra em que chega; o movimento começa antes dela para que CHEGUE nela) e saída (a palavra após a qual sai: fim daquele pensamento, a próxima pausa real, a palavra antes de um suavizante). Nunca uma pausa fixa, nunca "estava quieto por um tempo".

  • Rosto primeiro. Os primeiros 2-3 s são o rosto do apresentador, quadro 0 já uma imagem de gancho legível (não um fade do preto). Nenhum gráfico em tela cheia antes de ~2.5 s: a reprodução automática está mutada e uma abertura com estatísticas em primeiro lugar parece um infográfico e é ignorada.
  • Zoom (punch-in) (o carro-chefe): duração de uma frase, poucos, propositais. Ele chega enquanto a frase-chave se constrói, mantém-se nela, solta em sua última palavra. Nunca um zoom de uma palavra; nunca espaçado por um temporizador. Aproximadamente um a cada 30-45 s de cabeça falante em formato longo; mais apertado em vídeos curtos apenas se o script merecer. Ancorado no rosto rastreado. Duas frases ligadas: zoom na metade que carrega a história. Ênfase aninhada (sustentar + uma pequena ênfase na frase-chave) em vez de três zooms em uma frase.
  • Layout lateral (16:9): quando um número, lista ou comparação deve permanecer na tela enquanto é explicado. O assunto desliza para um lado, um cartão com conteúdo do outro, os cartões trocam em suas palavras e zoom no número sendo dito. A maioria dos momentos informativos em formato longo quer isso.
  • Cena de tela (16:9): o "aqui está como parece" passo a passo. Use uma ou duas vezes por vídeo, não para cada menção. Um-para-um com a interface real se recriar um produto; apenas os dados mudam, e os dados são reais.
  • Reenquadramento com cartões: uma versão mais leve do layout lateral, dentro da folga de zoom.
  • Rotoscopia (atrás do assunto): apenas para aberturas e momentos de herói. Orçamento padrão 15 s por vídeo; avise acima de 30 s; acima de 60 s pergunte. Qualquer coisa passando atrás deve valer a pena ser ocultada.
  • Palavra-herói atrás do assunto: um gancho, uma reviravolta difícil, a ideia nomeada. Acima da cabeça, cada glifo legível (verifique um quadro estático em chegada + 25). Uma por vídeo, a menos que duas estejam muito distantes.
  • Tipografia 3D de herói: uma grande afirmação ou número ao lado da cabeça ou na altura do peito, com espaçamento igual de cada borda do quadro (pelo menos ~90 px em 1080 de largura), nunca sobre o rosto.
  • Ativo 3D: um logotipo ou objeto que o apresentador nomeia, girando em espaço vazio ao lado do rosto, com roto atrás se sobrepor.
  • Cena em tela cheia: apenas quando mostrar claramente é melhor do que dizer, no máximo duas, fade+blur para entrar e sair.
  • Legendas: terço inferior fixo, mesma posição e estilo em todos os lugares (cabeça falante, lateral, tela). Ênfase = tipo de letra de destaque E tamanho 1.22x em frases inteiras, nunca dividido em dois cartões. Legendas com rastreamento de cabeça estão desligadas a menos que solicitadas.
  • Efeitos sonoros: um por evento visível (transição, chegada de herói, zoom forte, cartão, clique), sutil.

Regras rígidas

  • Nada no rosto. Nenhuma legenda, cartão, chip, logotipo ou objeto 3D sobre a caixa do rosto em qualquer quadro de sua janela. Mova-o, encolha-o, ou coloque atrás com rotoscopia. Meça a partir de track.json.
  • Sem chips de texto em caixa sobre o apresentador. Sem linhas de destaque unilaterais em qualquer cartão (topo, esquerda, qualquer borda): use um tom de preenchimento ou uma borda uniforme completa.
  • Apenas fades de quadro inteiro. Nunca desvaneça contêineres enquanto um título permanece.
  • Transições: fade+blur (padrão), fade simples, ou um stinger líquido. Nunca um obturador zigzag/denteado.
  • Nenhum texto cortado por um zoom ou pela borda do quadro. Interface com zoom desaparece acima da faixa de legenda (fade de borda World). Legendas nunca zoomam.
  • Um reenquadramento viaja na mesma renderização do que cria espaço. Nenhum movimento de câmera em direção a uma parede vazia.
  • Verifique cada número na tela em relação ao que é dito ou a uma consulta salva e com fonte. Nunca invente um.
  • Objetos e ícones são logotipos reais ou imagens geradas/obtidas. O código desenha movimento, texto, UI, gráficos. Pontas de seta são um ativo, não SVG.
  • Sem travessões na tela. Sem "comente abaixo" / "me mande DM" chamadas para ação, a menos que o humano peça.
  • Cada camada empilhada sobre o vídeo é seu próprio AbsoluteFill (um vídeo estático pinta abaixo de qualquer irmão posicionado absolutamente, que silenciosamente coloca gráficos na frente do matte).
  • Use translate + scale, nunca uma transform-origin deslocada, para reenquadramentos.

Parâmetros de efeito e números medidos: references/effects.md.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas