Communitygithub.com

beachyphotoandfilm-arch/video-skills

Cria sobreposições animadas de marca (motion graphics) para vídeos com cabeça falante, sincronizadas com as palavras exatas do locutor, além de um arquivo de importação para DaVinci Resolve.

O que é video-skills?

Esta skill automatiza a produção de overlays animados de marca para vídeos com cabeça falante, sincronizando cada elemento gráfico com as palavras exatas do locutor. É ideal para criadores de conteúdo que precisam de motion graphics profissionais sem edição manual. A skill funciona localmente, transcrevendo o vídeo com timestamps por palavra usando whisper.cpp, selecionando os momentos-chave, renderizando clipes .mov com fundo transparente e gerando um arquivo FCPXML para importação direta no DaVinci Resolve (ou Resolve via MCP, quando disponível). O estilo padrão é “in-scene type”: texto e diagramas posicionados ao lado ou atrás da cabeça do locutor, sem cartões ou fundos coloridos, mantendo sempre a visibilidade do rosto. Além disso, ela analisa a posição da cabeça e o brilho do fundo para ajustar automaticamente o layout, garantindo legibilidade. A skill é acionada por comandos como “make animations for this video” ou quando o usuário compartilha um corte bruto e pede gráficos.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beachyphotoandfilm-arch/video-skills/tree/HEAD/skills/video-overlays

Perguntar na sua IA favorita

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

Documentação

Sobreposições de vídeo

Transforma um corte bruto em um conjunto de sobreposições animadas que aparecem no frame exato em que o locutor diz cada coisa, além de um arquivo de importação para Resolve.

Defina sua marca aqui

Edite estas configurações uma vez, em scripts/scene.html (bloco :root no topo). Todo o resto as lê daí.

configuraçãovariável CSSpadrão
cor de destaque--brand-accent (+ --brand-accent-rgb como r,g,b)#4a90e2
cor de texto clara--brand-light (+ --brand-light-rgb)#f2f2f2
cor de tinta escura--brand-ink#0d131a
fonte de destaque (títulos, números)--font-display'Anton','Bebas Neue',Impact,sans-serif
fonte do corpo--font-body'Inter',-apple-system,sans-serif

A fonte de destaque deve estar instalada localmente (por exemplo, em ~/Library/Fonts), já que os clipes são renderizados offline em headless Chrome. Anton e Bebas Neue são gratuitas no Google Fonts. O nome BLUE no código significa apenas "a cor de destaque".

Estilo da casa: texto em cena. Sem cartões. O texto vive no ambiente ao lado da cabeça do locutor, títulos grandes flanqueiam a cabeça, perguntas aparecem enquanto são ditas. Sempre suas cores de marca e fonte de destaque.

A regra mais importante: mantenha os gráficos atrás da cabeça do locutor ou ao lado. Nada na frente do rosto e sem cor de fundo. Os diagramas também ficam na parede ao lado do locutor. Tudo tem matte, para que as mãos passem na frente dos gráficos.

Uma execução produz: N clipes .mov transparentes, PLACEMENT.txt, dois arquivos .fcpxml e um breve PREVIEW.mp4.

Sem som por padrão. Não adicione música ou efeitos sonoros a menos que seja solicitado.

