Communitygithub.com

ThomasHMD/rough-cut

Montagem automática de cortes brutos de vídeos com fala (monólogos, gravações faladas) para o Premiere Pro. Produz um XML do Final Cut Pro 7 (XMEML) cuja timeline já remove retomadas, falsos começos, tropeços, palavras de preenchimento e longos silêncios. O clipe original nunca é tocado.

O que é rough-cut?

O rough-cut é um skill para agentes de IA (como Claude Code) que automatiza a edição de cortes brutos de vídeos com fala — como monólogos, vlogs ou palestras — diretamente para o Adobe Premiere Pro. Ele não modifica o clipe original; em vez disso, produz um arquivo XML (formato Final Cut Pro 7 / XMEML) que, ao ser importado no Premiere, gera uma sequência já editada, com retomadas, falsos começos, gaguejos, palavras de preenchimento e silêncios longos removidos. A ferramenta usa três fontes principais: a transcrição nativa do Premiere (extraída do arquivo .prproj), o áudio original (processado pelo whisper.cpp para uma segunda opinião) e a análise semântica realizada pelo modelo de IA (Claude) para identificar padrões complexos como retomadas e tropeços. O skill também inclui verificações de qualidade determinísticas (como detecção de repetições e verificação de silêncios) e gera um relatório em Markdown resumindo as decisões tomadas. Atualmente suporta inglês e francês, mas pode ser estendido para outros idiomas via arquivos de configuração JSON.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ThomasHMD/premiere-rough-cut/tree/HEAD/skills/rough-cut

Perguntar na sua IA favorita

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

Documentação

rough-cut: montagem automática de cortes brutos para Premiere Pro

Configuração única: veja INSTALL.md na raiz do kit. Com o plugin, a linha de configuração é bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}"; com uma instalação manual (as quatro pastas skills/ copiadas lado a lado para ~/.claude/skills/), execute bash install.sh a partir da raiz do kit. Os scripts ficam na pasta scripts/ deste skill.

Escopo

  • SIM: um XML do Final Cut Pro 7 (XMEML, .xml) cuja timeline já tenha removido retomadas, falsos começos, tropeços, palavras de preenchimento e longos silêncios; um relatório em markdown; marcadores vermelhos sobre o que ainda precisa ser decidido.
  • NÃO: modificar o clipe, transcodificar, exportar o vídeo, fazer correção de cor, mixar, escolher entre duas tomadas além de repetições óbvias (essa é a decisão do editor).

Regra principal: o clipe original NUNCA é modificado

O skill apenas escreve ao lado do clipe:

  • <clip>_Derush_v1.xml: a edição a ser importada (FCP7 / XMEML);
  • <clip>_Derush_v1.report.md, <clip>_Derush_v1.log.txt;
  • <clip>_Derush_v1_work/: a pasta de trabalho, mantida (transcrições, cortes intermediários).

