Communitygithub.com

skailabinfo/claude-video-harness

Montaje de un nuevo video a partir de una toma bruta: búsqueda de tomas duplicadas y falsos inicios, corte de pausas, corrección de transcripción, recorte de la persona para el póster, lista de beats de tarjetas y stickers, fotogramas para aprobación, máster, portada y archivo. Ejecútalo con «monta takes/1.MOV», «nuevo video», «aquí está la toma».

¿Qué es claude-video-harness?

Este skill automatiza el flujo de trabajo completo de edición de video, desde una toma en bruto hasta el máster final, diseñado para creadores de contenido que buscan eficiencia y consistencia. Analiza la toma original para detectar duplicados y falsos inicios, aplica cortes precisos basados en pausas y genera automáticamente elementos visuales como póster, tarjetas y stickers según el perfil de estilo del usuario. Compatible con sistemas basados en Claude (como Claude Code) y entornos de código abierto, utiliza herramientas como ffmpeg y Remotion para orquestar todo el proceso. El skill guía al usuario paso a paso, solicitando aprobación en puntos clave (selección de tomas, generación de beats, fotogramas para revisión) antes de producir el máster final, la portada y el archivo del proyecto.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/skailabinfo/claude-video-harness/tree/HEAD/.claude/skills/new-video

Preguntar en tu IA favorita

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

Documentación

Nuevo video: de la toma al máster

Antes de empezar: harness.config.json → configured: true (de lo contrario, skill setup), bash video/scripts/doctor.sh sin MISSING. Lee brand-kit.md, editing-taste.md, «Perfil de estilo» en exemplars.md, anti-patterns.md, delivery-specs.md. El estilo del video proviene únicamente del perfil del usuario: si hay póster, tarjetas, stickers, b-roll, sonido, cuánta gráfica, qué ritmo. Lo que no esté en el perfil, pregúntalo, no lo decidas tú. El punto de partida del código es el actual video/src/.

Si video/public/footage.mp4 ya existe de un video anterior y no está archivado en edits/ — primero archívalo (paso 11), luego comienza.

1. Inspección de la toma

ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate:stream_side_data=rotation -of default=nw=1 takes/1.MOV

Mira la orientación por rotation, no por width (el iPhone escribe vertical como 1920x1080 + flag). Mira 3–4 fotogramas (ffmpeg -ss N -i … -frames:v 1 out/peek-N.jpg). No estabilices, si se grabó con trípode — vidstab añadirá vibración. Solo si es claramente a mano: estabiliza el ORIGINAL (vidstabdetect=shakiness=6:accuracy=15 → vidstabtransform=smoothing=25:optzoom=1:interpol=bicubic, -c:a copy; necesita ffmpeg con libvidstab) y luego trabaja con él.

2. Tomas duplicadas y falsos inicios — ANTES del corte

cd video && python3 scripts/chunks.py ../takes/1.MOV

Una transcripción completa esconde las repeticiones, pero el espectador las nota enseguida. Encuentra: fragmentos adyacentes con la misma frase (toma duplicada — deja la ÚLTIMA), fragmentos de 1–2 palabras que el siguiente fragmento comienza de nuevo (falso inicio). Muestra al usuario la lista de lo que vas a cortar, con códigos de tiempo — y obtén un «sí». Los límites están dentro de las pausas.

3. Corte

cp public/captions.json out/captions.backup.json 2>/dev/null   # cut.py sobrescribe la transcripción
DROP="12.40-15.80" python3 scripts/cut.py ../takes/1.MOV

El ritmo se toma de cut en el perfil (ajustado según referencias). El script imprime DURATION, los fotogramas de los cortes y una verificación de «corte en plena palabra». Si hay pocos cortes para el ritmo que desea el usuario, pasa argumentos por debajo del perfil, por ejemplo … 0.4 0.2 (pausa ~0.35 / 0.2); si hay muchos, por encima. Sin cortes en absoluto — habitación ruidosa: QUIET=-46. Hablante rápido/ritmo lento — SPEED=1.1. Corte en plena palabra — desplaza DROP o los parámetros, no lo dejes así.

4. Máscara — ejecútala INMEDIATAMENTE (si style.poster.enabled)

TITLE_OUT = primer corte de la salida de cut.py (el póster aparece ahí), normalmente 4–7 s. La máscara es la parte más larga (~8 s/fotograma en CPU, 2 workers ≈ 6 fotogramas/min), ejecútala en segundo plano y escribe código mientras:

python3 scripts/matte.py <TITLE_OUT> 2 > out/matte.log 2>&1      # en segundo plano (run_in_background)

No renderices fotogramas mientras se ejecuta, lo ralentizan. Espera a que termine mediante ps -axo command | grep "[m]atte.py", no con pgrep. El script omite fotogramas ya listos — tras reiniciar, simplemente ejecútalo de nuevo.

5. Transcripción

Abre public/captions.json (w, s, e en segundos, em):

  • corrige los errores auditivos: nombres, marcas, términos, anglicismos; acrónimos como se escriben (AI, ROI); whisper suele poner «Gracias por ver» / «Thank you.» en el silencio de la cola — elimínalo;
  • em: 2 (si style.captions.highlight es size o both) y "accent": 1 (si es color o both) — según el SIGNIFICADO, en la cantidad y en las palabras descritas en el perfil (brand-kit.md §2, §4). Si no está descrito, pregunta qué palabras destacar.