Padrões de estilo (ajuste a gosto)

  1. Nada aparece antes de ser dito. Fixe cada clipe ao timestamp no nível da palavra da frase, mais ~0,12s para que apareça logo após as palavras. O tempo no nível da seção é lido como antecipado.
  2. Curto. De 2,5 a 6,5 segundos. A maioria em torno de 3. Deve cortar para frente e para trás como em mídias sociais, sem ficar parado.
  3. Atrás da cabeça ou ao lado, nunca sobre o locutor. Sem cartões, sem fundos, sem escurecimento. Isso aposenta os chips de canto, todos os cartões full-* e define para novos vídeos.
  4. Ainda mostre o mecanismo. Recorra a um diagrama antes de uma frase. Use os tipos de diagrama em cena (dots, flow, bars, compare, math), que ficam na parede ao lado do locutor.
  5. Divida qualquer coisa com duas metades. Modo antigo e modo novo são dois clipes. 10% e 20% são dois clipes. Três opções são três clipes, cada um aparecendo quando nomeado.
  6. Cada linha aparece na sua palavra. Listas, linhas laterais e palavras digitadas carregam deslocamentos por linha (at, t) a partir dos timestamps das palavras, não um espaçamento uniforme. scripts/plan.example.py mostra como: cite a frase, nomeie as palavras-chave, e ele faz a busca.
  7. Uma boa mistura (cerca de 48 clipes em 11 minutos): aproximadamente um quarto de diagramas em cena (principalmente flow), depois side, pair, type, list2, num. Guarde pair para os momentos de impacto.
  8. Títulos grandes vão ao redor da cabeça, não atrás dela. pair divide cada linha em um limite de palavra em duas metades que flanqueiam a cabeça, com um intervalo de 1,9x a largura da caixa facial (cabelo e orelhas incluídos), dimensionado para que ambas as metades fiquem na tela. Portanto, cada linha de pair precisa de 2+ palavras ("UMA HORA", não "HORA"): uma palavra única não pode ser dividida e acaba escondida. "around": false em data traz de volta o visual centralizado. A linha com contorno tem 150px com traço de 5px e preenchimento claro de destaque (35%) para permanecer legível.

Antes de começar: o corte está travado?

As sobreposições são ancoradas a palavras exatas, portanto qualquer novo corte depois desloca todos os clipes. Se o usuário fornecer material bruto ou o corte não estiver travado, execute a skill paper-edit primeiro e coloque as sobreposições na linha do tempo que ela produz.

Pipeline

1. Obter o corte e analisá-lo

Peça uma exportação do Resolve (por exemplo, para ~/Movies/), ou material bruto em <YOUR_FOOTAGE_DRIVE> para um paper edit primeiro. Um arquivo de vídeo é suficiente; não é necessário exportar áudio separadamente. Quando o Resolve estiver aberto, leia a linha do tempo através do MCP em vez de pedir uma exportação.

ffprobe -v error -show_entries format=duration -show_entries stream=codec_type,r_frame_rate -of default=nw=1 "<file>"

Anote a taxa de quadros (o renderizador assume 23.976 = 24000/1001; altere FPSN/FPSD em render.mjs para outras taxas) e pergunte se a linha do tempo começa em 00:00:00:00 ou 01:00:00:00 (o padrão do Resolve é 01).

2. Transcrever com timestamps no nível da palavra

ffmpeg -y -i "<file>" -ac 1 -ar 16000 -c:a pcm_s16le cut.wav
whisper-cli -m ~/.cache/whisper-models/ggml-small.en.bin -f cut.wav -oj -ml 1 -sow -of cut

-ml 1 -sow dá um token por segmento, que é o que permite a ancoragem exata. Em seguida, encontre o tempo de início de cada frase combinando execuções de token em cut.json (transcription[].offsets.from é em ms).

3. Escolher os momentos

Leia a transcrição completa primeiro. Busque aproximadamente um clipe por 15 segundos de vídeo. Para cada um: a frase âncora, um tipo e a duração mais curta que permita que a animação apareça e respire.

Fundamente o conteúdo no que foi realmente dito, não em anotações escritas. Se as anotações dizem "30 minutos" e na câmera é "cerca de meia hora", a gravação vence, e sinalize a diferença para o usuário.

4. Escrever clips.json

Copie scripts/clips.example.json como modelo. Um objeto por clipe:

{"id":"06-math-10","start":52.96,"dur":3.6,"type":"dots","cue":"\"if 10 out of 100 meals are home cooked\"",
 "data":{"lit":10,"pct":"10%","count":"10 meals"}}

Mantenha-o fora da pasta da skill (um caminho temporário é suficiente) e passe-o com CLIPS=. start é o tempo bruto da frase em segundos; o renderizador adiciona o atraso de 0,12s sozinho. A ordem de id define a ordem dos arquivos, então numere-os.

5. Renderizar um corte limpo (necessário para os tipos em cena)

