软件产品启动视频
制作一段30–60秒的视频,让观众理解并想要该产品。
重塑一切的决策:重建,而非录制
屏幕录制问题重重。真实延迟就是死寂时间。重拍成本高昂。无法定格画面,无法放慢一帧而加速另一帧,也无法在不触发压缩伪影的情况下紧密裁剪。
因此,将UI重建为Remotion中帧驱动的React。每个视觉效果都是useCurrentFrame()的纯函数。文字打字效果落在精确的曲线上,加载状态在节拍上解析,重拍只需修改一个数字。
这种方法仅在你能够读取产品的实际代码(如果是本地)或DOM+CSS(如果是托管)并忠实地复现时才合理。这样做——获取真实的类名、真实的颜色、真实的文案。重建结果应与录制无异,然后更胜一筹。
何时改用录制: 重度3D、产品内的视频内容、canvas/WebGL表面或原生桌面应用。如果某个特定表面无法重建,仅录制该表面并通过<OffthreadVideo>合成。
阶段1 — 理解产品
在开始此阶段前,请先阅读references/discovery.md。它涵盖了浏览与分流流程、凭据交流,以及如何从实时站点提取设计系统。
简短版:
- 给定URL:浏览它。先看落地页(它告诉你产品如何定位自己),然后看应用本身。弄清楚产品为谁做什么工作。
- 给定本地仓库/开发服务器:阅读代码。内容丰富得多——你能获得真正的组件、真正的主题令牌、真正的种子数据。
- 分页面产品。 大多数产品有20个屏幕,其中3个重要。认证、设置、计费、隐私、账户、入职模板——这些几乎从不构成核心故事。找到产品执行其独有能力的关键屏幕。
- 如果核心内容需要登录,先询问——测试凭据,或他们本地开发中的种子账户。如果两者都不可用,不要放弃也不要伪造你从未见过的会话:切换到章节式结构,从落地页自己的功能卡片、文案和组件中构建。
discovery.md中有收集流程和诚实规则。
然后在构建前向用户确认你的理解——对产品的错误理解会导致整个构建失败。向他们展示:你认为产品做什么、你计划展示的2–4个屏幕、主角场景、镜头列表和音乐问题(见阶段4)。一次检查点,然后启动。
阶段2 — 选择结构
阅读references/structure.md。两种结构有效;选择错误会浪费整个构建。
结构A — 单一叙事。默认选项。 一个用户完成一项工作并获得一个成果。不是功能巡游。
| 拍子 | 任务 |
|---|---|
| 钩子 (0–5秒) | 用观众自己的语言陈述问题。尚未出现UI。 |
| 请求 (5–12秒) | 用户请求该事物。聚焦输入。 |
| 工作 (12–25秒) | 产品直观地执行某些困难操作。展示证据。 |
| 成果 (25–35秒) | 输出完整地以可读尺寸呈现。 |
| 控制 (35–45秒) | 用户更改它并保持掌控。 |
| 标板 (45–50秒) | 标志、一行文字、域名。 |
工作和控制拍子是将真实演示与模拟区分开来的关键。“它询问了我而不是猜测”和“我能编辑它生成的内容”是信任论据,而信任正是启动视频真正售卖的东西。
选择产品执行人类难以自行完成操作的时刻,并使输出具体可见——生成的文档、构建的图表、修复的bug、部署的站点。具体的成果是人们会记住的。
结构B — 章节式功能影片。 三个功能,每个由纯语言标签卡引入,然后展示。
hook → [01 label → feature] → [02 label → feature] → [03 label → feature] → slate
当产品受限且你从其落地页构建时,或功能之间确实没有共享用户旅程时,或你想从一个构建中获得三个独立片段时使用它。三是一个数字——四个意味着没有一个能落地。
不要对序列进行章节化。 如果功能在单个会话中依次发生(研究 → 草稿 → 编辑),那是一个工作流,将其标记为三个功能会与素材冲突。如果有人要求对顺序产品进行章节化,提供中间路径:保留单一叙事,在能力出现时将标签置于动作上方。相同的可读性,相同的剪辑边界,无运行时成本,故事完整。
structure.md涵盖章节卡设计、如何编写标签(命名结果,而非机制;借用产品自己的词汇)、过渡和排序。
阶段3 — 夯实一切
无论产品处于什么领域,不要虚构其内容。如果是法律产品,法规必须是真实的。如果是分析产品,数字必须合理且内部一致。如果是代码工具,代码必须在读者脑中编译。
从仓库、API、种子数据或文档中提取真实内容。领域专家观看这些视频,一个虚构的细节会失去所有专家。当事人名称、日期和金额数字可以虚构——那些是针对特定客户的,不是对世界的声明。
在数据文件中保留来源注释,说明每个事实来自哪里。未来的你会需要它。
阶段4 — 构建
运行脚手架,它会锁定实际能一起工作的版本并写入配置:
python3 <skill-dir>/scripts/scaffold_video.py <target-dir> \
--name "product-launch" --fps 60 --seconds 45
它会创建一个独立的Remotion项目(其自己的git仓库——除非被要求,否则绝不将视频工具添加到产品仓库中),复制useCamera.ts,并留给你一个时间线模块供填充。
然后,按顺序:
-
src/timeline.ts— 帧数学和镜头边界。选择一个节拍为整数帧的BPM(在60fps下:120 BPM = 30帧,90 BPM = 40)。将每个镜头边界放在一个节拍上。即使没有音乐,这也会给剪辑一个内在节奏,并且意味着以后添加音乐背景时无需重新编辑。 -
src/data/script.<lang>.ts— 每个字符串、每个数字、每个文档内容片段,都在一个文件中,带有来源注释。不要在组件中硬编码任何内容。后期调整时间和翻译都变得微不足道。 -
组件 — 重现产品的UI。复制真实的类名。如果产品使用Tailwind,将其配置和主题CSS引入;如果它使用CSS变量进行颜色设置,你必须将其带过来,否则所有内容都会渲染成无色。
-
src/scenes/ProductScene.tsx— 一个导出的B对象,持有每个拍子的绝对帧数。DOM、镜头、声音都从中读取。调整时间只需编辑该块,其他无需动。
阅读references/camera.md了解镜头系统,references/motion.md了解持续时间和排版。
阶段5 — 音频
两个轨道,两个文件,两个<Audio>标签:音效和音乐。将它们分开,以便任意一个都可以被替换而无需重新生成另一个。
音效 — references/sound.md。克制是整个纪律:一个45秒的视频通常总共需要三到五个事件。一个“砰”声意味着某物出现,一个“嗖”声意味着元素在镜头内移动,一个“呼”声意味着镜头移动。
python3 <skill-dir>/scripts/make_sfx.py sfx.spec.json public/sfx.wav
音乐 — references/music.md。在构建前先询问。 大多数人都有意见,很多人已经有一首曲子;询问只需一句话,可能节省整个努力:
你想要音乐背景吗?如果你有曲子,发给我,我会剪辑到它上面。如果没有,我可以合成一个——充满活力、平静、电影感、极简、温暖还是紧张?
如果他们有曲子,就剪辑到它上面:找到它的BPM,设置时间线匹配,将镜头边界移到它的节拍上。否则合成一个背景,其编排变化落在你的剪辑点上:
python3 <skill-dir>/scripts/make_music.py music.spec.json public/music.wav
在每个真实镜头边界放置一个sections条目,在你最大的剪辑点放置一个hits条目,在任何你想让观众阅读而不是感受的暂停台词下放置一个ducks条目。音乐峰值约为0.30,音效约为0.62。根据产品是什么选择情绪——严肃主题需要更平静的背景,繁忙的剪辑需要更稀疏的背景。
阶段6 — 用静帧验证,在渲染前
这是紧循环,跳过它会浪费数小时。
npx remotion still <CompositionId> out/f0700.png --frame=700
然后实际查看PNG。为每个镜头渲染一个静帧,再加上每个过渡处的一个。检查:主题是否在帧内,是否有单词被截断,是否有空白空间,文本是否合适。
添加一个静默组合(defaultProps: { withAudio: false }),这样静帧就不需要音频文件存在。
尽可能进行数值调优。 缓动曲线、滚动距离、频谱内容——这些都是可计算的。编写一个一次性Python脚本,对曲线进行采样并打印你原本猜测的内容。它比渲染快且准确。
只有在静帧正确后才渲染完整视频。
npx remotion render <CompositionId> out/video.mp4 --concurrency=4
在16GB机器上将并发数限制在4左右——Remotion为每个插槽生成一个Chrome标签页,默认值(核心数)会导致交换。
阶段7 — 诚实地交付
发送文件。然后直截了当地说:
- 你未能验证的内容。你可以阅读静帧;你无法判断八秒感觉如何,也无法听到音频。说明这一点。
- 任何你重建而非观察到的屏幕 —— 特别是在受限产品上。列出它们,并主动提出如果他们分享访问权限,可以重做那些拍子。
- 你做出的用户可能不同意的判断决策。
- 如何更换音乐:将任何WAV或MP3放在
public/music.wav并重新渲染。 - 在构建过程中你发现的产品问题——渲染bug、错误标签、缺失状态。你比大多数人都更仔细地阅读了他们的UI。那个观察往往比视频本身更有价值。
参考文件
当你到达相关阶段时再阅读它们——它们很详细,预先全部加载没有价值。
| 文件 | 何时使用 |
|---|---|
references/discovery.md | 阶段1 — 浏览、页面分流、凭据、设计系统,以及从受限产品的落地页构建 |
references/structure.md | 阶段2 — 单一叙事 vs 章节,章节卡设计,编写功能标签,过渡,排序 |
references/camera.md | 构建镜头 — 布局空间、焦点镜头、剪辑 vs 推进 vs 变形、隔离组件 |
references/motion.md | 动画持续时间、排版、钩子模式、问题卷轴 |
references/sound.md | 声音设计 — 砰/嗖/呼词汇表、克制、合成键盘和点击声 |
references/music.md | 寻找 vs 合成背景、选择情绪、将章节对齐到剪辑、在音效下混合 |
references/pitfalls.md | 在首次渲染前阅读。 耗费真实时间的bug,每个都有修复方法。 |
捆绑脚本
下面的<skill-dir>是此技能自己的目录——技能加载时传递给你的路径。不要假设固定的安装位置;技能可能作为个人安装、插件或检入到项目中使用。
| 脚本 | 作用 |
|---|---|
scripts/scaffold_video.py | 创建Remotion项目,包括可工作的版本锁定和配置 |
scripts/make_sfx.py | 根据JSON事件列表合成音效轨道。无样本,除numpy外无需其他依赖。 |
scripts/make_music.py | 在六种情绪之一中合成音乐背景,其编排与你的剪辑对齐。相同的依赖。 |
assets/useCamera.ts | 焦点镜头钩子——复制到src/hooks/ |
assets/ChapterCard.tsx | 章节式形状的章节卡——复制到src/components/ |
简短版本
重建而非录制。一个故事,一个成果——除非产品受限或其功能确实分离,则使用三个章节和纯标签。夯实每个领域事实。帧是一切单位。隔离组件而非裁剪页面。UI运动150–300ms,镜头移动约1秒。四个声音就足够了。制作音乐前先询问。在渲染前查看静帧。说出你无法检查的内容和你推断的内容。