Communitygithub.com

ThomasHMD/rough-cut

Corte automático de material de cabezas parlantes (monólogos, videos hablados) para Premiere Pro. Produce un XML de Final Cut Pro 7 (XMEML) cuya línea de tiempo ya tiene eliminados las repeticiones, falsos inicios, tropiezos, palabras de relleno y largos silencios. El clip original nunca se modifica.

¿Qué es rough-cut?

El skill rough-cut está diseñado para editores de video que trabajan con monólogos, videos hablados o cualquier grabación donde una persona habla directamente a la cámara. Su función principal es tomar un clip importado en Premiere Pro, analizar su transcripción (generada por Premiere) y opcionalmente un guion de referencia, para luego generar un archivo XML de Final Cut Pro 7 que, al importarse de vuelta en Premiere, muestra una secuencia ya editada, eliminando automáticamente repeticiones, falsos inicios, tropiezos, palabras de relleno y largos silencios. El skill nunca modifica el clip original, solo crea archivos auxiliares y el XML de edición. Utiliza un pipeline en dos versiones: la versión 2, que es la ruta normal y principal, extrae la transcripción directamente del archivo .prproj de Premiere, la realinea con el audio mediante whisper.cpp, y aplica reglas semánticas duras y aprendidas de ediciones reales para decidir cortes y dudas, con una verificación final mediante QC. La versión 1 es un plan de respaldo para cuando no hay transcripción de Premiere, usando solo whisper. El skill está disponible para Claude Code y requiere tener instalados whisper-cpp y ffmpeg. Una característica clave es su soporte multilingüe para palabras de relleno y patrones de falso inicio, actualmente con inglés y francés incorporados, y la capacidad de añadir nuevos idiomas mediante archivos JSON. El skill también maneja varias pistas: detecta instrucciones del presentador al editor, corta conectores huérfanos, y maneja repeticiones deliberadas (anáforas, enumeraciones) apoyándose en el guion. Su filosofía es sub-cortar en lugar de sobre-cortar, marcando las decisiones dudosas para que el editor decida, y nunca entregando clips desactivados o atenuados, sino una secuencia directamente utilizable.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

rough-cut: corte automático para Premiere Pro

Configuración única: ver INSTALL.md en la raíz del kit. Con el plugin, la línea de configuración es bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}"; con una instalación manual (las cuatro carpetas skills/ copiadas una al lado de la otra en ~/.claude/skills/), ejecute bash install.sh desde la raíz del kit. Los scripts residen en la carpeta scripts/ de este skill.

Alcance

  • SÍ: un XML de Final Cut Pro 7 (XMEML, .xml) cuya línea de tiempo ya tiene eliminados las repeticiones, falsos inicios, tropiezos, palabras de relleno y largos silencios; un informe en markdown; marcadores rojos en lo que queda por decidir.
  • NO: modificar el clip, transcodificar, exportar el video, etalonar, mezclar, elegir entre dos tomas más allá de reformulaciones obvias (eso es decisión del editor).

Regla central: el clip original NUNCA se modifica

El skill solo escribe junto al clip:

  • <clip>_Derush_v1.xml: la edición a importar (FCP7 / XMEML);
  • <clip>_Derush_v1.report.md, <clip>_Derush_v1.log.txt;
  • <clip>_Derush_v1_work/: la carpeta de trabajo, que se conserva (transcripciones, cortes intermedios).

