explainer-video-pipeline (generado automáticamente)
Cuándo usar
El usuario quiere un video explicativo narrado de 1 a 3 minutos sobre un tema (ciencia, un producto, una tecnología), entregado como un MP4 con voz en off, subtítulos, música y efectos de sonido.
Parámetros y valores predeterminados
Pregunta solo por el tema; toma todos los demás valores predeterminados a menos que el usuario especifique un valor. Indica en una línea qué valores usaste.
| Parámetro | Valor predeterminado | Otros valores |
|---|---|---|
topic | requerido | — |
storyboard_model | claude-opus-5.5 escribe el guion, la narración y el storyboard | cualquier ID de modelo de kiro-cli chat --list-models |
video_engine | opus-5.5: claude-opus-5.5 escribe cada escena como código que dibuja cada fotograma | otro modelo de código, p. ej. claude-sonnet-5.5; seedance (API de BytePlus ModelArk, necesita ARK_API_KEY); hybrid (clips de Seedance dentro de escenas dibujadas con código) |
renderer | remotion (React/SVG; Remotion maneja Chromium sin interfaz gráfica fotograma a fotograma) | html (Canvas 2D / SVG / GSAP / página p5.js, capturada con Playwright); manim (escenas de Manim Community; ideal para geometría, gráficos, vectores y derivaciones paso a paso) |
seedance_model | seedance-1-5-pro-251215 | cualquier modelo Seedance habilitado en la cuenta de ModelArk del usuario |
tts | polly, voz neural Zhiyu, cmn-CN, us-east-1 | gtts (gratuito, sin clave, voz más plana); cualquier otra voz/idioma de Polly |
captions | activado: temporización de palabras Whisper, incrustadas como subtítulos resaltados palabra por palabra | desactivado |
whisper_model | small (CPU, int8; aproximadamente 5 s para 10 s de habla) | base (más rápido), medium (temporización más precisa) |
music | synth (base de oscilador libre de regalías hecha con ffmpeg) | none; una ruta a un archivo de música que el usuario posee |
sfx | activado: los eventos listados en scenes.json se sintetizan y colocan en sus fotogramas | desactivado: omitir sfx en cada escena |
language | Narración en mandarín | cualquier idioma que admitan Polly y Whisper |
size, fps | 1920×1080, 30 fps | 1080×1920 para vertical |
"Hecho con Opus 5.5" significa que Opus 5.5 es el autor: escribe el guion y el código de dibujo, y un renderizador convierte ese código en píxeles. Ningún modelo de texto genera video directamente; solo Seedance lo hace. Di esto una vez en la primera respuesta.
Si la sesión ya se ejecuta en claude-opus-5.5, haz la escritura tú mismo.
De lo contrario, genera una tarea con model="claude-opus-5.5" y keep=true para el storyboard (paso 2) y continúa la misma ejecución con spawn_continue para el código de escena (paso 5), luego revisa su salida tú mismo.
Configuración (una vez por máquina)
Mantén las herramientas en un directorio de caché estable (p. ej. ~/.cache/explainer-video/), nunca en $KIROCREW_SCRATCH, que se recupera entre sesiones.
- ffmpeg: una compilación estática completa con
aevalsrc,anoisesrc,tremolo,sidechaincompressyass/libass. El ffmpeg incluido de Remotion carece de ellos. ApuntaFFMPEG/FFPROBEa él. - Entorno virtual Python (
boto3 gTTS playwright faster-whisper pillow numpy), luegopython -m playwright install chromium-headless-shelldesde ese entorno virtual. faster-whisper 1.2.x falla con PyAV 19 (unexpected keyword argument 'metadata_errors'): fijaav==16.1.0. EstableceHF_HOMEen el directorio de caché para que el modelo Whisper se descargue una sola vez. - Manim (solo para
renderer=manim): pip no puede compilarlo en aarch64 (no hay ruedas para pycairo, manimpango, moderngl). Sin root, usa micromamba:micromamba create -p <cache>/manim-env -c conda-forge python=3.12 manim.Text()con una fuente CJK funciona.MathTex/Texnecesitan una distribución LaTeX másdvisvgm;texlive-corede conda-forge en aarch64 no tienelatex.fmt, por lo que las fórmulas fallan allí. Escribe fórmulas conText()(Unicode: F = m·a, x², √, →), o instala un TeX Live del sistema donde el usuario pueda.
Pasos
Los helpers están en la carpeta scripts/ de esta habilidad.
- Proyecto. Crea una carpeta de proyecto en un repositorio git dentro del espacio de trabajo del usuario. Para
renderer=remotion, crea manualmentepackage.json,tsconfig.json(resolveJsonModule: true),src/index.ts,src/Root.tsxy ejecutanpm i remotion @remotion/cli react react-dom. - Guion y storyboard (por
storyboard_model). Escribescenes.json: un objeto por escena conid,narration(la línea hablada),visual(lo que se ve en pantalla), opcionalmentemanim(nombre de la clase Scene) y opcionalmentesfx:[{"at": FOTOGRAMA_EN_ESCENA, "kind": "whoosh|hiss|pop|rise|thud|PATH"}]. Usa 6–10 escenas, una idea cada una, con una escena de título y una tarjeta final. Verifica los hechos con búsqueda web y cita las fuentes en el README. - Imágenes de referencia. Cuando el video muestre un objeto real, pide o busca una foto clara y guárdala en
ref/. Nunca dibujes la forma de un objeto real de memoria: ejecuta detección de bordes en la foto, mide puntos clave y genera las formas a partir de esos puntos con un pequeño script guardado en el repositorio. - La narración marca el tiempo. Ejecuta
narrate.py scenes.json . --tts polly. Escribedurations.json(fotogramas por escena, calculados a partir de la longitud real de la voz más relleno),narration.wavyaudio/sNN.mp3. El código de la escena leedurations.json, por lo que cada escena dura exactamente lo que dura su línea. - Código de escena (por
video_engine).remotion: un componente React por escena, animado conuseCurrentFrameeinterpolate/springrelativas al inicio de la escena.html: unindex.htmlconwindow.seek = async (frame) => {...}que dibuja exactamente ese fotograma a partir del número de fotograma y el array dedurations.json. SinrequestAnimationFrame, sin reloj de pared, sinMath.randomsin semilla. Pega el array dedurations.jsonen la página como una constante: una página abierta comofile://no puedefetch()un archivo local, y el fallo es silencioso. GSAP: línea de tiempo pausada +tl.seek(frame / fps). p5.js:noLoop()+redraw()enseek.manim: unscenes.pycon una clase Scene por escena. Lee la longitud objetivo deos.environ["SCENE_SECONDS"]y termina conself.wait(max(0.04, secs - self.renderer.time)); dimensiona las animaciones largas desdesecstambién. Mantén el 15% inferior del fotograma libre para subtítulos.seedance:seedance_clips.py scenes.json .conARK_API_KEYconfigurada; descargaclips/<id>.mp4(las URL caducan después de 24 h).
- Verifica fotogramas congelados antes de la renderización completa. Renderiza 4–6 fotogramas, uno por escena clave, combínalos en una hoja de contacto reducida y mira esa sola imagen. Para una verificación independiente, genera un revisor nuevo con solo la hoja y
scenes.json. - Sonido. Si alguna escena tiene
sfx, ejecutasfx.py scenes.json .. Luegomix_bgm.py . --music <music>: atenúa la música debajo de la voz, añadesfx.wav, escribenarration_bgm.wavy muestra los niveles RMS. La introducción solo con música debe estar entre −20 y −30 dB; −55 dB o menos significa que es inaudible. - Subtítulos.
captions.py scenes.json . --size <WxH>transcribe cada línea con marcas de tiempo de palabras de faster-whisper y las asigna a los caracteres del propio guion, porque Whisper malinterpreta homófonos (oyó 气体 como 漆体). Escribecaptions.ass(cada carácter se resalta cuando se habla) ywords.json(tiempos por carácter, utilizables para énfasis en pantalla en el paso 5). - Renderizar (imagen silenciosa).
remotion:npx remotion render src/index.ts <Comp> out/silent.mp4.html:capture_html.py index.html out/silent.mp4 --frames <suma de durations.json>.manim:manim_scenes.py scenes.py . --manim <manim-env>/bin/manim --quality h. Renderiza cada clase y la rellena o recorta exactamente a su recuento de fotogramas.
- Componer con FFmpeg. Con subtítulos:
ffmpeg -i silent.mp4 -i narration_bgm.wav -vf "ass=captions.ass" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 192k -shortest final.mp4. (Sin subtítulos, usa-c:v copyy omite-vf). Verifica que las duraciones de video y audio coincidan dentro de aproximadamente 0.1 s, luego extrae 4–5 fotogramas del MP4 final y revísalos, incluyendo uno a mitad de frase para ver el resaltado del subtítulo. - Entregar. Confirma en una rama de características, abre un PR y, después de fusionar, confirma con
gh api repos/<o>/<r>/git/trees/<base>?recursive=1que los archivos llegaron.
Gotchas
- Nunca pongas comentarios
/* */dentro de una cadena de atributod=de una ruta SVG; Chromium deja de analizar en la/. Usa colores hexadecimales de 6 dígitos. - El código con números de fotograma absolutos codificados puede colocar un clímax después de que termine su escena.
- En Manim, posiciona las etiquetas y flechas después de que el objeto se haya movido (o fíjalas con
always_redraw/add_updater), de lo contrario se quedan en el lugar antiguo.DashedVMobjectno tiene puntos propios: toma posiciones de una forma simple. - Un Playwright instalado con pip puede querer una compilación de Chromium más reciente que la almacenada en caché.
- No edites un archivo con varias llamadas
strReplaceparalelas; las ediciones se pierden. No escribas código a través de heredocs de shell; las protecciones pueden bloquearlos. - Los modelos Seedance 2.x necesitan activación de cuenta y rechazan imágenes de referencia con rostros humanos reales. Los clips de Seedance 1.5 pro son de 4 a 12 s.
- Licencia de Remotion: gratuita para individuos y empresas de hasta 3 personas; las empresas más grandes necesitan una Licencia de empresa paga.
htmlymanimlo evitan.