CommunityProgramación y desarrollogithub.com

mathruffian-dot/soil-motion-deck

Convierte una presentación SOIL en dos productos: un .pptx con animaciones incrustadas y un video explicativo (MP4) con locución y subtítulos. Ideal para quienes quieren diapositivas dinámicas y un video de repaso generados a partir del mismo contenido.

¿Qué es soil-motion-deck?

Esta skill conecta dos herramientas complementarias: **soil-teaching-deck** (que genera presentaciones SOIL con 6 motores) y **motion-explainer** (que produce videos animados con locución y subtítulos). El resultado son dos archivos sincronizados: - **A:** Una presentación .pptx con 2–4 diapositivas clave que contienen fragmentos de video mudo (sin audio ni subtítulos), listos para proyectar en clase. - **B:** Un video MP4 completo con locución y subtítulos, ideal para que los estudiantes repasen o para subir a plataformas. El proceso es secuencial: primero se genera el video (B), luego se crea una versión silenciosa del mismo y se recortan los fragmentos correspondientes a las diapositivas animadas (A). Así, ambas piezas comparten exactamente la misma duración y contenido visual. La skill soporta los agentes Claude Code, Codex y Gemini CLI. Requiere Node.js 22+, ffmpeg, Python 3 y HyperFrames. Incluye scripts para crear la versión silenciosa (`make_silent.py`), recortar clips (`cut_clips.py`) y generar miniaturas de la presentación (`thumbs.py`). También maneja casos como cuando el usuario ya tiene una presentación SOIL y desea convertir algunas diapositivas a animadas.

Compatible con✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/mathruffian-dot/soil-motion-deck/tree/HEAD/skills/soil-motion-deck

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

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

Documentación

SOIL Presentación Animada: Una Creación, Dos Productos

ProductoContenidoPara quién
A Presentación (.pptx)Presentación generada por los 6 motores de SOIL. 2–4 diapositivas 🎬 con fragmentos animados sin sonido ni subtítulos, el profesor explica mientras proyectaClase presencial
B Video (MP4)Mismo contenido, versión completa narrada: locución, subtítulos, tema de tres coloresRepaso, recuperación, subida a plataformas

Ambos productos comparten las mismas animaciones: primero se crea B, luego se extraen los fragmentos 🎬 de su "gemelo silencioso" y se incrustan en A. Así, la animación se hace una sola vez y ambas piezas tienen exactamente la misma duración.

Esta skill solo se encarga de "conectar". Se basa en dos skills superiores:

  • soil-teaching-deck (mathruffian-dot/soil-teaching-deck): seis motores, roles de página, diseño visual, estructura sándwich, fuente F-0.
  • motion-explainer (mathruffian-dot/claude-motion-explainer), junto con sus skills asociadas motion-design, review-loop y las skills oficiales de HyperFrames: guion, locución, fotogramas, subtítulos, tema de tres colores, revisión, exportación.

0. Entorno y Rutas

Este documento usa tres códigos; antes de empezar, encuentra sus ubicaciones reales:

CódigoQué esUbicación típica
<smd>Carpeta de esta skill~/.claude/skills/soil-motion-deck (Claude Code), ~/.agents/skills/soil-motion-deck (Codex)
<me>Carpeta de la skill motion-explainerMisma, carpeta llamada motion-explainer
<soil>Carpeta de la skill SOILMisma, carpeta llamada soil-teaching-deck
ls -d ~/.claude/skills/{soil-motion-deck,motion-explainer,soil-teaching-deck,review-loop} ~/.agents/skills/{soil-motion-deck,motion-explainer,soil-teaching-deck,review-loop} 2>/dev/null

PowerShell (cuando no haya bash en Windows):

Get-ChildItem "$HOME\.claude\skills","$HOME\.agents\skills" -Directory -ErrorAction SilentlyContinue | Select-Object FullName

Otros agentes (p. ej., Gemini CLI): busca carpetas con el mismo nombre dentro de su directorio de skills.

Si falta alguna, pide al usuario que la instale siguiendo el README de cada repositorio (cada repo copia la carpeta skills/ o skill/ en la carpeta de skills del agente). El install.py de SOIL solo instalará en la primera carpeta que encuentre y esperará a que el usuario presione Enter. Si el agente lo instala por su cuenta, copia directamente: cp -r soil-teaching-deck/skill <carpeta de skills>/soil-teaching-deck.

