Communitygithub.com

v01d3tr/slidegen-video

Convierte el guion del usuario (archivo .txt con marcas [n] de diapositivas, archivos multimedia [file] y tokens de descripción [description]) y una grabación de voz en un video de diapositivas animadas sincronizadas palabra por palabra con la narración, con el estilo del juego nombrado y sus iconos/arte reales.

¿Qué es slidegen-video?

Esta habilidad transforma un guion de texto y una grabación de voz en un video de diapositivas animadas, sincronizadas palabra por palabra con la narración. Es ideal para creadores de contenido que desean producir videos estilo 'ensayo visual' sobre videojuegos, con un aspecto auténtico y coherente. La habilidad soporta plataformas como Claude Code y se basa en un pipeline que incluye: división del guion en diapositivas, alineación de la voz mediante reconocimiento de voz (Parakeet TDT v3), y renderizado con Playwright y ffmpeg. El proceso es altamente interactivo: antes de generar el video final, se muestran al usuario seis opciones de diseño visual inspiradas en el juego, y se espera su elección. Además, la habilidad busca y utiliza activos visuales reales del juego (iconos, arte, fondos) desde repositorios de GitHub y otras fuentes autorizadas, evitando contenido generado. El usuario debe proporcionar el guion con marcas específicas (como [1] para diapositivas, [archivo.mp4] para medios incrustados y [descripción] para buscar arte relevante) y una grabación de voz. El resultado es un video con diapositivas animadas, títulos, íconos y transiciones que reflejan fielmente el estilo del juego elegido.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/v01d3tr/claude-skills/tree/main/skills/slidegen-video

Preguntar en tu IA favorita

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

Documentación

Guion + voz → video de diapositivas animadas (slidegen)

Entradas del usuario (Michał):

  • script.txt — el texto completo de la narración (puede pegarse en el mensaje). Tokens entre corchetes:
    • [1], [2]… — marcos de diapositiva: la diapositiva n va desde [n] hasta [n+1]. Límites estrictos elegidos por el usuario. Si el guion no los tiene, dividir por tema (una idea por diapositiva, ~10–40 s).
    • [boss.mp4], [mapa.png] — un archivo multimedia que el usuario adjunta; mostrarlo desde ese punto de la narración.
    • [cualquier otro texto], p. ej. [imagen de WoW mostrando al Rey Exánime] — una descripción: encontrar contenido real que coincida (ver Recursos) y mostrarlo desde ese punto.
  • nombre del juego — el aspecto debe referenciar este juego directa o indirectamente; los iconos/arte deben ser de él (un nombre de archivo como ds_bronie sugiere Dark Souls; confirmar con el guion).
  • grabación de voz (cualquier audio/video) — puede llegar antes o después del guion; transcribirla tan pronto como llegue.

Regla estricta: antes de renderizar cualquier video, mostrar 6 direcciones visuales con sabor al juego sobre el contenido del usuario y esperar su elección (paso 4). El tablero solo necesita el guion.

Código: GitHub v01d3tr/claude-skills, carpeta slidegen/ (README allí enumera los archivos). script.py tokens → secciones → tiempos · align.py Parakeet TDT v3 → words.json · spec.json escrito por Claude · render.mjs Playwright Chromium + ffmpeg (solo ventanas en movimiento capturadas, retenciones en otros lugares, segmentos en caché, tableros) · template.html temas + diseños · icons.py iconos oficiales de WoW · assets.py arte del juego desde GitHub. El código fuente de esta habilidad es skills/slidegen-video/SKILL.md en el mismo repositorio.

1. Configuración (una vez por sesión; omitir si /home/claude/slidegen/render.mjs existe)

  1. Adjuntar el repositorio con la herramienta add_repo (propietario v01d3tr, repo claude-skills; access: "push" solo si se enviarán cambios de código) y clonarlo exactamente como dice la herramienta, en /home/claude/claude-skills.
  2. Instalar:
cp -r /home/claude/claude-skills/slidegen /home/claude/slidegen && cd /home/claude/slidegen && npm install
pip install -q --break-system-packages sherpa-onnx soundfile numpy
mkdir -p /home/claude/models && cd /home/claude/models && curl -sSL https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-parakeet-tdt-0.6b-v3-int8.tar.bz2 | tar xj

Si no se puede acceder al repositorio y el usuario adjuntó slidegen.zip, descomprimirlo en /home/claude/. Playwright + Chromium están preinstalados. Desde el shell, HuggingFace, Wowhead, wikis, Fandom y los CDN de juegos están bloqueados; GitHub (git, búsqueda API, lanzamientos) y npm/PyPI funcionan.

2. Leer el guion

