Communitygithub.com

MuhammadToffaha/Edición-de-Video

Convierte un video hablado en un Reel/TikTok/Short profesional con subtítulos sincronizados, gráficos animados, efectos de sonido y la opción de doblar a otro idioma con nueva voz y sincronización labial.

¿Qué es Edición-de-Video?

Este skill transforma videos hablados en contenido pulido para redes sociales, como Reels, TikToks o Shorts, sin necesidad de conexión a internet en la nube de desarrollo. Utiliza herramientas como ffmpeg, Chromium sin cabeza (headless), GSAP para animaciones y sherpa-onnx para transcripción con Whisper. El flujo de trabajo incluye detección automática del idioma, transcripción local, diseño de escenas con gráficos como tarjetas animadas, íconos y logotipos, y la generación de subtítulos palabra por palabra sincronizados con el audio. Además, soporta un modo de doblaje que traduce el video a otro idioma, clona la voz del hablante original con YourTTS (modelo Coqui) y reanima los labios del video usando Wav2Lip y GFPGAN para una sincronización creíble. Está diseñado para trabajar completamente offline en un sandbox, con todos los modelos descargados desde releases de GitHub, lo que garantiza privacidad y velocidad en el procesamiento de videos de hasta 60 segundos en aproximadamente 15-25 minutos.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MuhammadToffaha/Video-editing/tree/HEAD/.claude/skills/short-form-video-editor

Preguntar en tu IA favorita

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

Documentación

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.

  1. 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 con asr_chunks.py ... auto.
  2. 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 como projects/<slug>-<YYYYMMDD>/ cuando ese repositorio esté en la sesión, de lo contrario en el bloc de notas. cp -r template/. <project>/.
  3. Verifica/instala dependencias (una vez): ffmpeg, Node + Playwright Chromium (/opt/pw-browsers, nunca ejecutes playwright install), pip install numpy pillow sherpa-onnx, scripts/fetch_asr_model.sh. No hay red para huggingface; los releases de GitHub + npm + PyPI funcionan.
  4. 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.md para que se ajusten a lo que realmente se dice).
  5. Entrega: SendUserFile el 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 (sin work/) y el mp4 final en el repositorio y haz push a la rama designada de la sesión (o main si no se dio ninguna). Nunca crees un PR a menos que se te pida.
  6. 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".

  1. 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.
  2. Modelos: scripts/fetch_dub_models.sh (+ fetch_asr_model.sh para verificación).
  3. 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.json con los intervalos de habla REALES. YourTTS (coqui, fetch_dub_models.sh lo 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 mediante DISPLAY|spoken (y exclúyelos de la puntuación - automático). Fallback tts_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ó.
  4. 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. Luego scripts/01b_upscale_lipsynced.sh. NO uses el antiguo lipsync.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.
  5. 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.
  6. Gráficos: python3 -I scripts/build_transcript.py work/en16k.wav (establece max_chars ~22 en el json de origen para Inglés), regenera composition/transcript.js, luego reescribe scene.js copiando y las palabras de activación en el nuevo idioma (LTR: .row/.chunk direcció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)), nunca ts('your skin').
  7. Renderiza como de costumbre (LAST_SRC_FRAME=<n> scripts/02_render_all.sh, cues, sfx) y mezcla con VOICE=work/voice_en.wav OUT=out/name-en.mp4 scripts/03_mix_and_encode.sh.
  8. 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

  1. 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.
  2. 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/--brand en composition/style.css y #wm/#outro.
  3. Prepara: END=<trim seconds> scripts/01_prepare.sh input.mp4 (fotogramas, wav 16k, voz).
  4. Transcribe (sin acceso a HF en el sandbox; los releases de GitHub funcionan): scripts/fetch_asr_model.sh; luego
    • python3 -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 pase en deletrea 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.
  5. Temporización: python3 -I scripts/pauses.py work/asr16k.wav -> las pausas son los límites de frase fiables. Escribe data/transcript.source.json como frases [inicio, fin, "texto"] (ver data/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). Luego python3 -I scripts/build_transcript.py work/asr16k.wav y echo "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.
  6. Diseña escenas en composition/scene.js (ver reference/scene-patterns.md). Usa card(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. Establece finish(<segundos>) = fin de voz + ~1.7 s de outro.
  7. 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. Luego scripts/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, pasa LAST_SRC_FRAME=<n> para congelar el último fotograma limpio.
  8. 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 - usa split(' ') (ya en build_transcript.py).
  • Animar SVG <rect> con CSS scaleY lo voltea/desplaza en Chromium sin cabeza - usa tween attr:{y,height} en su lugar. Dibujo de trazo: draw(path,t,d).
  • Los elementos que comienzan ocultos necesitan CSS opacity:0 (clase hid) y tweens con immediateRender:false; cada tween debe ser buscable (los workers saltan directamente a su fotograma de inicio).
  • Las tarjetas con backdrop-filter solo se difuminan si el fotograma de video está en la misma página (#bg img) - 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 COSRX como letras: usa anulaciones DISPLAY|spoken.
  • GitHub MCP create_repository puede dar 403 - pide al usuario que cree el repositorio, luego add_repo + clona (clona a un directorio nuevo si la ruta existe).

Skills relacionados