Os tipos em cena leem a posição da cabeça e isolam o locutor de uma cópia do corte sem sobreposições. Renderize a linha do tempo travada do Resolve com todos os clipes de sobreposição desabilitados, H.264 1080p, no diretório temporário. Na API, SetTrackEnable em V2 não funcionou no Resolve 19; item.SetClipEnabled(False) em cada clipe da faixa funcionou. O material bruto precisa estar online, portanto a unidade de material deve estar montada; se não estiver, peça ao usuário para conectá-la e aguarde a montagem em vez de renderizar um master finalizado (sobreposições antigas seriam incorporadas a ele).

6. Renderizar

cd <skill>/scripts && npm i                   # primeira vez apenas, instala puppeteer-core
swiftc -O person.swift -o person              # primeira vez apenas, o localizador de matte + cabeça
TITLE="<video name>" CLIPS=/path/to/clips.json FOOTAGE=/path/to/clean.mp4 OUT_DIR="$HOME/Movies/<video-name>-overlays" node render.mjs
# um ou alguns clipes apenas:
ONLY=06-math-10,07-math-30 OUT_DIR=... node render.mjs

Aproximadamente 10 a 15 segundos de tempo real por segundo de sobreposição (pair é mais lento, pois aplica matte em todos os quadros). Colocar em segundo plano e verificar depois é a abordagem correta. Ele escreve PLACEMENT.txt e ambos os arquivos .fcpxml no final.

Sempre verifique sobre o vídeo real antes de uma renderização completa. node proof.mjs <clean.mp4> <clips.json> out.jpg [email protected] [email protected] ... renderiza um quadro por clipe (prefixo@segundos após o início do clipe) sobre a gravação real, com matte incluído, organizado em uma imagem. Olhe para ela. Texto saindo do quadro, um título cruzando os olhos, texto sobre um fundo ocupado: tudo invisível no código e óbvio na imagem. Para diagramas, a composição sobre cinza ainda é suficiente.

Quadros de prova: extraia para PNG primeiro. Sobrepor um .mov qtrle diretamente em uma fonte de cor lavfi com -ss resulta em um quadro em branco. Extraia o quadro (ffmpeg -ss 2.8 -i clip.mov -frames:v 1 f.png), depois componha o PNG.

Colocação no Resolve: duplique a linha do tempo travada como YouTube Final, importe os movs para um compartimento Overlays e AppendToTimeline cada um com trackIndex: 2 e recordFrame do timecode IN em PLACEMENT.txt (((h*3600+m*60+s)*24+ff), então 01:00:00:00 = 86400). Analise PLACEMENT.txt uma linha de cada vez (line.split()[0] é o id, [1] o timecode). Uma regex de arquivo inteiro pode ler texto de cue como "60-second" como um id de clipe e roubar o timecode da próxima linha, fazendo com que um clipe não seja colocado silenciosamente. Verifique se a contagem colocada é igual à contagem de clipes.

7. Pré-visualizar e depois entregar

Construa uma pré-visualização de 10 a 15 segundos sobre o vídeo real para que o usuário possa avaliar antes de aplicar:

ffmpeg -y -ss <t> -t 11 -i "<cut>" -itsoffset <a> -i "<clip1>.mov" -itsoffset <b> -i "<clip2>.mov" \
  -filter_complex "[0:v][1:v]overlay=0:0:eof_action=pass[v1];[v1][2:v]overlay=0:0:eof_action=pass[vo];[vo]scale=1280:-2[v]" \
  -map "[v]" -map 0:a -c:v libx264 -crf 20 -preset veryfast -c:a aac PREVIEW.mp4

O áudio original vem com o vídeo, que é tudo que a prévia precisa. Em seguida, forneça as etapas de importação (File > Import > Timeline > Import AAF, EDL, XML, escolha o arquivo starts-01, copie os clipes para uma faixa acima do vídeo em 01:00:00:00).

Trabalhando diretamente no Resolve (preferível quando o Resolve está aberto)

Se um servidor MCP resolve estiver instalado (por exemplo, o de terceiros barckley75/resolve-claude-mcp), ele se comunica com a API de script do Resolve Studio. Se a skill paper-edit fornecer um ensure_resolve.sh, execute-o primeiro para que o Resolve seja iniciado se estiver fechado. Com Preferences > System > General > External scripting using: Local, prefira-o em vez do processo de exportação e importação.