mkdir -p /home/claude/proj && cd /home/claude/proj && cp "<subida del guion>" script.txt   # o escribir el texto pegado; más cualquier archivo multimedia que el usuario haya adjuntado
python3 /home/claude/slidegen/script.py split script.txt   # secciones, conteos de palabras, duraciones aproximadas, tokens de medios/descripción, archivos FALTANTES

Archivos multimedia faltantes → pedir al usuario que los adjunte (continuar mientras tanto). Si la grabación ya está, ejecutar el paso 5 align.py + script.py align ahora: muestra qué partes del guion se hablaron realmente — no poner contenido no hablado en las diapositivas.

3. Planificar diapositivas, encontrar recursos, escribir spec.json

El usuario prefiere planificar primero: enviar un breve esquema (diapositiva n → título, diseño, elementos clave, medios) antes de pulir, a menos que diga que solo continúe. El esquema puede ir junto con el tablero de estilo (paso 4).

  • Una diapositiva por cada marco [n]. Un token [archivo]/[descripción] dentro de un marco se convierte en una diapositiva de medios que comienza en esa palabra; si el marco continúa > ~8 s después de que termina un clip, añadir una diapositiva de contenido después ("at": "").
  • Inicios de diapositiva: "mark": "3" para [3], "mark": "m:boss.mp4" para archivos, "mark": "d:1"… para descripciones en orden (claves impresas por script.py). Sin marcas [n] usar "at": "<primeras palabras del tema>".
  • Los elementos aparecen en la palabra donde el narrador los nombra: "at": "<1–3 palabras distintivas>" (coincidencia difusa; buscadas desde el inicio de la diapositiva). Elegir palabras que el ASR reconozca bien (revisar transcript.txt), no nombres propios deformados.
  • Títulos ≤ ~26 caracteres (autoacortados), leyendas ≤ ~35, ≤ 5 iconos por fila, ≤ 4 tarjetas (3 con una figura). Polaco con diacríticos correctos; las diapositivas resumen, nunca transcriben. Escribir los nombres del guion, nunca del ASR.
  • Una entidad por diapositiva (arma, clase, jefe, build) → diseño feature; cuando la narración nombre a un personaje/enemigo/NPC, añadir su figure de cuerpo completo en esa señal (al usuario le gustó esto).
  • Los campos de aspecto (theme, vars, bgImage, fonts) provienen de la dirección que el usuario elija en el paso 4.

Formato del spec (ejemplo completo funcional: slidegen/examples/dark-souls-bronie/spec.json):

{
  "series": "Dark Souls · mejores armas PvE",
  "theme": "parchment", "vars": { "--accent": "#8c2a17" }, "bgImage": "art/Mapa_Lordran.webp", "fonts": ["marcellus-sc/400.css"],
  "boardThemes": [ /* las 6 direcciones, paso 4 */ ],
  "audio": "voice.wav", "words": "words.json", "marks": "marks.json", "output": "out.mp4", "lead": 0.12,
  "slides": [
    { "mark": "1", "section": "1/4 Introducción", "kicker": "Dark Souls · PvE", "title": "Mejores armas", "layout": "icons",
      "items": [ { "icon": "icons/Zweihander.png", "tone": "fire", "label": "Zweihander", "caption": "fuerza" } ],
      "note": { "at": "según el estilo", "text": "división según el estilo de juego" } },
    { "mark": "3", "kicker": "Favorito de los speedrunners", "title": "Black Knight Halberd", "layout": "feature",
      "feature": { "icon": "icons/Black Knight Halberd.png", "tone": "danger", "label": "BK Halberd", "caption": "quality / fuerza" },
      "figure": { "src": "art/black-knight-figure.jpg", "label": "Caballero Negro", "caption": "Darkroot Basin", "at": "del caballero negro" },
      "items": [ { "at": "del caballero negro", "icon": "icons/Black Knight Helm.png", "tone": "shadow", "label": "Drop del Caballero Negro", "caption": "drop raro" } ] },
    { "mark": "m:boss.mp4", "layout": "media", "src": "boss.mp4", "caption": "Enfrentamiento con el jefe", "audio": true, "volume": 0.3, "clip": [12, 30] },
    { "mark": "d:1", "layout": "media", "src": "art/icc_raid.jpg", "kicker": "Raid", "title": "Icecrown Citadel", "kenburns": true },
    { "mark": "4", "layout": "meter", "items": [ { "at": "subir de nivel", "value": 0.14, "tone": "nature", "label": "Subir de nivel", "caption": "simple y seguro" } ] },
    { "at": "talentos", "layout": "stats", "items": [ { "at": "décimo", "label": "10", "caption": "primer punto" } ] },
    { "at": "resumiendo", "layout": "hero", "kicker": "Resumen", "title": "Buscamos magos", "subtitle": "servidor PvP, Horda" }
  ]
}
  • Formas de señal: "at": "frase", "at": 12.5, {"at": "frase", "offset": -0.3}; "mark" (+ "markLead", por defecto 0.25 s). Los elementos sin señal se escalonan después del encabezado; mantener en pantalla el orden de la lista (usar offset si un elemento posterior apareciera antes).
  • Diseños: hero (título grande + subtítulo) · icons (fila de fichas, etiqueta + leyenda; off: true gris + tachado) · cards (icono opcional, leyenda, insignia) · feature (feature: {icon,label,caption,tone,at} ficha grande a la izquierda + tarjetas a la derecha; opcional figure: {src,label,caption,at} retrato alto con marco que aparece en su señal a la derecha, --fig-pos = object-position) · meter (marcador se mueve al value 0–1 de cada tarjeta, tarjetas anteriores se atenúan; una segunda diapositiva de medidor puede continuar) · stats (números grandes) · media (imagen o clip; título/kicker opcional; "fit": "full", "contain": true, "kenburns": true; clips: "clip": [i,f], "audio": true + volume (por defecto 0.35) mezcla el sonido del clip debajo de la voz, de lo contrario silenciado; "mediaAt" lo retrasa).
  • tone: arcane, fire, frost, nature, holy, shadow, danger, neutral.

