Communitygithub.com

morph-edit

Transforme um vídeo com apresentador e sua transcrição em um motion graphics B-roll com uma única forma que nunca corta, sincronizada com as palavras do locutor.

O que é morph-edit?

Morph Edit é uma skill especializada para agentes de IA (como Claude Code) que permite criar clipes de motion graphics B-roll com um estilo contínuo e orgânico: uma única forma que se transforma (morph) sem cortes, enquanto o conteúdo troca com um breve blur. Ideal para criadores de conteúdo que desejam substituir momentos de tela cheia com gráficos animados que reagem diretamente às palavras faladas. A skill suporta transcrição de áudio (com timestamps precisos) e o fluxo inclui inspeção de vídeo, planejamento aprovado pelo usuário, geração de código HTML para cada clipe, renderização (com alpha para sobreposições), e saída final com clipes, preview e arquivos de timing. Ferramentas como `engine/build.py`, `render.js` e `beats.js` automatizam a construção, renderização e verificação, enquanto `scripts/composite.py` e `make_pages.py` montam o preview final. O usuário recebe clips prontos para o editor, um preview com cortes secos, páginas HTML interativas e, opcionalmente, legendas e cartões de inscrição.

Funciona com~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/mrgoraya/morph-edit/tree/main/skills/morph-edit

Perguntar na sua IA favorita

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

Documentação

Morph Edit (motion B-roll)

Você cria clipes de motion graphics para o vídeo de um criador. Cada clipe é uma forma que nunca corta: ela transforma (morph) seu tamanho, cantos e cor de estado a estado enquanto seu conteúdo troca com um breve blur. Um cursor impulsiona as mudanças com cliques e arrastos reais, e cada mudança cai sobre uma palavra falada.

A saída é um conjunto de clipes que o criador insere em seu editor. Você também fornece uma renderização de preview do vídeo com os clipes inseridos, e duas páginas HTML: uma para percorrer os clipes, outra para comparar antes e depois.

Tudo que você precisa está nesta pasta da skill:

  • engine/: o motor de motion (motion.js), o shell da página (base.css), build.py (clipe → HTML autocontido), render.js (renderização quadro a quadro com motion blur), beats.js (folhas de contato de stills), fontes (Geist, OFL).
  • scripts/: setup.sh, inspect_video.py, words.py, composite.py, make_pages.py.
  • reference/engine-api.md: como escrever um clipe. Leia antes de escrever seu primeiro clipe.
  • examples/opus-aoe2/: seis clipes finalizados para um vídeo real de 54 segundos. Use-os como referência de qualidade e como pontos de partida.

Abaixo, $SKILL significa a pasta desta skill. Trabalhe em uma pasta motion/ dentro do projeto do usuário.

1. Configuração (apenas na primeira execução)

bash $SKILL/scripts/setup.sh ./motion

Isso verifica Node, Python 3 e ffmpeg, e instala Playwright + Chromium em motion/node_modules. Execute cada script do motor com NODE_PATH=./motion/node_modules.

2. Entrevista

Use a ferramenta AskUserQuestion; limite a uma rodada. Você precisa:

  • O vídeo. Um caminho. Copie ou referencie como motion/work/source.*.
  • A transcrição. Opcional. Se não houver (ou apenas texto simples), transcreva o áudio com scripts/transcribe.py (veja o passo 3). Isso fornece timestamps reais das palavras, que são mais precisos que estimativas SRT.
  • Densidade:
    • Leve: 2–4 clipes por minuto, apenas nos momentos mais fortes.
    • Médio (padrão): 4–7 por minuto.
    • Pesado: a maioria das linhas coberta, com pequenos intervalos de rosto.
  • Visual:
    • A paleta padrão: tela cinza quente, componentes preto e branco, um acento laranja.
    • Ou a marca deles: cores e, opcionalmente, uma fonte. Peça para colocarem um logotipo, capturas de tela ou cores da marca em motion/inputs/, e leia esses arquivos.
  • O que evitar ou incluir. Linhas para manter no rosto, números ou nomes reais para mostrar, capturas de tela de produtos para recriar.

Pule qualquer pergunta que o usuário já tenha respondido.

3. Inspecione a filmagem

python3 $SKILL/scripts/inspect_video.py motion/work/source.mp4 motion/work
python3 $SKILL/scripts/words.py transcript.srt > motion/work/words.txt
# sem transcrição (ou você quer timings exatos das palavras): transcreva o áudio
motion/.venv/bin/python $SKILL/scripts/transcribe.py motion/work/source.mp4 motion/work

transcribe.py escreve words.txt e transcript.srt. Mostre a transcrição ao usuário para que ele possa corrigir nomes ou termos ouvidos errados antes do planejamento.

Veja você mesmo motion/work/contact.png. video.json fornece resolução, fps e seções de layout:

  • full: o apresentador preenche o quadro.
  • pip: o apresentador está em uma caixa e o resto está vazio. Inclui a posição da caixa e um aviso se a caixa mudar de tamanho ou se mover.

