Communitygithub.com

carissadarmafissaleha/remotion

Guía maestra integral para la creación programática de videos en React con Remotion. Diseña, ensambla, anima, sincroniza narración/voiceover y renderiza videos de motion graphics profesionales (explicativos 16:9, verticales 9:16 para TikTok/Reels) de forma programática usando React, Remotion 4.x, física de resortes, GSAP, Tailwind/CSS y renderizado acelerado por hardware desde la CLI. Utiliza esta habilidad cada vez que el usuario solicite crear un video con Remotion, renderizar un MP4, hacer tipografía cinética, transiciones de escena (Series/TransitionSeries), sincronización de voz en off u optimización del rendimiento de renderizado.

¿Qué es remotion?

Esta habilidad de agente de IA proporciona una guía maestra completa y detallada para la creación programática de videos utilizando Remotion y React. Está diseñada para desarrolladores y creadores que desean producir videos cinemáticos de alta calidad, como videos explicativos 16:9, verticales para TikTok/Reels, tipografía cinética y motion graphics, todo a través de código React. La habilidad cubre la configuración de la composición raíz, el uso de primitivas de línea de tiempo como Sequence y Series para la sincronización de escenas, y la implementación de animaciones realistas con las funciones spring() e interpolate(). También incluye guías para sincronizar voz en off con audio, manejar activos asincrónicos con delayRender, y ejecutar renders optimizados desde la línea de comandos con aceleración por hardware. El objetivo es permitir la creación de videos complejos de forma programática, evitando errores comunes y maximizando la eficiencia del renderizado.

Compatible con~Claude Code~Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/carissadarmafissaleha/office-nara/tree/main/skills/remotion

Preguntar en tu IA favorita

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

Documentación

Guía Maestra de Remotion — Creación Programática de Videos en React

Remotion permite la creación de videos cinematográficos con código React puro. Cada fotograma del video se trata como un estado determinista (frame) => UI, generando visuales perfectos a 60 FPS sin tirones ni caídas de fotogramas.


1. Arquitectura de Composición y Configuración Raíz

A. Punto de Entrada Raíz (Root.tsx)

import { Composition } from 'remotion';
import { MainExplainer } from './compositions/MainExplainer';
import { VerticalShort } from './compositions/VerticalShort';

export const RemotionRoot: React.FC = () => {
  return (
    <>
      {/* Explicativo Cinemático 16:9 */}
      <Composition
        id="MainExplainer-1080p"
        component={MainExplainer}
        durationInFrames={30 * 32} // 32 segundos @ 30 FPS = 960 fotogramas
        fps={30}
        width={1920}
        height={1080}
        defaultProps={{
          title: 'Misterio del Derretimiento de los Picos de Hielo del Mundo',
          author: 'NARA Studio',
          themeColor: '#f97316',
        }}
      />

      {/* Vertical 9:16 para TikTok / Reels / Shorts */}
      <Composition
        id="VerticalShort-60fps"
        component={VerticalShort}
        durationInFrames={60 * 15} // 15 segundos @ 60 FPS = 900 fotogramas
        fps={60}
        width={1080}
        height={1920}
      />
    </>
  );
};

B. Reglas de Duración y FPS

  • 16:9 YouTube / Explicativo: Recomendación 30 fps (equilibrio entre velocidad de renderizado y suavidad de movimiento) o 60 fps para tipografía cinética ultra nítida.
  • Duración en Fotogramas: Siempre calcula durationInFrames = Math.round(seconds * fps).
  • Sin Tirones: No uses setInterval o setTimeout. Usa siempre useCurrentFrame() y useVideoConfig().

2. Primitivas de Diseño y Línea de Tiempo

AbsoluteFill

Base de toda la capa de la escena. Automáticamente position: absolute; inset: 0; width: 100%; height: 100%;:

import { AbsoluteFill } from 'remotion';

export const SceneBackground: React.FC = () => {
  return (
    <AbsoluteFill style={{ backgroundColor: '#090812', overflow: 'hidden' }}>
      {/* Contenido visual */}
    </AbsoluteFill>
  );
};

