Communitygithub.com

corte-de-video

Transforma vídeos longos e não editados em um primeiro corte compacto e assistível, com decisões editoriais humanas e precisão mecanizada.

O que é corte-de-video?

Esta skill permite que um agente de IA produza um primeiro corte (rough cut) de um vídeo longo e não editado, a partir de um arquivo local ou URL do YouTube. O modelo humano decide o que manter (decisões editoriais), enquanto scripts automatizados cuidam do alinhamento preciso de bordas, remoção de silêncios, renderização com segurança de memória e auto-verificação. Suporta transcrição com faster-whisper (CPU), análise de pausas, preenchimentos e velocidade de fala, e aplica velocidade variável automática para normalizar o ritmo da fala sem alterar o conteúdo. O resultado é um vídeo renderizado e um relatório de verificação, com todos os passos rastreáveis em arquivos de projeto. É ideal para cenários onde se deseja reduzir pela metade a duração de um vídeo bruto, mantendo o conteúdo relevante e garantindo cortes limpos e síncronos.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/WhiteTowerAI/cut-as-code/tree/main/skills/video-cut

Perguntar na sua IA favorita

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

Documentação

Corte de Vídeo

Transforme um vídeo longo não editado em um primeiro corte compacto e assistível — decisivo, consciente do conteúdo e autoverificado. O humano (você, o modelo) toma a decisão editorial do QUE manter; os scripts incluídos cuidam da precisão mecânica (alinhamento de bordas, remoção de silêncio, renderização segura de memória, autoverificação).

Quando usar

  • Um vídeo bruto/não editado (URL do YouTube ou arquivo local) precisa se tornar um corte mais enxuto.
  • O pedido é "reduzir pela metade", "cortar as partes chatas", "fazer um primeiro corte/rough cut".
  • NÃO serve para: microcirurgia de vícios de linguagem palavra por palavra, montagem de múltiplas câmeras (B-roll), ajuste de cor/áudio — esses são passos posteriores de polimento (P1/P2). Esta skill é P0: validar o diagnóstico + produzir um corte sólido.

Dependências

/video-understand é um pré-requisito. Execute-o primeiro e use sua mídia, transcrição, análise e linha do tempo validados, em vez de recriá-los nesta skill. Antes de começar, verifique se está instalado. Se não estiver, avise o usuário que este pré-requisito está faltando e pare antes de processar a mídia.

Ative qualquer ambiente que tenha estes itens (NÃO assuma um nome de conda env específico):

  • yt-dlp (download), ffmpeg/ffprobe (corte/renderização/inspeção) no PATH
  • Python com faster-whisper (CPU funciona: device=cpu, compute_type=int8) Verifique primeiro: yt-dlp --version, ffmpeg -version, python -c "import faster_whisper".

Fluxo de trabalho do protocolo de projeto

Use estes arquivos de projeto duráveis:

work/cut/edit-plan.json          # decisões de manter/descartar escritas à mão
work/timeline.json               # intervalos de precisão gerados + mapeamento fonte/programa
review/01-cut/cut-summary.md
review/01-cut/timeline-map.png
review/01-cut/boundary-review.mp4
review/01-cut/full-proxy.mp4  # opcional: revisão de ritmo do programa completo

Cada decisão canônica tem um id estável, action (keep ou drop), start_s, end_s, reason e evidence_refs semânticos/de transcrição. Mantenha as decisões de keep em ordem cronológica; a V1 não suporta clipes de origem reordenados ou duplicados.

Reutilize a camada de evidência compartilhada em vez de transcrever ou diagnosticar novamente:

python skills/video-understand/scripts/transcribe.py work/cache/audio16k.wav work/understand/transcript
python skills/video-understand/scripts/analyze.py work/understand/transcript.json work/understand/analysis.json

Os scripts de precisão existentes aceitam o plano canônico. Expanda os limites seguros para palavras, atribua opcionalmente velocidade variável linear e, em seguida, gere a linha do tempo compartilhada:

python skills/video-cut/scripts/build_edit.py work/cut/edit-plan.json work/understand/transcript.json work/cache/edit-final.json
python skills/video-cut/scripts/assign_speed.py work/cache/edit-final.json work/understand/transcript.json
python skills/video-understand/scripts/build_timeline.py work/cache/edit-final.json work/timeline.json --fps-num SOURCE_FPS_NUM --fps-den SOURCE_FPS_DEN