Os clipes devem corresponder à resolução e fps do vídeo. Os tempos das palavras de um SRT são estimativas (±0,2s); trate-os como tal.

4. Planeje e obtenha aprovação antes de qualquer código

Mostre uma tabela com uma linha por clipe:

| # | Entrada–Saída | A linha que cobre | O que a forma faz, em quais palavras | Tratamento | Porquê |

Direção criativa: decida quanto do quadro cada clipe ocupa. Esta é a decisão mais importante; tome-a por clipe e dê a razão.

  • Corte total para tela cheia. O quadro é todo o apresentador, e a linha descreve algo para ver: um produto, um processo, uma comparação, um número, uma mudança de capítulo.
    • Corte pelo tempo da ideia (3–10s), depois devolva o rosto.
    • Não corte no primeiro segundo do gancho ou em linhas pessoais, emocionais ou de opinião.
    • Deixe pelo menos ~2s de rosto entre os cortes.
  • Painel no espaço vazio. A edição já deixa espaço: uma caixa PiP, uma divisão, uma região plana.
    • Renderize um clipe transparente (bg:null) centralizado na área vazia, dimensionado para ficar longe da caixa do apresentador em todos os momentos.
    • Pode ser longo (15s+) como um morph contínuo, porque o apresentador permanece na tela.
    • Se inspect_video.py relatar que a caixa muda, pergunte se isso é intencional, depois dimensione para a maior caixa ou divida o painel na mudança.
  • Nada. A linha é sobre o apresentador, ou está muito próxima de outro clipe.

Regras de conteúdo:

  • Mostre os objetos reais do assunto: a pasta, o terminal, o arquivo, o produto, o resultado. Extraia-os das palavras. Mapeie cada ideia em uma interação do vocabulário em reference/engine-api.md (pílula + clique, progresso, verificação, ilha de status, cartão com arrasto, controle deslizante, alternância, abas, gráfico + dica de ferramenta, pesquisa/filtro, arrastar e soltar de arquivo, digitação no terminal, comparação lado a lado, cartão de capítulo).
  • Nunca invente números, citações, preços ou resultados. Use barras relativas, linhas de texto esqueleto ou rótulos retirados da transcrição, e liste o que é ilustrativo. Coloque números reais apenas quando o usuário os fornecer.
  • Uma ideia por clipe. Um trecho contínuo (uma seção PiP inteira) pode ser um clipe longo com vários estados.
  • Ritmo para a fala, não para a música: uma mudança por batida falada, cerca de 0,4–1,2s de intervalo.

Aguarde o usuário aprovar ou editar o plano.

5. Construa

Escreva um fragmento por clipe em motion/clips/NN-nome.html, seguindo reference/engine-api.md e os exemplos. Depois construa:

python3 $SKILL/engine/build.py motion/dist motion/clips/*.html

Coloque cada mudança de estado em sua palavra: tempo local do clipe = tempo da palavra − ponto de entrada do clipe.

6. Verifique stills nas palavras-chave

NODE_PATH=./motion/node_modules node $SKILL/engine/beats.js motion/dist/NN-nome.html motion/work/NN.png 0.4 1.2 2.1 …

Escolha os tempos em que cada estado se estabilizou e alguns momentos intermediários. Examine cada folha você mesmo. Corrija qualquer coisa apertada, cortada, ilegível ou fora da palavra, ou onde o cursor saia do quadro. Depois verifique mais uma vez. Clipes de painel renderizam em preto na folha para que você possa julgá-los.

7. Renderize

NODE_PATH=./motion/node_modules node $SKILL/engine/render.js motion/dist/NN-nome.html motion/out/NN-nome_0m32s40.mp4 30000/1001
  • Use o fps do vídeo.
  • Clipes de painel (bg:null) devem ser escritos como .mov, que fornece ProRes 4444 com alfa.
  • Nomeie cada arquivo pelo seu ponto de entrada na linha do tempo (0m32s40 = 0:32.40).
  • A renderização leva 4 subquadros por quadro, portanto é mais lenta que o tempo real. Execute dois clipes em paralelo em uma máquina multi-core.

8. Entregue

Escreva motion/plan.json (esquema em reference/engine-api.md). Para efeitos sonoros de UI, dê a cada clipe uma lista "sfx": [[tempo local do clipe, tipo], …] extraída de suas pistas: click e toggle em cliques do cursor, pickup/drop no início/fim do arrasto, whoosh em morphs de forma, pop na introdução e em badges, rise/fall em barras, type em digitação, tick em itens aparecendo, shutter em capturas de tela e success em verificações. Depois:

python3 $SKILL/scripts/composite.py motion/plan.json motion/out/preview.mp4
python3 $SKILL/scripts/sfx.py motion/plan.json motion/out/preview.mp4   # Efeitos sonoros de UI, se o usuário quiser
python3 $SKILL/scripts/make_pages.py motion/plan.json motion/out/preview.mp4
python3 $SKILL/scripts/make_gallery.py motion/plan.json motion/out/preview.mp4

O usuário recebe, tudo em motion/out/:

  • os clipes
  • TIMING.md: arquivo, entrada, saída, a linha que cobre, o tratamento e o que é ilustrativo
  • preview.mp4: o vídeo deles com os clipes inseridos, cortes secos, áudio original (mais SFX quando usado)
  • sfx/: os efeitos sonoros de cada clipe como um WAV separado, para mixagem no editor deles
  • index.html: todos os clipes tocando ao mesmo tempo em uma grade, com o preview completo e links para as outras páginas (abra este primeiro)
  • viewer.html: percorra os clipes
  • compare.html: original vs preview, sincronizados, lado a lado, empilhados ou com efeito wipe

Diga claramente que o preview é para revisão: para o corte final, eles colocam os clipes em seu próprio editor, onde podem ajustar o timing, adicionar transições e mixar áudio.

Cartões de inscrição (opcional)

Pergunte ao criador se ele deseja um cartão de inscrição final em sua linha de call-to-action e um ou dois lembretes curtos. Os modelos são fragmentos de clipe em $SKILL/templates/subscribe/ (end-card.html, reminder.html). Copie um para motion/clips/, depois:

  • Substitua __CHANNEL__, __HANDLE__ e __AVATAR__ (o logotipo ou foto do criador como uma data URI; sem imagem, use uma letra no círculo). Pergunte por estes; nunca adivinhe um nome ou handle.
  • Reajuste o tempo das constantes no topo do <script> (IN, os tempos de clique, T) para as próprias palavras do criador. O cartão final clica em Compartilhar, Inscrever-se, Sininho, Curtir e Comentar nas palavras que o criador diz; o lembrete clica em Inscrever-se e Sininho.
  • Construa, verifique stills, renderize e adicione a plan.json como qualquer outro clipe. Renderize o cartão como um .mov transparente para que fique sobre a filmagem.

Legendas (opcional)

Crie um SRT no idioma falado e um SRT em inglês, para upload como legendas ocultas (não queimadas). Trabalhe em motion/work/cap/:

  1. motion/.venv/bin/python $SKILL/scripts/captions/find_gaps.py motion/work/words.txt "<video>": Whisper pode pular trechos inteiros de fala em vídeos longos. Ele imprime as lacunas; retranscreva-as com retx.py "<video>" "<lista de lacunas>" motion/work/gapwords.json [idioma].
  2. python3 $SKILL/scripts/captions/make_cues.py motion/work/words.txt motion/work/gapwords.json motion/work/cap escreve as pistas e quatro blocos.
  3. Traduza os blocos em paralelo (quatro subagentes, um por bloco) usando templates/caption_brief.md. Cada um escreve out1..4.json com {"i","orig","en"} para cada pista.
  4. Corrija as pistas sinalizadas, depois python3 $SKILL/scripts/captions/build_srt.py motion/work/cap motion/out/captions escreve captions_original.srt e captions_english.srt (duas linhas balanceadas, até 42 caracteres cada).
  5. Diga ao criador para testar o SRT no VLC ou em um upload não listado antes de publicar.

Padrões de estilo

A marca do usuário substitui estes.

  • Cor: tela #E9E7E2, tinta #0B0B0B, componentes brancos, um acento #FF5A1F. Clipes de painel sobre filmagem escura usam formas claras (#F4F2EE).
  • Tipografia e ícones: Geist para texto de UI, Geist Mono para código, nomes de arquivo e terminais. Um conjunto de ícones com um peso de traço (M.icon).
  • Movimento: molas com um pequeno overshoot no máximo. Bordas de entrada e saída usam molas diferentes para que os indicadores estiquem. A câmera amplia para que cada estado preencha o quadro.
  • Proibido: easing saltitante, partículas, brilhos, gradientes em cromo de UI, traços de ícones misturados, tempo morto, qualquer coisa que pareça um modelo, dados inventados.

Armadilhas

  • Nunca coloque will-change em algo que a câmera escala; o texto fica borrado.
  • A troca de texto dentro de um contêiner em morph precisa de seu próprio tempo de entrada e saída (M.vis din/lin/lout), ou o texto antigo e o novo se sobrepõem.
  • Rótulos com mix-blend-mode: difference devem estar em uma camada que tenha o próprio modo de mesclagem. Um pai com filtro os isola.
  • Itens que deslizam sob um destaque precisam de molas M.FAST, ou a linha de destaque fica vazia por um momento.
  • Mantenha o cursor dentro do quadro em cada zoom da câmera, inclusive durante morphs.
  • Estimativas de palavras de um SRT derivam dentro de uma pista; coloque mudanças importantes na primeira ou última palavra de uma pista quando possível.
  • Um clipe termina mantendo seu último estado; o composto mantém o último quadro se seu slot for mais longo.

Habilidades Relacionadas