Otros requisitos:

  • Dependencias de las dos skills superiores: Node.js 22+, ffmpeg, Python 3, HyperFrames y un TTS: edge-tts (por defecto), sin necesidad de GPU, la mayoría lo usa; o Breeze TTS 2 (avanzado, requiere GPU NVIDIA, solo para investigación y uso no comercial, solo instalar si el usuario lo solicita siguiendo motion-explainer/references/tts-setup.md).
  • Presentación: PptxGenJS 3.12.0 (instalar con templates/package.json de esta skill, ver §5), fuente GenSekiGothic2 H / B / M (instalar según F-0 de SOIL).
  • Miniaturas: PowerPoint en Windows es lo mejor (thumbs.py lo usará directamente para exportar, las fuentes y portadas de video serán idénticas a las de clase). Sin él, usar LibreOffice + poppler, solo para verificar diseño, no siempre se verán las portadas de video.
  • Versiones probadas: HyperFrames 0.8.168, PptxGenJS 3.12.0.

Agentes sin sub-agentes (p. ej., ciertas configuraciones de Codex, Gemini): donde motion-explainer dice "asignar un sub-agente a cada fotograma en paralelo", hacerlo secuencialmente un fotograma tras otro, leyendo los mismos archivos en el mismo orden.

1. Entrevista Inicial (preguntar todo de una vez)

  1. Asignatura, unidad, audiencia, tiempo de clase (pregunta adicional de SOIL).
  2. Qué productos se desean: A+B (por defecto), solo A, solo B. Incluso si solo se pide A, se hará B primero: la locución marca el ritmo de cada fotograma, así la animación será natural. Solo que no se entregará B, y no es necesario que el usuario escuche una prueba de la locución.
  3. Combinación de colores. Por defecto es "tres colores del video + sándwich SOIL":
    • Video (y ventana de animación en la presentación): tres colores de motion-explainer, por defecto fondo negro #121212, texto blanco #F2F0EA, acento naranja #FF7A1A.
    • Presentación: portada, diapositiva de acción y conclusión son páginas oscuras, usando los tres colores del video; las páginas de contenido son claras, la animación se coloca en una "ventana de reproducción" oscura.
  4. Voz de la locución: según las reglas de motion-explainer.

La entrevista inicial de motion-explainer (plataforma, duración, voz, tres colores) ya se ha hecho aquí, no volver a preguntarla. La duración no está limitada por su recomendación de "60–90 segundos": la duración es igual a la de la locución, normalmente 15–25 segundos por cada diapositiva 🎬, más unos pocos fotogramas al inicio y al final.

2. Motores SOIL 1–3: Marcar Diapositivas 🎬

Ejecutar los motores 1 (posicionamiento conceptual), 2 (posicionamiento contextual) y 3 (arquitectura de páginas) según soil-teaching-deck. Después de cada motor, pedir confirmación al usuario. En la tabla de roles de página del motor 3, añadir un campo animate a las diapositivas que se animarán. Usar 🎬, no ★ (el ★ de SOIL significa "diapositiva clave", concepto diferente):

Diapositiva 6: ¿Por qué se cumple siempre? Rompecabezas de áreas 🎬
- Rol de página: página de proceso
- Único punto principal: el cuadrado grande y los triángulos no cambian, por lo que el área vacía es igual
- animate: { frame: 04-proof, poster: last }

frame es el nombre del archivo (sin .html) de ese fotograma en el video, que se fija al escribir el storyboard en §3: si en STORYBOARD.md el src de ese fotograma es compositions/frames/04-proof.html, aquí se escribe 04-proof. La duración de cada segmento la determina la locución, no se especifica aquí.

Qué diapositivas merecen animación (2–4 en total, cada segmento de 15–25 segundos): aquellas donde "el cambio en el tiempo" es el núcleo del contenido.

AdecuadoEjemplo
Deducciones, demostraciones, procesosDemostración con rompecabezas, reacción química, trayectoria de la luz
Acumulación o comparación de cantidadesContar cuadrados 9 + 16 = 25, crecimiento de una barra
Inversión de conceptos erróneosAfirmación falsa → tachada → corregida
Relaciones espacialesRotación, traslación, desarrollo, cuadrado inclinado

No adecuado: definiciones, tablas, ejercicios, resúmenes. Estas diapositivas usarán el diseño visual de SOIL.

3. Escribir el Guion del Video a partir del Flujo de la Presentación (Transición)

Los fotogramas del video siguen el flujo de la presentación. Primero, en BRIEF.md del proyecto de video, escribir una tabla de correspondencia; aquí se deciden los nombres de archivo:

Diapositiva de la presentaciónFotograma del video (nombre de archivo)Qué debe decir la locuciónPropósito
2 Introducción del problema01-ladderProblema contextual del motor 1Solo en el video
🎬 302-squaresÚnico punto principal de esta diapositivaSe recorta como p03
4–5 Concepto03-namesConcepto general + términosSolo en el video
🎬 604-proofÚnico punto principal de esta diapositivaSe recorta como p06
…………
13 Conclusión07-takeaway"La frase para llevar" del motor 1Solo en el video