Use o FPS racional exato de work/understand/media.json; nunca arredonde 30000/1001 para 30/1. Revise timeline-map.png e o curto boundary-review.mp4. Gere full-proxy.mp4 apenas quando o ritmo do programa completo precisar ser revisado. Escreva o resultado em cut-summary.md e aponte o relatório de verificação da operação para esse arquivo.

Registre a contribuição da linha do tempo com sua entrada de origem necessária, atualize o inteiro da operação revision e defina based_on para a revisão exata de entendimento consumida:

"render": {
  "kind": "timeline-transform",
  "input": "../input/original-video.mp4",
  "plan": "timeline.json"
}

O renderizador de entrega compartilhado codifica a sequência ativa após todas as verificações de revisão passarem.

Fluxo de trabalho de compatibilidade independente

Os arquivos e comandos legados abaixo permanecem suportados durante a migração. build_edit.py aceita tanto edit_coarse.json quanto decisions[] canônicos; cut_render.py aceita tanto edit_final.json quanto timeline.json; o transcribe.py desta skill é um wrapper de compatibilidade em torno de ../video-understand/scripts/transcribe.py.

Mantenha todos os intermediários em work/, entregue na raiz do projeto:

work/source.mp4            # original baixado
work/audio16k.wav          # áudio mono 16k para whisper
work/transcript.json/.srt  # timestamps no nível da palavra
work/analysis.json         # diagnóstico (silêncios/pausas preenchidas/sequências longas)
work/edit_coarse.json      # *** SUA decisão editorial (escrita à mão) ***
work/edit_final.json       # segmentos de renderização expandidos e precisos (gerados; carrega velocidade por segmento)
work/selfcheck/            # re-transcrição do corte + quadros de junção
first_cut.mp4              # O ENTREGÁVEL
first_cut_report.md        # relatório de edição + autoverificação

O pipeline (6 passos)

1. Download

Maior qualidade acessível + áudio. O player cliente padrão frequentemente falha (não disponível / DRM / login necessário). A alternativa confiável é o cliente android:

yt-dlp --extractor-args "youtube:player_client=android" \
       -o work/source.mp4 "<URL>"

Se apenas um 360p muxado (formato 18) estiver acessível sem login, aceite-o e documente a restrição — HD DASH é frequentemente bloqueado por DRM/login. Em seguida, extraia o áudio:

ffmpeg -y -i work/source.mp4 -ac 1 -ar 16000 work/audio16k.wav

2. Transcrição (nível da palavra)

python scripts/transcribe.py work/audio16k.wav work/transcript [base.en]

Produz work/transcript.json (segmentos + início/fim por palavra) e .srt. faster-whisper, CPU/int8, VAD ativado, word_timestamps=True. Não inglês: passe um modelo multilíngue + --lang, por exemplo, python scripts/transcribe.py work/audio16k.wav work/transcript medium --lang zh (os modelos .en são apenas para inglês). Verifique o idioma em uma amostra curta primeiro. Nota: Whisper remove a maioria dos "hum/ah" vocalizados — eles NÃO são mensuráveis na transcrição, portanto a detecção de pausas preenchidas deve combinar a pesquisa lexical de palavras abaixo com a análise de lacunas de silêncio, não confiar apenas no texto da transcrição.

3. Diagnosticar ("ver" + "ler")

python scripts/analyze.py work/transcript.json work/analysis.json

Levanta: silêncio inicial/final, silêncios entre palavras ≥0,8s (com a palavra que seguem), contagem de pausas preenchidas, palavras por minuto, taxa de fala, repetições quase duplicadas, monólogos >40s (candidatos a divagação).

Para ver a imagem, amostre um quadro a cada ~2s em uma folha de contato e leia você mesmo; confirme a estrutura da cena / procure quadros pretos ou defeituosos:

ffmpeg -y -i work/source.mp4 -vf "fps=1/2,scale=240:-1,tile=10x10" -frames:v 1 work/contact.png
ffmpeg -i work/source.mp4 -vf "blackdetect=d=0.1:pic_th=0.98" -an -f null -

Para um único take de um entrevistado estático, não há cortes de cena — espere isso e observe que os cortes abruptos posteriores são normais, não falhas.

4. Decidir o corte — escreva edit_coarse.json À MÃO