O XML aponta para o clipe pelo caminho absoluto (file://localhost/...): o Premiere apenas o referência. Uma nova passagem cria v2, v3... sem sobrescrever nada.

O que o usuário faz (3 passos)

  1. No Premiere: importe o clipe, execute a transcrição (Painel de Texto > Transcrever), salve o projeto. A transcrição então fica DENTRO do .prproj: nunca peça ao usuário para exportá-la.
  2. Forneça ao Claude o caminho do clipe e o roteiro de referência do vídeo, se houver (texto simples, Markdown, um Google Doc, uma página do Notion, qualquer coisa legível). O roteiro serve apenas para saber se uma repetição é deliberada. Sem roteiro, a passagem ainda funciona; as repetições deliberadas então se tornam sinalizações em vez de cortes.
  3. Importe o .xml (File > Import). Uma sequência Derush_vN aparece, já editada: os cortes estão ausentes da timeline (clipes unidos em sequência, nada a fechar), e dúvidas permanecem como clipes ativos com um marcador vermelho.

Não pergunte mais nada: idioma, tipo de clipe e opções são inferidos (veja abaixo), e uma pergunta só vale a pena ser feita quando o tipo de clipe é realmente ambíguo.

Idioma

Tudo que é específico do idioma (palavras de preenchimento, frases de falso começo, padrões de claquete, conectores órfãos, aberturas a cortar, alucinações do whisper, textos de motivo dos marcadores) fica em languages/<code>.json, nunca no código. Francês (fr) e inglês (en) vêm integrados. O idioma é escolhido por --lang <code>, senão pelo idioma gravado na transcrição, senão en. Detalhes e como adicionar um idioma: references/languages.md.

Pipeline v2: seleção de tomadas (a rota normal)

Detectar apenas defeitos (v1, abaixo) atinge no máximo cerca de 57% de recall porque o whisper silenciosamente deduplica retomadas repetidas: seu decodificador anti-loop trata uma frase repetida palavra por palavra como uma alucinação e a transcreve uma vez. Isso não pode ser corrigido por configuração. A transcrição do Premiere mantém cada retomada, palavra por palavra, e os inícios de palavra não se desviam após longos silêncios (os do whisper, sim). Portanto:

EtapaFerramentaFunção
1extract_prproj_transcript.py project.prproj words_premiere.json [--rush CLIP.MOV].prproj para words_premiere.json (fonte PRIMÁRIA). Código de saída 2 se o projeto não tiver transcrição: peça ao usuário para executá-la e salvar o projeto. Alternativa: parse_premiere_transcript.py em uma exportação JSON manual
2extract_audio.py + transcribe.pywhisper = SEGUNDA OPINIÃO (verificar o texto, nunca os limites)
2bcalibrate_premiere_times.pyrealinha a transcrição do Premiere com o áudio. Execute-o em CADA corte bruto, logo após a extração de áudio (ele não altera nada quando a transcrição está no tempo certo). Mede o deslocamento por correlação cruzada, janela por janela; já foi visto um desvio de 1,8 s no final de um clipe de 21 min. Sintoma se esquecido: silence_cuts.py relata dezenas de "ruído suspeito"
3Claude em contextoanálise semântica: identificar retomadas, falsos começos e tropeços comparando a transcrição do Premiere com o roteiro e com o whisper. Regras abaixo
4silence_cuts.pysilêncios >= 1,0 s entre palavras do Premiere, finais de palavra realinhados ao nível de som, proteção de enumeração (pausas curtas entre dois blocos curtos = ritmo deliberado), zona ruidosa: sinalizar ou cortar (veja abaixo). Padrões calibrados contra edições finalizadas: não os altere sem re-medir (veja references/lessons.md, "Medição")
5apply_takes.py <work>as tomadas decididas na etapa 3 são escritas em takes.json (índices de palavras; limites definidos manualmente ou cortes em segundos são opcionais). O script coloca limites em vales de energia, mescla com os silêncios, funde os fragmentos mudos deixados entre dois cortes, realinha cada borda de clipe ao som real e sinaliza um som isolado de menos de 0,25 s em uma borda de clipe, escrevendo cuts_final.json. protect (manter um silêncio) apenas se o usuário pedir
6build_premiere_xml.pyXMEML. Opção meta["audio_file"]: apontar o áudio para um WAV processado de duração total (veja Limitações conhecidas). Vários clipes: um XML por clipe, depois merge_xml.py output.xml "nome" a.xml b.xml = uma única sequência, de ponta a ponta
6ba edição, transcrita novamenteverificação ponta a ponta: concatene os intervalos mantidos de audio.wav, execute o whisper nela e LEIA o texto com os pontos de corte. Pega o que as outras verificações perdem: silêncios deixados na edição (um clipe de 8 s para 3 palavras), palavras cortadas, uma retomada fracassada sobrevivente
7qc_repeat_scan.pyverificação determinística: código de saída 2 se um 5-grama repetido dentro de 30 s sobreviver na edição, ou se duas palavras que seguem uma pausa ou um corte já foram ditas há menos de 8 s de edição antes (uma tomada repetida com variação). Cada ocorrência é verificada contra o roteiro e de ouvido (hear.py): retomada sobrevivente (manter a ÚLTIMA) OU retórica deliberada (anáfora, enumerações)
7bmontage_qc.py <work>o áudio da edição é transcrito e lido clipe por clipe, palavras do Premiere (P) contra whisper (W): código de saída 2 em um branco > 1,6 s ou um fragmento < 1 s. Uma borda duvidosa é verificada com hear.py audio.wav 12.3-14.0 ... (whisper em fatias isoladas)
8report_v2.pyrelatório: duração da EDIÇÃO e do clipe, tomadas, dúvidas; --notes para "mantido de propósito" e passagens que tocam pontos sensíveis do roteiro

Etapa 3, as regras de decisão

Regras rígidas:

  • texto repetido: manter a ÚLTIMA tomada (mesmo quando estiver menos limpa que uma anterior);
  • tropeço: manter o maior pedaço contínuo;
  • dúvida: flag, nunca disable. Sub-cortar é sempre melhor que super-cortar: adicionar um corte é fácil, recuperar uma passagem perdida é um inferno.
  • Os limites do corte se fixam nas palavras do Premiere, com cerca de 0,15 s de ar antes da primeira palavra mantida.

Regras aprendidas de edições reais:

  • Qualquer ilha com menos de 2 s espremida entre dois cortes de tomada deve ser ouvida (hear.py). Quase sempre é um falso começo. Nunca julgue pelo texto do Premiere: uma respiração pode carregar palavras no Premiere, e uma alucinação do whisper do tipo "Thanks for watching" significa que não há palavras nenhumas.
  • Um silêncio com ruído que não é uma frase do roteiro (um aparte, um "aqui vamos nós", manuseio da câmera) é cortado, não sinalizado.
  • Um preenchimento de abertura no início de uma frase (a lista "openers" do arquivo de idioma, por exemplo "Então," ou "Bem,") é cortado.
  • Gagueira literal dentro de uma frase ("É é") é desabilitada. Mas um nome repetido em ambos os lados de um ponto final ("menos documentado que a Nikon. A Nikon tem muitos documentos") não é gagueira: o Premiere pode tê-lo escrito como duplicado. Ouça a fatia (hear.py) antes de qualquer corte de palavra única.
  • Conector órfão (um "E / Então / Mas" isolado) imediatamente antes de um silêncio de corte é incluído no corte. O mesmo vale para qualquer palavra de falso começo solitária espremida entre um corte e uma pausa seguida por outro ataque.
  • Uma palavra sem sentido na transcrição do Premiere sem equivalente no whisper dentro de um aparte redundante é um tropeço: pelo menos sinalize.
  • Frase de preenchimento sem informação que repete a próxima frase: sinalizar apenas (é editorial).
  • Uma "retomada" pode ser o fim da frase anterior, mal datada pelo Premiere (uma palavra com 5 s de duração). O texto do whisper da edição mostra isso.
  • O Premiere às vezes divide uma frase em duas: um "falso começo" de duas palavras pode ser o início da próxima frase.
  • O Premiere perde pequenas palavras murmurradas: cortar uma frase repetida pode deixar um lead-in órfão. Ouça a fatia (hear.py) primeiro; defina o limite manualmente (6º elemento de uma entrada em takes.json).
  • Uma única palavra duplicada ("o o"): o limite pode engolir a palavra anterior, porque o Premiere data ambas na mesma respiração. Ouça a junção (ffmpeg atrim dos dois pedaços mantidos, depois hear.py).
  • Uma emenda entre dois clipes: o final do clipe 1 e o início do clipe 2 são ouvidos juntos. Uma frase iniciada no final do clipe 1 e repetida no início do clipe 2 é cortada a partir da sua primeira palavra.
  • Instruções faladas para a câmera para o editor ("isto é para você, coloque alguns gráficos aqui") são cortadas como instruções e listadas no relatório, porque dizem onde ilustrar.
  • Após cortar uma tomada, ouça o ataque da tomada mantida (uma primeira palavra pode ser engolida quando o Premiere tem duas delas).

A transcrição do Premiere está dentro do .prproj

O .prproj é um XML gzipado contendo um bloco <ExternallyProvidedTranscriptDocument><TranscriptData Encoding="base64">, cujo payload é um buffer FlatBuffers. extract_prproj_transcript.py o decodifica:

Segment -> f0 i64 start_ticks, f3 vector<Word>, f4 string language
Word    -> f0 i64 start_ticks, f1 i64 duration_ticks, f2 string text, f3 f32 confidence
Premiere ticks = 254016000000 por segundo

Itens com texto vazio são as PAUSAS marcadas pelo Premiere (sua duração cobre todo o silêncio). O script as descarta; caso contrário, cada lacuna entre palavras é 0 e silence_cuts.py não encontra nada (sintoma: "lacunas > 1s: 0" e palavras com 39 s de duração).

Vários clipes em um projeto: o .prproj contém uma transcrição POR clipe. --rush NAME.MOV escolhe aquela que se encaixa na duração do clipe (sem ele, a mais longa, com um aviso). Compara o início da última palavra, com uma margem de desvio de 0,3% da duração. Verifique se a contagem de palavras difere de um clipe para o outro. Uma pasta de trabalho por clipe, depois merge_xml.py.

Duas armadilhas nesta transcrição:

  1. Ela pode se desviar em relação ao arquivo: etapa 2b. Os cortes estão no TEMPO do arquivo (é o que o XML lê), então as palavras são corrigidas, nunca o contrário.
  2. As durações das palavras podem engolir o silêncio que as segue: o silêncio não existe mais entre as palavras e não é mais cortado. silence_cuts.py traz essas palavras de volta ao seu fim real (trim_overflow). Nunca confie no fim de uma palavra do Premiere; apenas os inícios são confiáveis.

Mais armadilhas (palavras datadas dentro de um silêncio, fragmentos mudos, ilhas minúsculas): references/lessons.md.

Limites de corte de tomada: no vale de energia mais próximo do início da palavra, com 0,12 s de ar antes do ataque da palavra mantida. Descreva os cortes por índices de palavras, não segundos: eles sobrevivem a um realinhamento.

O pipeline v1 (abaixo) permanece como alternativa quando não há transcrição do Premiere (aviso de que retomadas palavra por palavra provavelmente serão perdidas).

Requisitos da máquina

Verificados na inicialização; se algo estiver faltando, aponte para INSTALL.md (references/whisper-setup.md apenas para whisper).

brew install whisper-cpp ffmpeg
mkdir -p ~/Models/whisper
curl -L -o ~/Models/whisper/ggml-large-v3-turbo.bin \
  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin

Python 3 com numpy (nada mais). Nenhuma chave de API, nenhuma conta, nada sai da máquina após o download do modelo.

Pipeline v1 (alternativa, 8 estágios)

Executado por scripts/derush.py. Cada estágio escreve em <clip>_Derush_vN_work/, ao lado do clipe, nunca deletado (retomada e inspeção permanecem possíveis).

#ScriptFunção
1derush.py (ponto de entrada)metadados ffprobe, número de versão
2extract_audio.pyffmpeg para audio.wav 16 kHz mono
3transcribe.pywhisper.cpp para transcript.json
4mechanical_cuts.pylistas de palavras e padrões do arquivo de idioma para cuts_mechanical.json
5análise semântica (Claude)para cuts_semantic.json (veja abaixo)
6merge_cuts.pymesclar, ajustar às palavras, pontuações para cuts_final.json
7build_premiere_xml.pypara .xml (XMEML / FCP7)
8build_report.pypara .report.md

Estágio 5: análise semântica

O script escreve prompt_semantic.txt e para. Essa é a rota normal: Claude, executando o skill, então faz o seguinte.

  1. ler prompt_semantic.txt na íntegra;
  2. analisar a transcrição seguindo as regras no prompt;
  3. escrever o JSON em cuts_semantic.json (caminho fornecido no prompt);
  4. retomar: derush.py <clip> --resume-from=6 --work-dir=<work>.

Se cuts_semantic.json já existir, o estágio é pulado.

Decisões de três níveis (a filosofia do skill)

Cada corte proposto tem uma confiança entre 0 e 1.

  • disable: a passagem é removida da timeline, não desativada. build_spine_clips() constrói a sequência por subtração: apenas os intervalos mantidos permanecem, de ponta a ponta, e a duração da sequência é a soma dos intervalos mantidos. O equivalente a um "ripple delete" já aplicado. Limiares: >= 0,85 para um corte mecânico, >= 0,92 para um corte semântico (um LLM frequentemente ultrapassa seus limites).
  • flag (0,6 a 0,85): nenhum corte. A passagem permanece como um clipe ativo, com um marcador de sequência vermelho ("DÚVIDA (conf X): motivo") no lugar certo. O usuário decide.
  • ignore (< 0,6): nada, para evitar sobrecarregar a timeline.

Nunca inverta essas semânticas. Entregar clipes desativados e esmaecidos para deletar manualmente transfere o trabalho para o usuário em vez de removê-lo: a promessa é uma sequência diretamente utilizável.

Tipos de corte

  • filler: palavras de preenchimento ("hum", "uh"...) e início de frase...

Individual skills in this repo

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

Habilidades Relacionadas