Los nombres de los fragmentos recortados usan p + número de dos dígitos (p03, p06), y deben coincidir con los nombres usados en build_deck.js (video(s, "p06", …)).

Luego, escribir SCRIPT.md según el formato de motion-explainer (un ## Line N por fotograma) y STORYBOARD.md (el src de cada fotograma usando los nombres de la tabla anterior). El material para la locución se toma directamente de la salida de SOIL:

  • "Tres conceptos erróneos comunes" del motor 1 → las tres líneas de locución del fotograma de inversión de conceptos.
  • "La frase para llevar" del motor 1 → la locución del último fotograma, sin cambios; la diapositiva de conclusión de la presentación usará la misma frase.
  • Cada 🎬 "único punto principal" → la última línea de locución de ese fotograma.
  • Estimar duración: 4–4.5 caracteres chinos por segundo. La locución de un fotograma 🎬 debe tener entre 70 y 100 caracteres (15–25 segundos).

Al enviar los fotogramas 🎬 al worker, en _dispatch_context.md añadir estas cuatro reglas (se aplican de forma independiente, ya que el fragmento se reproducirá sin sonido ni subtítulos):

  1. Que se entienda solo con las imágenes: los números clave, etiquetas y conclusiones deben escribirse en la pantalla, no solo en la locución.
  2. Empezar desde cero y terminar en la conclusión: el estado final debe estar completo y estático al menos 1 segundo, porque será la portada de la diapositiva.
  3. No poner contenido importante en la zona de subtítulos (y > 896 px): los subtítulos del video lo taparían; aunque en la presentación no haya subtítulos, el mismo fotograma debe servir para ambos.
  4. Las transiciones entre fotogramas (misma escalera, mismo triángulo) se hacen normalmente; al recortar se eliminarán automáticamente las partes solapadas.

A continuación, seguir completamente el flujo de motion-explainer: locución → cámara → cada fotograma (con sub-agentes en paralelo si están disponibles, secuencialmente si no) → ensamblaje, subtítulos, combinación de colores → borrador → revisión → exportación de B.

4. Gemelo Silencioso → Recortar Fragmentos 🎬

Usar rutas absolutas o ejecutar desde la misma carpeta; a continuación, $FILM representa la ruta completa del proyecto de video:

python <smd>/scripts/make_silent.py --project "$FILM"            # Crear $FILM-silent: eliminar todas las pistas de audio y subtítulos
(cd "$FILM-silent" && npx hyperframes render --quality high --output renders/silent.mp4)
python <smd>/scripts/cut_clips.py --project "$FILM" --video "$FILM-silent/renders/silent.mp4" \
    --map p03=02-squares p06=04-proof p09=06-myths@first --out "$FILM/deck/media"
  • cut_clips.py lee el inicio y la duración de cada fotograma en index.html, y recorta desde el final de la superposición con el fotograma anterior hasta el inicio de la superposición con el siguiente. Independientemente de si la transición es crossfade, push-slide o zoom-through, no se mezclarán fotogramas adyacentes. Imprime la duración de cada segmento y la escribe en las notas del orador.
  • La imagen de portada por defecto es el último fotograma (detenido en la conclusión). Para especificar por segmento, añadir @first o @segundos después del nombre en --map (ej. [email protected]). Para páginas de conceptos erróneos donde no se quiere revelar la respuesta antes de tiempo, usar @first.
  • Cualquier modificación del video (cualquier fotograma, combinación de colores, duración): volver a ejecutar make_silent.py, exportar y cut_clips.py. El gemelo es una instantánea; no se actualiza automáticamente.

5. Crear la Presentación (Motores SOIL 4–6)

  1. Ejecutar el motor 4 (edición cognitiva) y el motor 5 (estilo) según las reglas de SOIL. En el motor 5, usar la combinación de colores elegida en el paso 1.
  2. Crear la carpeta de la presentación. Usar obligatoriamente el package.json de esta skill: el package.json raíz del proyecto de HyperFrames tiene "type": "module"; si no tiene su propio package.json, require fallará.
mkdir -p "$FILM/deck" && cp <smd>/templates/package.json <smd>/templates/deck_helpers.js "$FILM/deck/"
cp <smd>/templates/example_pythagoras.js "$FILM/deck/build_deck.js"     # Partir del ejemplo
(cd "$FILM/deck" && npm install)
  1. Modificar build_deck.js. El inicio debe escribirse así. Usar siempre LAYOUT_WIDE (13.333 × 7.5 pulgadas): la referencia rápida de PptxGenJS de SOIL usa LAYOUT_16x9 (10 pulgadas de ancho) y la fuente Microsoft JhengHei; aquí no copiar eso, las coordenadas de deck_helpers.js están diseñadas para 13.333 pulgadas de ancho. Las fuentes siguen las reglas de SOIL: título GenSekiGothic2 TW H, cuerpo GenSekiGothic2 TW M.
const path = require("path");
const pptxgen = require("pptxgenjs");
const { makeDeck } = require("./deck_helpers");
const pptx = new pptxgen();
pptx.layout = "LAYOUT_WIDE";
const D = makeDeck(pptx, { theme: { bg: "121212", fg: "F2F0EA", accent: "FF7A1A" }, mediaDir: path.join(__dirname, "media") });
const s = D.lightSlide("Proceso・Animación");
D.title(s, "¿Por qué se cumple siempre? Rompecabezas de áreas");
D.video(s, "p06", 0.6, 2.0, 8.0);   // Ventana de reproducción de 8 pulgadas de ancho (16:9) a la izquierda, con un mensaje "Haz clic para reproducir" debajo
// Derecha x = 9.0, ancho 3.9 pulgadas: resumen de los pasos de la animación o puntos clave, para que se entienda incluso sin reproducir
pptx.writeFile({ fileName: path.join(__dirname, "NombreUnidad.pptx") });
  1. Diseño de las diapositivas 🎬: izquierda con la animación (8.0 × 4.5 pulgadas), derecha con 2–3 líneas de pasos o conclusión. En las notas del orador escribir: duración, dónde detenerse para preguntar a los estudiantes y las respuestas esperadas.
  2. Las demás diapositivas seguir los roles de página y el diseño visual de SOIL. Las respuestas de los ejercicios se escriben en las notas del orador, no en la diapositiva.
  3. node build_deck.js. Si los fragmentos aún no están recortados, video() colocará un recuadro de marcador de posición; se puede diseñar el diseño primero.

El usuario ya tiene una presentación SOIL: PptxGenJS no puede modificar un .pptx existente. Seguir el "modo de diagnóstico y modificación" de SOIL: leer el contenido de cada diapositiva (python -m markitdown <archivo>.pptx, si no hay markitdown, pedir al usuario que pegue el texto), escribir las diapositivas a conservar exactamente como estaban en build_deck.js, convertir las seleccionadas al diseño 🎬 y regenerar todo el archivo. Al entregar, explicar que es un archivo reconstruido, el original no ha sido modificado.

6. Revisión

python <smd>/scripts/thumbs.py "$FILM/deck/<presentación>.pptx" --out "$FILM/deck/thumbs"   # Un PNG por diapositiva + imagen general deck-*.png

No es necesario buscar thumbnail.py (skill pptx) por separado; usar este thumbs.py. Revisar cada diapositiva en la imagen general, comparando con la siguiente lista:

  • La portada de las diapositivas 🎬 es el fotograma de la animación, no un marco negro ni texto de marcador de posición.
  • La ventana de animación no está cubierta por texto ni gráficos; el mensaje de reproducción debajo es visible.
  • Cada diapositiva tiene un único punto principal; estructura sándwich (portada, acción y conclusión oscuras; contenido claro).
  • El color de énfasis de la presentación y del video es de la misma gama (en páginas claras se puede usar un tono más oscuro del mismo color, ej. #E8601A combinado con #FF7A1A del video); los números y términos son coherentes en ambos.
  • Las notas del orador incluyen duración, lugares para detenerse y preguntar, y respuestas.
  • Las respuestas de los ejercicios se han calculado una vez.
  • La revisión del video B se ha realizado según review-loop (capturar un fotograma de cada cláusula y revisarlos uno por uno).

7. Entrega

Entregar las rutas del .pptx y del MP4, y explicar:

  • Las diapositivas 🎬 son cuáles, cuántos segundos cada una y qué fotograma se usó como portada.
  • El ordenador de reproducción debe tener instalada la fuente GenSekiGothic2 (.pptx no incrusta fuentes; si no está instalada, se usará la fuente del sistema).
  • El video ya está incrustado en el .pptx; se puede reproducir directamente en PowerPoint y Keynote. Al importar en Google Slides, es posible que no se conserven los videos incrustados; si se usa Google Slides, subir media/*.mp4 a Drive e insertar el video.
  • Pedir al usuario que escuche la locución (el ASR no distingue tonos). Las palabras mal pronunciadas se corrigen con fix_voice.py de motion-explainer; después de corregir, hay que recortar los fragmentos y reconstruir la presentación.

references/lessons.md contiene los problemas encontrados durante la primera implementación (Teorema de Pitágoras, 13 diapositivas, 3 animaciones, video de 110 segundos).

Skills relacionados