ContenidoAvanzado45 min
Videos con IA: Remotion + Claude
Generación automática · Templates · Pipeline completo · de script a MP4
RemotionVideosAutomatización
✓ Guía gratuita · Acceso completo
Mapa rápido · salta al paso que te interese
01
Qué es Remotion: React para videos
Remotion te deja escribir videos como componentes de React. Cada frame es un render. Puedes usar todo el ecosistema React: hooks, state, componentes. El resultado es un MP4.
Setup básico
# Crear proyecto Remotion
npx create-video@latest
# Estructura
remotion/
├── src/
│ ├── Root.tsx # Registro de composiciones
│ ├── Composition.tsx # Tu video
│ └── components/ # Componentes reutilizables
├── public/ # Assets estáticos
└── remotion.config.ts # Config de renderingComposición básica
// src/MyVideo.tsx
import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate } from 'remotion'
export const MyVideo: React.FC<{ title: string }> = ({ title }) => {
const frame = useCurrentFrame()
const { fps, durationInFrames } = useVideoConfig()
// Animación de opacidad
const opacity = interpolate(
frame,
[0, 30], // frames 0 a 30
[0, 1], // opacidad 0 a 1
{ extrapolateRight: 'clamp' }
)
return (
<AbsoluteFill style={{ backgroundColor: '#1c1b18' }}>
<h1 style={{
color: '#e9e7e2',
fontSize: 80,
textAlign: 'center',
marginTop: '40%',
opacity,
}}>
{title}
</h1>
</AbsoluteFill>
)
}
// Root.tsx - registrar la composición
import { Composition } from 'remotion'
import { MyVideo } from './MyVideo'
export const RemotionRoot = () => (
<Composition
id="MyVideo"
component={MyVideo}
durationInFrames={150} // 5 segundos a 30fps
fps={30}
width={1080}
height={1920} // Vertical para Shorts/Reels
defaultProps={{ title: 'Hola Mundo' }}
/>
)02
Pipeline de generación: Script → Escenas → MP4
El flujo completo: Claude genera el script estructurado, Remotion consume el JSON, FFmpeg renderiza el MP4.
1. Claude genera el script
interface VideoScript {
title: string
duration: number // segundos
scenes: {
type: 'hook' | 'content' | 'cta'
text: string
duration: number
animation?: 'fade' | 'slide' | 'zoom'
}[]
}
async function generateScript(topic: string): Promise<VideoScript> {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 2048,
messages: [{
role: 'user',
content: `Genera un script para un video vertical de 60 segundos sobre: ${topic}
Formato JSON:
{
"title": "Título del video",
"duration": 60,
"scenes": [
{ "type": "hook", "text": "Gancho inicial", "duration": 5, "animation": "zoom" },
{ "type": "content", "text": "Punto 1", "duration": 15 },
{ "type": "content", "text": "Punto 2", "duration": 15 },
{ "type": "content", "text": "Punto 3", "duration": 15 },
{ "type": "cta", "text": "Llamado a la acción", "duration": 10, "animation": "fade" }
]
}
Solo devolvé el JSON, nada más.`
}]
})
return JSON.parse(response.content[0].text)
}2. Remotion consume el script
// src/ScriptedVideo.tsx
import { AbsoluteFill, Sequence, useVideoConfig } from 'remotion'
interface Scene {
type: string
text: string
duration: number
animation?: string
}
export const ScriptedVideo: React.FC<{ scenes: Scene[] }> = ({ scenes }) => {
const { fps } = useVideoConfig()
let currentFrame = 0
return (
<AbsoluteFill style={{ backgroundColor: '#1c1b18' }}>
{scenes.map((scene, i) => {
const durationInFrames = scene.duration * fps
const from = currentFrame
currentFrame += durationInFrames
return (
<Sequence key={i} from={from} durationInFrames={durationInFrames}>
<SceneComponent scene={scene} />
</Sequence>
)
})}
</AbsoluteFill>
)
}
const SceneComponent: React.FC<{ scene: Scene }> = ({ scene }) => {
const frame = useCurrentFrame()
const opacity = interpolate(frame, [0, 15], [0, 1], { extrapolateRight: 'clamp' })
return (
<AbsoluteFill style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: 60,
}}>
<p style={{
color: '#e9e7e2',
fontSize: scene.type === 'hook' ? 72 : 48,
textAlign: 'center',
opacity,
}}>
{scene.text}
</p>
</AbsoluteFill>
)
}3. Render a MP4
# Desde CLI
npx remotion render ScriptedVideo out/video.mp4 --props='{"scenes":[...]}'
# Desde Node.js
import { bundle } from '@remotion/bundler'
import { renderMedia, selectComposition } from '@remotion/renderer'
async function renderVideo(script: VideoScript): Promise<string> {
const bundled = await bundle(require.resolve('./src/index.ts'))
const composition = await selectComposition({
serveUrl: bundled,
id: 'ScriptedVideo',
inputProps: { scenes: script.scenes },
})
const outputPath = `./out/${Date.now()}.mp4`
await renderMedia({
composition,
serveUrl: bundled,
codec: 'h264',
outputLocation: outputPath,
inputProps: { scenes: script.scenes },
})
return outputPath
}03
5 Templates reutilizables
Templates probados para diferentes tipos de contenido.
Vertical 1080x1920, 60 segundos max.
// Config
width: 1080,
height: 1920,
fps: 30,
durationInFrames: 1800 // 60s
// Estructura típica
- Hook (0-3s): Pregunta o statement impactante
- Contenido (3-50s): 3-5 puntos con animaciones
- CTA (50-60s): Seguir, like, comentarTip Pro
Pro tip: Renderizá en Lambda para escalar. Remotion Lambda puede procesar 100 videos en paralelo.
"Video es el formato con mayor engagement. Remotion + Claude te deja producir 10 videos en el tiempo que antes hacías 1. La barrera técnica ya no existe."
— El Arsenal, Renderz Studio
¿Quieres el sistema completo?
500+ páginas, 25 capítulos, código de producción, acceso a todas las guías del Arsenal.
Curso Completo · €29PayPal · Acceso inmediato