Contenido
Crea un vídeo de motion graphics con HTML y Opus 5.5
Escribe un beat sheet, pide a Opus 5.5 una escena HTML determinista vía API de Felo, captura los fotogramas con Playwright y codifica un MP4 con ffmpeg. Funciona en WorkBuddy, ChatGPT con ejecución de código, Codex, Pi Agent o Claude Code.
Copiar el prompt
Sustituye los campos entre corchetes y pégalo en Claude Code, Codex o cualquier IA con acceso a terminal. Instala el skill de Felo, pregunta antes de gastar créditos y ejecuta el flujo.
Crea un vídeo de [duración] segundos, formato [vertical / horizontal], sobre [idea]. Estilo: [estilo]. Audiencia: [audiencia]. Audio: [ninguno / una pista con licencia en ./audio.mp3 / TTS]. Trabajas en una carpeta con terminal y [WorkBuddy / ChatGPT con ejecución de código / Codex / Pi Agent / Claude Code]. Si no puedes ejecutar Node y un navegador headless, detente y dímelo en lugar de fingir que has renderizado. Sigue este orden: 1. Escribe un storyboard de 3–6 beats con segundos exactos de inicio y fin. 2. Paso HTML: llama a Claude Opus 5.5 mediante la API de Felo. Usa el ID de modelo claude-opus-5-5 y mi FELO_API_KEY. No me pidas una suscripción de Claude ni otra clave de Anthropic. 3. Pide a Opus un único archivo HTML autocontenido: que defina window.DURATION y exponga async window.seek(t). Sin recursos externos, CDN, Date.now(), requestAnimationFrame(), transiciones CSS ni temporizadores. Siembra todos los valores aleatorios para que el mismo t dibuje siempre el mismo fotograma. 4. Previsualiza en t = 0, 25 %, 50 %, 75 % y el último fotograma. Revisa desbordes, recortes, fuentes y zonas seguras antes de renderizar todo. 5. Renderiza cada fotograma con Playwright, codifica en H.264 con ffmpeg y mezcla la pista de audio si existe. 6. Muestra el primer fotograma, el último y la ruta final. No publiques nada. Reglas: - Antes de gastar créditos, muestra las llamadas a la API de Felo y el uso estimado de tokens. - Usa solo el texto que te doy, o marca claramente el texto de relleno inventado. - No uses material, música, logotipos ni fuentes con copyright. Solo fuentes del sistema y formas generadas. - Mantén el vídeo final por debajo de 30 segundos, salvo que pida explícitamente uno más largo. - Escribe todo en ./video/ y resume los comandos ejecutados.
La copia también incluye los pasos de instalación y las reglas de seguridad.
Lo que obtienes
Salida de ejemplo de una ejecución. No es generación en vivo.
Informe de render
Escena: video/scene.html (18 KB) Duración: 12 s · 1080x1920 · 30 fps · 360 fotogramas Comprobaciones: window.DURATION = 12 · seek(t) presente · sin Date.now / rAF / temporizadores
Vista previa: preview-0ms.png · preview-3000ms.png · preview-6000ms.png · preview-9000ms.png Codificación: video/video.mp4 (H.264, 360 fotogramas) Audio: video/final.mp4 (AAC, 12,0 s)
Las llamadas exactas
Para desarrolladores: el mismo flujo como código, en orden de ejecución.
Mostrar las llamadas reales a la API
Escribe primero el beat sheet
Fija duración y 3–6 beats, cada uno con inicio, fin, texto en pantalla y cambio visual principal.
Genera la escena HTML con Opus 5.5
Apunta el Anthropic SDK a la base URL de Felo, usa
claude-opus-5-5y pide solo HTML conwindow.DURATIONyasync seek(t).generate-scene.ts import { mkdir, writeFile } from "node:fs/promises"; import Anthropic from "@anthropic-ai/sdk"; const SYSTEM = `You write a single, self-contained HTML video scene. Requirements: - 1080x1920 (or 1920x1080), no external assets, system fonts only. - set window.DURATION = <seconds>. - expose async window.seek(t) that draws the frame for time t. - no Date.now(), no requestAnimationFrame(), no CSS transitions, no timers. - seed every random value; the same t must always produce the same frame. - return only the HTML file, no markdown fences.`; const brief = `12-second vertical motion graphic about [idea]. Beats: [0-3s hook], [3-7s point], [7-10s proof], [10-12s CTA]. Palette: [colors]. Type: system sans. Keep text inside a 64px safe area.`; const anthropic = new Anthropic({ apiKey: process.env.FELO_API_KEY, baseURL: "https://openapi.felo.ai/api", }); const message = await anthropic.messages.create({ model: "claude-opus-5-5", max_tokens: 32000, system: SYSTEM, messages: [{ role: "user", content: brief }], }); const raw = message.content .filter((block) => block.type === "text") .map((block) => block.text) .join(""); const html = raw.replace(/^```(?:html)?\s*/i, "").replace(/```\s*$/, "").trim(); await mkdir("video", { recursive: true }); await writeFile("video/scene.html", html); console.log(`scene.html: ${html.length} bytes`);Salida de ejemplo
scene.html: 18432 bytes
Comprueba determinismo y previsualiza
Haz capturas en t=0, 25%, 50%, 75% y el último fotograma, revisando desbordes, fuentes y zonas seguras.
preview.ts import { chromium } from "playwright"; import { pathToFileURL } from "node:url"; const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: 1080, height: 1920 }, deviceScaleFactor: 1, }); await page.goto(pathToFileURL("video/scene.html").href); await page.waitForFunction(() => typeof (window as any).seek === "function"); const duration = await page.evaluate(() => (window as any).DURATION as number); for (const t of [0, duration * 0.25, duration * 0.5, duration * 0.75]) { await page.evaluate(async (time) => { await (window as any).seek(time); }, t); await page.screenshot({ path: `video/preview-${Math.round(t * 1000)}ms.png` }); } await browser.close(); console.log(`duration ${duration}s`);Salida de ejemplo
duration 12s video/preview-0ms.png video/preview-3000ms.png video/preview-6000ms.png video/preview-9000ms.png
Renderiza todos los fotogramas
Llama a
seek(t)cont = frame / fps, captura y codifica H.264 con ffmpeg.render.ts import { spawn } from "node:child_process"; import { mkdir, rm } from "node:fs/promises"; import { pathToFileURL } from "node:url"; import { chromium } from "playwright"; const FPS = 30; const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: 1080, height: 1920 }, deviceScaleFactor: 1, }); await page.goto(pathToFileURL("video/scene.html").href); await page.waitForFunction(() => typeof (window as any).seek === "function"); const duration = await page.evaluate(() => (window as any).DURATION as number); const frames = Math.ceil(duration * FPS); await rm("video/frames", { recursive: true, force: true }); await mkdir("video/frames", { recursive: true }); for (let frame = 0; frame < frames; frame++) { await page.evaluate(async (time) => { await (window as any).seek(time); }, frame / FPS); await page.screenshot({ path: `video/frames/${String(frame).padStart(5, "0")}.png`, }); } await browser.close(); const ffmpeg = spawn("ffmpeg", [ "-y", "-framerate", String(FPS), "-i", "video/frames/%05d.png", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-movflags", "+faststart", "video/video.mp4", ], { stdio: "inherit" }); await new Promise<void>((resolve, reject) => { ffmpeg.on("exit", (code) => { if (code === 0) resolve(); else reject(new Error(`ffmpeg exited with ${code}`)); }); }); console.log(`${frames} frames -> video/video.mp4`);Salida de ejemplo
360 frames -> video/video.mp4
Mezcla audio y mira completo
Añade la pista con licencia con
-c:v copy, revisa duración y volumen y míralo entero.mux.sh ffmpeg -i video/video.mp4 -i video/audio.wav \ -c:v copy -c:a aac -b:a 192k -shortest \ video/final.mp4 ffprobe -v error -show_entries format=duration \ -of default=nw=1:nk=1 video/final.mp4Salida de ejemplo
12.000000
Itera con el mismo modelo
Describe solo el fotograma fallido y el cambio deseado, pasa el HTML actual a Opus y relanza la previsualización antes del render completo.
Qué incluye
- Storyboard y línea de tiempo escritos primero
- Escena HTML determinista de Opus 5.5
- Script de render de Playwright y codificación ffmpeg
- MP4 final con pista de audio opcional
- Bucle de revisión y corrección fotograma a fotograma
Qué no hace
- Opus 5.5 entrega código, no fotogramas; el renderizador del navegador captura
- No hace falta suscripción Claude, pero el uso del modelo Felo se factura por uso
- Siguen haciendo falta Node, Playwright Chromium y ffmpeg
- Sin recursos externos ni CDN; solo HTML/CSS/SVG/Canvas o archivos locales
- Los vídeos largos requieren dividir escenas; no es grabación de pantalla en vivo
- Narración y música son pasos separados; el flujo solo mezcla audio proporcionado
Preguntas
¿Opus 5.5 genera vídeo directamente?
No. Genera texto y código escribiendo la escena HTML; el navegador y ffmpeg convierten la escena en fotogramas y MP4.
¿Necesito suscripción Claude?
No. Usa la clave Felo para llamar a `claude-opus-5-5` vía API de Felo con facturación por uso; no necesitas suscripción Claude aparte.
¿En qué agents funciona?
WorkBuddy, ChatGPT con ejecución de código, Codex, Pi Agent, Claude Code o cualquier agent que ejecute Node y un navegador headless.
¿Por qué seek(t)?
La captura no es en tiempo real: el fotograma 400 puede capturarse mucho después del 399, así que cada fotograma debe ser función pura de t.
¿Puedo usar HyperFrames o Remotion?
Sí, para composiciones largas o proyectos estructurados. Esta receta mantiene un solo HTML para revisar la llamada y el bucle de render.
¿Cuánto cuesta un vídeo de 12 segundos?
Depende del prompt, tokens de salida e iteraciones. El modelo Felo factura por token; consulta precios antes de un render largo.
¿Puedo usar mi música y narración?
Sí, si tienes derechos. Renderiza primero y mezcla la pista con licencia o tu TTS con ffmpeg. El flujo no genera narración.
Referencias
Tutoriales y proyectos en los que se basa este flujo.
Flujos relacionados
Convierte una página de investigación en una presentación
Extrae la página, guárdala como contexto LiveDoc, deja que la API PPT Task construya el deck y consulta hasta obtener el enlace final.
Abrir el flujo de trabajoContenidoConvierte un brief de producto en una landing page
Investiga la audiencia, guarda el brief en LiveDoc, crea una tarea de Landing Page desde ese contexto y consulta hasta que la página alojada esté lista.
Abrir el flujo de trabajoContenidoLlena un mes de contenido con las preguntas de tu audiencia
Mapea temas con Chat, encuentra las preguntas de la audiencia en X, toma un ángulo real de una transcripción de vídeo y compón un calendario de cuatro semanas donde cada fila nombra su evidencia.
Abrir el flujo de trabajoHazlo tuyo
La misma receta, adaptada a cómo entregas de verdad.
Proyecto HyperFrames o Remotion
Para composiciones largas usa estos frameworks; la llamada al modelo es igual y solo cambia el comando de render.
Versión cuadrada para redes
Mantén el beat sheet, pasa a 1080x1080 y ajusta tipografía y zonas seguras.
Tres variantes de un brief
Genera tres escenas con colores y ritmos distintos, previsualiza y renderiza solo la mejor.
Seguir
Las páginas de referencia detrás de esta receta y los siguientes pasos.