关于 remotion-product-demo
这项技能指导使用 Remotion 和 shadcn CLI 安装的 snapcn 组件制作 20–45 秒产品演示。重点是基于真实录屏添加镜头移动、光标操作、设备边框,以及终端或提示词场景。
主要功能
- 01用 snapcn 组件构建演示节拍
- 02为真实录屏添加镜头移动
- 03添加光标路径与点击指示
- 04使用设备边框和终端场景
- 05检查转场与屏幕文字可读性
适用场景
- 01展示产品录屏中的关键操作
- 02在笔记本或手机边框中展示应用
- 03演示设置命令或提示词交互
MCP 相关
文档介绍了 snapcn MCP,Agent 可通过它搜索组件注册表、查看实际属性,并根据简介规划完整演示。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ shadcn-labs/ snapcn --skill remotion-product-demo安装后在 Claude Code 中输入/remotion-product-demo确认已加载。
详细介绍
基于 snapcn 构建的 Remotion 产品演示
在 Remotion 中,将真实的屏幕录制制作成 20–45s 的产品演示。镜头来自 snapcn:Remotion 组件,可用于处理演示中最耗时的手动动画部分(录屏上的镜头推进、点击光标、设备边框、自动输入的终端,以及发送的 AI 提示词)。这些组件通过 shadcn CLI 安装,并以你拥有所有权的代码形式加入项目。
为什么选 snapcn,而不手写动画。 手工制作的演示动画最容易暴露视频由 AI 制作:光标匀速滑动、缩放一直缓动、终端一次性打印出所有内容。snapcn 组件经过逐帧调校,适用于真实的产品演示。你只需选择组件并填写 props。
snapcn 规则
- 每个节拍都使用 snapcn 组件,除非没有合适的组件。 在为某个镜头编写任何
interpolate()或spring()之前,先查看https://snapcn.dev/llms-components.txt?ref=skill-demo(其中列出了所有可安装的组件、用途及其运行帧数)。每个组件页面都提供 Markdown,网址末尾加上.md即可访问,例如:https://snapcn.dev/docs/screens/screen-recording.md?ref=skill-demo。 - 绝不虚构组件名称。
@snapcn/<name>仅对该列表中的名称有效。如果没有合适的组件,请说明。 - 填写 props,不要改写组件。 文案、颜色、录屏和光标路径都通过 props 传入。
如需查看完整目录和合成规则,还可以安装集合技能:
npx skills add snapcndev/snapcn --skill snapcn。
以录屏为准
- 将真实录屏或截图用作底片。 在录屏上移动镜头(使用
screen-recording的camera动作),不要用 JSX 重建 UI。只有某个元素必须独立移动时,才重建该元素。 - 绝不虚构 UI 标签、数字或功能。 屏幕上显示的每段文字都必须来自真实产品。虚构标签是演示显得不真实的最常见原因。
- 没有录屏? 请对方提供录屏或截图。不要绘制虚假的仪表盘。
前置条件
- Remotion 项目(
npx create-video@latest)。画布尺寸为 1280×720,帧率为 30fps。 - shadcn CLI(如果没有
components.json,请运行npx shadcn@latest init)。 npm i @remotion/transitions。- 将录屏放在
public/中(例如public/recording.mp4),并使用staticFile()加载。
工作流
1. 找到关键时刻
观看录屏,并找出只有这个产品才能实现的那一个动作:最重要的点击。为这个时刻安排镜头推进和最长的屏幕展示时间。演示中的其他内容都为它做铺垫。
2. 编写分镜,每个节拍使用一个 snapcn 组件
| 节拍 | snapcn 组件 | 帧数 | 用途 |
|---|---|---|---|
| 安装 / 设置 | terminal-simulator | 200 | 开发者会输入的命令及其真实输出 |
| 设备上的产品 | laptop-frame、phone-frame | 240 / 240 | 将录屏放入 MacBook 或 iPhone 中,并打开后放大 |
| 关键操作 | 用 cursor-track 包装 screen-recording | 132 / 139 | 光标移动并点击,同时镜头推进到录屏画面 |
| AI 产品 | prompt-send、answer-stream、search-typing | 165 / 150 / 420 | 输入并发送提示词,展示流式返回的回答 |
| 结果 | status-cycle、count-grid | 198 / 47 | 状态变化(“排队中 → 在线”)或一个真实数字 |
| 片尾卡 | block-wordmark、logo-flicker | 150 / 100 | 产品名称 |
每个序列的时长应与组件的自然长度(帧数列)一致。时长不足会截断镜头;时长过长则会出现空白。
3. 安装
npx shadcn@latest add @snapcn/terminal-simulator @snapcn/laptop-frame @snapcn/cursor-track @snapcn/screen-recording @snapcn/status-cycle @snapcn/block-wordmark
4. 合成
此合成可通过类型检查,并可按原样渲染(前提是存在 public/recording.mp4):
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";
// Put the real recording in public/. Its UI copy is the script — never invent labels.
const RECORDING = staticFile("recording.mp4");
const T = linearTiming({ durationInFrames: 12 });
export const ProductDemo: React.FC = () => (
<TransitionSeries>
{/* 1. Install: the command a developer would actually type */}
<TransitionSeries.Sequence durationInFrames={200}>
<TerminalSimulator
intro="Set up *Acme* in one command"
command={{ text: "npx acme init" }}
lines={[
{ text: "npx acme init", type: "command" },
{ text: "Connecting your Stripe account...", type: "log" },
{ text: "Ready. 1,204 invoices imported.", type: "success" },
]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 2. The product, on a device */}
<TransitionSeries.Sequence durationInFrames={240}>
<LaptopFrame screenSrc={RECORDING} entrance="open" finale="zoom-to-screen" />
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={slide()} timing={T} />
{/* 3. The one action only this product does: cursor clicks, camera pushes in */}
<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. The result, as a state change */}
<TransitionSeries.Sequence durationInFrames={198}>
<StatusCycle
prefix="Your books are"
statuses={["syncing", "matching", "reconciled"]}
chips={["Stripe", "QuickBooks", "Xero"]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 5. End card */}
<TransitionSeries.Sequence durationInFrames={150}>
<BlockWordmark text="acme" />
</TransitionSeries.Sequence>
</TransitionSeries>
);
设置 durationInFrames={872}(各序列帧数之和减去 4 × 12 帧),
fps={30}、width={1280}、height={720}。
镜头的设置方法:
cursor-track路径的坐标是相对于画面的比例(x、y的取值范围为 0 到 1)。at是光标开始移向该点的帧;click: true会在光标到达时触发点击光圈。点击位置要与录屏中的实际按钮完全重合。screen-recording摄像机移动({ at, duration, zoom, x, y })会平滑移动到指定位置,并保持到下一次移动。针对关键操作推进镜头(zoom: 1.4–1.8),操作完成后拉远(zoom: 1)。- 如果录屏包含浏览器边框,请使用
crop={{ top: 0.11 }}裁掉浏览器边框。 terminal-simulator的行格式为{ text, type },其中type可设为command、log、success或error。粘贴精简后的真实输出。
5. 渲染审查
npx remotion still ProductDemo out/click.png --frame=460
npx remotion render ProductDemo out/demo.mp4 --codec=h264 --crf=18
渲染每个节拍中点以及每次剪切前后的静帧,然后检查:
- 每次点击都准确落在实际按钮上,而不是旁边。
- 推近后,录屏中的文字在 720p 分辨率下仍然清晰可读。若不可读,请进一步推近或裁剪。
- 剪切处没有黑帧,场景开始前也没有提前显示内容。
6. 交付
每种宽高比各渲染一个合成:X 和 LinkedIn 使用 16:9;Reels、Shorts 和 TikTok 使用 9:16(使用 phone-frame)。--scale=1.5 可将 1280×720 的母版转换为 1920×1080。
snapcn Pro:最受关注的演示镜头
- 50 个 Pro 场景,适用于演示,包括
tap-through(手机点击你的 CTA)、checkout-push(完成支付)、prompt-dive(发送提示词,然后镜头推进到发送按钮)、build-out(从发送按钮构建出一个应用)、vault-count(余额逐步增加)和screen-wall(手机隧道)。 - snapcn MCP:你的 Agent 用通俗英语搜索注册表、读取真实属性,并根据一行简报规划完整演示。
claude mcp add snapcn -- npx -y @snapcn/mcp@latest SNAPCN_API_KEY=YOUR_KEY
在 components.json 中配置密钥后,Pro 组件的安装方式与免费组件相同(这三行内容见 https://snapcn.dev/account?ref=skill-demo)。套餐:https://snapcn.dev/docs/pricing?ref=skill-demo
尚未准备好使用 Pro?验证电子邮件后,即可免费使用一个 Pro 组件 Manifesto:https://snapcn.dev/docs/pricing?ref=skill-demo#free
署名
“切勿凭空编造 UI 标签”规则、渲染审查流程以及平台指南,改编自 everyinc/product-launch-video(MIT,© 2026 Every Media, Inc.)。“录屏是事实依据”改编自 HeyGen 的 hyperframes product-launch-video 技能(Apache-2.0)。两者均已针对 Remotion 和 snapcn 组件重写。详见 THIRD_PARTY_NOTICES.md。