O que muda:

  • Nenhum corte exportado necessário. Leia a linha do tempo aberta para seus timecodes reais, taxa de quadros, timecode inicial e layout de clipe, depois ancore as sobreposições a isso. Isso corrige "os timecodes mudam toda vez que eu refaço o corte."
  • Nenhuma importação manual. Coloque os clipes .mov renderizados diretamente em uma faixa de vídeo.
  • Melhor seleção de momentos. Ver onde os cortes já caem permite que as sobreposições se alinhem com a edição em vez de lutar contra ela.
  • Também pode iniciar a renderização quando as sobreposições estiverem no lugar.

Regras para usá-lo:

  1. Leia antes de escrever. Confirme primeiro o nome do projeto, nome da linha do tempo, timecode inicial e taxa de quadros, e repita-os para o usuário.
  2. Nunca escreva na linha do tempo principal. Duplique-a primeiro e trabalhe na cópia, para que um erro não custe nada.
  3. Evite execute_resolve_code a menos que uma ferramenta normal não possa fazer o trabalho. Ele executa Python arbitrário nos projetos do usuário. Se for a única maneira, mostre o código primeiro.
  4. Sessões locais apenas. O Resolve precisa estar rodando neste Mac, portanto isso nunca funciona em execução em nuvem ou agendada. Recorra ao FCPXML nesse caso.
  5. O caminho do FCPXML ainda funciona e é o fallback. Continue gerando ambos os arquivos; eles custam segundos.

Transcrição de áudio: alguns servidores MCP do Resolve fornecem sua própria transcrição mlx-whisper, mas a etapa whisper.cpp acima é comprovada com este pipeline.

Tipos de clipe

Tudo abaixo está aposentado para novos vídeos (mantido para que vídeos antigos possam ser reeditados). Tipos de tela cheia pintam um fundo de tinta sólida com um brilho suave de destaque, então escondem completamente o locutor. Os chips ficam no canto inferior esquerdo.

tipouse paradata
full-dotsaposentado, use dotslit, pct, count
full-flowaposentado, use flowlabel, steps[], good
full-compareaposentado, use comparetitle, left{label,value,sub}, right{...,hi}, vs
full-barsaposentado, use barstitle, bars[{label,value,value_label,hi}]
full-mathaposentado, use mathparts[] (operadores x = + → renderizam na cor de destaque), sub
full-packaposentado, use bars ou sidename, note, size 0-1, hi
full-stataposentado, use pairlabel, value, sub, hi
full-titleaposentado, use pair ou typetitle (<br> permitido), size, sub
full-listaposentado, use list2title, items[], step segundos
chipaposentado, use side ou numnum, title, sub, hi
chip-stackaposentado, use list2items[]

Os tipos aposentados ainda renderizam, para reedição de vídeos antigos.

Tipos em cena (o padrão)

Sem cartões, o texto vive no ambiente ao lado da cabeça do locutor, e títulos grandes vão ao redor da cabeça.

tipouse paradata
pairum título de impacto: linha com contorno acima da cabeça, linha sólida na altura da testatop, bottom, outline (top/bottom)
side2-3 linhas curtas ao lado da cabeça, cada uma aparecendo na sua palavralines[], accent (índice, grande + cor de destaque), at[]
typeuma citação ou pergunta digitada palavra por palavra enquanto é ditawords[{w,t,hi,br}]
defineaposentado: escurece o plano. Use side ou pairword, sub
numnúmero com contorno aparece, palavras ao lado ("01 planeje a semana")num, lines[]
list2itens construindo à esquerda e/ou direita da cabeçaleft[], right[], at[] (em ordem, esquerda primeiro)

Diagramas em cena (mesma colocação na parede e matte):

tipouse paradata
dotsuma taxa em 100, grade de preenchimento ao lado do locutorlit, pct, count
flowum processo, etapas encadeadas de cima para baixo, a última na cor de destaquelabel, steps[], at[] opcional
barsdois ou três números por tamanhotitle, bars[{label,value,value_label,hi}]
compareduas opções, uma de cada lado da cabeçaleft{label,value,sub}, right{...,hi}
mathuma equação lida na parede, operadores lideram cada linhaparts[], sub

