Communitygithub.com

MuhammadToffaha/Video-editing

Transforme vídeos de fala em Reels/TikToks/Shorts profissionais com legendas sincronizadas, gráficos animados, efeitos sonoros e suporte a dublagem com sincronia labial.

O que é Video-editing?

Esta skill transforma vídeos de fala (talking-head) em conteúdos curtos e de alta retenção para plataformas como Reels, TikTok e YouTube Shorts. Ela opera em dois modos: **Edição**, que mantém o idioma original e adiciona legendas sincronizadas, gráficos animados (como infográficos, diagramas, cartões de UI), close-ups de câmera, logotipo da marca e efeitos sonoros sutis; e **Dublagem**, que traduz o áudio para outro idioma com uma nova voz sintetizada (clonagem zero-shot do timbre do falante original) e sincroniza os movimentos labiais (Wav2Lip + GFPGAN). Totalmente offline, a skill usa ffmpeg, Chromium headless com GSAP para animações CSS/JS, e sherpa-onnx Whisper para transcrição. O resultado é um vídeo 1080x1920 @30fps, H.264/AAC com loudness normalizado a -14 LUFS. Ideal para profissionais de marketing, criadores de conteúdo e editores que precisam de um fluxo automatizado e de alta qualidade sem usar templates genéricos.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MuhammadToffaha/Video-editing/tree/HEAD/.claude/skills/short-form-video-editor

Perguntar na sua IA favorita

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

Documentação

AUTOPILOTO — o que fazer quando o usuário digitar /short-form-video-editor