6. Lista de beats

Tú mismo o con el subagente script-beats (para videos largos) escribe video/SCRIPT.md:

  • póster — solo si style.poster.enabled: líneas con las palabras y el tono del usuario, acento y kicker como en el perfil;
  • tarjetas — si style.cards no es none, con la densidad de editing-taste.md §3 (número → count; paso → num + head; enumeración → head + lines o row con iconos en las palabras); from = primera palabra de la frase + 4 fotogramas;
  • stickers FLOATS — solo si style.stickers: subtítulo de una palabra, pictograma compacto (ART_NAMES);
  • tarjeta pain: true — solo si el usuario quiere «así no».

Antes del código, muestra al usuario la lista de beats de forma breve (qué y dónde aparece) — es su video, sus decisiones.

7. Código

  • src/Composition.tsx: DURATION, TITLE_OUT, KICKER, TITLE, BEATS, FLOATS; Captions from = inicio de la segunda frase, si hay póster, si no 0.
  • src/ui/Footage.tsx: tabla BEATS estrictamente según los cortes de cut.py, a plena potencia (primer plano 1.16–1.21×, normal 1.06–1.09×) — style.motion.punch lo suavizará o desactivará. Dónde poner primer plano — según editing-taste.md §4; después del primer plano — vuelve a abrir más, de lo contrario el primer plano se «pega»; si hay póster, en el primer corte.
  • Nuevo componente — solo si ni una tarjeta, ni un sticker, ni Photo/Clip/Tag pueden expresarlo (entonces — scene-builder).
  • B-roll de Higgsfield — si está conectado y el perfil lo desea (brand-kit.md §5): muéstralo mediante <Clip> (recorta y silencia previamente: ffmpeg -an -t <seg>), verifica el texto/las caras/las manos en los fotogramas de generación antes de insertarlo. Primero pregunta al usuario y menciona el precio.
  • Sonido — solo si style.sfx: los roles faltantes (card, count, end) — mediante subagente audio-agent según la descripción del perfil.
  • npm run lint — limpio.

8. Fotogramas para aprobación (después de la máscara)

Renderiza un fotograma por cada tarjeta y sticker en el momento completamente ensamblado, el póster en la mitad de su vida (la última línea se lee sobre el cabello), varias frases de subtítulos, el ÚLTIMO fotograma:

npx remotion still MyComp out/key/f<N>.png --frame=<N> --scale=0.5 --timeout=120000

Combínalos en una lista de 4 por fila con subtítulos-números (PIL; fuente con cirílico, por ejemplo /System/Library/Fonts/Supplemental/Arial Bold.ttf), muéstrasela al usuario (SendUserFile). El máster — solo después de su «ok». La lista — minutos, el máster — 10–20 minutos.

Comprueba tú mismo antes de mostrar: el texto clave fuera del 15% inferior / 8% superior; nada se superpone; el sticker no se cruza con la tarjeta; el último fotograma no está vacío ni cortado; todo como en el perfil del usuario y nada más.

9. Máster

npm run master        # en segundo plano; espera el proceso, no la aparición del archivo

El script comprueba los recortes, cuenta los fotogramas y genera out/preview.mp4. Verifica el volumen: ffmpeg -i out/final-master.mp4 -af ebur128 -f null - 2>&1 | grep -A3 Summary ≈ objetivo de audio.lufs. Envía al usuario la vista previa.

Corrección después del máster («corta esta frase») — corta el propio máster (ffmpeg trim+concat en silencio), no re-cortes la toma ni lo renderices todo de nuevo; indica el ETA de antemano. Verifica el empalme: corta 6 s alrededor y ejecuta whisper — deben coincidir exactamente las dos frases necesarias.

10. Portada

Pregunta qué portada se necesita, si no se indica en el perfil: fotograma con título (Cover), póster del video (PosterCover) o propia. Elige el fotograma junto con el usuario: propón 3–4 fotogramas nítidos con ojos abiertos (ffmpeg -ss <seg> -i takes/1.MOV -frames:v 1 -q:v 2 out/cover-N.jpg).

  1. Fotograma seleccionado → public/cover-bg.jpg.
  2. rembg i -m birefnet-portrait public/cover-bg.jpg out/cover-matte.png
  3. python3 scripts/cover-sticker.py public/cover-bg.jpg out/cover-matte.png public/cover-cutout.png 20
  4. En Root.tsx → Cover defaultProps.lines: título con las palabras del usuario, accent / em — como él quiera. Los tamaños se ajustan solos — no modifiques los tamaños de fuente.
  5. npx remotion still Cover out/cover.png --timeout=120000 — muéstra.

Alternativa: PosterCover — póster del video como portada (fotograma + su recorte en poster-bg.jpg / poster-cutout.png).

11. Archivo

edits/<N>/ (en la raíz, no en video/): Composition.tsx, Footage.tsx, captions.json, SCRIPT.md, cover.png, final-master.mp4, preview.mp4. Si el usuario lo desea — luego el skill publish.

Individual skills in this repo

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

Skills relacionados