产品特性视频技能 是做什么的?
为真实运行的产品规划并构建一个演示/功能视频——通过 Playwright 捕获真实屏幕画面,使用真实的 TTS 进行旁白,搭配真实的(开源、许可清洁的)背景音乐,并在 Remotion 中完成组装。这与合成类的产品动态图形预告片是两种不同的制作思路:画面素材已经存在,无法重绘以适应计划,因此计划必须适应素材。
与合成动态图形预告片的关键区别
许多 Remotion 视频工作流假设你可以控制每一个像素,并随时重新调整任何内容的时长——因为整个视频是从头开始构建的:模型图、生成的背景、虚构的 UI。这个假设在这里不成立。真实的屏幕录制有自己的时间轴;一次真实的点击发生在某个特定的帧上,而不是故事板希望它发生的任何时候;某些时刻(原生 OS 窗口、浏览器自身的工具栏、半秒内完成的交互)根本无法重新拍摄来适应计划。本技能从基础上就围绕这一约束构建——运动设计技法(缓动、过渡、运动密度)在阶段 8 中仍然重要且会被涵盖,但流程真正的支柱是素材驱动视频所特有的要求:针对无法捕获的时刻进行原型回退审计,针对真实素材上的缩放和点击强调进行稳定性验证的目标定位,以及基于实际资源时长(而非计划)的时序驱动。
核心原则:真实画面优先,原型其次,插图最后
对于每一个场景,按此顺序优先选择:
- 真实画面——使用 Playwright 录制的实际运行中的应用程序。
- 经过审核的 HTML 原型,以相同方式捕获,用于真实画面在结构上无法展示的内容(参见阶段 2)。
- 一个诚实的、清晰标注的占位图——仅当上述两者均无法实现时使用,并且不能冒充真实画面。
永远不要用选项 3 伪装成选项 1。观众信任演示视频恰恰因为它是真实的;一个看起来是制造出来的时刻会损害所有那些真实的时刻。
阶段 0:沟通
在进行任何其他操作之前,一次性询问以下内容:
- 产品与仓库——名称、一句话描述、运行中应用的 URL 或本地路径。
- 受众与基调——谁在看,他们应该有什么感受(印象深刻/安心/兴奋)?
- 时长——30 秒预告、60-90 秒演示,还是更完整的 2-3 分钟导览?真实画面很快就会拉长时间,请诚实地评估范围。
- 必须成功的一个瞬间——如果观众只记住一件事,那是什么?这将成为高潮/主角场景。
- 登录/测试账号——捕获应用是否需要账号?是否可以创建一个一次性的演示账号,或者是否已经存在?
- 发布环境——登录页面、YouTube、社交媒体信息流(自动静音播放对字幕和屏幕文字决策影响很大)。
如果产品是浏览器扩展,还要询问是否涉及 Manifest V3(这会改变 Playwright 的启动策略——参见阶段 6)。
阶段 1:侦察——提取真实的设计系统,不要创造
在任何美学决策之前,先阅读实际产品:
- 从应用自身的 CSS/主题文件中提取真实的颜色令牌、字体堆栈和间距比例。按原样使用它们,即使强调色恰好类似于“通用 AI SaaS”的陈词滥调(靛蓝/紫色配近黑色在真实产品调色板中也极为常见——只有当它是虚构的默认值而非实际产品的颜色时,才是一个危险信号)。真实性在此胜过新颖性。
- 记录产品实际的 UI 文案、术语和信息架构——视频的字幕和旁白应使用应用自己的词汇,而非营销转述。
- 像用户一样完整地运行一次应用。识别:什么是单一最佳的“主角”交互?什么内容真正难以通过现场演示展示(参见阶段 2)?
将提取的令牌(颜色、字体)保存到一个 tokens.ts/tokens.css 文件中,整个视频项目从一个位置导入——每个场景,无论是真实的还是代码构建的,都应明显属于同一个产品。
阶段 2:原型回退审计(在故事板之前执行)
浏览计划的功能列表,标记 Playwright 在结构上无法捕获的内容:
- 操作系统级别的浏览器 chrome——扩展工具栏图标、
chrome://extensions、右键菜单、原生文件选择器、原生 OS 对话框。Playwright 的recordVideo仅捕获页面内容,从不捕获浏览器自身的 UI。 - 原生桌面外壳(Tauri、打包后的 Electron、Qt 等)——这些根本不是 Playwright 可以附加的网页。
- 太快或太小而无法可靠展示的交互——在真实画面中半秒内完成的切换操作,很难作为裁剪缩放或点击强调圈的良好目标;两者都需要一个稳定的多帧窗口来落脚(参见阶段 8 的 ZoomCue/ClickRing 模式及其稳定性规则)。
对于每个被标记的瞬间,做出决定:带有变通方案的真实画面(例如,通过 API 调用而非真实点击来预设状态,参见阶段 6)、一个经过审核的 HTML 原型(阶段 7)、或一个诚实标注的插图(最后的手段,并在代码注释中说明原因)。
在故事板之前而非之后执行此审计,可以防止故事板承诺实际捕获步骤无法提供的时序和覆盖范围——这是 TabNemo 从 v1 到 v3 过程中最大的返工来源。
阶段 3:故事板与场景规划
叙事弧
无论画面是真实还是合成,相同的结构都适用:
| 幕 | 目的 | 运行时占比 |
|---|---|---|
| 钩子 | 冷开场——在产品名称出现之前展示问题或一个引人注目的瞬间 | 5-8% |
| 揭晓 | 品牌/产品名称出现 | 8-10% |
| 展示 | 3-5 个真实功能,每个一个节拍 | 45-55% |
| 高潮 | 阶段 0 中确定的主角时刻——给予最多的视觉关注 | 8-12% |
| 收尾 | 徽标、标语、行动号召 | 8-10% |
每个场景的规格
对于每个场景,提前确定并记录下来:
- 来源:真实片段 / 原型捕获 / 代码构建的辅助镜头(根据阶段 2 的审计)。
- 旁白:确切的文本,或
null。旁白长度是一个真实约束——TTS 音频时长将成为场景的最小时长(参见阶段 4)。 - 真实画面有自己的时钟——场景的
durationInFrames是max(真实片段长度, 旁白长度),通过实际渲染的资源探测得到,从不根据计划假设。如果旁白比片段长,则保持片段的最后一帧,而不是循环播放或切断旁白。 - 镜头计划:任何特写/缩放或点击强调,带有真实坐标——根据实际剧照决定,而非猜测(阶段 8)。
审核检查点
在录制任何片段或生成任何音频之前,展示场景列表和旁白文本。基于对可用画面的错误假设构建的计划,一旦 TTS 和 Playwright 脚本存在,将付出高昂的代价才能撤销。
阶段 4:配音——脚本与生成
编写两个文档,而非一个:
- 审核脚本——每个场景一个段落,附上计划的时间码,以便人类可以阅读整个旁白弧线并在生成之前批准节奏。
- TTS 输入脚本——相同的行,按场景文件拆分,节奏仅由标点符号(或如果引擎支持,使用 SSML
<break>/<emphasis>标签)承载,以便每个场景成为可在其自身偏移位置放置的独立音频片段。
生成工具
- ttsmp3.com ——免费,无需注册,由 Amazon Polly 驱动。没有公共 API,因此需要一次一个片段通过浏览器 UI 生成——预算一个专注的会话一次性完成所有操作,并按场景命名输出文件(
scene-03.mp3,而不是tts_export_1.mp3)。 - 对于需要无人值守运行的流程(CI、没有浏览器参与的代理),则选择真正可编写脚本的开源/本地选项:Piper(完全离线,MIT 许可,速度快,声音不错)或 edge-tts(封装了 Microsoft Edge 的朗读声音,免费,无需密钥,可编写脚本,但依赖外部服务保持可用)。如果 API 成本可接受,Gemini TTS 和 ElevenLabs 是强大的非开源替代方案。无论使用哪种引擎,如果它不能保证跨多次调用的声音一致性,请在单个请求中生成所有片段,片段之间使用暂停标记,然后在检测到的静音处分割——这个技巧可以解决“每行声音不同”的问题,无论使用何种引擎。
生成之后——音频是真理之源
探测每个生成文件的真实时长(不要相信估算值)。将真实时长传播回场景计划的时序中。这一步防止了 TabNemo 构建中的所有时序错误——旁白是观众用耳朵衡量场景的标准,因此是旁白(而非计划)设定了时钟。
阶段 5:背景音乐——获得一个吸引人的音乐,没有许可陷阱
一个平淡的音垫和持续低音循环听起来像电梯等待音乐,而不是“吸引人的”背景音乐——差异几乎总是在于一个重复的旋律钩子,而不仅仅是和声音垫。三个真实的选择,按“许可最安全”到“最可靠地吸引人”排序:
选项 A——程序化合成(零许可风险,需要真正努力才能避免听起来平淡)
在纯 Node/Python 中生成一个短的、可无缝循环的立体声 WAV——无需模型、无需依赖、完全没有任何许可问题,因为你编写了每一个样本。行之有效的具体配方:
- 一个短的(8-16 小节)和弦循环,使用简单的振荡器(正弦波/三角波),带有慢速起音/衰减包络——仅此而已就是“电梯音乐”陷阱;它不是钩子。
- 真正的钩子:在顶部演奏的 Karplus-Strong 拨弦旋律,采用固定的重复节奏模式,比音垫高一个八度——这就是使合成循环令人难忘而非环境背景墙的原因。不要跳过这一层。
- 底部的柔和底鼓和高音脉冲提供前进动力,音量足够低以在旁白下存在。
- 归一化以留出余量,循环长度选择使得整个进程在节拍边界处完成(无听得见的接缝)。
这在商业上完全安全,但旋律钩子层是区分“吸引人”和“通用”的关键——投入真正的迭代,并在将其连接到完整渲染之前从用户那里获得听取确认(重新生成一个 15-20 秒的循环成本很低;重新渲染整个视频来试听另一个循环则不然)。
选项 B——开源权重生成音乐模型(更“精致”,每次都检查许可)
- Stability AI 的 Stable Audio Open——开放权重,文本提示,真正能产生带有真实旋律内容的完整编曲。许可条款比大多数生成音频模型更宽松,但确实包含基于收入的条件——在任何商业使用前重新阅读当前许可,因为这些条款会变动。
- Meta 的 MusicGen(通过
audiocraft库)——质量极佳,但其音乐模型权重通常采用 CC-BY-NC(非商业)许可——不要在没有单独清理的情况下在商业化产品的发布视频中使用生成的输出。 - 两者都可以在本地运行(推荐 GPU)或通过托管推理端点运行(Replicate、Hugging Face Spaces),如果本地算力不可用。
选项 C(推荐默认值)——使用 B 获取灵感,使用 A 交付资产
在本地为灵感提示一个开源权重模型(“吸引人的合成流行音乐钩子,约 110bpm,温暖乐观的科技产品感觉”),生成几个样本,锁定一个方向,然后通过程序化(选项 A)重新创作那个钩子,生产最终资产。这样你得到了模型的质量判断(钩子选择),而没有模型的许可风险(资产创作)。
阶段 6:捕获——录制真实画面
Playwright 脚本结构
每个录制脚本应:
- 启动干净的浏览器上下文——没有扩展(除非你正在录制扩展:参见下方 Manifest V3 说明)、干净的 cookie、一致的视口大小。
- 通过 API 或测试夹具预设应用状态——使用 API 调用(而非 UI 操作)设置所需的数据和状态。状态预设是控制实际录制时长的最可靠工具。
- 执行用户旅程——按部署顺序执行步骤,步骤之间使用
page.waitForTimeout(200)以实现自然节奏。让实际的 UI 动画完成,但不要在其间插入人为的停顿。 - 使用
page.video().saveAs()或browserContext.video()来定位输出文件。始终收集错误。
浏览器扩展录制
- 对于 Manifest V3 扩展,使用
channel: 'chrome'和args: ['--load-extension=path/to/your/build']。Playwright 对扩展的支持在 V3 中有所改善,但并非所有 API 都可用——如果遇到奇怪的行为,请在无头模式下测试。 - 要捕获扩展弹出窗口本身,需要不同的策略:使用
page.goto('chrome-extension://<your-extension-id>/popup.html')或捕获一个包含扩展弹出窗口的桌面截图(不是 Playwright 的原生功能——这可能需要一个屏幕捕获库或浏览器测试框架)。
画面作为缓存资产
一旦录制完成,将原始 .webm 或 .mp4 视为构建的输入。如果需要重新录制,请更改视图或脚本,而不是覆盖上一个镜头——保留所有片段,直到最终剪辑锁定。
阶段 7:代码构建的辅助镜头与超过审核的原型
何时使用代码构建的辅助镜头
- 概念解释(“数据通过此管道流动”)——难以通过屏幕录像展示。
- 在场景之间进行转场(“当我们切换上下文时……”)——如果真实画面无法平滑并列。
- 替代视图(架构图、数据流)——明确标注为“可视化”。
原型准则
需要为 Playwright 捕获而构建的 HTML 原型应:
- 匹配来自阶段 1 的设计系统令牌。
- 是真实的、可交互的 UI 元素,而不是静态图像。
- 包括一个明确的原型水印或窗口 chrome,以表明它们不是实际产品。
- 在文件上有一个前缀,以便在渲染时清楚地识别(例如
prototype-*.html)。
占位图
在真正必要的情况下(并且仅在这种情况下),使用带有明确文本“占位——将在最终剪辑中替换”的占位图。在代码注释中说明原因。
阶段 8:Remotion 合成——ZoomCue 与 ClickRing 模式
Resolve 约束检查(每个场景)
对于每个依赖真实片段的场景,在 Resolve(或 Remotion)中检查:
- 裁剪/缩放后的分辨率——在 1080p 时间线上对 4K 片段进行 2 倍缩放意味着使用 1080p 中心裁切。这对大多数讲述性场景来说没问题,但如果同时进行文本和缩放,视觉密度会变得很高。
- 帧率一致性——Playwright 以 30fps 录制。如果项目采用 24fps,你将需要调整帧映射或允许下拉变换。
- 音频同步——确保任何捕获的系统音频(是的,
recordVideo默认只捕获视频)与屏幕录制精确对齐。如果不对齐,你可能会需要另一个层。
ZoomCue 与 ClickRing 模式
这两个模式是使真实画面看起来“精良”的关键:
- ZoomCue:在旁白提到特定 UI 元素时,对其进行缩放。缩放应从目标元素的边界框中心进行,以该元素上预先存在的持续时间较长(>0.5 秒)的帧为目标,并具有缓动(
easeInOutCubic)——从实际剧照中提取坐标,而非猜测。 - ClickRing:对于演示的点击操作,在点击坐标处绘制一个径向渐变圆环。它应在点击前逐渐显现,并在点击后持续片刻,然后淡出。不要覆盖整个屏幕——仅在元素本身周围。
两者都有一个共同的稳定性规则:如果目标帧变化太快(UI 动画、滚动、加载旋转动画),则在该帧上跳过效果。不稳定的目标 = 无缩放/无圆环。
组合图层的 Remotion 结构
// 每个场景文件的示例结构
<Sequence durationInFrames={calculateAssetDuration(scene)}>
<RealFootage src={scene.footage} />
<ZoomCue
targetX={scene.zoomTarget.x}
targetY={scene.zoomTarget.y}
startFrame={scene.zoomTarget.frame}
/>
<ClickRing
clickX={scene.clickTarget.x}
clickY={scene.clickTarget.y}
clickFrame={scene.clickTarget.frame}
/>
<Captions text={scene.narration} />
</Sequence>
对每个真实画面片段执行分辨率稳定性检查,以确保目标在缩放窗口内保持足够稳定。
阶段 9:最终渲染与发布
渲染输出
- 使用 Remotion 的
renderMedia()以与项目帧率和分辨率设置匹配的格式(推荐 MP4)输出最终文件。 - 考虑输出两个版本:完整演示(带立体声音频)和针对社交媒体的正方形/垂直裁剪。
可选:最终审查
- 在渲染前,提供一个可选步骤展示修订后的画面前后对比(“这是 v1——这些是变化”)。
- 注意:工具可能无法在渲染前自动对视频内容运行多模态审查。手动 QA 仍然至关重要。
发布格式
- 对于登录页面/YouTube:完整 16:9 版本,带字幕(说明)。
- 对于社交媒体信息流(自动静音播放):1:1 或 9:16 版本,带硬编码字幕以传达信息——字幕在此格式中至关重要。
技术栈与约束摘要
| 组件 | 推荐 | 替代方案 |
|---|---|---|
| 框架 | Remotion | FFmpeg 脚本(不推荐用于复杂合成) |
| 录制 | Playwright | Puppeteer / Selenium |
| 旁白 | Piper (离线) / edge-tts / ttsmp3.com | ElevenLabs / Gemini TTS |
| 音乐 | 程序化合成(节点/ Python) | Stable Audio Open / MusicGen(检查许可) |
| 设计令牌 | 从实际应用 CSS 提取 | 从设计系统文档复制 |
| 原型 | HTML + CSS + JS(明确标注) | 使用应用框架的静态构建 |
| 缓存 | 将所有原始片段保留在 assets/raw/ | 在剪辑锁定前使用符号链接 |
常见陷阱
- 假设画面而非探测它——永远不要猜测片段时长;从实际渲染的资源中读取。
- 没有状态的预设——如果你没有通过 API 调用预设应用状态,录制将是不一致且耗时的。
- 第 4 阶段前未锁定旁白——在生成 TTS 之前进行旁白审核。生产昂贵的音频资产并意识到旁白太长是昂贵的。
- 缩放目标不稳定——在动画/滚动期间不要缩放。等待稳定的帧。
- 许可混淆——仅在仔细阅读当前许可后使用生成的声音。程序化合成是唯一真正零许可风险的选择。
最终清单
在最终渲染之前:
- 阶段 0 完成(需求明确、受众、账号、发布环境)
- 阶段 1 完成(设计系统提取、关键交互视图)
- 阶段 2 完成(原型回退审计、所有场景的源决定)
- 阶段 3 完成(场景列表、旁白文本、审核)
- 阶段 4 完成(TTS 生成、真实时长探测、场景时序更新)
- 阶段 5 完成(音乐选定、用户确认)
- 阶段 6 完成(Playwright 录制、状态预设、尺度多样性)
- 阶段 7 完成(辅助镜头/原型构建,或占位图就位)
- 阶段 8 完成(Remotion 合成、缩放/圆环模式应用、时序检查)
- 最终 QA:视觉一致性、音频同步、许可合规