使用 Windows-MCP 操控 JOY Media
此技能基于 JOY Media 1.1.0 版本(Electron 44.3.0,Windows 11)开发。它指导 AI 代理如何在不影响用户真实安装或数据的情况下运行桌面应用,通过 Windows-MCP 工具在编辑器中执行操作,并依据事实(而非外观)来评估导出结果。
使用的工具:Snapshot、Screenshot、Click、Type、App、Wait(Windows-MCP),以及用于启动、文件检查和 ffmpeg/ffprobe 的 PowerShell。
0. 基本原则(不可跳过)
- 每次运行前先询问用户。 启动应用、导入和导出操作需要用户在场并明确同意。一次只运行一个任务。绝不能针对用户的真实配置文件进行操作。
- 绝不要触碰已安装的应用(其文件夹、安装脚本、卸载程序)。应运行一个独立的解包副本(见第 1 节)。
- 数据隔离:始终传递一个新的
--user-data-dir参数。若要复用已有项目,请先关闭应用,然后使用robocopy /E将旧的配置文件复制到新文件夹(不要使用/MIR,不要清除),并在复制的副本上启动应用。 joy://注册表项(HKCU\Software\Classes\joy)必须保持不变。在启动前、启动后和关闭后,分别使用reg export将其导出为新文件,并比较其 SHA-256 值。如果值不同,请停止操作并告知用户;只有用户同意后才能恢复。- 测试期间不要删除任何内容(副本、配置文件、导出的文件都是证据)。Chromium 可能会在新的测试配置文件中清理其自身的临时文件,这是正常的。
- 一旦发现崩溃迹象(GPU 进程退出、应用程序错误事件、驱动重置)立即停止:保留所有内容,不要在其之上重新运行,并告知用户。
- 切勿在应用中输入密码或在备注中包含令牌。
1. 获取可安全运行的应用副本
将你想要测试的提交构建或解包到一个短路径(长度不超过 260 个字符)下,例如 C:\jg\app-<sha>:
- 使用
git archive <sha>打包为 tar 文件,解压到C:\jg\<名称>。 - 运行
pnpm install --offline --frozen-lockfile(需要预先存在的 pnpm store)。 - 从现有副本的
node_modules\.pnpm\electron@<ver>\node_modules\electron复制 Electron 的dist文件夹和path.txt(离线安装不会下载 Electron)。检查electron.exe的 SHA-256 值。 - 运行
pnpm build,然后运行pnpm --filter @joy-media/desktop package:unpacked。 - 使用
robocopy apps\desktop\dist\joy-media-unpacked C:\jg\app-<sha> /E。
解包后的副本在 isPackaged = false 状态下运行,因此它不会注册 joy:// 协议。但仍需检查该注册表项。
2. 启动应用(PowerShell)
$env:NODE_ENV = 'production'
$app = 'C:\jg\app-<sha>'
Start-Process -FilePath '<path to>\electron.exe' `
-ArgumentList @($app, '--user-data-dir=C:\jgp\<new-profile>', '--enable-logging=stderr') `
-WorkingDirectory $app `
-RedirectStandardOutput 'C:\jgp\run\stdout.log' -RedirectStandardError 'C:\jgp\run\stderr.log' -PassThru
--enable-logging=stderr 会将渲染进程的 console.* 输出写入 stderr 文件(对临时诊断很有用)。检查没有进程的命令行包含 --joy-media-gpu-encode-fallback(那将是后备重启,而不是正常启动)。窗口标题是 JOY Studio。在新配置文件中,应用会打开“项目”页面;在复制的配置文件中,它会恢复上一次的项目。
3. 使用 Windows-MCP 操控窗口
缩放:截图大约是真实屏幕的 2.56 倍小。务必使用来自 Snapshot 的真实坐标进行点击,切勿使用截图中的像素坐标。每次页面变更后,拍摄一张小的 Screenshot(scale 为 0.4)。
顺序:一次只执行一个窗口操作。曾经有一次,在导出后立即发送了一批操作,导致点击和输入落在了错误的项目中。App switch "JOY Studio" 有时会失败并提示“无效的窗口句柄”;如果窗口已经处于前端,则继续执行。
以下坐标来自一个 4920x2160 的屏幕,且 JOY 窗口为默认大小和位置。它们只是一个起始映射,并非绝对准确:当任何内容看起来不同时,请使用 Snapshot 并参考其元素列表。
| 操作 | 位置(真实坐标) |
|---|---|
| 文件菜单 | (910, 288) |
| 文件 > 项目库 | (1077, 358) |
| 新建项目按钮 | (3023, 311),然后点击名称字段 (1165, 727),使用 Type 输入名称并附加 press_enter |
| 第一个项目卡片 | (1680, 873) |
| 时间线“导入媒体”(空时间线) | (2199, 1312) |
| 打开文件对话框:名称框 / 打开 | (1587, 1208) / (2268, 1264) |
| 导出 MP4 | (2672, 288) |
| 选择片段,检查缩放 | 点击片段条 (1762, 1349);检查器中会显示缩放 X/Y |
| 关闭应用窗口 | (3143, 288) |
| 保存对话框:名称框 / 保存 | 约 (1717, 1058) / (2283, 1266) |
一个典型用例的流程:项目库 > 新建项目 > 输入名称 > 导入媒体 > 输入完整的文件路径 > 打开(片段会放入时间线) > 检查预览 > 导出 MP4 > 等待 > 保存对话框 > 验证。
保存对话框。 导出操作最终会显示一个标准的 Windows 保存对话框(默认文件夹为“下载”,建议一个不带扩展名的文件名)。只有用户点击保存后,文件才会出现在桌面上,因此从“工作线程完成”到“文件出现在桌面”之间的延迟正是这个对话框等待操作的时间。在工作线程应完成时截图;要么由用户点击保存,要么(在用户同意后)将完整的目标路径 ...\Desktop\<建议的文件名>.mp4 输入到名称框中并点击保存。应用数据库中的作业计时不受等待时间的影响。
4. 运行前、运行中和运行后
运行前:使用 reg export 导出 joy:// 注册表项并计算哈希值;列出用户的真实配置文件夹和任何证据文件夹(scripts/list-tree.ps1),以便证明在运行期间没有发生任何更改。
运行中(长时间导出):在后台启动 scripts/sampler.ps1 -Pattern '*<profile>*' -Out <csv> -Stop <stopfile>。它会每秒记录一次每个 Electron 进程的工作集、私有字节、CPU 时间、NVENC 会话和 GPU 使用率。创建停止文件以结束记录。
运行后:关闭应用(点击关闭窗口按钮),确认没有残留的 electron 进程,再次导出注册表项并对比哈希值,再次列出文件夹并进行差异对比,检查配置文件中是否有 .upload 残留文件,并检查应用程序错误/WER 以及 Display/nvlddmkm 事件(忽略无关信息,如 Docker 相关事件)。
5. 根据事实评估导出结果
ffprobe -show_streams:编码格式、尺寸、帧数、时长、颜色标签(color_space、color_primaries、color_transfer、color_range)。- 完整解码必须干净:
ffmpeg -v error -i out.mp4 -f null -且退出码为 0。 - 计算文件哈希值(
Get-FileHash);当代码路径相同时,不同构建版本的相同布局应产生相同的哈希值。 - 从应用自身数据库获取的阶段时间(
joy-media.sqlite3的副本及其-wal/-shm文件,以只读方式打开):运行scripts/export-times.py <copy>,会为每次导出打印浏览器阶段(从点击时间戳到原始素材暂存)、暂存字节数和工作线程时间。点击时间戳是文件名中的 13 位数字。 - 色彩准确性:使用
scripts/fxgen.py <folder>构建测试素材(包含已知 sRGB 值的纯色块以及二进制帧计数器;素材类型包括 BT.709、BT.601、未标记 SD、全范围、旋转、VFR、10-bit、HEVC、VP9、AV1、隔行扫描、一个过渡对和音频率对),然后使用scripts/fxcheck.py <folder>进行检查,最终使用JOY_FX_DIR=<folder> python -I scripts/fxplace.py <export.mp4> <fixture-file-name> [frame]对导出结果进行评分。该脚本会找到素材在画布上的位置(尺寸小于画布的素材会在左上角以 1:1 比例放置,不缩放),并打印在四种矩阵/范围读取方式下的最大/平均偏差;正确的读取结果应在约 3 个级别范围内。 - 音频:通过
astats的过零率检测音调,通过 RMS 检测电平;单声道源会变为立体声(每个声道降低约 3 dB)。
6. 值得注意的已知行为(JOY Media 1.1.0 版本)
- 每次色彩测试都应在全新的应用会话中运行。 在测试的机器上(RTX 5070 Ti,Electron 44.3.0),启动后的第一次导出以 BT.709 编码(标签 bt709);后续的导出在同一会话中会以 BT.601 编码(标签 smpte170m),文件变得更大,在长布局上速度更慢,且字节不同。诊断版本显示,第一次的捕获画布帧是 RGBA(GPU 支持),之后的则是 BGRA(CPU 支持);应用本身未设置任何色彩空间。在应用内部转换为 NV12 BT.709 可使每次导出结果一致。
- 未标记的 SD 视频会被当作 BT.709 读取(颜色偏移最多可达约 20 个级别)。
- 没有音轨的源文件会导出一个静音的立体声 AAC 轨道。
- 只有在对等条件下才能比较构建版本:相同的布局、在会话中的相同位置(第一次导出与第一次导出)、窗口在前端并处于焦点(未聚焦的窗口可能慢约 30%)、使用同一配置文件的副本。
- 同一桌面上的其他代理或聊天窗口可能会窃取焦点:点击前先截图。
- 窗口上的第一次点击可能只会使其获得焦点。
7. 报告格式如下
说明运行的内容(构建版本、配置文件副本、布局),列出数据(阶段时间、峰值内存、文件大小、标签),通过哪些检查(joy:// 注册表项未改变、文件夹差异为空、解码干净),未验证的内容,以及需要用户做出的一个决定。当你只有一次运行时,请说“每个构建版本只运行一次”。