reel-subs — subtítulos y animaciones para reels
Conviertes un corte editado de video vertical (exportado desde CapCut / Premiere / teléfono) en un reel con subtítulos frase por frase y gráficos animados limpios. Todo se ejecuta localmente en la máquina del usuario.
Cómo funciona: voz → palabras con tiempos (sherpa-onnx, offline) → tú escribes edit.json
(subtítulos + elementos gráficos) → Remotion renderiza SOLO una capa de gráficos transparente → ffmpeg la superpone
sobre el video original intacto, conservando sus propias etiquetas de color. Nunca renderices el video completo a través de Remotion:
esto lo re-codifica con una matriz de color diferente y produce desplazamiento en los tonos de piel.
SKILL_DIR abajo = la carpeta que contiene este archivo. ENGINE = ~/.reel-subs/engine
(en Windows %USERPROFILE%\.reel-subs\engine; o $REELS_HOME/engine si esa variable de entorno está configurada).
Todos los scripts son Node plano — ejecútalos con node, igual en macOS, Windows y Linux.
Habla al usuario en su idioma. Responde en el idioma en que el usuario te escribe (normalmente ruso), aunque este archivo esté en inglés: líneas de progreso, preguntas, errores, el resumen final. Los comandos, rutas y claves JSON se quedan como están.
Lee primero las preferencias del usuario. Si ~/.reel-subs/preferences.md existe (o
$REELS_HOME/preferences.md), léelo antes del paso 1 y síguelo: contiene lo que este usuario pidió en
sesiones anteriores y anula los valores por defecto de este archivo. Ver "Aprendiendo el gusto del usuario" más abajo.
0. Configuración (primera vez, o cuando doctor dice NOT READY)
node SKILL_DIR/scripts/setup.mjs # Modelo de ruso (por defecto)
node SKILL_DIR/scripts/setup.mjs --lang multi # Inglés + 24 idiomas europeos
Solo necesita Node.js 18+. Si falta node, dile al usuario que instale la LTS desde nodejs.org
(macOS: brew install node también funciona; Windows: winget install OpenJS.NodeJS.LTS) y detente.
La configuración copia el motor a ENGINE, ejecuta npm install (binarios de Remotion, ffmpeg/ffprobe, sherpa-onnx),
descarga el modelo de voz (~170 MB ru / ~490 MB multi) y Chrome headless. Es idempotente.
Tarda 2–5 minutos la primera vez — dilo en una línea. Termina con READY.
Si imprime ✗ headless browser: la descarga de Chrome de Remotion está bloqueada en esta red y no se
encontró ningún Chrome/Edge instalado → pídele al usuario que instale Google Chrome, luego vuelve a ejecutar la configuración.
1. Preparación
node ENGINE/scripts/prepare.mjs "<video>" [--lang ru|multi] [--audio clean_voice.wav]
--lang:ru(GigaAM, mejor para ruso) omulti(inglés, alemán, español, francés, ucraniano…). Elige según el idioma hablado en el video; pregunta solo si no está claro. Los modelos que falten se descargan automáticamente.--audio: si el usuario tiene una pista de voz limpia (Auphonic, Adobe Podcast…), úsala — mejor reconocimiento, y el render la pone en el video final.- Crea
<nombre del video>.reels/junto al video:transcript.txt,words.json,edit.json(borrador). - Se detiene en video HDR con una explicación (superponer sobre HDR cambia colores) — transmítelo al usuario.
2. Comprender el video
- Lee
transcript.txt(frases con códigos de tiempo) y hojeawords.jsonpara los tiempos exactos de las palabras. - Mira los fotogramas:
node ENGINE/scripts/look.mjs "<video>" --every 1→ abre la imagen de la hoja. Observa dónde está la cara (arriba / medio), dónde gesticulan las manos, dónde se muestra una pantalla / producto, dónde ocurren los cortes. Para un video largo, haz la hoja por partes (--from 0 --to 30).
3. Corregir los subtítulos (edit.json → captions)
Los fragmentos del borrador ya están divididos por frase (~2 s, ≤ 32 caracteres). Tu trabajo:
- Corrige errores de reconocimiento: nombres de productos, términos en inglés, números (
четыре бакса→$4), ortografía de marcas. El reconocimiento no tiene puntuación — agrega solo la que ayude a la lectura, casi ninguna. - Mantén las palabras y el idioma del hablante; no traduzcas a menos que te lo pidan.
- Fusiona/divide fragmentos para que cada uno sea una frase natural. Mantén
startMs/endMsalineados conwords.json. - Marcado dentro del texto del subtítulo:
*palabra*→ color de acento (rara vez, para la palabra clave),~palabra~→ rojo (un lapsus del que el hablante se ríe). - Enumera las palabras sobre las que tengas dudas en tu mensaje final en lugar de adivinar en silencio.
4. Planificar los gráficos (edit.json → items)
Referencia completa de campos con ejemplos: SKILL_DIR/reference/edit-schema.md — léelo antes de escribir items.
- hook — los primeros 2–4 s, hasta el primer corte o chiste: la esencia del video en una línea corta, en el idioma del hablante. Los subtítulos se ocultan automáticamente mientras está activo.
- card — un punto clave:
label(en versalitas) +titley/ochipsque aparecen sobre las palabras que ilustran (at),on: truepara el chip de resultado,strikeAtpara tachar algo. - big — un número o una palabra que el hablante enfatiza ("$1", "5000").
- terminal — solo cuando se habla de código, agentes, comandos.
- punch — un chiste / autocrítica:
ase tacha,baparece grande. Los subtítulos se ocultan automáticamente. - pop — pequeños widgets HUD que aparecen junto a las manos cuando el hablante gesticula ("y estas animaciones van…"). Colócalos ~0.3 s antes de la palabra: los tiempos reconocidos van retrasados.
- badge — una etiqueta persistente en la esquina superior izquierda (número de episodio, etc.), solo si el usuario la quiere.
Reglas:
- Nunca cubras la cara. Las tarjetas por defecto van en el tercio superior (
top: 260). Si la cara está en la mitad superior del fotograma, usatop: 1110(abajo). Tampoco cubras lo que el hablante está señalando. - Todo se mantiene dentro de la zona segura (las tarjetas tienen 840 px de ancho, centradas) — no muevas cosas a los bordes.
- Densidad: un gráfico cada 5–10 s de media, sincronizado con las palabras. Sin subtítulos en recuadro que repitan lo que se dice, sin explicar lo obvio, sin movimientos rebotantes/infantiles.
- Primera mención de un producto/proyecto: la tarjeta debe decir qué es en pocas palabras — los espectadores son nuevos.
- Los tiempos están en segundos del video fuente. Los items pueden solaparse con subtítulos; hook/punch los ocultan.
- No inventes hechos: los chips y tarjetas dicen exactamente lo que dice el hablante.
5. Vista previa — mira siempre antes del render completo
node ENGINE/scripts/preview.mjs "<trabajo>/edit.json" # un fotograma dentro de cada item
node ENGINE/scripts/preview.mjs "<trabajo>/edit.json" --at 1.2,7,15
Abre previews/sheet.jpg (y los individuales at_<t>.jpg cuando sea necesario). Verifica: cara clara, texto ajustado,
nada toca los bordes, subtítulos legibles. Corrige edit.json y previsualiza de nuevo. ~10–30 s por ejecución.
6. Render
node ENGINE/scripts/render.mjs "<trabajo>/edit.json" [--out archivo.mp4]
~1–4 min por minuto de video. La salida por defecto es <video>_final.mp4 junto al video fuente.
Imprime el recuento de fotogramas de salida vs el original — si dice MISMATCH, comunícalo al usuario.
Luego dale al usuario: la ruta de salida, un resumen de 2–3 líneas de lo que añadiste, palabras dudosas.
Revisiones
Edita edit.json → previsualiza los momentos cambiados → renderiza de nuevo. Nunca vuelvas a ejecutar prepare.mjs --force
después de que el usuario haya aprobado los subtítulos (los restablecería). Copia edit.json antes de cambios grandes.
Aprendiendo el gusto del usuario
La skill debe mejorar para este usuario cada vez. Sus notas viven en
~/.reel-subs/preferences.md ($REELS_HOME/preferences.md si está configurado) — fuera de la carpeta de la skill y
fuera de ENGINE, así que actualizar la skill o volver a ejecutar la configuración nunca las borra.
Cuándo ofrecer guardar:
- El usuario corrige el mismo tipo de cosa dos veces (fuente, colores, tamaño o posición de subtítulos, cantidad de gráficos, redacción del hook, qué palabras llevan acento…).
- El usuario dice algo como «запомни», «в следующий раз делай так», «мне так больше нравится».
- Al final de una sesión con revisiones: enumera las correcciones en 2–4 líneas cortas y pregunta una vez si guardarlas para la próxima vez.
Cómo:
- Siempre pregunta primero, muestra exactamente lo que escribirás, escribe solo después de un sí. Nunca guardes por tu cuenta.
- Escribe reglas, no historial: «Fuente de subtítulos más grande: captionSize 60», «Hook sin emojis», «No más de una tarjeta cada 10 s». Agrúpalas bajo encabezados cortos (Estilo, Subtítulos, Gráficos, Redacción). Actualiza o elimina una regla antigua en lugar de añadir una contradictoria.
- Los valores de estilo que
edit.json→stylesoporta se ponen como valores exactos, para que puedas copiarlos en cada nuevoedit.json. - Si un deseo requiere un cambio de código (una nueva fuente, una nueva animación, un aspecto diferente de tarjeta), hazlo en
ENGINE/src/y también regístralo bajo Cambios en el motor enpreferences.md: qué archivo, qué cambió, por qué. La configuración copia el motor de nuevo y sobrescribe los archivos editados (los archivos nuevos sobreviven), así que después de cualquier ejecución de configuración revisa esta lista y vuelve a aplicar lo que falte. - El usuario también puede editar
preferences.mda mano o simplemente decirte qué cambiar en él.
Personalización
- Colores / tamaños:
edit.json→style(accent,captionSize,captionTop,font). - Nuevos tipos de gráficos: añade un componente en
ENGINE/src/components/, un tipo ensrc/types.tsy un caso ensrc/Overlay.tsx— el bundle se reconstruye automáticamente en la siguiente vista previa. Mantén la capa transparente (sin fondo, sin video dentro de Remotion). npm run studiodentro deENGINEabre Remotion Studio para ajustes en vivo.
Solución de problemas
doctor:node ENGINE/scripts/doctor.mjs— muestra ✓/✗ para cada dependencia.- Advertencia de velocidad de fotogramas variable → pídele al usuario que exporte a 30 o 60 fps constantes.
- No es 9:16 → los gráficos están diseñados para video vertical; se escalan para ajustarse, pero dilo.
- Windows: usa los mismos comandos; pon rutas con espacios entre comillas. PowerShell y cmd funcionan ambos.
- No se sube nada a ningún lado: los modelos y Chrome se descargan una vez, luego todo funciona sin conexión.