O usuário envia um vídeo (e, opcionalmente, uma imagem de logotipo) e digita o comando. Execute TODO o trabalho sem fazer perguntas; pare apenas se algo realmente impedir (nenhum vídeo encontrado, sem ffmpeg). Texto extra após o comando = notas de estilo/marca, aplique-as.

  1. Encontrar entradas: o vídeo mais recente nos uploads da sessão (ls -t /root/.claude/uploads/*/*.{mp4,mov,webm} ou o caminho fornecido na mensagem); logotipo = imagem anexada se houver (sem logotipo -> pule watermark/hero/outro-logo, use um encerramento limpo sem texto). Idioma = detecção automática com asr_chunks.py ... auto.
  2. Localizar o kit de ferramentas: a pasta desta skill (o diretório que contém este SKILL.md) contém template/. Trabalhe em uma nova pasta de projeto: dentro do clone do repositório Video-editing como projects/<slug>-<YYYYMMDD>/ quando esse repositório estiver na sessão, caso contrário no scratchpad. cp -r template/. <project>/.
  3. Verificar/instalar dependências (uma vez): ffmpeg, Node + Playwright Chromium (/opt/pw-browsers, nunca execute playwright install), pip install numpy pillow sherpa-onnx, scripts/fetch_asr_model.sh. Sem rede para huggingface; GitHub releases + npm + PyPI funcionam.
  4. Execute o Fluxo de Trabalho abaixo de ponta a ponta, tomando decisões de design você mesmo (cor da marca extraída do logotipo; caso contrário, paleta tech coral/teal; cenas escolhidas de reference/scene-patterns.md para se adequar ao que é realmente dito).
  5. Entregar: SendUserFile o mp4 (exibir renderização), depois um breve resumo: especificações, quais gráficos foram adicionados, pontos de transcrição COM BAIXA CONFIANÇA para verificar de ouvido, ressalva sobre a resolução do vídeo original, "áudio não auditado". Salve o projeto (sem work/) e o mp4 final no repositório e faça push para o branch designado da sessão (ou main se nenhum foi fornecido). Nunca crie um PR a menos que solicitado.
  6. Espere ~15-25 min para um vídeo de 60 s (transcrição ~3 min, renderização ~4 min, codificação ~2 min). Avise o usuário em uma linha no início e depois trabalhe em silêncio até terminar.

MODO DUBLAGEM — traduzir + nova voz + sincronia labial (testado uma vez no clipe Glow: Árabe -> Inglês)

Use quando o usuário quiser o vídeo em outro idioma "com os lábios acompanhando as palavras".

  1. Roteiro: transcreva + verifique o original como no modo Edição, depois escreva a tradução você mesmo como data/phrases.<lang>.json = [[win_start, win_end, "texto com *palavras-chave e SUBSTITUIÇÕES DISPLAY|faladas (NBSP dentro de tokens com várias palavras)"], ...]. Mantenha as JANELAS de frases ORIGINAIS para que os beats de câmera/gráficos sobrevivam; você pode mesclar janelas vizinhas. Planeje cerca de 2,5-3 palavras/s (Inglês) por janela — condense em vez de apressar; mantenha o significado, sem novas alegações. Exemplo de substituição falada: *COSRX|Cosrex, Axis-Y|Axis\u00a0Y.
  2. Modelos: scripts/fetch_dub_models.sh (+ fetch_asr_model.sh para verificação).
  3. Voz (padrão = CLONADA para o falante): construa work/ref.wav = 4-5 clipes limpos entre pausas (cerca de 15 s) da fala original do falante (16k mono, concatenados). python3 -I scripts/tts_clone.py data/phrases.en.json work/ref.wav 8 <total_seconds> -> work/voice_en.wav + data/transcript.source.json com os intervalos de fala REAIS. YourTTS (coqui, fetch_dub_models.sh baixa) clona timbre zero-shot; o script gera N takes por linha, mantém o take cuja leitura de volta do Whisper corresponde melhor ao roteiro e depois estica o tempo (0,72-1,25x, preservando o tom) para preencher ~90% da janela original. Números comprovados no clipe Glow: tom mediano 144 Hz vs falante 154 Hz (voz Kokoro padrão 123 Hz), similaridade do espectro de longo prazo 0,96 vs 0,90, cada linha é lida corretamente. Soletre nomes de marcas foneticamente via DISPLAY|spoken (e exclua-os da pontuação — automático). Fallback tts_phrases.py = voz Kokoro padrão (clara, mas não a do falante). Sotaque: o modelo transfere timbre/tom, NÃO um sotaque nativo — não prometa um inglês com sotaque egípcio; diga o que foi alcançado.
  4. Sincronia labial nos quadros na RESOLUÇÃO ORIGINAL: ffmpeg -t <end> -i src -vf fps=30 work/raw/%05d.png; ffmpeg -i work/voice_en.wav -ac 1 -ar 16000 work/en16k.wav; MODELS=work/models python3 -I scripts/lipsync2.py work/raw work/en16k.wav work/ls --model wav2lip_gan_96.onnx --enhance 0.7 (teste primeiro com --range a b; execução completa ~25 min para 1700 quadros em 4 CPUs: caixas Haar, landmarks 2dfan4 em cada quadro, depois Wav2Lip + GFPGAN por quadro). lipsync2 = recorte FFHQ-512 alinhado por landmark, landmarks suavizados, Wav2Lip na caixa facial do landmark, restauração GFPGAN com blend 0.7, máscara em formato de boca (nunca toca o nariz), colagem de volta. Depois scripts/01b_upscale_lipsynced.sh. NÃO use o antigo lipsync.py (recorte Haar grosseiro: lábios borrados, artefatos semelhantes a língua — o usuário chamou de "muito ruim"). EDTalk-256 foi testado e é pior (boca fantasmagórica). Modelos: 2dfan4, gfpgan_1.4, wav2lip_gan_96 do lançamento do facefusion-assets no GitHub.
  5. Prova de sincronia visual: folha de contato de recortes de boca com o envelope de áudio sob cada quadro — a boca deve estar fechada nas lacunas silenciosas e aberta/variada enquanto a barra está ativa. Métricas de correlação de pixel são muito ruidosas aqui; não confie nelas.
  6. Gráficos: python3 -I scripts/build_transcript.py work/en16k.wav (defina max_chars ~22 no json de origem para Inglês), regenere composition/transcript.js, depois reescreva a cópia de scene.js e palavras de gatilho no novo idioma (LTR: direção .row/.chunk ltr, fonte Inter, origem do traço à esquerda, setas de fluxo esquerda->direita). Tokens com várias palavras são palavras separadas no transcript: pesquise palavras únicas (ts('skin',0,43.5)), nunca ts('your skin').
  7. Renderize como de costume (LAST_SRC_FRAME=<n> scripts/02_render_all.sh, cues, sfx) e mixe com VOICE=work/voice_en.wav OUT=out/name-en.mp4 scripts/03_mix_and_encode.sh.
  8. Seja honesto no resumo: Wav2Lip em rostos de ~100px dá uma boca suave e levemente alisada (visível em inspeção próxima), o movimento da cabeça/mãos ainda é do falante original, a voz é sintética, o falante deve aprovar uma versão dublada de sua imagem, considere rotulá-la como dublada por IA. NOMEIE qualquer frase traduzida cuja fonte tenha baixa confiança.

Editor de vídeo curto (legendas + gráficos animados + SFX)

Dois modos: Editar (manter o idioma, adicionar legendas/gráficos/SFX) e Dublar (traduzir para outro idioma, nova voz, lábios reanimados para o novo áudio — acionado quando o usuário disser inglês/traduzir/dublar/sincronia labial). Pipeline comprovada em um promo de farmácia egípcia-árabe de 57 s (Glow Cosmetics). Saída: 1080x1920 @30, H.264/AAC, -14 LUFS. Projeto de exemplo: projects/glow-kbeauty-reel/ em https://github.com/MuhammadToffaha/Video-editing

Regras que definem "profissional, não template"

  • Mantenha o falante, a voz e o significado intocados. Nunca invente alegações (números, "100%", preços). Se um gráfico precisar de texto que não foi falado, mantenha-o genérico (nomes de categorias, rótulos de sobrancelha).
  • Cada visual apoia uma frase falada e é acionado NA palavra (ts('palavra')), não no início da frase. Cartões saem antes do próximo entrar; sem fantasmas sobrepostos.
  • Uma linguagem visual: cor da marca (amostra do logotipo) + branco + painéis de vidro ink profundo, Inter para rótulos latinos, Cairo (Árabe) para manchetes/legendas. Menta apenas para estados de sucesso.
  • Zonas de layout (1080x1920, rosto do falante y 790-1110): cartões y 235-735 (nunca sobre o rosto, mesmo após zoom de 1,15x), legendas y1545, mantenha os 220 px inferiores e 130 px superiores livres de conteúdo chave (UI da plataforma). Refaça a verificação da posição do rosto para cada fonte.
  • Dispositivos de retenção, com moderação: snap de zoom (1,12-1,15x) no início das frases com deslocamentos lentos entre eles, um gráfico a cada 2-4 s, destaque da palavra ativa na legenda, microanimações de tachado / verificação / contagem regressiva, momento de herói do logotipo quando a marca é dita, cartão de encerramento da marca.
  • SFX: whoosh na entrada do cartão, pop/tique nos elementos, chime no sucesso, thud no logotipo. Silenciosos (cerca de -10 dB abaixo da voz). Sem música, a menos que o usuário a forneça.

Fluxo de Trabalho

  1. Inspecionar: ffprobe, folha de contato (ffmpeg -vf "fps=1/6,scale=239:-1,tile=5x2"), encontre cartões de encerramento (quadro preto do WhatsApp/CapCut) e anote a posição do falante. A fonte geralmente é de baixa resolução (telefone/WhatsApp): amplie com lanczos, avise ao usuário que o vídeo ficará suave enquanto os gráficos se mantêm nítidos.
  2. Projeto: cp -r <skill>/template/. my-project/ && cd my-project; cp <logo> assets/; python3 -I scripts/extract_logo.py assets/logo_original.png assets/logo_white.png (imprime o hex da marca). Atualize --coral/--brand em composition/style.css e #wm/#outro.
  3. Preparar: END=<segundos de corte> scripts/01_prepare.sh input.mp4 (quadros, 16k wav, voz).
  4. Transcrever (sem acesso HF no sandbox; GitHub releases funcionam): scripts/fetch_asr_model.sh; depois
    • python3 -I scripts/asr_chunks.py work/asr16k.wav <lang|auto> 3.2 a, repita com 2.4 e 4.5. Whisper trunca caudas de chunks; mescle as 3 hipóteses você mesmo e corrija com seu conhecimento do idioma.
    • Palavras incertas / nomes de marcas: python3 -I scripts/asr_probe.py work/asr16k.wav ar,en 14.0-16.8 14.5-16.6 ... (a passagem en soletra nomes de marcas latinas). Confie apenas no que é consistente em janelas sobrepostas; liste o resto como BAIXA CONFIANÇA na mensagem final e no README. Não construa gráficos com nomes adivinhados.
  5. Tempo: python3 -I scripts/pauses.py work/asr16k.wav -> pausas são os limites confiáveis de frases. Escreva data/transcript.source.json como [start, end, "text"] frases (veja data/transcript.source.example.json; *palavra = pílula de destaque; use NBSP dentro de nomes latinos com várias palavras; marcas latinas em texto RTL: evite colar o prefixo Árabe و a elas, escreva و Brand). Depois python3 -I scripts/build_transcript.py work/asr16k.wav e echo "window.TRANSCRIPT=$(cat data/transcript.json);" > composition/transcript.js. Ele distribui os tempos das palavras por peso silábico dentro de cada frase e ajusta aos vales de energia, depois faz blocos de legenda balanceados de 2-4 palavras. Verificação de sanidade: nenhum início de palavra dentro de silêncio.
  6. Projetar cenas em composition/scene.js (veja reference/scene-patterns.md). Use card(t0,t1,{y,h,html}), pop, fade, draw, cue, ts. Use os exemplos de cenas como padrões: cartão de gancho, chips de marca (slots de esqueleto que preenchem quando cada nome é dito), tiles de categoria, diagrama A->B com ponto viajante + verificação, chips tachados, nós de fluxo, classificação por estrelas, linhas de checklist, roadmap, gráfico de barras, anéis de confiança, revelação de herói do logotipo, encerramento da marca. Defina finish(<segundos>) = fim da voz + ~1.7 s de encerramento.
  7. Renderizar + QA: renderize alguns quadros de teste primeiro (node scripts/render.mjs <f> <f+1> work/test), construa folhas de contato com Pillow, OLHE para elas. Depois scripts/02_render_all.sh (4 workers, ~8 fps total), node scripts/render.mjs cues work/cues.json && python3 -I scripts/sfx.py work/cues.json work/sfx.wav, OUT=out/name.mp4 scripts/03_mix_and_encode.sh. Se a fonte terminar com um cartão de encerramento, passe LAST_SRC_FRAME=<n> para congelar o último quadro limpo.
  8. Entregar: envie o mp4 (SendUserFile), informe especificações, os pontos de transcrição com baixa confiança, o limite de resolução do vídeo original e que o áudio não foi auditado de ouvido (você não pode ouvi-lo) — apenas verificado com medidores de loudness e testes de onset-vs-energy.

Armadilhas já resolvidas (não reaprenda)

  • Python str.split() divide em NBSP — use split(' ') (já em build_transcript.py).
  • Animação de SVG <rect> com CSS scaleY o inverte/desloca no Chromium headless — use tween attr:{y,height}. Desenho de traço: draw(path,t,d).
  • Elementos que começam ocultos precisam de CSS opacity:0 (classe hid) e tweens com immediateRender:false; todo tween deve ser buscável (workers pulam direto para seu quadro inicial).
  • Cartões com backdrop-filter só desfocam se o quadro de vídeo estiver na mesma página (#bg img) — é por isso que os quadros são compostos na página.
  • Cartões desfocados vazios parecem quebrados: ou inicie o cartão em sua palavra de gatilho ou mostre linhas/slots de placeholder escuros que acendem quando falados.
  • Árabe precisa de formatação real: Chromium + Cairo woff2 (split unicode-range Árabe/Latino) funciona; Pillow/ffmpeg drawtext não.
  • Whisper no sherpa-onnx não tem timestamps de palavra e trunca caudas; daí janelas curtas + ancoragem em pausa.
  • opencv 5.x não tem CascadeClassifier (fixar 4.10.0.84); caixas faciais Haar dão falsos positivos em mãos/camisa e perdem ~30% dos quadros -> rejeição de outliers de caixa mediana + segunda passagem ROI + interpolação (já em lipsync.py).
  • TTS estilo Kokoro/Whisper lê COSRX como letras: use substituições DISPLAY|spoken.
  • MCP do GitHub create_repository pode dar 403 — peça ao usuário para criar o repositório, depois add_repo + clone (clone para um diretório novo se o caminho existir).

Habilidades Relacionadas