¿Qué hace Rough Cut: recortar lo superfluo?
Los editores llaman a esto el montaje y el primer corte. Cada línea útil entra, en orden, y todo lo que no se gana su lugar sale. No es el video terminado. Es la versión en la que cada segundo es el hablante diciendo bien la línea, para que las pasadas posteriores (ritmo, color, gráficos, sonido) trabajen sobre buen material.
La idea detrás de esto: editar las palabras, no la forma de onda. Obtén una transcripción donde cada palabra tenga hora de inicio y final, decide qué conservar leyéndola, y los cortes se siguen de los tiempos. Descript y la edición basada en texto en Premiere y Resolve funcionan así. Esta skill añade dos cosas que ellos no hacen: ajusta cada corte al sonido real y verifica el render escuchándolo de nuevo.
Configuración (una vez)
sh ~/simcraft/skills/rough-cut/setup.sh
Crea .venv junto a este archivo con Whisper (mlx-whisper en Apple Silicon, faster-whisper en otros). Necesita ffmpeg: ffmpeg en PATH, o $FFMPEG, o ~/neatlogs-motion/ffmpeg. Ejecuta cada script de abajo con ~/simcraft/skills/rough-cut/.venv/bin/python.
Espacio de trabajo
Una carpeta por video. Si el usuario no ha creado una, crea ~/Movies/edits/YYYY-MM-DD-<slug>/ y copia (nunca muevas) los archivos originales a raw/. Los scripts escriben en audio/, cuts/ y renders/ junto a ella. Nunca se modifica nada en raw/.
La pasada, en orden
1. Transcribir
python scripts/transcribe.py <workspace> [--lang en]
Escribe audio/words.json (cada palabra: inicio, final, texto, confianza) y audio/transcript.txt (una línea por toma). Aproximadamente 1 minuto por cada 2 minutos de metraje en un Mac con chip M.
Pasa --lang en cuando sea inglés (más preciso). Omítelo para habla mixta hindi/inglés.
Cómo se mantiene preciso (cada uno soluciona una falla que encontramos en metraje real):
- Cada toma se transcribe por separado. El audio se divide en cada pausa de 0,5s o más. Al transcribir un archivo completo de una vez, Whisper escribe una línea dicha cinco veces solo una vez, por lo que las tomas adicionales no tienen palabras y no se pueden cortar.
- Las muletillas se conservan en la transcripción. Whisper elimina "um" y "uh" por defecto. Un mensaje lleno de hesitaciones las recupera para que puedan ser cortadas.
- Se descartan los bucles de transcripción. Whisper a veces repite una frase docenas de veces sobre ruido ("there you go there you go ..."). Más de 7 palabras por segundo es imposible, así que esas líneas se descartan.
2. Encontrar los cortes
python scripts/find_cuts.py <workspace> [--gap 0.35] [--keep-fillers]
Escribe cuts/edl.json (fragmentos a conservar, en orden) y cuts/cut_sheet.md (cada corte y por qué, además de palabras de baja confianza para revisar).
| Corte | Regla |
|---|---|
| Silencio | Cualquier pausa mayor que --gap (0,35s). También el silencio inicial y final. |
| Muletillas | um, uh, erm, hmm, mm, ah. |
| Repeticiones | Una palabra o fragmento de hasta 4 palabras dicho dos veces seguidas ("so the so the"): conserva la segunda. |
| Tomas repetidas | La misma línea dicha de nuevo en menos de 20s, emparejada por letras para que coincidan incluso malentendidos ("Vanta" / "Wanda", "1" / "one"): conserva la última toma. |
| Falsos arranques | Una línea abandonada a medias y luego dicha completa ("A 300 billion." y luego "A 300 million dollar business."). |
| Mismo final | Una línea reformulada al inicio pero con el mismo final ("That's, it's Vanta's own founder" y luego "And that's not me saying it, it's Vanta's own founder"). |
| Palabras fantasma | Una palabra sola sin voz debajo. Whisper las inventa en el silencio ("Thank you.", "hallelujah"). |
Dónde aterriza cada corte:
- Cada borde se ajusta a donde realmente comienza y termina la voz, medido a partir de la sonoridad en pasos de 10ms con un umbral que se adapta a la sala. Los tiempos de palabra de Whisper pueden estar desviados entre 0,1 y 0,3s.
- Un borde solo se mueve más tarde hasta 0,12s, porque cortar una palabra es peor que conservar una respiración.
- Se dejan 0,06s de espacio antes de la voz y 0,10s después.
- Cuando no hay espacio real, como un "uh" pegado a la palabra siguiente, el corte va en el punto más silencioso de 10ms entre ellas.
- Una pausa oculta dentro de una "palabra" larga de Whisper aún se detecta y se corta.
3. Pasada de juicio (la edición real, nunca la saltes)
Lee cuts/cut_sheet.md junto con audio/transcript.txt y corrige cuts/edl.json a mano. Un script no puede juzgar esto:
- Cuál toma es la mejor. Por defecto se conserva la última, pero la mejor es la que tiene energía, un final limpio y sin que la rompa una risa. A veces la primera mitad de una toma más el final de otra es lo mejor.
- Muletillas que son parte del chiste. Un "uhh" deliberado antes de un remate se queda.
- "like", "you know", "I mean", "basically". Nunca se cortan automáticamente. Corta solo las que sean puro titubeo. Cortarlas todas hace que el hablante no suene como él mismo.
- Pausas que son ritmo. Una pausa antes de un remate, una reacción o una mirada a cámara se queda. No todo silencio es aire muerto.
- Decir el mismo punto dos veces con diferentes palabras. Corta frases enteras.
- Momentos no verbales, como una canción, un gag visual o un plano de reacción. Solo se conserva el habla, así que añade estas piezas a mano.
- Orden. Las piezas siguen el orden del archivo. Mueve la línea más fuerte al principio para una apertura en frío si el usuario quiere una.
- La lista "revisar estas palabras". Baja confianza a menudo significa murmullos. Si la línea no es clara, busca una toma más limpia.
Cada pieza es {"clip", "in", "out", "text"} y "speed" es opcional. Mantén los cortes entre palabras.
4. Ritmo (pregunta antes)
La hoja de cortes informa palabras por segundo. El contenido rápido de talking-head suele estar entre 3,3 y 3,8. Si el hablante es más lento, sugiere una velocidad de 1,05 a 1,2 y establece "speed" en edl.json para todo el video, o por pieza. El tono se mantiene igual. Nunca acelere música o reacciones.
5. Render de previsualización
python scripts/render.py <workspace> --w 854 --v 1 [--aspect 9:16]
Una previsualización de 480p va a renders/v1_854.mp4. Aumenta --v para cada ronda de notas para que las versiones anteriores se conserven.
- Cada pieza se renderiza con un conteo exacto de fotogramas y audio sin comprimir, luego todas las piezas se unen decodificando. Las uniones por stream-copy pierden fotogramas en los cortes y el audio se desvía unos 2s en pocos minutos.
- Cada pieza recibe una entrada de 12ms y una salida de 20ms, para que los cortes no hagan clic.
- Los clips con una forma diferente se colocan sobre una copia borrosa de sí mismos en lugar de barras negras.
6. Verificar (siempre, antes de mostrar al usuario)
python scripts/verify.py <workspace> --v 1 [--lang en]
Escucha el render de nuevo, pieza por pieza, lo compara con la lista de cortes y escribe cuts/verify_v1.md. El informe tiene cuatro secciones:
- Cortes que caen mientras la voz aún está sonando: una prueba de sonido que no depende de Whisper. Este es el verdadero detector de palabras cortadas. Arregla cada uno moviendo ese borde en edl.json.
- Palabras faltantes: esperadas pero no escuchadas.
- Palabras inesperadas: una muletilla o un fragmento de una toma repetida que se filtra.
- Malentendidos: las dos transcripciones discrepan en las palabras. Eso suele ser murmullos, no un problema de corte.
En audio limpio, el objetivo es 100% de palabras presentes, 0 cortes dentro del sonido y 0 palabras inesperadas. El audio ruidoso o con murmullos puede dar algunos pares faltante/inesperado que en realidad son malentendidos. Confía en la prueba de sonido sobre ellos.
Arregla lo que encuentre, renderiza de nuevo y verifica de nuevo.
7. Mostrar al usuario, luego el final
- Dile al usuario: la duración antes y después, la cantidad de cortes, el resultado de la verificación y cualquier decisión de juicio que hayas tomado (qué toma conservaste, una pausa que mantuviste a propósito).
- Anota sus notas antes de hacer la siguiente versión.
- Solo después de que aprueben la previsualización:
python scripts/render.py <workspace> --w <ancho original> --v N.
Resultados en material real
En 3 minutos de metraje de talking-head con muchas tomas repetidas (9 tomas de una línea, 4 de otra), 2:55 de habla se convirtieron en 0:36. Se conservó la última toma limpia de cada línea y la verificación encontró 100% de palabras presentes, 0 cortes dentro del sonido y 0 filtraciones.
El gusto del usuario
- Ágil. Los jump cuts en huecos de palabra están bien; los zooms constantes alternando entre planos no.
- Conserva insultos, bromas y las partes divertidas. Nunca limpies la personalidad.
- Sin swooshes, y sin corrección de color en esta etapa.
- Cuando el usuario pide "solo lo bueno, máximo X minutos", corta momentos completos, no solo pausas.