Crear vídeos con Claude Opus 5.5: qué genera y cómo sacar un MP4
Opus 5.5 no genera vídeo: escribe el código que dibuja cada fotograma. Vale para motion graphics y explicativos; la imagen realista pide un modelo de vídeo.
En esta página

Claude Opus 5.5 no genera vídeo. Lo que devuelve es texto, y ese texto puede ser un programa que dibuja cada fotograma; un navegador sin ventana los captura uno a uno y ffmpeg los une en un MP4. Por eso los «vídeos hechos con Opus 5.5» que circulan desde su lanzamiento, el 22 de septiembre de 2026, son casi siempre motion graphics, vídeos explicativos y presentaciones de producto, y casi nunca personas ni escenas con aspecto de rodaje. Si tu vídeo se puede describir con formas, texto, datos y movimiento, esta vía te sirve y puedes probarla hoy en tu ordenador. Si necesitas imagen fotorrealista, te hace falta un modelo de generación de vídeo, y Opus 5.5 como mucho lo coordina.
Una escena de 12 segundos escrita por el modelo se convirtió en un MP4 de 1920×1080 en menos de medio minuto en un portátil, con las medidas que verás más abajo. La parte delicada no es renderizar, sino pedirle al modelo una escena que se pueda capturar fotograma a fotograma sin que el movimiento se descuadre.
Qué produce Opus 5.5 cuando «hace un vídeo»
La tabla de modelos de Anthropic lo dice sin rodeos: todos los modelos actuales admiten texto e imagen como entrada y devuelven texto. No hay salida de vídeo ni de imagen. El anuncio de Opus 5.5 tampoco menciona el vídeo, la animación ni los motion graphics: este uso lo descubrió la comunidad, no es una función que Anthropic haya presentado.
Lo que sí hace Claude desde hace tiempo es dibujar con código. El centro de ayuda de Claude explica que no produce fotos ni ilustraciones como las herramientas de generación de imágenes, pero que construye diagramas, gráficos y visuales interactivos con HTML y SVG; el detalle de esa parte está en ¿Puede Claude generar imágenes? Guía completa de capacidades visuales de Claude (2026). Un vídeo hecho con Opus 5.5 es el mismo truco con una dimensión más, el tiempo:
- El modelo escribe una escena, normalmente un único archivo HTML con Canvas, CSS o Three.js, en la que cada imagen depende del instante
t. - Un navegador sin ventana (headless) coloca la escena en
t = 0, hace una captura, avanza 1/30 de segundo, hace otra, y así hasta el final. - ffmpeg codifica esas capturas como un MP4.
El ejemplo público más claro es LaunchVideo, cuyo repositorio se llama shipvideo. Su descripción empieza por «No video model»: Opus 5.5 escribe una película en un solo documento HTML de 1920×1080, un paso de comprobación la carga bajo un reloj virtual y revisa errores de JavaScript y el texto visible en varios instantes, y después Chromium la renderiza fotograma a fotograma y ffmpeg la codifica. El resultado que promete es un vídeo de lanzamiento de 20 a 40 segundos.
De ahí sale la ambigüedad de «generar». El modelo genera código. Los fotogramas los calcula el navegador al ejecutar ese código, y no hay ninguna red neuronal inventando píxeles. Esa diferencia explica tanto lo que sale bien como lo que no sale.
Qué vídeos salen bien y cuáles necesitan un modelo de vídeo
Lo que se dibuja con código queda nítido y exacto: el texto es texto de verdad, los números coinciden con tus datos y un cambio se hace editando una línea. Lo que no se puede describir con formas y reglas, como una cara, una tela o la luz de una calle, no sale de aquí.
El repositorio opus-video-prompts, que recopila casos publicados entre el 22 y el 25 de septiembre, resume así lo que ha visto: funciona en motion graphics, animación de línea o tinta, vídeos explicativos, vídeos de lanzamiento y vídeos con letra de canciones; no funciona en planos fotorrealistas de acción real. Es la valoración de quien recopila los casos, no una medición. Para esos planos, la práctica habitual que describe es que el modelo llame a un modelo de vídeo y se quede con la planificación y el montaje.
| Tu vídeo necesita | Vía que encaja | Por qué |
|---|---|---|
| Texto animado, interfaces, gráficos, diagramas, logotipos | Dibujar con código | Todo es geometría y tipografía; el resultado es exacto y editable |
| Explicar un concepto o un proceso paso a paso | Dibujar con código | El modelo ordena la explicación y la anima en la misma pasada |
| Personas, animales o lugares con aspecto real | Modelo de vídeo | No hay forma de dibujar una imagen fotorrealista con formas y reglas |
| Alguien hablando a cámara con sincronía labial natural | Modelo de vídeo | Depende de imagen y voz generadas, no de código |
| Planos reales con rótulos, cifras y transiciones encima | Las dos | El modelo de vídeo da los planos; el código pone los gráficos y el montaje |

