基于 SOC 职业分类
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/MatrixReligio/ProductVideoCreator --skill recording命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | recording |
| description | 使用 Playwright 进行浏览器自动化录屏。当需要录制 Web 应用操作演示、生成带时间线的屏幕录像时使用。 |
| argument-hint | ["目标URL"] |
const { chromium } = require("playwright");
const path = require("path");
const fs = require("fs/promises");
const BASE_URL = "http://localhost:5173";
const OUTPUT_DIR = path.join(__dirname, "..", "public", "recordings");
const VIEWPORT = { width: 1920, height: 1080 };
// 测试数据 - 使用真实有意义的数据
const TEST_DATA = {
// 定义测试数据
};
// 时间线记录器 - 关键组件
class TimelineRecorder {
constructor() {
this.startTime = Date.now();
this.events = [];
}
mark(event) {
const elapsed = (Date.now() - this.startTime) / 1000;
this.events.push({ time: elapsed, event });
console.log(` [${elapsed.toFixed(1)}s] ${event}`);
return elapsed;
}
getTimeline() {
return this.events;
}
}
async function recordDemo() {
await fs.mkdir(OUTPUT_DIR, { recursive: true });
const browser = await chromium.launch({
headless: false,
slowMo: 50, // 稍微放慢操作,更自然
});
const context = await browser.newContext({
viewport: VIEWPORT,
recordVideo: {
dir: OUTPUT_DIR,
size: VIEWPORT,
},
locale: "zh-CN",
});
const page = await context.newPage();
const timeline = new TimelineRecorder();
try {
// 场景录制...
} finally {
// 保存时间线
const timelineData = {
totalDuration: (Date.now() - timeline.startTime) / 1000,
events: timeline.getTimeline(),
};
await fs.writeFile(
path.join(OUTPUT_DIR, "timeline.json"),
JSON.stringify(timelineData, null, 2)
);
await page.close();
await context.close();
await browser.close();
}
}
// 页面加载后等待
await page.goto(url, { waitUntil: "networkidle" });
await page.waitForTimeout(1500);
// 点击后等待响应
await element.click();
await page.waitForTimeout(2000);
// 表单输入后等待
await input.fill(value);
await page.waitForTimeout(500);
// 弹窗打开后等待
await dialog.waitFor({ state: "visible" });
await page.waitForTimeout(1500);
| 操作类型 | 建议等待时间 |
|---|---|
| 页面加载 | 1.5-3 秒 |
| 点击按钮 | 1-2 秒 |
| 表单输入 | 0.5-1 秒 |
| 弹窗出现 | 1.5-2 秒 |
| 数据加载 | 2-3 秒 |
| 场景切换 | 2-3 秒 |
// 悬停显示 tooltip
await element.hover();
timeline.mark("悬停显示提示");
await page.waitForTimeout(3000); // 留足时间让观众看清
// 更真实的输入效果
for (const char of text) {
await input.type(char, { delay: 80 });
}
timeline.mark("页面加载完成");
timeline.mark("点击[按钮名]按钮");
timeline.mark("输入用户名: xxx");
timeline.mark("[弹窗名]弹窗打开");
timeline.mark("显示查询结果");
timeline.mark("录制结束");
录制完成后转换为 MP4:
// 使用 FFmpeg 转换
const { execSync } = require("child_process");
execSync(`ffmpeg -y -i ${webmPath} -c:v libx264 -preset fast -crf 23 ${mp4Path}`);
npx playwright install chromium
确保 headless: false
增加 slowMo 值或 waitForTimeout
使用更稳定的选择器:
// 推荐
page.locator('button:has-text("查询")')
page.locator('.el-button--primary')
// 避免
page.locator('button:nth-child(2)')