at e t são segundos a partir do início do clipe; construa-os a partir dos timestamps das palavras para que cada linha apareça na sua palavra.

Estes precisam de FOOTAGE=, o corte sem sobreposições (renderize a linha do tempo do Resolve com os clipes de sobreposição desabilitados). O renderizador lê a caixa facial e uma grade de brilho de fundo para cada clipe, para que o texto encontre a parede vazia, vire de lado ou encolha se sair do quadro, e mude para tinta em fundo claro e texto claro em fundo escuro. Ele isola o locutor de cada quadro de cada clipe em cena (segmentação de pessoa Apple Vision, person.swift), para que os títulos fiquem atrás da cabeça e as mãos passem na frente dos gráficos. Compile uma vez: swiftc -O person.swift -o person. Sem FOOTAGE=, os tipos em cena caem em camadas de cor sólida e não cavam o locutor.

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

beachyphotoandfilm-arch/video-skills

Sync camera footage to a separate lapel or field-recorder track (e.g. Tascam DR-10L and similar) and lay it up in DaVinci Resolve. Stitches the recorder's split files, finds each clip's exact place in the audio by matching words then waveforms, cuts one lapel slice per clip so every later skill works unchanged, checks for clipping, and builds a synced timeline in a new Resolve project. Trigger on "sync the lapel", "sync my audio", "line up the recorder", "I used a lav", or any shoot with a separate audio folder (live talks, events, workshops). Run it before paper-edit or video-reels.

beachyphotoandfilm-arch/video-skills

Turn raw talking-head footage into an assembled rough cut inside DaVinci Resolve. Pulls the clips off your footage drive, transcribes them locally, removes failed takes, restarts, asides and dead air, then creates a new Resolve project with two paper-edit timelines ready for your fine trim. Trigger on "paper edit", "cut my raw footage", "make a rough cut", "clean up this video", or when the user points at a folder of raw camera files for a YouTube video.

beachyphotoandfilm-arch/video-skills

Design a unique Instagram cover for each reel in your house style. Reads what the reel is about, writes a short hook headline, picks one of your own photos from a tagged photo library, lays it out like your existing covers, and proofs it in grid view at phone size. Renders locally, never with AI image generation. Can be called by a scheduling skill before reels are scheduled. Trigger on "make covers", "reel covers", "cover photo for this reel", "design the IG covers".

beachyphotoandfilm-arch/video-skills

Render finished reels out of DaVinci Resolve, write captions in the creator's voice, attach a custom Instagram cover from reel-covers, and schedule them to Instagram, TikTok and YouTube Shorts through Metricool. Handles the Drive upload hop, collision checks against the existing calendar, and cleanup. Trigger on "schedule the reels", "post these", "put these on the calendar", or after reels are approved.

beachyphotoandfilm-arch/video-skills

Cut vertical Instagram reels out of a long-form talking-head video, hook first. Picks the strongest standalone moments from the transcript, opens each reel on its punchiest line, builds vertical timelines in DaVinci Resolve framed on the speaker's face with the LUT applied, and finishes them: a hook (a held text card, or a word-by-word "build" hook with punch-in) and burned-look captions on V3; this-or-that reels get product graphics and a comment-keyword CTA card. You trim and render, nothing to import. Trigger on "make reels", "clip this for Instagram", "cut some verticals", or after a YouTube video is cut.

beachyphotoandfilm-arch/video-skills

Design YouTube thumbnails and titles for a talking-head video. Pulls graded full-res frames out of the raw footage, renders brand-styled variants in two proven layouts, and proofs them at phone size where the click actually gets decided. Trigger on "make thumbnails", "thumbnail for this video", "title and thumbnail", or after a video is cut.

beachyphotoandfilm-arch/video-skills

Run the whole YouTube video pipeline end to end, one stage at a time, stopping for the creator's approval at every gate. Paper edit, punch-ins, reels, reel covers, scheduling the reels, overlays, thumbnail and title, then scheduling the long-form video, all through Metricool. Keeps state per video so you can stop anywhere and pick up later. Trigger on "/youtube", "let's do the whole video", "run the video pipeline", "continue the <name> video", or when handed raw footage for a YouTube video.

Habilidades Relacionadas