AUTOPILOTO - qué hacer cuando el usuario escribe /short-form-video-editor
El usuario sube un video (y opcionalmente una imagen de logotipo) y escribe el comando. Realiza TODO el trabajo sin hacer preguntas; solo detente si algo realmente te bloquea (no se encuentra video, no hay ffmpeg). El texto adicional después del comando = notas de estilo/marca, aplícalas.
- Encuentra las entradas: el video más reciente en las subidas de la sesión (
ls -t /root/.claude/uploads/*/*.{mp4,mov,webm}o la ruta dada en el mensaje); logotipo = una imagen adjunta si la hay (sin logotipo -> omite marca de agua/hero/outro-logo, usa un outro limpio sin texto). Idioma = detectar automáticamente conasr_chunks.py ... auto. - Localiza el kit de herramientas: la carpeta de este skill (el directorio que contiene este SKILL.md) contiene
template/. Trabaja en una nueva carpeta de proyecto: dentro del clon del repositorio Video-editing comoprojects/<slug>-<YYYYMMDD>/cuando ese repositorio esté en la sesión, de lo contrario en el bloc de notas.cp -r template/. <project>/. - Verifica/instala dependencias (una vez):
ffmpeg, Node + Playwright Chromium (/opt/pw-browsers, nunca ejecutesplaywright install),pip install numpy pillow sherpa-onnx,scripts/fetch_asr_model.sh. No hay red para huggingface; los releases de GitHub + npm + PyPI funcionan. - Ejecuta el Flujo de trabajo a continuación de principio a fin, tomando decisiones de diseño tú mismo (color de marca del logotipo; si no, paleta técnica coral/teal; escenas elegidas de
reference/scene-patterns.mdpara que se ajusten a lo que realmente se dice). - Entrega:
SendUserFileel mp4 (muestra el renderizado), luego un resumen breve: especificaciones, qué gráficos se añadieron, puntos de transcripción de BAJA CONFIANZA para verificar de oído, advertencia de resolución del metraje, "audio no escuchado". Guarda el proyecto (sinwork/) y el mp4 final en el repositorio y haz push a la rama designada de la sesión (omainsi no se dio ninguna). Nunca crees un PR a menos que se te pida. - Espera ~15-25 min para un video de 60 s (transcripción ~3 min, renderizado ~4 min, codificación ~2 min). Informa al usuario al inicio en una línea, luego trabaja en silencio hasta terminar.
MODO DOBLAJE - traducir + nueva voz + sincronización labial (probado una vez en el clip Glow: Árabe -> Inglés)
Úsalo cuando el usuario quiera el video en otro idioma "con los labios siguiendo las palabras".
- Guión: transcribe + verifica el original como en el modo Editar, luego escribe tú la traducción como
data/phrases.<lang>.json=[[win_start, win_end, "texto con *palabras clave y anulaciones DISPLAY|hablado (NBSP dentro de tokens de varias palabras)"], ...]. Mantén las ventanas de frase ORIGINALES para que sobrevivan los beats de cámara/gráficos; puedes fusionar ventanas vecinas. Presupuesta alrededor de 2.5-3 palabras/s (Inglés) por ventana - condensa antes que apresurar; mantén el significado, sin nuevas afirmaciones. Ejemplo de anulación hablada:*COSRX|Cosrex,Axis-Y|Axis\u00a0Y. - Modelos:
scripts/fetch_dub_models.sh(+fetch_asr_model.shpara verificación). - Voz (por defecto = CLONADA al hablante): construye
work/ref.wav= 4-5 clips limpios delimitados por pausas (unos 15 s) del discurso original del hablante (16k mono, concatenados).python3 -I scripts/tts_clone.py data/phrases.en.json work/ref.wav 8 <total_seconds>->work/voice_en.wav+data/transcript.source.jsoncon los intervalos de habla REALES. YourTTS (coqui,fetch_dub_models.shlo descarga) clona el timbre sin necesidad de entrenamiento previo; el script genera N tomas por línea, conserva la toma cuya relectura de Whisper coincide mejor con el guión, luego estira el tiempo (0.72-1.25x, preservando el tono) para llenar ~90% de la ventana original. Números probados en el clip Glow: tono mediano 144 Hz vs hablante 154 Hz (voz Kokoro estándar 123 Hz), similitud del espectro a largo plazo 0.96 vs 0.90, cada línea se lee correctamente. Deletrea los nombres de marca fonéticamente medianteDISPLAY|spoken(y exclúyelos de la puntuación - automático). Fallbacktts_phrases.py= voz Kokoro estándar (clara pero no la del hablante). Acento: el modelo transfiere timbre/tono, NO un acento nativo - no prometas un inglés con acento egipcio; di lo que se logró. - Sincronización labial en fotogramas de resolución ORIGINAL:
ffmpeg -t <end> -i src -vf fps=30 work/raw/%05d.png;ffmpeg -i work/voice_en.wav -ac 1 -ar 16000 work/en16k.wav;MODELS=work/models python3 -I scripts/lipsync2.py work/raw work/en16k.wav work/ls --model wav2lip_gan_96.onnx --enhance 0.7(prueba primero con--range a b; ejecución completa ~25 min para 1700 fotogramas en 4 CPUs: cuadros Haar, puntos de referencia 2dfan4 en cada fotograma, luego Wav2Lip + GFPGAN por fotograma). lipsync2 = cultivo FFHQ-512 alineado con puntos de referencia, puntos de referencia suavizados, Wav2Lip en el cuadro facial del punto de referencia, restauración GFPGAN combinada al 0.7, máscara con forma de boca (nunca toca la nariz), pegar de nuevo. Luegoscripts/01b_upscale_lipsynced.sh. NO uses el antiguolipsync.py(cultivo Haar tosco: labios manchados, artefactos similares a lengua - el usuario lo llamó "muy malo"). Se probó EDTalk-256 y es peor (boca fantasmal). Modelos: 2dfan4, gfpgan_1.4, wav2lip_gan_96 del release de facefusion-assets en GitHub. - Prueba de sincronización visual: hoja de contactos de cultivos de boca con la envolvente de audio debajo de cada mosaico - la boca debe estar cerrada en los espacios de silencio y abierta/variada mientras la barra está arriba. Las métricas de correlación de píxeles son demasiado ruidosas aquí; no confíes en ellas.
- Gráficos:
python3 -I scripts/build_transcript.py work/en16k.wav(establecemax_chars~22 en el json de origen para Inglés), regeneracomposition/transcript.js, luego reescribescene.jscopiando y las palabras de activación en el nuevo idioma (LTR:.row/.chunkdirección ltr, fuente Inter, origen del trazo izquierdo, flechas de flujo izquierda->derecha). Los tokens de varias palabras son palabras separadas en la transcripción: busca palabras individuales (ts('skin',0,43.5)), nuncats('your skin'). - Renderiza como de costumbre (
LAST_SRC_FRAME=<n> scripts/02_render_all.sh, cues, sfx) y mezcla conVOICE=work/voice_en.wav OUT=out/name-en.mp4 scripts/03_mix_and_encode.sh. - Sé honesto en el resumen: Wav2Lip en caras de ~100px da una boca suave y ligeramente alisada (visible en inspección cercana), el movimiento de la cabeza/manos sigue siendo del hablante original, la voz es sintética, el hablante debe aprobar una versión doblada de su imagen, considera etiquetarlo como doblado por IA. Nombra cualquier frase traducida cuya fuente fuera de baja confianza.
Editor de video de formato corto (subtítulos + gráficos en movimiento + SFX)
Dos modos: Editar (mantén el idioma, añade subtítulos/gráficos/SFX) y Doblar (traduce a otro idioma, nueva voz, labios re-animados al nuevo audio - se activa cuando el usuario dice inglés/traducir/doblar/sincronización labial). Pipeline probado en un promocional farmacéutico de 57 s en árabe egipcio (Glow Cosmetics). Salida: 1080x1920 @30, H.264/AAC, -14 LUFS.
Proyecto de ejemplo: projects/glow-kbeauty-reel/ en https://github.com/MuhammadToffaha/Video-editing
Reglas que definen "profesional, no plantilla"
- Mantén al hablante, la voz y el significado intactos. Nunca inventes afirmaciones (números, "100%", precios). Si un gráfico necesita texto que no fue dicho, mantenlo genérico (nombres de categorías, etiquetas de cejas).
- Cada elemento visual apoya una frase hablada y se activa EN la palabra (
ts('palabra')), no al inicio de una frase. Las tarjetas salen antes de que entre la siguiente; sin superposiciones fantasma. - Un lenguaje visual: color de marca (muestréalo del logotipo) + blanco + paneles de vidrio tinta profunda, Inter para etiquetas latinas, Cairo (Árabe) para titulares/subtítulos. Menta solo para estados de éxito.
- Zonas de diseño (1080x1920, cara del hablante
y 790-1110): tarjetas y 235-735 (nunca sobre la cara, incluso después de zoom 1.15x), subtítulos y1545, mantén los 220 px inferiores y 130 px superiores libres de contenido clave (IU de la plataforma). Revisa la posición de la cara para cada fuente. - Dispositivos de retención, con moderación: snap de acercamiento (1.12-1.15x) al inicio de frases con desplazamientos lentos entre medias, un gráfico cada 2-4 s, resaltado de palabra activa en subtítulos, micro-animaciones de tachado / verificación / cuenta regresiva, momento de logotipo hero cuando se dice la marca, tarjeta final de marca.
- SFX: whoosh al entrar tarjeta, pop/tick en elementos, campana en éxito, thud en logotipo. Silencioso (aproximadamente -10 dB bajo la voz). Sin música a menos que el usuario la proporcione.
Flujo de trabajo
- Inspecciona:
ffprobe, hoja de contactos (ffmpeg -vf "fps=1/6,scale=239:-1,tile=5x2"), encuentra tarjetas finales al final (marco negro de WhatsApp/CapCut) y anota la posición del hablante. La fuente suele ser de baja resolución (teléfono/WhatsApp): amplía con lanczos, informa al usuario que el metraje será suave mientras los gráficos se mantienen nítidos. - Proyecto:
cp -r <skill>/template/. my-project/ && cd my-project;cp <logo> assets/;python3 -I scripts/extract_logo.py assets/logo_original.png assets/logo_white.png(imprime el hex de la marca). Actualiza--coral/--brandencomposition/style.cssy#wm/#outro. - Prepara:
END=<trim seconds> scripts/01_prepare.sh input.mp4(fotogramas, wav 16k, voz). - Transcribe (sin acceso a HF en el sandbox; los releases de GitHub funcionan):
scripts/fetch_asr_model.sh; luegopython3 -I scripts/asr_chunks.py work/asr16k.wav <lang|auto> 3.2 a, repite con 2.4 y 4.5. Whisper trunca las colas de los fragmentos; fusiona las 3 hipótesis tú mismo y corrige con tu propio conocimiento del idioma.- Palabras inciertas / nombres de marca:
python3 -I scripts/asr_probe.py work/asr16k.wav ar,en 14.0-16.8 14.5-16.6 ...(el paseendeletrea nombres de marca latinos). Confía solo en lo que es consistente en ventanas superpuestas; enumera el resto como BAJA CONFIANZA en el mensaje final y README. No construyas gráficos en nombres adivinados.
- Temporización:
python3 -I scripts/pauses.py work/asr16k.wav-> las pausas son los límites de frase fiables. Escribedata/transcript.source.jsoncomo frases[inicio, fin, "texto"](verdata/transcript.source.example.json;*palabra= píldora de acento; usa NBSP dentro de nombres latinos de varias palabras; marcas latinas en texto RTL: evita pegar el prefijo árabeو, escribeو Brand). Luegopython3 -I scripts/build_transcript.py work/asr16k.wavyecho "window.TRANSCRIPT=$(cat data/transcript.json);" > composition/transcript.js. Distribuye los tiempos de las palabras por peso silábico dentro de cada frase y los ajusta a los valles de energía, luego hace fragmentos de subtítulos equilibrados de 2-4 palabras. Verificación de cordura: ningún inicio de palabra dentro del silencio. - Diseña escenas en
composition/scene.js(verreference/scene-patterns.md). Usacard(t0,t1,{y,h,html}),pop,fade,draw,cue,ts. Toma los ejemplos de escenas como patrones: tarjeta de gancho, chips de marca (ranuras de esqueleto que se llenan cuando se dice cada nombre), mosaicos de categoría, diagrama A->B con punto viajero + verificación, chips tachados, nodos de flujo, clasificación por estrellas, filas de lista de verificación, hoja de ruta, gráfico de barras, anillos de confianza, revelación de logotipo hero, outro de marca. Establecefinish(<segundos>)= fin de voz + ~1.7 s de outro. - Renderiza + QA: renderiza algunos fotogramas de prueba primero (
node scripts/render.mjs <f> <f+1> work/test), construye hojas de contactos con Pillow, MÍRALOS. Luegoscripts/02_render_all.sh(4 workers, ~8 fps total),node scripts/render.mjs cues work/cues.json && python3 -I scripts/sfx.py work/cues.json work/sfx.wav,OUT=out/nombre.mp4 scripts/03_mix_and_encode.sh. Si la fuente termina con una tarjeta final, pasaLAST_SRC_FRAME=<n>para congelar el último fotograma limpio. - Entrega: envía el mp4 (SendUserFile), indica las especificaciones, los puntos de transcripción de baja confianza, el límite de resolución del metraje, y que el audio no fue escuchado de oído (no puedes oírlo) - solo verificado con medidores de sonoridad y pruebas de onset vs energía.
Errores ya resueltos (no los vuelvas a aprender)
str.split()de Python divide en NBSP - usasplit(' ')(ya en build_transcript.py).- Animar SVG
<rect>con CSSscaleYlo voltea/desplaza en Chromium sin cabeza - usa tweenattr:{y,height}en su lugar. Dibujo de trazo:draw(path,t,d). - Los elementos que comienzan ocultos necesitan CSS
opacity:0(clasehid) y tweens conimmediateRender:false; cada tween debe ser buscable (los workers saltan directamente a su fotograma de inicio). - Las tarjetas con
backdrop-filtersolo se difuminan si el fotograma de video está en la misma página (#bgimg) - por eso los fotogramas se componen en la página. - Las tarjetas borrosas vacías se ven mal: comienza la tarjeta en su palabra de activación o muestra filas/ranuras de marcador de posición tenues que se iluminan cuando se habla.
- El árabe necesita formato real: Chromium + Cairo woff2 (división unicode-range árabe/latino) funciona; Pillow/ffmpeg drawtext no.
- Whisper en sherpa-onnx no tiene marcas de tiempo de palabras y trunca colas; de ahí las ventanas cortas + anclaje de pausa.
- opencv 5.x no tiene
CascadeClassifier(fija 4.10.0.84); los cuadros faciales Haar dan falsos positivos en manos/camisa y fallan ~30% de los fotogramas -> rechazo de valores atípicos de caja mediana + segunda pasada ROI + interpolación (ya en lipsync.py). - La TTS estilo Kokoro/Whisper lee
COSRXcomo letras: usa anulacionesDISPLAY|spoken. - GitHub MCP
create_repositorypuede dar 403 - pide al usuario que cree el repositorio, luegoadd_repo+ clona (clona a un directorio nuevo si la ruta existe).