Sequence vs Series

  • Sequence: Coloca elementos en un tiempo absoluto (from y durationInFrames). Ideal para audio de fondo, marcas de agua, superposiciones HUD o elementos que se superponen entre sí.
  • Series: Ordena las escenas secuencialmente de forma automática sin necesidad de calcular el desplazamiento de fotogramas manualmente.
import { Series, Sequence, Audio, staticFile } from 'remotion';

export const VideoStory: React.FC = () => {
  return (
    <AbsoluteFill>
      {/* Audio de Música de Fondo a lo Largo del Video */}
      <Audio src={staticFile('audio/ambient_score.mp3')} volume={0.35} />

      {/* Secuencia Automática de Escenas */}
      <Series>
        <Series.Sequence durationInFrames={120}>
          <HookScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={180}>
          <ProblemScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={240}>
          <SolutionScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={150}>
          <CallToActionScene />
        </Series.Sequence>
      </Series>
    </AbsoluteFill>
  );
};

3. Física de Animación: spring() e interpolate()

A. Fórmula de Resorte Natural (spring())

Usa spring() para generar movimientos de física real (elimina la rigidez típica de "PowerPoint"):

import { spring, useCurrentFrame, useVideoConfig } from 'remotion';

const frame = useCurrentFrame();
const { fps } = useVideoConfig();

// 1. Pop Rápido (Texto/Insignia Aparece con Impacto)
const popScale = spring({
  frame,
  fps,
  config: { damping: 10, mass: 0.4, stiffness: 180 },
});

// 2. Desplazamiento Suave (Cámara se Desliza con Suavidad)
const smoothSlide = spring({
  frame,
  fps,
  config: { damping: 20, mass: 1.2, stiffness: 60 },
});

// 3. Caída con Rebote (Icono/Partícula Cae y Rebotan)
const bounce = spring({
  frame: frame - 10, // retraso de 10 fotogramas
  fps,
  config: { damping: 8, mass: 0.6, stiffness: 140 },
});

B. Mapeo de Valores Suave (interpolate())

import { interpolate, Easing } from 'remotion';

// Transición de Alpha y Rotación con Easing Bezier
const opacity = interpolate(frame, [0, 20], [0, 1], {
  extrapolateRight: 'clamp',
});

const rotateY = interpolate(frame, [0, 60], [-45, 0], {
  easing: Easing.bezier(0.16, 1, 0.3, 1),
  extrapolateRight: 'clamp',
});

4. Tipografía Cinética y Sincronización con Voz en Off

A. Revelación de Palabras Escalonada (Texto Aparece Palabra por Palabra)

import React from 'react';
import { useCurrentFrame, useVideoConfig, spring, interpolate } from 'remotion';

interface KineticTextProps {
  sentence: string;
  startFrame?: number;
  wordDelay?: number;
}

export const KineticText: React.FC<KineticTextProps> = ({
  sentence,
  startFrame = 0,
  wordDelay = 4, // 4 fotogramas de separación entre palabras
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const words = sentence.split(' ');

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px', justifyContent: 'center' }}>
      {words.map((word, idx) => {
        const wordStart = startFrame + idx * wordDelay;
        const progress = spring({
          frame: frame - wordStart,
          fps,
          config: { damping: 12, mass: 0.4, stiffness: 160 },
        });

        const translateY = interpolate(progress, [0, 1], [40, 0]);
        const opacity = interpolate(progress, [0, 1], [0, 1]);

        return (
          <span
            key={idx}
            style={{
              display: 'inline-block',
              transform: `translateY(${translateY}px)`,
              opacity,
              fontSize: '48px',
              fontWeight: 800,
              color: idx === 0 ? '#f97316' : '#ffffff',
              letterSpacing: '-1px',
              fontFamily: "'JetBrains Mono', sans-serif",
            }}
          >
            {word}
          </span>
        );
      })}
    </div>
  );
};

