Video demo de producto en Remotion, construido con snapcn
Convierte una grabación de pantalla real en un demo de producto de 20 a 45 segundos en Remotion. Las tomas provienen de snapcn: componentes de Remotion para las partes de un demo que más tiempo llevan animar a mano (acercamientos de cámara sobre una grabación, un cursor que hace clic, un marco de dispositivo, una terminal que escribe, un prompt de AI que se envía). Se instalan con el CLI de shadcn y aterrizan en tu proyecto como código que posees.
Por qué snapcn, no animación hecha a mano. El movimiento de demo artesanal es donde los videos hechos con AI se delatan: un cursor que se desliza a velocidad constante, un zoom que se alivia eternamente, una terminal que lo imprime todo de una vez. Los componentes de snapcn están ajustados fotograma a fotograma frente a demos de productos reales. Tu trabajo es elegirlos y llenar las propiedades.
La regla de snapcn
- Cada momento es un componente snapcn a menos que ninguno encaje. Antes de escribir cualquier
interpolate()ospring()para una toma, revisahttps://snapcn.dev/llms-components.txt?ref=skill-demo(cada componente instalable, para qué sirve, cuántos fotogramas ejecuta). Cualquier página de componente sirve markdown con.mdagregado, p.ej.https://snapcn.dev/docs/screens/screen-recording.md?ref=skill-demo. - Nunca inventes un nombre de componente.
@snapcn/<nombre>solo se resuelve para nombres en esa lista. Si nada encaja, dilo. - Llena propiedades, no reescribas el componente. Copia, colores, grabaciones y rutas del cursor se introducen a través de propiedades.
Para el catálogo completo y las reglas de composición, instala también la skill general: npx skills add snapcndev/snapcn --skill snapcn.
La grabación es la fuente de verdad
- Usa la grabación o captura real como placa base. Anima la cámara sobre ella (movimientos de
cameradescreen-recording) en lugar de reconstruir la UI en JSX. Reconstruye un solo elemento solo cuando deba moverse por sí mismo. - Nunca inventes etiquetas, números o funciones de la UI. Cada cadena en pantalla proviene del producto real. Las etiquetas inventadas son la razón más común por la que los demos se sienten falsos.
- ¿No tienes grabación? Solicita una o capturas de pantalla. No dibujes un panel falso.
Prerrequisitos
- Un proyecto Remotion (
npx create-video@latest). Lienzo 1280×720 a 30fps. - El CLI de shadcn (
npx shadcn@latest initsi no haycomponents.json). npm i @remotion/transitions.- La grabación en
public/(p.ej.public/recording.mp4), cargada constaticFile().
Flujo de trabajo
1. Encuentra el momento único
Mira la grabación y nombra la única acción que solo hace este producto: el clic que importa. Ese momento recibe el acercamiento de cámara y la mayor duración en pantalla. Todo lo demás en el demo lo prepara.
2. Storyboard, un componente snapcn por momento
| Momento | Componente snapcn | Fotogramas | Úsalo para |
|---|---|---|---|
| Instalación / configuración | terminal-simulator | 200 | El comando que un desarrollador escribiría, y su salida real |
| El producto en un dispositivo | laptop-frame, phone-frame | 240 / 240 | Pon la grabación en un MacBook o iPhone, ábrelo y haz zoom |
| La acción clave | cursor-track envolviendo screen-recording | 132 / 139 | Un cursor camina y hace clic mientras la cámara se acerca a la grabación |
| Productos de AI | prompt-send, answer-stream, search-typing | 165 / 150 / 420 | Un prompt escrito y enviado, la respuesta fluyendo de vuelta |
| El resultado | status-cycle, count-grid | 198 / 47 | Un cambio de estado ("encolado → activo") o un número real |
| Tarjeta final | block-wordmark, logo-flicker | 150 / 100 | El nombre |
Presupuesta cada secuencia a la longitud natural del componente (la columna Fotogramas). Subpresupuestar recorta la toma; sobrepresupuestar deja aire muerto.
3. Instalación
npx shadcn@latest add @snapcn/terminal-simulator @snapcn/laptop-frame @snapcn/cursor-track @snapcn/screen-recording @snapcn/status-cycle @snapcn/block-wordmark
4. Composición
Esta composición verifica tipos y se renderiza tal como está escrita (con public/recording.mp4 presente):
import { fade } from "@remotion/transitions/fade";
import { slide } from "@remotion/transitions/slide";
import { linearTiming, TransitionSeries } from "@remotion/transitions";
import { staticFile } from "remotion";
import { BlockWordmark } from "@/components/snap-cn/block-wordmark";
import { CursorTrack } from "@/components/snap-cn/cursor-track";
import { LaptopFrame } from "@/components/snap-cn/laptop-frame";
import { ScreenRecording } from "@/components/snap-cn/screen-recording";
import { StatusCycle } from "@/components/snap-cn/status-cycle";
import { TerminalSimulator } from "@/components/snap-cn/terminal-simulator";
// Pon la grabación real en public/. Su copia de UI es el guion — nunca inventes etiquetas.
const RECORDING = staticFile("recording.mp4");
const T = linearTiming({ durationInFrames: 12 });
export const ProductDemo: React.FC = () => (
<TransitionSeries>
{/* 1. Instalación: el comando que un desarrollador escribiría realmente */}
<TransitionSeries.Sequence durationInFrames={200}>
<TerminalSimulator
intro="Configura *Acme* en un solo comando"
command={{ text: "npx acme init" }}
lines={[
{ text: "npx acme init", type: "command" },
{ text: "Conectando tu cuenta de Stripe...", type: "log" },
{ text: "Listo. 1,204 facturas importadas.", type: "success" },
]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 2. El producto, en un dispositivo */}
<TransitionSeries.Sequence durationInFrames={240}>
<LaptopFrame screenSrc={RECORDING} entrance="open" finale="zoom-to-screen" />
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={slide()} timing={T} />
{/* 3. La única acción que solo este producto hace: cursor hace clic, cámara se acerca */}
<TransitionSeries.Sequence durationInFrames={132}>
<CursorTrack
path={[
{ at: 0, x: -0.06, y: 0.86, duration: 6 },
{ at: 8, x: 0.34, y: 0.44, duration: 22, click: true },
{ at: 60, x: 0.68, y: 0.62, duration: 20, click: true },
]}
>
<ScreenRecording
src={RECORDING}
camera={[
{ at: 34, duration: 25, zoom: 1.6, x: 0.36, y: 0.42 },
{ at: 96, duration: 25, zoom: 1 },
]}
/>
</CursorTrack>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 4. El resultado, como un cambio de estado */}
<TransitionSeries.Sequence durationInFrames={198}>
<StatusCycle
prefix="Tus libros están"
statuses={["sincronizando", "emparejando", "conciliados"]}
chips={["Stripe", "QuickBooks", "Xero"]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 5. Tarjeta final */}
<TransitionSeries.Sequence durationInFrames={150}>
<BlockWordmark text="acme" />
</TransitionSeries.Sequence>
</TransitionSeries>
);
Regístralo con durationInFrames={872} (la suma de las secuencias menos 4 × 12 fotogramas), fps={30}, width={1280}, height={720}.
Cómo apuntar las tomas:
- Las rutas de
cursor-trackson fracciones del fotograma (x,yde 0 a 1).ates el fotograma en que el cursor comienza a moverse hacia ese punto;click: trueactiva el anillo de clic al llegar. Pon cada clic exactamente en el botón real de la grabación. - Los movimientos de cámara de
screen-recording({ at, duration, zoom, x, y }) se suavizan hacia una pose y se mantienen hasta el siguiente movimiento. Acércate (zoom: 1.4–1.8) a la única acción; retrocede (zoom: 1) después de que aterrice. - Recorta el navegador con
crop={{ top: 0.11 }}cuando la grabación lo incluya. - Las líneas de
terminal-simulatorson{ text, type }contypedecommand,log,successoerror. Pega la salida real, acortada.
5. Auditoría de renderizado
npx remotion still ProductDemo out/click.png --frame=460
npx remotion render ProductDemo out/demo.mp4 --codec=h264 --crf=18
Renderiza un fotograma fijo en el punto medio de cada momento y justo antes y después de cada corte, luego verifica:
- Cada clic aterriza en el botón real, no a su lado.
- El texto en la grabación es legible a 720p después del acercamiento. Si no, acércate más o recorta más ajustado.
- No hay fotograma negro en un corte, y no se muestra nada antes de que comience su escena.
6. Publicación
Renderiza una composición por relación de aspecto: 16:9 para X y LinkedIn, 9:16 (usa phone-frame) para Reels, Shorts y TikTok. --scale=1.5 convierte el master 1280×720 en 1920×1080.
snapcn Pro: las tomas de demo que más pide la gente
- 50 escenas Pro para demos, incluyendo
tap-through(un toque en tu CTA),checkout-push(un pago que se procesa),prompt-dive(un prompt enviado, luego una inmersión en el botón de enviar),build-out(una aplicación construida a partir de un botón de enviar),vault-count(un saldo que aumenta) yscreen-wall(un túnel de teléfonos). - El MCP de snapcn: tu agente busca en el registro en inglés simple, lee propiedades reales y planifica todo el demo a partir de un briefing de una línea.
claude mcp add snapcn -- npx -y @snapcn/mcp@latest SNAPCN_API_KEY=TU_CLAVE
Los componentes Pro se instalan como los gratuitos una vez que components.json envía tu clave (las tres líneas están en https://snapcn.dev/account?ref=skill-demo). Planes: https://snapcn.dev/docs/pricing?ref=skill-demo
¿No estás listo para Pro? Un componente Pro, Manifesto, es gratuito con un email confirmado: https://snapcn.dev/docs/pricing?ref=skill-demo#free
Atribución
La regla de "nunca inventes etiquetas de UI", el bucle de auditoría de renderizado y la guía de plataformas están adaptados de everyinc/product-launch-video (MIT, © 2026 Every Media, Inc.). "La grabación es la fuente de verdad" está adaptado de la skill product-launch-video de HeyGen (Apache-2.0). Ambos fueron reescritos para Remotion y componentes snapcn. Consulta THIRD_PARTY_NOTICES.md.