Una recopilación de terceros da una idea de qué publica la gente. El repositorio awesome-opus-5-5-videos reunió 1.401 archivos de vídeo de X hasta el 26 de septiembre de 2026 y un clasificador automático etiquetó 1.119 como probablemente relacionados con Opus 5.5. De ellos, 350 eran motion graphics o interfaces y 324 eran render 3D, el 60,2 % entre los dos, con una mediana de 39,2 segundos por vídeo. El propio repositorio avisa de que las etiquetas no demuestran qué modelo se usó ni quién hizo cada pieza, así que describe la muestra pública, no la capacidad del modelo.
Si lo tuyo es la segunda mitad de la tabla, los puntos de partida son otros: API de Seedance 2.5: ID de modelo, Python y Node.js para llamar desde código a un modelo de vídeo, y API gratis para generar vídeo con IA: qué existe y qué cuesta para probar sin pagar.
Tu primer MP4 en tu ordenador
Necesitas cuatro cosas: Claude Code con Opus 5.5 (o cualquier otra forma de pedirle al modelo un archivo), Node.js, Google Chrome instalado y ffmpeg accesible desde la terminal. El script de abajo usa playwright-core para manejar el Chrome que ya tienes, sin descargar otro navegador.
mkdir video-opus && cd video-opus
npm init -y
npm install playwright-corePide una escena que se pueda recorrer en el tiempo
La escena tiene que cumplir un contrato pequeño: declarar su duración y ofrecer una función que dibuje el instante que se le pida. Un encargo como este funciona:
Escribe scene.html, una animación de 12 segundos en un canvas de 1920x1080
que explique [tu tema] en tres pasos.
Reglas:
- Define window.DURATION (segundos) y window.seek(t), que dibuja el
fotograma del instante t. Cada píxel debe depender solo de t.
- No uses requestAnimationFrame, Date, performance.now, setTimeout
ni transiciones CSS para mover nada.
- Si necesitas azar, usa un generador con semilla fija, no Math.random.
- Sin imágenes ni fuentes externas.El esqueleto que debería devolver se parece a este:
<!doctype html>
<meta charset="utf-8">
<style>html,body{margin:0;background:#0b1020}canvas{display:block}</style>
<canvas id="c" width="1920" height="1080"></canvas>
<script>
window.DURATION = 12;
const W = 1920, H = 1080;
const ctx = document.getElementById("c").getContext("2d");
// Azar con semilla: las mismas partículas en cada render
function rng(seed) {
return () => { seed = (seed * 1664525 + 1013904223) >>> 0; return seed / 4294967296; };
}
const r = rng(55);
const dots = Array.from({ length: 140 }, () => ({ x: r() * W, y: r() * H, v: 0.2 + r() * 0.8 }));
window.seek = async (t) => {
ctx.fillStyle = "#0b1020";
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = "rgba(160,180,255,0.5)";
for (const d of dots) {
ctx.beginPath();
ctx.arc(d.x, (d.y + t * 12 * d.v) % H, 2, 0, 6.283);
ctx.fill();
}
// ...títulos, cajas y gráficos, todos calculados a partir de t
};
window.seek(0);
</script>El script que captura y codifica
Guárdalo como render.mjs junto a la escena. Abre el HTML en Chrome sin ventana, llama a seek para cada fotograma, envía cada captura a ffmpeg y al final imprime las medidas del render.
// node render.mjs scene.html salida.mp4 [fps] [png|jpeg]
import { chromium } from "playwright-core";
import { spawn } from "node:child_process";
import { once } from "node:events";
import { createHash } from "node:crypto";
import { statSync } from "node:fs";
import path from "node:path";
import { pathToFileURL } from "node:url";
const [scene, out, fpsArg = "30", type = "png"] = process.argv.slice(2);
if (!scene || !out) throw new Error("Uso: node render.mjs scene.html salida.mp4 [fps] [png|jpeg]");
const fps = Number(fpsArg);
const started = Date.now();
const browser = await chromium.launch({ channel: "chrome", headless: true });
const page = await browser.newPage({ viewport: { width: 1920, height: 1080 }, deviceScaleFactor: 1 });
await page.goto(pathToFileURL(path.resolve(scene)).href);
await page.waitForFunction(() => typeof window.seek === "function");
await page.evaluate(() => document.fonts.ready);
const total = Math.round((await page.evaluate(() => window.DURATION)) * fps);
const ff = spawn("ffmpeg", ["-y", "-loglevel", "error", "-f", "image2pipe", "-framerate", String(fps), "-i", "-",
"-c:v", "libx264", "-pix_fmt", "yuv420p", "-crf", "18", "-movflags", "+faststart", out],
{ stdio: ["pipe", "inherit", "inherit"] });
const hash = createHash("sha256");
const shotOpts = type === "jpeg" ? { type: "jpeg", quality: 92 } : { type: "png" };
const captureStart = Date.now();
for (let i = 0; i < total; i++) {
await page.evaluate((t) => window.seek(t), i / fps);
const buf = await page.screenshot(shotOpts);
hash.update(buf);
if (!ff.stdin.write(buf)) await once(ff.stdin, "drain");
}
const captureMs = Date.now() - captureStart;
ff.stdin.end();
const [code] = await once(ff, "close");
await browser.close();
if (code !== 0) throw new Error(`ffmpeg terminó con el código ${code}`);
console.log(JSON.stringify({
scene, out, fps, frames: total, shot: type,
capture_seconds: +(captureMs / 1000).toFixed(2),
total_seconds: +((Date.now() - started) / 1000).toFixed(2),
ms_per_frame: +(captureMs / total).toFixed(1),
mp4_bytes: statSync(out).size,
frames_sha256: hash.digest("hex").slice(0, 16),
}));node render.mjs scene.html salida.mp4 30 pngRevisa el resultado antes de darlo por bueno
Tres comprobaciones rápidas evitan la mayoría de los sustos:
- Que el archivo sea lo que esperas.
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,nb_frames,duration -of default=nw=1 salida.mp4debe devolver h264, 1920×1080, 30 fps y un número de fotogramas igual a duración × 30. - Que el tiempo cuadre. Saca un fotograma suelto con
ffmpeg -ss 9.5 -i salida.mp4 -frames:v 1 f.pngy mira si muestra lo que la escena debería mostrar en el segundo 9,5. Pintar el número de fotograma en una esquina durante las pruebas lo hace evidente. - Que se repita. Renderiza dos veces y compara el campo
frames_sha256. Si cambia, la escena depende de algo que no est.
LaunchVideo automatiza la primera revisión con su paso check_scene, que carga la película antes de renderizarla y devuelve los errores de JavaScript y el texto visible en varios instantes. Pedirle a Claude Code que haga lo mismo con un par de capturas, y que las mire antes de renderizar todo, ahorra renders enteros.
Cuánto tarda y cuánto pesa: 360 fotogramas medidos
Los datos siguientes son de un solo equipo y una sola escena, a 1 de octubre de 2026: un Mac con chip Apple M4 de 10 núcleos y 16 GB de memoria, macOS 26.1, Node 24.11.0, playwright-core 1.63.0 manejando Chrome 154 sin ventana a 1920×1080 y ffmpeg 8.0.1 con libx264, crf 18 y yuv420p. La escena era una animación Canvas 2D de 12 segundos, escrita por Opus 5.5 de una sola vez en Claude Code y sin retoques a mano, con partículas de azar con semilla y sin audio.
| Capturas | Fotogramas | Tiempo de captura | Por fotograma | Frente a la duración del vídeo | Tamaño del MP4 |
|---|---|---|---|---|---|
| PNG, primer render | 360 | 25,93 s | 72 ms | 2,2 veces | 915.183 bytes |
| PNG, segundo render | 360 | 25,80 s | 71,7 ms | 2,2 veces | 915.183 bytes |
| JPEG, calidad 92 | 360 | 11,51 s | 32 ms | 0,96 veces | 1.093.045 bytes |
El proceso completo, contando el arranque de Chrome y el cierre de ffmpeg, tardó 33,46 y 27,24 segundos en los dos renders con PNG. ffprobe confirmó h264, 1920×1080, 30 fps, 360 fotogramas y 12,000 segundos, y el fotograma extraído en el segundo 9,5 mostraba en pantalla «frame 285 / 360, t = 9.500 s», que es exactamente 9,5 × 30.
Dos conclusiones prácticas. La primera: capturar en JPEG fue más del doble de rápido y dejó el render en tiempo casi real, a cambio de un archivo un 19 % mayor. Es el mismo orden que declara LaunchVideo para su propia infraestructura, donde una película de 30 segundos tarda entre 30 y 40 con capturas JPEG. La segunda: los dos renders con PNG dieron la misma huella en todos los fotogramas y el mismo tamaño al byte, y los dos MP4 seguían siendo idénticos después de decodificarlos. Eso es lo que significa que el proceso sea determinista: la misma escena produce siempre el mismo vídeo, así que puedes corregir un detalle y volver a renderizar sin que cambie nada más.
Una escena 3D pesada, con fuentes externas o con muchas capas no tiene por qué comportarse igual; estas cifras valen para una escena 2D sencilla.
Por qué una animación web normal se rompe al capturarla
Una animación web corriente avanza con el reloj real: usa requestAnimationFrame, lee performance.now() y dibuja lo que toca según el tiempo transcurrido. En pantalla se ve bien. Capturada fotograma a fotograma, falla, porque cada captura tarda lo que tarda y la escena sigue avanzando por su cuenta.
Con el mismo script y el mismo equipo, una escena de 3 segundos escrita así, con Math.random() sin semilla y un seek que no hacía nada, dio este resultado:
- Dos renders seguidos produjeron fotogramas distintos y archivos de 115.816 y 131.033 bytes.
- El fotograma del segundo 1,5 del vídeo mostraba en pantalla «t = 1.572 s»: 72 milésimas de desfase a mitad de un vídeo de 3 segundos.
- La velocidad parecía correcta por casualidad, porque esas capturas tardaron entre 33,6 y 38 ms por fotograma, casi lo mismo que los 33,3 ms que dura un fotograma a 30 fps.

Esa casualidad no se sostiene con escenas más pesadas. A los 72 ms por fotograma que costó la escena de 12 segundos, el reloj real avanzaría 72 ms por cada 33,3 ms de vídeo, y el movimiento iría unas 2,2 veces más rápido de lo previsto. Esto último es una deducción a partir de los dos tiempos, no un render grabado.
Hay dos maneras de evitarlo. La que no requiere nada más es la del encargo de arriba: que todo dependa de t y que el azar lleve semilla. La otra es la de LaunchVideo, que inyecta un reloj virtual para que requestAnimationFrame, los temporizadores, Date y las animaciones CSS obedezcan al instante que marca el renderizador; aun así, prohíbe en sus escenas las etiquetas de vídeo, audio e iframe, las transiciones CSS, Math.random y las imágenes externas. Si un vídeo te sale acelerado, a saltos o distinto en cada render, mira primero si la escena lee el reloj.
Script propio, HyperFrames o Remotion
El script de arriba basta para una escena. Cuando haya varias escenas, audio o un equipo detrás, compensa un marco de trabajo. Los dos nombres que más aparecen junto a Opus 5.5 son estos, descritos aquí según su propia documentación:
| Opción | Cómo escribes la escena | Licencia | Encaja si |
|---|---|---|---|
| Script propio con Playwright y ffmpeg | HTML con window.seek(t) | La de las herramientas que uses | Quieres entender el proceso o solo necesitas un clip |
| HyperFrames | HTML y CSS con animaciones recorribles (GSAP, animaciones CSS, Lottie, Three.js, Anime.js, WAAPI) | Apache 2.0, sin cuotas por render ni umbrales de uso comercial | Prefieres HTML y quieres un plugin de Claude Code ya hecho; pide Node 22 o superior |
| Remotion | Componentes de React | Gratis para particulares, empresas de hasta 3 empleados y entidades sin ánimo de lucro; el resto necesita licencia de empresa | Tu equipo ya trabaja con React y cumple las condiciones, o tiene la licencia |
HyperFrames funciona con el mismo principio que el script: su renderizador sitúa cada fotograma en Chrome sin ventana y codifica con FFmpeg, de modo que la misma entrada da el mismo vídeo. El plugin se instala desde Claude Code:
claude plugin marketplace add heygen-com/hyperframes
claude plugin install hyperframes@hyperframesy se invoca con /hyperframes:hyperframes. En Remotion, lo que cambia la decisión es el tamaño de la organización: una empresa con cuatro empleados o más ya no entra en la licencia gratuita.
El audio va aparte en cualquiera de las tres opciones. Los casos recopilados en opus-video-prompts sintetizan la música con Web Audio o con Python y la narración con un servicio de texto a voz, y luego lo mezclan con la imagen; el script de arriba produce un MP4 mudo.
Cuánto cuesta un vídeo en tokens
No existe una cifra típica medida. Lo que hay es una fórmula con los precios de lista de la API, que son 4 $ por millón de tokens de entrada y 20 $ por millón de tokens de salida:
coste = tokens de entrada × 4 / 1.000.000 + tokens de salida × 20 / 1.000.000Como ejemplo de entrada sirven las cifras que, según un artículo publicado en Hugging Face por un revendedor de API, dan los creadores de LaunchVideo: unos cuatro minutos y aproximadamente 90.000 tokens de entrada y 15.000 de salida por película. El mismo artículo aclara que son cifras de ellos y no una medición propia, y no figuran en el repositorio del proyecto. Con esos números:
90.000 × 4 / 1.000.000 = 0,36 $
15.000 × 20 / 1.000.000 = 0,30 $
total = 0,66 $ por película, sin cachéEn el otro extremo, el repositorio opus-video-prompts recoge una instrucción de una sola línea de Deedy Das, «make a modern slick and punchy video for a modern startup that works on inference», y anota que su autor habla de alrededor de un minuto y unos 2 $. Entre 0,66 y 2 $ hay un factor de tres con dos casos nada más, lo que da una idea de cuánto varía.
Lo que mueve la cuenta:
- Cada corrección se paga otra vez. Pedir cambios reenvía el contexto y genera una escena nueva.
- El razonamiento se cobra como salida. En Opus 5.5 el razonamiento está siempre activo y sus tokens se facturan al precio de salida. El ajuste effort viene en
mediumpor defecto, y opus-video-prompts recomiendahighoxhighpara vídeo, que consumen más. - Renderizar no gasta tokens. Lo hace tu ordenador. La voz, la música y los planos de un modelo de vídeo se pagan aparte.
- Con suscripción no hay factura por token. Los planes de Claude descuentan de tus límites de uso, así que la fórmula solo vale para la API. La diferencia está explicada en Claude Opus 5.5: precio de la API y restablecimiento de límites.
Para saber lo que cuesta el tuyo, mira el consumo de tokens de la sesión al terminar un vídeo y aplica la fórmula.
Preguntas frecuentes
¿Puede Opus 5.5 generar vídeo directamente en la aplicación de Claude?
No. La aplicación puede mostrar una animación HTML que el modelo haya escrito, pero no devuelve un archivo de vídeo generado por el modelo, porque ningún modelo actual de Claude tiene salida de vídeo. Para obtener un MP4 hace falta el paso de captura y codificación, y por eso el inicio rápido de opus-video-prompts parte de Claude Code, donde el modelo puede escribir el archivo, ejecutar el render y revisar el resultado en la misma sesión.
¿Se puede hacer lo mismo con Sonnet 5.5 o con un Opus anterior?
El mecanismo no es exclusivo de Opus 5.5: todos los modelos actuales de Claude devuelven texto, y una escena es texto. Lo que cambia de un modelo a otro es la calidad de la escena que escriben, y de eso no hay datos comparativos publicados. Si dudas entre los dos modelos de la serie 5.5 por precio, la comparación general está en Claude Sonnet 5.5 vs Opus 5.5: cuál gasta menos por tarea.
¿Cuánto puede durar un vídeo hecho así?
No hay un límite técnico en el render: son más fotogramas y más tiempo de captura. El límite práctico está en la escena, porque cuanto más larga es, más código tiene que escribir el modelo de forma coherente y más cuesta corregirla. LaunchVideo se queda en 20 a 40 segundos y la mediana de la muestra de X recopilada en awesome-opus-5-5-videos es de 39,2 segundos. Para piezas más largas, lo razonable es dividir en escenas cortas, renderizarlas por separado y unirlas después.
¿Por qué mi vídeo sale acelerado o cambia en cada render?
Porque la escena avanza con el reloj real o usa azar sin semilla. Comprueba que window.seek(t) dibuje de verdad el instante que recibe y que nada dependa de requestAnimationFrame, performance.now() o Math.random(). Dos renders con la misma huella de fotogramas confirman que está arreglado.