B. Sincronización de Voz en Off y Efectos de Sonido

  • Coloca los archivos de audio en la carpeta public/audio/.
  • Usa staticFile('audio/file.mp3').
  • Crea transiciones de audio de entrada/salida usando la propiedad volume:
<Audio
  src={staticFile('audio/naskah_vo.mp3')}
  volume={(f) =>
    interpolate(f, [0, 15, 880, 900], [0, 1, 1, 0], {
      extrapolateLeft: 'clamp',
      extrapolateRight: 'clamp',
    })
  }
/>

5. Activos Asíncronos y Precarga (delayRender)

Cuando el video carga fuentes personalizadas, imágenes externas o datos de API, Remotion DEBE ser notificado para no renderizar fotogramas vacíos:

import { delayRender, continueRender } from 'remotion';
import { useEffect, useState } from 'react';

export const DynamicScene: React.FC = () => {
  const [handle] = useState(() => delayRender('Cargando Fuentes y Activos'));

  useEffect(() => {
    document.fonts.ready.then(() => {
      continueRender(handle);
    });
  }, [handle]);

  return <AbsoluteFill>...</AbsoluteFill>;
};

6. Plantillas y Recetas de Motion Graphics NARA

Fórmula de 8 Etapas Cinematográficas (Anti-PPT)

  1. Escena 1: Gancho Frío (00-03s) $ ightarrow$ Misterio visual + Tipografía cinética grande.
  2. Escena 2: Problema Expuesto (04-07s) $ ightarrow$ Visual de hielo derrumbándose / gráfico rojo ardiente.
  3. Escena 3: Inmersión Profunda en Datos (08-12s) $ ightarrow$ Números estadísticos que cuentan hacia arriba (Math.floor).
  4. Escena 4: Cambio de Escala Dinámico (13-16s) $ ightarrow$ Cambio de escala macro a micro.
  5. Escena 5: Impacto Humano (17-20s) $ ightarrow$ Personaje de dibujos animados reacciona en el lienzo.
  6. Escena 6: Revelación de la Solución (21-25s) $ ightarrow$ Visual cambia a colores verde/naranja brillante.
  7. Escena 7: Pasos de Acción (26-29s) $ ightarrow$ 3 puntos en tarjetas flotantes 3D.
  8. Escena 8: Clímax y Llamada a la Acción (30-32s) $ ightarrow$ Logotipo del estudio palpita + audio whoosh de caída.

7. Ejecución de Renderizado desde CLI y Aceleración por Hardware

A. Renderizar un Solo Video (1080p 60fps)

npx remotion render src/remotion/index.ts MainExplainer-1080p out/output.mp4 --gl=angle

B. Renderizado Rápido con Alta Concurrencia

npx remotion render src/remotion/index.ts MainExplainer-1080p out/output.mp4 --concurrency=8 --gl=angle --jpeg-quality=90

C. Banderas de Renderizado Importantes

  • --gl=angle: Utiliza aceleración de GPU DirectX en Windows (mucho más rápido que el rasterizador por software).
  • --gl=swiftshader: Retroceso por software si no hay GPU disponible en contenedor/CI.
  • --concurrency=N: Número de núcleos de CPU utilizados para renderizado paralelo.
  • --muted: Renderiza sin flujo de audio si solo se necesita el visual.
  • --props='{"title":"Nuevo"}': Pasa parámetros dinámicos a través de JSON en la línea de comandos.

8. Guía de Solución de Problemas

  1. Pantalla Negra / Imágenes que No Aparecen: Asegúrate de que los activos estén en la carpeta public/ y se llamen con staticFile('nombre_archivo').
  2. Video se Congela Durante el Renderizado: Verifica si hay un bucle infinito en useMemo o un componente React que no cierra delayRender.
  3. Audio Desincronizado: Asegúrate de que el valor fps de la composición coincida exactamente con el cálculo de los segundos de la voz en off (segundos = fotogramas / fps).

Skills relacionados