¿Qué hace remotion-demo-video?
Un flujo de trabajo destilado para construir videos promocionales, demo o trailer con Remotion 4.x. Codifica la disposición del proyecto, las primitivas de animación, los comandos de renderizado y las dificultades específicas que cuestan tiempo real al redescubrirlas.
Cuándo recurrir a esta habilidad
Actívala cada vez que el usuario quiera crear, editar, renderizar o depurar un video de Remotion. Especialmente:
- Iniciar un nuevo proyecto de Remotion para una demo de producto / artículo / repositorio
- Añadir una nueva escena a un proyecto existente de Remotion
- Unir capturas de pantalla pre-grabadas en un video pulido con superposiciones, títulos y transiciones
- Renderizar: escena individual, línea de tiempo completa, superposiciones transparentes (alfa), secuencias PNG
- Depurar rarezas específicas de Remotion (desajuste de ID de composición, valores predeterminados desincronizados,
useCurrentFramedevolviendo valores inesperados dentro de<Sequence>, error EPERM de Windows durante la limpieza de ffmpeg, etc.)
Cómo pensar en el flujo de trabajo
Un video pulido de Remotion no es "una línea de tiempo gigante que renderizas como un solo MP4". Es un conjunto de escenas pequeñas e individualmente renderizables, cada una renderizada como su propio clip y ensamblada en un editor downstream (DaVinci Resolve, Premiere, Final Cut) donde añades música, locución y transiciones entre escenas.
Esta es la comprensión más importante al enviar la promoción de SimWorld, y la habilidad debe empujar al usuario hacia este flujo de trabajo por defecto. Intentar hacer todo dentro de Remotion (ajustes finales de tiempo, mezcla de audio, fundidos) es doloroso y lento; hacerlo en un editor es trivial.
Usa cada herramienta para lo que es buena
- Remotion es excelente para: escenas programáticas, repetibles y paramétricas: títulos animados, gráficos basados en datos, maquetas de UI, cualquier cosa que de otro modo animarías manualmente en After Effects. La lógica de la escena vive en el código; reconstruir "el mismo título con 30 nombres de producto diferentes" es un cambio de propiedad.
- Los editores downstream son excelentes para: tiempo, audio, fundidos, gradación de color, "hacer esta escena 1,2 segundos más larga". Todo lo que es inmediato en un editor y una edición de código y re-renderizado en Remotion.
El bucle
- Decide el guion. Esquema paso a paso con segundos objetivo para cada paso. Total típicamente 30–90s.
- Configura el shell del proyecto una vez.
theme.ts(paleta, fuentes, fps, dimensiones),Root.tsx(registro de composición), componentes compartidos (Reveal,ProgressBar, funciones de easing). - Construye escenas una a la vez. Cada escena es un componente React
<AbsoluteFill>autocontenido, diseñado contraframe 0, con su propio<Composition>independiente para que puedas renderizarlo solo. Itera en Studio (npm run dev) con el panel de propiedades; renderiza a MP4 (npm run render:<scene>) cuando te guste. - Renderiza cada escena terminada como su propio clip — este es el entregable real, no el MP4 de la línea de tiempo completa. Los clips por escena se arrastran a la línea de tiempo de cualquier editor. Usa
--codec=prores --pixel-format=yuva444p10le --prores-profile=4444para clips que quieras con alfa (tercios inferiores, logotipos para componer sobre capturas de pantalla). - Opcionalmente, conecta las escenas en
Main.tsxcon bloques<Sequence>que lean de una constanteTIMELINEentheme.ts. Esto te da una vista previa de la línea de tiempo completa (npm run render) para verificar el flujo general, pero trátala como una vista previa, no como el máster. - Ensambla en DaVinci / Premiere / Final Cut. Suelta los clips por escena en una pista en orden, ajusta los tiradores de recorte para el tiempo exacto, añade música / locución / diseño de sonido, aplica transiciones entre escenas (los fundidos de 1 cuadro suelen sentirse bien para esta estética), gradación de color, exporta.
Cuándo sugerir el renderizado completo de Remotion
El renderizado de la línea de tiempo completa es la salida correcta SOLO cuando:
- El usuario no tiene un editor downstream y necesita un único entregable hoy.
- El video es completamente silencioso (sin música ni locución).
- No hay transiciones entre escenas más complejas que cortes directos (e incluso esos son más fáciles de ajustar en código con el enfoque escena por escena).
De lo contrario, por defecto recomienda renderizados por escena + ensamblaje en editor.
Esta habilidad incluye un andamio funcional en scaffold/ — cópialo como punto de partida para un nuevo proyecto, luego lee las referencias a continuación según las necesites.
El bucle real de principio a fin (cuando la entrada es un artículo / especificación / repositorio)
Este es el flujo de trabajo para el que realmente está diseñada esta habilidad. El usuario normalmente no llega diciendo "Quiero un título animado que diga X". Llega con un PDF de un artículo, una especificación de proyecto o un repositorio existente, y la pregunta es "convierte esto en un video de 60 segundos". La habilidad existe para hacer que ese bucle sea rápido y manejable.
1. Material fuente → PDF de artículo / especificación / repositorio existente / README
↓
2. Claude analiza → extrae los pasos narrativos; identifica lo que cada
paso necesita MOSTRAR (pantalla de UI, grabación de
experimento, gráfico, punto de vista del agente, etc.)
↓
3. Claude crea andamio → código de escena + <VideoPlaceholder slot="..." />
con marcadores de posición en cada región visual, más un ASSETS.md
que enumera cada clip que el usuario necesita grabar
(nombre del slot, duración, lo que debe mostrar)
↓
4. El usuario graba material → coloca mp4 en public/clips/<slot>.mp4
de archivo coincidiendo con los nombres de slot del andamio
↓
5. Claude reemplaza → reemplaza <VideoPlaceholder> con
marcadores por clips <OffthreadVideo src={staticFile("clips/<slot>.mp4")}>
↓
6. Iterar escena por escena → npm run render:<scene>, observar, ajustar texto /
tiempo / animación, re-renderizar. Los cambios del lado
del código son rápidos; si el material necesita regrabación,
esa es la parte más lenta del bucle.
↓
7. Ensamblar en editor → MP4 por escena en DaVinci / Premiere / FCP,
añadir música + locución + transiciones entre
escenas, exportar.
Paso 2 en detalle: analizar el material fuente
Cuando el usuario entrega un artículo / especificación, haz esto ANTES de escribir cualquier código:
- Extrae la narrativa. ¿Cuál es el arco de 3–5 pasos? ("Problema → nuestro método → resultados clave → impacto" es una plantilla inicial; varíala para el artículo real.) La narrativa impulsa la lista de escenas.
- Para cada paso, decide qué MOSTRAR. El texto animado por sí solo es aburrido. Cada paso debe tener una visual concreta: una pantalla de UI, una grabación de experimento, un gráfico, una comparación, un diagrama de sistema. Iguala las visuales a las afirmaciones: si el artículo afirma que "el método X es 3 veces más rápido", muestra la comparación de tiempos.
- Distingue lo que genera Remotion de lo que el usuario tiene que grabar. Remotion es excelente para: títulos, transiciones, gráficos, maquetas de UI, diseños, diagramas animados. Remotion NO PUEDE generar: grabaciones de pantalla reales del producto del usuario, material de experimentos, punto de vista del agente, nada de fuera del proyecto. Enumera esos como material proporcionado por el usuario.
- Diseña la línea de tiempo antes de crear el andamio. Paso a paso con duraciones objetivo que sumen 30–90s. Actualiza
TIMELINEentheme.tspara que coincida. La longitud total debe decidirse antes de construir las escenas para que cada escena conozca su presupuesto.
Paso 3 en detalle: crear andamio con marcadores de posición
La convención clave de entrega de la habilidad: nombres de slot. Cada clip que el usuario necesita grabar obtiene una cadena slot estable. El marcador de posición y el clip real comparten ese nombre de slot.
// Durante la creación del andamio:
<VideoPlaceholder
slot="agent-loop"
description="Grabación continua del agente: camina, falla, reintenta con política actualizada."
accent={COLORS.blue}
/>
// Después de que el usuario grabe public/clips/agent-loop.mp4, cambia a:
<OffthreadVideo
src={staticFile("clips/agent-loop.mp4")}
muted
style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }}
/>
Escribe siempre un ASSETS.md en la raíz del andamio (el andamio incluye una plantilla). Enumera cada slot que el usuario necesita llenar, con: nombre del slot (= nombre de archivo), lo que debe mostrar, duración objetivo, recomendación de relación de aspecto y cualquier nota de tiempo (por ejemplo, "evento de fallo alrededor del segundo 7"). Esta es la única fuente de verdad para la tarea de grabación del usuario.
Pasos 4–5 en detalle: la entrega de activos
El usuario regresa con archivos colocados en public/clips/. Tres cosas que verificar:
- Los nombres de archivo coinciden exactamente con los nombres de slot.
agent-loop.mp4, noagent_loop.mp4niAgentLoop.mp4. - La duración es al menos la longitud de la escena (o usa
<Loop>si es más corta y está destinada a repetirse). - La relación de aspecto es sensata: para escenas de pantalla completa, coincide con la composición de 1920×1080. Para tarjetas en una cuadrícula de 2×2, tanto 4:3 como 16:9 funcionan; solo sé consistente.
Luego reemplaza mecánicamente cada <VideoPlaceholder> con <OffthreadVideo>. Eso es un intercambio de una línea por slot; no cambia la lógica de animación. Si la grabación del usuario es sensible al tiempo (por ejemplo, "evento de fallo a los 7s"), exponlo como una propiedad de la escena para que las superposiciones dependientes del tiempo (sello de FALLO, número de recompensa) se puedan ajustar sin regrabar.
Por qué este bucle es importante para la habilidad
El trabajo de la habilidad no es "escribir código de Remotion bajo demanda" — es hacer que el bucle de material fuente a video enviado sea manejable. El patrón de marcador de posición es lo que permite a Claude estructurar todo un video en un solo paso, y luego devolver un ASSETS.md para que el usuario sepa exactamente qué grabar. Sin él, el bucle se estanca: el usuario graba las cosas equivocadas, o la creación del andamio espera el material, o la estructura del código tiene que ser adaptada después del hecho.
Cuando un usuario llega con material fuente, el movimiento de apertura correcto suele ser:
"Déjame leer el artículo / especificación primero. Luego propondré un esquema escena por escena con duraciones objetivo, una lista de clips que necesitarás grabar y crearé el andamio del código con marcadores de posición para que puedas empezar a grabar mientras yo sigo construyendo escenas."
Inicio rápido para un nuevo proyecto
# 1. Copia el andamio
cp -r <directorio-de-habilidad>/scaffold ./mi-demo
cd mi-demo
npm install
# 2. Abre Remotion Studio para edición en vivo
npm run dev # abre http://localhost:3000
# 3. Renderiza una sola escena mientras iteras
npm run render:apertura
# 4. Renderiza la línea de tiempo completa cuando esté listo
npm run render
El andamio incluye una escena funcional (OpeningTitle), el tema cálido crema, Reveal + funciones de easing, una ProgressBar, una línea de tiempo Main con marcador de posición y un package.json con scripts de renderizado pre-configurados.
Disposición del proyecto (la forma que funciona)
mi-demo/
├── package.json # scripts de renderizado, ganchos de pre-renderizado
├── remotion.config.ts # valores predeterminados de códec / formato de píxel
├── tsconfig.json
├── public/
│ ├── assets/ # logotipos, imágenes estáticas (staticFile("assets/..."))
│ └── clips/ # capturas de pantalla / fuentes de video
├── scripts/
│ └── sync-clips.mjs # normaliza clips antes de cada renderizado
└── src/
├── index.ts # registerRoot(Root)
├── Root.tsx # registro de <Composition> — id, esquema, defaultProps
├── theme.ts # COLORS, FONT_STACK, RADIUS, SHADOWS, TIMELINE
├── fonts.ts # @remotion/google-fonts + @font-face local
├── Main.tsx # compositor de línea de tiempo completa (bloques <Sequence>)
├── components/
│ ├── Reveal.tsx # envoltorio de fundido + elevación (retraso/duración/elevación)
│ ├── Easing.ts # EASE_OUT, EASE_IN_OUT (curva bezier)
│ ├── ProgressBar.tsx # indicador de etapa de 4 etapas anclado en la parte inferior
│ └── VideoPlaceholder.tsx # tarjeta gris con etiqueta de slot, cambia a OffthreadVideo más tarde
└── scenes/
├── OpeningTitle.tsx # una escena por archivo, cada una es un <AbsoluteFill>
├── ProductReveal.tsx
├── AgentLoop.tsx
└── ...
Por qué esta forma: las escenas son independientes (fáciles de renderizar solas e iterar), el lenguaje visual compartido vive en theme.ts + components/ para que la apariencia se mantenga consistente, y Root.tsx es la única fuente de verdad sobre lo que se puede renderizar.
El patrón de composición (léelo con atención)
Cada escena exporta tres cosas:
- Un esquema Zod — define la interfaz de usuario del panel de propiedades en Remotion Studio (deslizadores, menús desplegables).
- Una constante
*_DEFAULTS— los valores consumidos porMain.tsxcuando esta escena está incrustada en la línea de tiempo completa. - El propio componente React, tipado como
React.FC<Props>.
// src/scenes/ProductReveal.tsx
import { z } from "zod";
export const productRevealSchema = z.object({
titleSize: z.number().min(40).max(280),
subtitleSize: z.number().min(14).max(80),
outerPaddingV: z.number().min(0).max(200),
});
export type ProductRevealProps = z.infer<typeof productRevealSchema>;
export const PRODUCT_REVEAL_DEFAULTS: ProductRevealProps = {
titleSize: 168,
subtitleSize: 64,
outerPaddingV: 80,
};
export const ProductReveal: React.FC<ProductRevealProps> = (p) => { ... };
Luego en Root.tsx, regístralo con una copia en línea de los valores predeterminados:
<Composition
id="ProductReveal"
component={ProductReveal}
durationInFrames={120}
fps={30}
width={1920}
height={1080}
schema={productRevealSchema}
defaultProps={{
// ⚠ COPIA EN LÍNEA de PRODUCT_REVEAL_DEFAULTS — el botón
// "Guardar propiedades predeterminadas" de Remotion Studio escribe
// de nuevo en este objeto mediante manipulación del AST. Mantén
// sincronizado con la constante exportada anterior.
titleSize: 168,
subtitleSize: 64,
outerPaddingV: 80,
}}
/>
Por qué la duplicación: El botón "Guardar propiedades predeterminadas" de Remotion Studio edita el literal defaultProps={…} en Root.tsx mediante manipulación del AST. No puede reescribir una constante importada. Por lo tanto, la copia en línea es la que Studio muta, y la constante exportada *_DEFAULTS es la que lee Main.tsx. Cuando Studio escribe nuevos valores, cópialos a la constante exportada para que el renderizado de la línea de tiempo completa también los use. Este es el escollo #4 en references/pitfalls.md.
Primitivas de animación (el pequeño conjunto que realmente necesitas)
Toda la animación en Remotion es useCurrentFrame() + interpolate(). No hay reloj interno, no hay "reproducir" — cada cuadro es una función pura de frame.