Este é o núcleo editorial. Leia a transcrição + análise, depois escreva um plano bruto de blocos manter e intervalos descartar que cubram toda a linha do tempo sem lacunas/sobreposições, cada um com in, out e um reason de uma linha. Comprima o preâmbulo lento em algumas pepitas de alto valor; mantenha o conteúdo substancial como blocos grandes; descarte tangentes/divagações claras. Preserve a ordem cronológica; a linha do tempo canônica V1 rejeita reordenações. Mire em aproximadamente metade do tempo de execução.

  • Especificação do formato + um exemplo real trabalhado: reference/edit_coarse.schema.md.
  • Alinhe cada limite de bloco a um final de frase/cláusula — nunca inicie/para no meio de uma frase ou em uma gagueira. Use:
    python scripts/inspect_bounds.py work/edit_coarse.json work/transcript.json
    
    Aceita tanto planos keep[] legados quanto decisions[] canônicos e imprime as palavras que cruzam cada limite para que você possa ajustá-los para bordas limpas.

5. Expandir → velocidade automática → renderizar

Transforme blocos brutos em segmentos de renderização justos e sem silêncio morto, normalize o ritmo da fala e renderize:

python scripts/build_edit.py   work/edit_coarse.json work/transcript.json work/edit_final.json 1.5
python scripts/assign_speed.py work/edit_final.json   work/transcript.json   # adiciona velocidade por segmento
python scripts/cut_render.py    work/edit_final.json   work/source.mp4 first_cut.mp4
  • build_edit.py divide cada bloco em pausas internas > SPLIT_GAP (4º argumento, ex. 1,5s) e corta cada limite DENTRO do silêncio (LEAD 0,10s / TRAIL 0,30s) para que nenhuma palavra seja cortada e o silêncio morto seja recuperado. SPLIT_GAP menor = mais apertado, mas mais entrecortado; para um locutor lento e deliberado, prefira ~1,5, não 0,6 (evita microcortes bruscos).
  • assign_speed.py (velocidade variável automática) — agrupa segmentos de renderização por decision_ref, mede o ritmo de fala de cada decisão de manutenção escrita à mão e escreve um fator speed compartilhado mais o out_dur resultante de cada segmento de volta em edit_final.json. O ritmo já dentro da faixa confortável permanece em 1,0; o ritmo fora da faixa move-se apenas para a borda mais próxima da faixa morta. Blocos de decisão adjacentes diferem em no máximo 0,08x para evitar junções "instáveis". Altera apenas o ritmo — nunca qual conteúdo é mantido. Leia a tabela impressa antes de renderizar:
    • Métrica: palavras/min (inglês) — muda automaticamente para caracteres/min para CJK (zh/ja/ko).
    • Os padrões são pontos de partida da primeira execução, não constantes validadas: faixa morta 145–185 WPM e velocidade limitada a 1.0–1.3. Isso é apenas aumento de velocidade: blocos de decisão lentos podem ser apertados, enquanto a entrega naturalmente rápida permanece em 1.0. Blocos de decisão curtos (<3,5s / <6 palavras) são muito ruidosos para medir e herdam o fator global.
    • A taxa é medida após a recuperação do silêncio morto, portanto lê mais alto que o WPM bruto e está mais próxima da taxa de articulação. A revisão da tabela impressa é crucial: examine-a e ajuste deadband para o locutor antes de renderizar, não confie cegamente nos padrões.
    • Controles (k=v): mode=segment|global|off (padrão segment; global=um fator para o vídeo inteiro, off=desabilitado), deadband=lo,hi, min_speed=/max_speed=, min_seg=/min_words=, lang=auto|en|cjk. Para pular o recurso completamente, simplesmente não execute esta etapa — cut_render.py trata uma speed ausente como 1.0.
  • cut_render.py usa N entradas separadas com busca + filtro concat, única re-codificação. Isso é obrigatório: cortar N vezes de UMA entrada decodificada faz o ffmpeg armazenar em buffer todo o fluxo decodificado (dezenas de GB para um vídeo longo). Veja reference/pitfalls.md. Quando os segmentos carregam uma speed, ele re-temporiza cada entrada (setpts vídeo / atempo áudio) e normaliza fps/timebase/taxa de amostragem por entrada antes do concat para que A/V permaneça sincronizado; sem velocidade, ele recai no gráfico original exato.
  • Comparação final: video-edit-compare lê a linha do tempo canônica mais a entrega final real. Ele projeta os pixels finais de volta ao tempo de origem, estica clipes com velocidade variável para sua duração de origem e mostra intervalos descartados como preto.