Recursos — contenido real del juego nombrado

  • Iconos de WoW: python3 /home/claude/slidegen/icons.py find frostbolt lichking; icons.py get /home/claude/proj/icons <nombre>… (64×64, ≈14k iconos oficiales de WeakThorr/wowinterfaceicons, uso no comercial para fans). Especializaciones de mago: arcano spell_holy_magicalsentry, fuego spell_fire_firebolt02, escarcha spell_frost_frostbolt02; jefes a menudo achievement_boss_*. Si no está seguro de un nombre → WebSearch " wowhead".
  • Otros juegos / arte más grande: python3 /home/claude/slidegen/assets.py search "<juego> icons" "<juego> item icons" "<juego> assets" "<juego> wiki" "<juego> fan site" "<juego> landing page" "<juego> loading screens"; assets.py readme owner/repo (volcado oficial vs. hecho por fans); assets.py ls owner/repo <regex>; assets.py get owner/repo /home/claude/proj/art <ruta>…. Los repositorios de wikis de fans / sitios de fans / páginas de aterrizaje son la mejor fuente de capturas de pantalla, arte de áreas y renders de personajes — buscar con grep el tema en varios idiomas (black|knight|caballero|rycerz). También npm (curl -s "https://registry.npmjs.org/-/v1/search?text=<juego>%20icons&size=20").
  • Fuentes conocidas — WoW: Jestokyzz/mod-loading-screen-16x9 (88 pantallas de carga clásicas/TBC/WotLK 1920×1080, rehechas por fans, con marco + logotipo), Zogmaw/encounter-journal-images. Dark Souls 1: SlendyMawn/DarkSoulsItemIcons (todos los iconos de objetos de DSR, PNG transparente ~185 px, Weapons/, Armor/, Consumables/…), ozankasikci/dark-souls-wiki (assets/images/{areas,armor,bosses,npcs,weapons,shields,rings,items}; armor/*-set.jpg = figura de cuerpo completo con el conjunto, p. ej. black-knight-set.jpg = Caballero Negro, 180×342 → escalar 3× Lanczos + enfoque ligero), LeaGaj04/dark-souls-hub (public/: fogata 4K 44.jpg, Mapa_Lordran.webp, gwyn.jpg, artorias.jpg, solaire.jpg, OrnsteinSmough.jpg), ABDUSSALAM0005/dark-souls-ui (src/background.png pergamino oscuro, renders de clases).
  • Iconos de objetos transparentes (estilo Souls): vars globales del juego "--icon-crop": "0%", "--icon-pad": "7%", "--icon-fit": "contain", "--tile-bg": "radial-gradient(circle at 50% 42%,#2e2a25 0%,#141210 70%,#0a0908 100%)", "--tile-border": "#4d463c". Los iconos de WoW mantienen los valores predeterminados (8% de recorte del borde).
  • Imágenes con marco/logotipo del juego como diapositiva de medios: precortar a la banda de arte con PIL (pantallas WotLK 1920×1080: crop((437,340,1482,928)) → 1152×648); como bgImage usar --bgart-size: 200% auto; --bgart-pos: 50% 70%. No puede mostrarse ningún logotipo.
  • Siempre Leer cada imagen obtenida y confirmar que muestra el tema. Nunca generar/dibujar un sustituto presentado como arte del juego; nunca image_search personajes del juego.
  • No encontrado → mejor alternativa real (arte de área, figura de conjunto de armadura, icono en una tarjeta) + listar los vacíos con enlaces (WebSearch) para que el usuario pueda adjuntar archivos.
  • Decir al usuario una vez de dónde provino el arte (nombres de repositorios; decir cuando es sitio de fans/rehecho) y que es propiedad intelectual del editor bajo términos de contenido para fans. game-icons.net (gi:<nombre>, CC BY 3.0, crédito) solo para conceptos genéricos.

4. Tablero de estilo — 6 direcciones con sabor al juego, requeridas antes de cualquier renderizado

Construir spec.boardThemes (máx. 6) {name, base, bgImage, fonts, vars}; las vars globales del juego permanecen en spec.vars. Conjuntos ya hechos: Dark Souls (en el spec de ejemplo — el usuario eligió 2 · Mapa de Lordran: pergamino + mapa de Lordran con --bgart-op .17 + Marcellus SC) y WoW (Karazhan / Diario de misiones / Nexo / Arena / Kirin Tor / Corona de Hielo en pantallas de carga de WoW). Construir un conjunto nuevo por juego y tema. Reglas:

  • Dirección = estructura base + paleta derivada del juego (vars) + arte de fondo real opcional (bgImage, ajustado con --bgart-op/-blur/-bright/-sat/-size/-pos) + fuente opcional. Nombrarlo después de un lugar, facción, elemento o pieza de UI del juego.
  • ≥ 4 de 6 usan arte real del juego como fondo o imitan una pieza reconocible de la UI del juego (diario de misiones, inventario, mapa, marco de pantalla de carga). Las 6 claramente diferentes (centradas/alineadas a la izquierda, claras/oscuras, arte diferente).
  • Bases claras con arte ocupado: --bgart-op ≈ .17, --muted más oscuro; establecer --fcap-color (leyenda de característica) a un acento oscuro — los colores de tono están hechos para tarjetas oscuras.
  • Fuentes solo con latin-ext (polaco): ls /home/claude/slidegen/node_modules/@fontsource/<f>/files | grep -c latin-ext > 0. OK: Cinzel, Marcellus SC, Pirata One, Cormorant Garamond, Oswald, Rajdhani, Inter. No: IM Fell English SC, Orbitron. Otras: npm i -s @fontsource/<f>, "fonts": ["<f>/400.css"], establecer --title-font/--label-font.
  • Bases (body[data-theme=…] en template.html): grimoire oscuro cálido oro Cinzel centrado · parchment papel claro, títulos rojo profundo, tarjetas oscuras · arcane brillo índigo/verde agua, Rajdhani · esports carbón, Oswald, alineado a la izquierda, kicker de etiqueta · codex editorial claro Cormorant, alineado a la izquierda · frostforge acero frío azul, hielo blanco Cinzel. Añadir una base si un juego lo necesita.

Ejecutar en las 2 diapositivas más representativas (diferentes diseños; añadir una diapositiva de medios si el guion depende de ellas):

cd /home/claude/slidegen && node render.mjs /home/claude/proj/spec.json --board 1,3   # funciona sin grabación

Leer proj/build/board_*.jpg primero (desbordamiento, texto sobre arte, fugas de logotipo, iconos incorrectos, bajo contraste), corregir, luego SendUserFile ambos + el esquema, pedir un número o una combinación. Detenerse y esperar. Luego copiar la dirección elegida al nivel superior del spec: theme = base, vars = {...spec.vars, ...direction.vars}, bgImage, fonts.

5. Alinear la grabación, renderizar

cd /home/claude/proj
ffmpeg -v error -y -i "<subida de la grabación>" -vn -ac 1 -ar 44100 voice.wav
python3 /home/claude/slidegen/align.py voice.wav words.json          # ~0.1× tiempo real; escribe transcript.txt
python3 /home/claude/slidegen/script.py align script.txt words.json  # marks.json; revisar "baja confianza" / "NO ENCONTRADO"
cd /home/claude/slidegen
node render.mjs /home/claude/proj/spec.json --cues                    # todos los tiempos; corregir "Cue not found" / coincidencias difusas extrañas
node render.mjs /home/claude/proj/spec.json --preview 12.4,95.2       # momento más completo de cada diapositiva → build/preview_*.jpg, Leerlas
node render.mjs /home/claude/proj/spec.json --budget 540              # primer plano, tiempo de espera 600000; salida 3 = PARCIAL → reejecutar hasta terminar

Los ad-libs están bien (la alineación omite palabras no coincidentes); una marca NO ENCONTRADA obtiene "at" con una frase de transcript.txt. Un video ocupado de 1 minuto se renderiza en ~40 s; charlas largas son principalmente retenciones (≈25–35 min por 40 min). Las ediciones del spec re-renderizan solo los cambios.

...

Skills relacionados