Build or update the BlueBubbles external channel plugin for Moltbot (extension package, REST...
12
4
# Install this skill:
npx skills add MatrixReligio/ProductVideoCreator --skill "recording"
Install specific skill from multi-skill repository
# Description
使用 Playwright 进行浏览器自动化录屏。当需要录制 Web 应用操作演示、生成带时间线的屏幕录像时使用。
# 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();
}
}
录屏最佳实践
1. 等待时间设置
// 页面加载后等待
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);
2. 操作节奏
| 操作类型 | 建议等待时间 |
|---|---|
| 页面加载 | 1.5-3 秒 |
| 点击按钮 | 1-2 秒 |
| 表单输入 | 0.5-1 秒 |
| 弹窗出现 | 1.5-2 秒 |
| 数据加载 | 2-3 秒 |
| 场景切换 | 2-3 秒 |
3. 悬停展示
// 悬停显示 tooltip
await element.hover();
timeline.mark("悬停显示提示");
await page.waitForTimeout(3000); // 留足时间让观众看清
4. 逐字输入效果
// 更真实的输入效果
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}`);
故障排除
Chromium 未安装
npx playwright install chromium
录制黑屏
确保 headless: false
操作太快
增加 slowMo 值或 waitForTimeout
元素未找到
使用更稳定的选择器:
// 推荐
page.locator('button:has-text("查询")')
page.locator('.el-button--primary')
// 避免
page.locator('button:nth-child(2)')
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Amp
Antigravity
Claude Code
Clawdbot
Codex
Cursor
Droid
Gemini CLI
GitHub Copilot
Goose
Kilo Code
Kiro CLI
OpenCode
Roo Code
Trae
Windsurf
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.