6. Autoverificação — não declare concluído até que isso passe

# verificação de regressão de precisão do protocolo (execute a partir da raiz do repositório)
python skills/video-cut/scripts/check_project_protocol.py
# re-transcreva o corte final
ffmpeg -y -i first_cut.mp4 -ac 1 -ar 16000 work/selfcheck/cut_audio16k.wav
python scripts/transcribe.py work/selfcheck/cut_audio16k.wav work/selfcheck/cut_transcript
# verificação de conteúdo + pausas preenchidas + limites
python scripts/verify_cut.py work/edit_final.json work/transcript.json work/selfcheck/cut_transcript.json
# verificação de quadros / preto / junção (os tempos de junção usam out_dur pós-velocidade, portanto permanecem precisos)
python scripts/selfcheck_frames.py work/edit_final.json first_cut.mp4 work/selfcheck
# sincronia A/V + sem silêncio morto residual
ffprobe -v error -select_streams v:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffprobe -v error -select_streams a:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffmpeg -i first_cut.mp4 -af silencedetect=noise=-32dB:d=1.5 -f null -

Limites de aprovação:

VerificaçãoCondição de aprovação
Quadros pretosnenhum
Quadros de junçãolimpos — apenas saltos naturais de cabeça, sem preto/congelado/rasgado
Sincronia A/Vduração do vídeo vs áudio dentro de ~1 quadro (≈30ms); total ≈ final_duration_s_after_speed quando a velocidade variável está ativa
Silêncio morto ≥1,5s0 (a taxa de fala deve aumentar marcadamente)
Segmento descartado/duplicadonenhum — todo o conteúdo principal presente (difflib ~0.90 é OK; índice
menor geralmente é ruído de transcrição de segunda passagem em fala murmurante, não perda — verifique
pela presença de palavras-chave antes de culpar o corte)
Meias-frases cortadasnenhuma — limites caem em silêncio / no final de frases

Ressalva honesta sobre pausas preenchidas: o corte no nível do parágrafo NÃO alcançará "quase nenhuma pausa preenchida". A densidade por minuto pode até aumentar porque o conteúdo mantido é coloquial. Relate isso honestamente; a remoção de pausas preenchidas no nível da palavra pertence ao P1/P2 (e tornaria um único take de um entrevistado visivelmente entrecortado).

Finalmente

Escreva first_cut_report.md: resumo da fonte, o que foi cortado e por quê, a tabela de autoverificação, e quaisquer ressalvas honestas (limite de qualidade devido à fonte 360p, densidade de pausas preenchidas, etc.). Se a velocidade variável foi aplicada, divulgue-a: quantos segmentos foram re-temporizados e a faixa de velocidade (da tabela de assign_speed.py / speed_params), para que o leitor saiba que o corte não é 1:1 em tempo real. Observe também que o valor de pausas preenchidas por minuto do verify_cut.py lê ligeiramente mais alto após o aumento de velocidade (mesmas palavras, minutos mais curtos) — um artefato de relatório, não pausas preenchidas adicionadas.

Princípios-chave (os conquistados com esforço)

  • Você decide o conteúdo; os scripts decidem os quadros. Escreva edit_coarse.json à mão; deixe build_edit.py fazer a precisão e assign_speed.py fazer o ritmo.
  • A velocidade toca o ritmo, nunca o conteúdo. A velocidade variável automática dá a todos os segmentos de renderização de um decision_ref a mesma velocidade, move o ritmo fora da faixa apenas para a borda mais próxima da faixa morta, limita decisões adjacentes a um delta de 0,08x e limita a saída a 1.0–1.3. atempo preserva o tom. Revise a tabela; mode=off ou pule a etapa para desabilitar.
  • Nunca corte uma palavra. Os limites sempre caem dentro do silêncio.
  • Renderização segura de memória apenas (N entradas com busca + concat). Nunca faça múltiplos cortes em uma entrada.
  • Seja decisivo. Faça chamadas razoáveis e prossiga; não pergunte demais.
  • A autoverificação é inegociável. Re-transcreva + verifique quadros antes de declarar concluído.
  • Veja reference/pitfalls.md para a lista completa de armadilhas e correções.

Individual skills in this repo

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

Habilidades Relacionadas