El XML apunta al clip por ruta absoluta (file://localhost/...): Premiere solo lo referencia. Una nueva pasada crea v2, v3... sin sobrescribir nada.

Lo que hace el usuario (3 pasos)

  1. En Premiere: importar el clip, ejecutar la transcripción (Panel de texto > Transcribir), guardar el proyecto. La transcripción queda DENTRO del .prproj: nunca pedir al usuario que la exporte.
  2. Dar a Claude la ruta del clip y el guion de referencia del video si lo hay (texto plano, Markdown, un Google Doc, una página de Notion, cualquier cosa legible). El guion solo sirve para saber si una repetición es deliberada. Sin guion, la pasada sigue funcionando; las repeticiones deliberadas se convierten en banderas en lugar de cortes.
  3. Importar el .xml (Archivo > Importar). Aparece una secuencia Derush_vN, ya editada: los cortes están ausentes de la línea de tiempo (los clips van uno tras otro, no hay nada que cerrar), y las dudas permanecen como clips activos con un marcador rojo.

No preguntar nada más: el idioma, el tipo de clip y las opciones se deducen (ver más abajo), y solo vale la pena hacer una pregunta cuando el tipo de clip es realmente ambiguo.

Idioma

Todo lo específico del idioma (palabras de relleno, frases de falso inicio, patrones de pizarra, conectores huérfanos, aperturas a cortar, alucinaciones de whisper, los textos de razón de los marcadores) vive en languages/<code>.json, nunca en el código. El francés (fr) y el inglés (en) están integrados. El idioma se elige mediante --lang <código>, o el idioma registrado en la transcripción, o en. Detalles y cómo añadir un idioma: references/languages.md.

Pipeline v2: selección de tomas (la ruta normal)

Detectar defectos por sí solo (v1, más abajo) alcanza como máximo un 57% de recall porque whisper silenciosamente deduplica tomas repetidas: su decodificador anti-bucle trata una oración repetida palabra por palabra como una alucinación y la transcribe una sola vez. Esto no se puede arreglar con configuración. La transcripción de Premiere conserva cada toma, palabra por palabra, y sus inicios de palabra no se desplazan después de largos silencios (los de whisper sí). Por lo tanto:

PasoHerramientaFunción
1extract_prproj_transcript.py project.prproj words_premiere.json [--rush CLIP.MOV].prproj a words_premiere.json (fuente PRIMARIA). Código de salida 2 si el proyecto no tiene transcripción: pedir al usuario que la ejecute y guarde el proyecto. Alternativa: parse_premiere_transcript.py en una exportación JSON manual
2extract_audio.py + transcribe.pywhisper = SEGUNDA OPINIÓN (verificar el texto, nunca los límites)
2bcalibrate_premiere_times.pyrealinea la transcripción de Premiere con el audio. Ejecutarlo en CADA corte bruto, justo después de la extracción de audio (no hace nada cuando la transcripción está a tiempo). Mide el desplazamiento por correlación cruzada, ventana por ventana; se ha visto un desfase de 1,8 s al final de un clip de 21 min. Síntoma si se olvida: silence_cuts.py reporta docenas de "ruido sospechoso"
3Claude en contextoanálisis semántico: detectar repeticiones, falsos inicios y tropiezos comparando la transcripción de Premiere con el guion y con whisper. Reglas más abajo
4silence_cuts.pysilencios >= 1,0 s entre palabras de Premiere, finales de palabra realineados al nivel de sonido, guardia de enumeración (pausas cortas entre dos bloques cortos = ritmo deliberado), zona ruidosa: bandera o corte (ver más abajo). Los valores por defecto están calibrados contra ediciones terminadas: no cambiarlos sin volver a medir (ver references/lessons.md, "Measuring")
5apply_takes.py <work>las tomas decididas en el paso 3 se escriben en takes.json (índices de palabra; los límites o cortes establecidos a mano en segundos son opcionales). El script pone los límites en valles de energía, los fusiona con los silencios, funde los fragmentos mudos que quedan entre dos cortes, realinea cada borde de clip al sonido real, y marca un sonido aislado de menos de 0,25 s en un borde de clip, escribiendo cuts_final.json. protect (mantener un silencio) solo si el usuario lo pide
6build_premiere_xml.pyXMEML. Opción meta["audio_file"]: apuntar el audio a un WAV procesado de longitud completa (ver Límites conocidos). Varios clips: un XML por clip, luego merge_xml.py output.xml "name" a.xml b.xml = una sola secuencia, de principio a fin
6bla edición, transcrita de nuevoverificación de extremo a extremo: concatenar los intervalos conservados de audio.wav, ejecutar whisper en él, y LEER el texto con los puntos de corte. Detecta lo que otras comprobaciones pasan por alto: silencios dejados en la edición (un clip de 8 s para 3 palabras), palabras recortadas, una toma fallida superviviente
7qc_repeat_scan.pycomprobación determinista: código de salida 2 si sobrevive en la edición un 5-grama repetido en 30 s, o si dos palabras que siguen a una pausa o un corte ya se dijeron menos de 8 s de edición antes (una toma repetida con una variante). Cada acierto se verifica contra el guion y de oído (hear.py): retoma superviviente (conservar la ÚLTIMA) O retórica deliberada (anáfora, enumeraciones)
7bmontage_qc.py <work>el audio de la edición se transcribe y se lee clip por clip, palabras de Premiere (P) contra whisper (W): código de salida 2 en un espacio en blanco > 1,6 s o un fragmento < 1 s. Un borde dudoso se verifica con hear.py audio.wav 12.3-14.0 ... (whisper en porciones aisladas)
8report_v2.pyinforme: duración de la EDICIÓN y del clip, tomas, dudas; --notes para "conservado a propósito" y pasajes que tocan los puntos sensibles del guion

Paso 3, las reglas de decisión

Reglas duras:

  • texto repetido: conservar la ÚLTIMA toma (incluso si es menos limpia que una anterior);
  • tropiezo: conservar la pieza consecutiva más larga;
  • duda: flag, nunca disable. Infra-cortar siempre es mejor que sobre-cortar: añadir un corte es fácil, recuperar un pasaje perdido es un infierno.
  • los límites del corte se ajustan a las palabras de Premiere, con aproximadamente 0,15 s de aire antes de la primera palabra conservada.

Reglas aprendidas de ediciones reales:

  • Cualquier isla de menos de 2 s apretada entre dos cortes de toma se escucha (hear.py). Casi siempre es un falso inicio. Nunca juzgarla por el texto de Premiere: un suspiro puede transportar palabras en Premiere, y una alucinación de whisper del tipo "Gracias por ver" significa que no hay palabras en absoluto.
  • Un silencio con ruido que no es una oración del guion (un comentario al margen, un "aquí vamos", manejar la cámara) se corta, no se marca.
  • Un abridor de relleno al inicio de una oración (la lista de "openers" del archivo de idioma, por ejemplo "So," o "Bueno,") se corta.
  • El tartamudeo textual dentro de una oración ("Es es") se deshabilita. Pero un nombre repetido a ambos lados de un punto ("menos documentado que Nikon. Nikon tiene muchos documentos") no es un tartamudeo: Premiere puede haberlo escrito como un doble. Escuchar la porción antes de cualquier corte de una sola palabra.
  • Conector huérfano (un "Y / Entonces / Pero" aislado) justo antes de un silencio de corte se incluye en el corte. Lo mismo va para cualquier palabra de falso inicio solitaria apretada entre un corte y una pausa seguida de otro ataque.
  • Una palabra sin sentido en la transcripción de Premiere sin equivalente en whisper dentro de un comentario redundante es un tropiezo: al menos marcarlo.
  • Frase de relleno que no aporta información y repite la siguiente oración: marcar solo (es editorial).
  • Una "retoma" puede ser el final de la oración anterior, mal fechado por Premiere (una palabra de 5 s de duración). El texto de whisper de la edición lo muestra.
  • Premiere a veces divide una oración en dos: un "falso inicio" de dos palabras puede ser el inicio de la siguiente oración.
  • Premiere omite pequeñas palabras murmuradas: cortar una oración repetida puede dejar un inicio huérfano. Escuchar la porción primero; establecer el límite a mano (6º elemento de una entrada en takes.json).
  • Una sola palabra duplicada ("el el"): el límite puede comerse la palabra anterior, porque Premiere fecha ambas en el mismo aliento. Escuchar la unión (ffmpeg atrim de las dos piezas conservadas, luego hear.py).
  • Una costura entre dos clips: el final del clip 1 y el inicio del clip 2 se escuchan juntos. Una oración comenzada al final del clip 1 y repetida al inicio del clip 2 se corta desde su primera palabra.
  • Instrucciones habladas a la cámara para el editor ("esto es para ti, pon algunos gráficos aquí") se cortan como instrucciones y se listan en el informe, porque dicen dónde ilustrar.
  • Después de cortar una toma, escuchar el ataque de la toma conservada (una primera palabra puede perderse cuando Premiere tiene dos de ellas).

La transcripción de Premiere está dentro del .prproj

El .prproj es XML comprimido con gzip que contiene un bloque <ExternallyProvidedTranscriptDocument><TranscriptData Encoding="base64">, cuya carga útil es un búfer FlatBuffers. extract_prproj_transcript.py lo 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

Los elementos con texto vacío son las PAUSAS marcadas por Premiere (su duración cubre todo el silencio). El script los elimina; de lo contrario, cada espacio entre palabras es 0 y silence_cuts.py no encuentra nada (síntoma: "gaps > 1s: 0" y palabras de 39 s de duración).

Varios clips en un proyecto: el .prproj contiene una transcripción POR clip. --rush NAME.MOV elige la que coincide con la duración del clip (sin ella, la más larga, con una advertencia). Compara el inicio de la última palabra, con un margen de deriva del 0,3% de la duración. Verificar que el recuento de palabras difiere de un clip a otro. Una carpeta de trabajo por clip, luego merge_xml.py.

Dos trampas en esta transcripción:

  1. Puede derivar en relación con el archivo: paso 2b. Los cortes están en TIEMPO del archivo (eso es lo que lee el XML), por lo que las palabras se corrigen, nunca al revés.
  2. Las duraciones de las palabras pueden tragarse el silencio que sigue: el silencio ya no existe entre palabras y ya no se corta. silence_cuts.py devuelve esas palabras a su final real (trim_overflow). Nunca confiar en un final de palabra de Premiere; solo los inicios son fiables.

Más trampas (palabras fechadas dentro de un silencio, fragmentos mudos, islas diminutas): references/lessons.md.

Límites de corte de toma: en el valle de energía más cercano del inicio de la palabra, con 0,12 s de aire antes del ataque de la palabra conservada. Describir los cortes por índices de palabras, no en segundos: sobreviven a una realineación.

El pipeline v1 (más abajo) sigue siendo el plan de respaldo cuando no hay transcripción de Premiere (advertir que probablemente se perderán las repeticiones palabra por palabra).

Requisitos de la máquina

Comprobados al inicio; si falta algo, señalar a INSTALL.md (references/whisper-setup.md solo 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 con numpy (nada más). Sin clave de API, sin cuenta, nada sale de la máquina después de la descarga del modelo.

Pipeline v1 (plan de respaldo, 8 etapas)

Ejecutado por scripts/derush.py. Cada etapa escribe en <clip>_Derush_vN_work/, junto al clip, nunca se elimina (la reanudación y la inspección siguen siendo posibles).

#ScriptFunción
1derush.py (punto de entrada)metadatos de ffprobe, número de versión
2extract_audio.pyffmpeg a audio.wav 16 kHz mono
3transcribe.pywhisper.cpp a transcript.json
4mechanical_cuts.pylistas de palabras y patrones del archivo de idioma a cuts_mechanical.json
5análisis semántico (Claude)a cuts_semantic.json (ver más abajo)
6merge_cuts.pyfusionar, ajustar a palabras, puntuaciones a cuts_final.json
7build_premiere_xml.pya .xml (XMEML / FCP7)
8build_report.pya .report.md

Etapa 5: análisis semántico

El script escribe prompt_semantic.txt y se detiene. Esa es la ruta normal: Claude, ejecutando el skill, entonces hace lo siguiente.

  1. leer prompt_semantic.txt por completo;
  2. analizar la transcripción siguiendo las reglas del prompt;
  3. escribir el JSON en cuts_semantic.json (ruta dada en el prompt);
  4. reanudar: derush.py <clip> --resume-from=6 --work-dir=<work>.

Si cuts_semantic.json ya existe, la etapa se omite.

Decisiones de tres niveles (la filosofía del skill)

Cada corte propuesto tiene una confianza entre 0 y 1.

  • disable: el pasaje se elimina de la línea de tiempo, no se desactiva. build_spine_clips() construye la secuencia por sustracción: solo los intervalos conservados permanecen, uno tras otro, y la duración de la secuencia es la suma de los intervalos conservados. El equivalente a una "eliminación en cadena" ya aplicada. Umbrales: >= 0,85 para un corte mecánico, >= 0,92 para un corte semántico (un LLM a menudo sobrepasa sus límites).
  • flag (0,6 a 0,85): sin corte. El pasaje permanece como un clip activo, con un marcador de secuencia rojo ("DOUBT (conf X): razón") en el lugar correcto. El usuario decide.
  • ignore (< 0,6): nada, para no saturar la línea de tiempo.

Nunca invertir estas semánticas. Entregar clips desactivados y atenuados para eliminar a mano traslada el trabajo al usuario en lugar de eliminarlo: la promesa es una secuencia directamente utilizable.

Tipos de corte

  • filler: palabras de relleno ("um", "uh"...) e inicio de oración ...

[truncado para traducción]

Individual skills in this repo

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

Skills relacionados