openvidstudio 是做什么的?
从项目的实际运行应用构建演示视频。每个画面都来自真实产品;不生成任何内容。
开始之前
运行 preflight。它会检查 node、ffmpeg、Playwright 的 Chromium、应用是否实际响应以及旁白引擎是否存在。每个失败都会指明修复方法。跳过这一步意味着缺少的依赖会在长时间渲染后暴露出来。
如果工具未注册,则表示服务器未安装。请指引用户在 MCP 配置中添加以下内容,然后重启客户端:
{ "mcpServers": { "openvidstudio": { "command": "npx", "args": ["-y", "@openvidstudio/mcp-server"] } } }
流程
preflight -> extract_brand -> plan_beats -> [write VO] -> validate_beats -> APPROVAL GATE
-> write_beats_file -> capture_screenshot -> scaffold_scene -> validate_scenes
-> [plan_sound_effects] -> generate_narration -> stitch_composition -> contact_sheet
-> render_video -> qc_extract_frames
1. 需求收集
先自己搞清楚,再提问。 常见的请求就是“给这个项目做个演示视频”,没有其他说明。这就足够了,不必追问。
先阅读仓库,而不是询问用户:
README.md说明了产品是什么,以及它重要的功能。package.json中的脚本说明了如何启动它,开发脚本通常会指明端口。- 路由或页面说明了有哪些内容可以拍摄。
然后自行启动应用并确认其响应。不要问用户需要查找的 URL;找到开发命令,运行它,并检查。仅当启动需要你不知道的信息(如缺少 .env 或数据库未启动)时才询问。
真正值得询问的是仓库无法告诉你的:
- 视频应该多长?
- 如果仓库有很多功能,应该展示哪两三个?
- 视频面向谁,是落地页访客还是正在安装的用户?
一次只问一个问题,并且只问仓库无法回答的问题。 一开始就抛出六个问题是最快让人感到厌烦的方式。如果情况不明确,docs/PLANNING.md 中有完整的决策树。
通过展示结果来结束工作:mp4 路径、时长以及 contact_sheet 或几张 qc_extract_frames 截图。没人看的渲染结果不是交付的视频。
1b. 采用仓库的品牌风格
使用 extract_brand,并将 sourceRepo 设置为要拍摄的仓库。它会读取 Tailwind v4 的 @theme 块和 :root 自定义属性,从 next/font 导入中挑选字体,复制找到的最佳 logo,并写入 src/brand.ts。
在 scaffold_scene 之前运行它。事后才应用主题意味着需要重新搭建场景。
检查它返回的 unresolved 列表,并手动填写任何重要的内容。它只报告它实际能找到的内容,而不是臆造一个合理的颜色,因此未解析的令牌是真正的缺口,而不是失败。
这对手写场景施加了一条规则:在组件内部读取令牌,而不是在模块作用域。applyBrand 会修改共享的令牌对象,因此文件顶部的 const MONO = \"${font.mono}"`会捕获默认值,并且永远不会看到品牌。请改用monoStack()和uiStack()`。
2. 规划节拍
使用 plan_beats,并指定目标时长和功能。它会返回一个连续的骨架,包含捕获方法和每个节拍的字数预算。
按照该预算编写旁白。validate_beats 强制每个节拍的语速在 2.3 到 2.9 词/秒之间(硬性下限和上限),因此一行可能因为过于稀疏而被拒绝。按照规定的数量编写可以避免往返。
每个 screenshot 节拍还需要 visual.url 和 visual.interactions(一个数组,可能为空)。没有其他文档提前说明这一点。
3. 审批关口
向用户展示完整的节拍文件,而不是摘要,并等待明确的同意。 在此之前不写入磁盘。这是一条协议规则,而不是建议,这是错误的视频只花费一句话而不是一小时的关键点。
然后运行 write_beats_file。
4. 捕获
为每个截图节拍运行 capture_screenshot。它会补偿每个来源的 Chrome 缩放不同步,否则会导致捕获的图像小、模糊或取景错误。
如果页面有入场动画,则传递 wait 交互,否则截图会在动画进行中捕获,看起来错误而不是明显不对。
5. 场景
为每个节拍运行 scaffold_scene。它会生成一个直接可渲染的场景,使用该节拍自己的副本和时长。编辑内容;不要重建结构。
然后运行 validate_scenes。它会捕获那些渲染成功但内容错误的情况:以全舞台宽度布局的内容在摄像机推近时会被裁剪,因为可见区域是舞台除以摄像机缩放。它还会标记静态摄像机、缺少的素材以及没有旁白的节拍。
阅读 docs/API.md 了解属性。不要阅读库源码。
6. 旁白
运行 generate_narration。它会为每个节拍写入一个剪辑,stitch_composition 会查找这些剪辑,并将时间拉伸限制在保持自然的范围内,而不是不惜一切代价将剪辑与节拍对齐。当它说某个节拍不匹配时,请修复脚本或节拍时长;不要进一步拉伸。
6b. 音效,仅当内置音效不够用
合成包已经包含了点击、按键、铃声、哔哔声、成功音、嗖嗖声和音乐背景,并且由于 ffmpeg 生成,它没有第三方权利。优先使用它。
如果视频确实需要其他声音,询问用户想要什么音效,然后使用 plan_sound_effects,每个声音对应一个条目。它会告诉您哪些请求已被内置音效覆盖,并返回 Pixabay 搜索链接以及其余声音的确切保存路径。
它不会从 Pixabay 下载,您也不应该这样做。Pixabay 的条款禁止自动收集,并声明 API 仅用于真实的人类请求,并且他们没有发布音效端点。用户下载;您验证。之后使用 verify: true 再次调用该工具,以确认每个文件都是真实的音频并规范化格式。
provider: "freesound" 会自动获取,但仅使用用户自己的 API 令牌,并且它获取的每个剪辑都会记录在 ATTRIBUTION.md 中。该文件中的任何内容都必须出现在视频描述中,否则会违反许可。
音乐是所有例外。find_music_bed 搜索两个 CC0 公共领域目录(约 9400 首曲目),import_music_bed 修剪、淡出并将用户选择的曲目匹配响度后放入 public/audio/music-bed.mp3。那里的任何内容都不需要署名。bgmusic 技能有详细信息;当合成背景对于发布或推广视频来说过于平淡时,请使用它。
7. 组装和检查
运行 stitch_composition,然后渲染前运行 contact_sheet。联系表是每个节拍两帧,放在一张图像中,只需完整渲染的一小部分时间,这一点很重要,因为五分钟的视频有 9000 帧。
首先使用 draft: true 运行 render_video。只有在草稿看起来正确后才进行全质量渲染。
然后运行 qc_extract_frames 并对照 docs/PIPELINE.md 的检查清单。
无法通过质量控制的规则
来自 docs/STYLE.md,重新说明是因为它们是最常被破坏的:
- 不使用线性缓动。 使用
E.*预设。 - 每个场景都在
CinematicScene内部。 - 运动永不停止。 静态帧即为失败。
- 不使用 em 破折号,无论是在屏幕上还是旁白中。
- 字幕放在
overlay中,而不是children中,否则它们会随着摄像机移动而漂移出屏幕。 - 截图仅在
BrowserFrame内部。 录制和 AI 剪辑不得使用,否则生成的素材会获得真实捕获的视觉特征。
不能声称的内容
真实的用户界面,无论是 DOM 渲染、截图还是录制,都是基本事实。AI 生成的剪辑只是氛围,不能包含产品文本。如果旁白声称了某些内容,则视觉必须展示它;如果无法展示,请重写该行。