SOIL Presentación Animada: Una Creación, Dos Productos
| Producto | Contenido | Para 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 proyecta | Clase presencial |
| B Video (MP4) | Mismo contenido, versión completa narrada: locución, subtítulos, tema de tres colores | Repaso, 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 asociadasmotion-design,review-loopy 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ódigo | Qué es | Ubicació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-explainer | Misma, carpeta llamada motion-explainer |
<soil> | Carpeta de la skill SOIL | Misma, 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.jsonde esta skill, ver §5), fuente GenSekiGothic2 H / B / M (instalar según F-0 de SOIL). - Miniaturas: PowerPoint en Windows es lo mejor (
thumbs.pylo 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)
- Asignatura, unidad, audiencia, tiempo de clase (pregunta adicional de SOIL).
- 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.
- 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.
- Video (y ventana de animación en la presentación): tres colores de motion-explainer, por defecto fondo negro
- 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.
| Adecuado | Ejemplo |
|---|---|
| Deducciones, demostraciones, procesos | Demostración con rompecabezas, reacción química, trayectoria de la luz |
| Acumulación o comparación de cantidades | Contar cuadrados 9 + 16 = 25, crecimiento de una barra |
| Inversión de conceptos erróneos | Afirmación falsa → tachada → corregida |
| Relaciones espaciales | Rotació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ón | Fotograma del video (nombre de archivo) | Qué debe decir la locución | Propósito |
|---|---|---|---|
| 2 Introducción del problema | 01-ladder | Problema contextual del motor 1 | Solo en el video |
| 🎬 3 | 02-squares | Único punto principal de esta diapositiva | Se recorta como p03 |
| 4–5 Concepto | 03-names | Concepto general + términos | Solo en el video |
| 🎬 6 | 04-proof | Único punto principal de esta diapositiva | Se recorta como p06 |
| … | … | … | … |
| 13 Conclusión | 07-takeaway | "La frase para llevar" del motor 1 | Solo 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):
- 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.
- 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.
- 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.
- 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.pylee el inicio y la duración de cada fotograma enindex.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
@firsto@segundosdespué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 ycut_clips.py. El gemelo es una instantánea; no se actualiza automáticamente.
5. Crear la Presentación (Motores SOIL 4–6)
- 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.
- Crear la carpeta de la presentación. Usar obligatoriamente el
package.jsonde esta skill: elpackage.jsonraíz del proyecto de HyperFrames tiene"type": "module"; si no tiene su propiopackage.json,requirefallará.
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)
- Modificar
build_deck.js. El inicio debe escribirse así. Usar siempreLAYOUT_WIDE(13.333 × 7.5 pulgadas): la referencia rápida de PptxGenJS de SOIL usaLAYOUT_16x9(10 pulgadas de ancho) y la fuente Microsoft JhengHei; aquí no copiar eso, las coordenadas dedeck_helpers.jsestán diseñadas para 13.333 pulgadas de ancho. Las fuentes siguen las reglas de SOIL: títuloGenSekiGothic2 TW H, cuerpoGenSekiGothic2 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") });
- 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.
- 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.
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.
#E8601Acombinado con#FF7A1Adel 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/*.mp4a 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.pyde 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).