Video de anuncio de producto, hecho en código
Un pipeline para anuncios de producto de 15–20 segundos sin editor de video: cada fotograma, sonido y línea de locución es generado por scripts, por lo que todo es reproducible y editable como texto.
datos del proyecto ─► brief + storyboard ─► visuales ─────────────► Render Remotion ─► MP4
├ 2D: React (Remotion) ▲
└ 3D: Blender (headless) ─► fotogramas JPG
sonido: scripts/score.py ─► WAV ┘
voz: scripts/kokoro_tts.py ─┘
Ejemplo práctico (GhostCommits, archivos reales): examples/ghostcommits/.
Paso 1 — Comprender el producto, escribir el brief
Lee el README, la página de aterrizaje y el código. Extrae: una frase de presentación, 3–4 puntos de prueba concretos (los números superan a los adjetivos: "1 archivo", "0 inicios de sesión"), los colores de la marca del CSS, el logotipo SVG, la URL. Escribe lo que NO debe afirmarse (p. ej., "solo testnet", "no es anónimo", sin recuentos de usuarios). Cada línea en pantalla y de locución se verifica contra esta lista. Pide al usuario que elija una paleta/estilo solo si la marca no define una.
Paso 2 — Storyboard (escribir en un archivo .md antes de construir)
18 s a 30 fps = 540 fotogramas. 5–6 tomas de ~2.5 s (75 fotogramas = un compás a 96 BPM, por lo que los cortes caen en el ritmo). Cada toma: fotogramas, cámara/movimiento, texto en pantalla, sonido. Finaliza con una tarjeta final de 3–4 s (nombre, eslogan, URL). Plantilla: references/storyboard.md.
Paso 3a — Estilo 2D (Remotion)
Tipografía cinética + formas planas, energía al estilo "Spotify Wrapped". Consulta references/remotion-2d.md.
npx create-video@latest --yes --blank --no-tailwind video luego un componente por anuncio, impulsado únicamente por useCurrentFrame() + interpolate con easing. Sin transiciones CSS.
Paso 3b — Estilo 3D (Blender, headless)
Objeto heroico brillante en un vacío negro, primeros planos macro, rayos de luz en la superficie, cortes duros, gran estadística + pequeño texto explicativo en la parte inferior izquierda. Consulta references/blender-3d.md.
Un script de Python construye la escena, anima cada toma y renderiza fotogramas:
blender -b --factory-startup -P scene.py -- anim ../public/frames. Remotion superpone el texto sobre los fotogramas (examples/ghostcommits/GhostAdV2.tsx). Renderiza primero 2–3 imágenes fijas y revísalas antes de la animación completa.
Paso 4 — Sonido (scripts/score.py)
Escribe una hoja de referencia JSON con señales: una entrada por evento visual, indexada por número de fotograma tomado del código de animación (corte → cut_hit, objeto que entra volando → whoosh, aterriza → click/lock, rayo de luz → glint, tarjeta final → impact, acumulación → riser). Luego python scripts/score.py cues.json.
Sintetiza todo (sin muestras, sin licencias), agrega una pista musical a 96 BPM que cae en break_frame y resuelve en end_frame, e imprime el volumen por segundo para que puedas verificarlo sin escuchar. Detalles y guía de ganancia: references/sound.md.
Paso 5 — Locución (opcional)
Líneas cortas, ≤ 6 palabras, una por toma, que coincidan con el texto en pantalla. Mejor opción gratuita:
python scripts/kokoro_tts.py lines.txt vo/ (Kokoro alojado, 3 voces para comparar). Agrega los archivos a la lista voiceover de la hoja de referencia con tiempos de inicio = cuando aparece el texto de esa toma; score.py recorta el silencio y baja la música debajo de la voz. Mide la duración de cada línea y asegúrate de que termine antes de que comience la siguiente. Opciones y lecciones: references/voiceover.md.
Paso 6 — Renderizar y entregar
<Html5Audio src={staticFile("audio/soundtrack.wav")} /> en la composición, luego
npx remotion render <CompositionId> out/ad.mp4. Envía el MP4 al usuario. Di claramente que no puedes escuchar el audio: los niveles y los tiempos se verificaron numéricamente, no de oído.
Reglas importantes
- Texto honesto: ninguna afirmación que el producto no pueda respaldar; mantén las advertencias (beta, testnet) en pantalla.
- No recrees el anuncio de una marca específica (logotipos, música, personajes) — toma prestado solo el estilo.
- Texto ≥ 48 px a 1080p, en pantalla ≥ 1.2 s, en la parte inferior izquierda o centrado, nunca sobre la cara del héroe.
- Renderiza imágenes fijas antes del renderizado completo; revisa un fotograma de cada toma.
- Mantén los fotogramas y el audio generados fuera de git (
.gitignore); confirma los scripts + storyboard.