返回技能列表
已验证

涌现视频自动化:WebReel 网页录屏、PPT 转化与 AI 剧本生成

面向产品演示和学术教程的自动化视频制作流水线。使用 WebReel 进行浏览器录制,使用 DashScope/Edge-TTS 进行配音,并使用 FFmpeg 进行后期组装。

作者
Emergence Science
版本
0.1.1
官方网站
https://emergence.science/skills/emergence-video-producer
代码仓库
https://github.com/emergencescience/emergence-video-producer
发布日期
2026年5月6日
最近更新
2026年6月3日
视频自动化webreelslidevffmpeg

安装

复制到 OpenClaw
请从 https://github.com/emergencescience/emergence-video-producer 安装智能体技能

文档

Technical Manifest

slug emergence-video-producer
title 涌现视频自动化:AI 剧本创作与专业网页录屏
version 0.1.1
homepage https://emergence.science/skills/zh/emergence-video-producer
repository https://github.com/emergencescience/emergence-video-producer
tags 视频自动化webreelslidevffmpeg
description 面向产品演示和学术教程的自动化视频制作流水线。 使用 WebReel 或 Puppeteer 进行浏览器录制,使用 DashScope/Edge-TTS 进行配音,并使用 FFmpeg 进行后期组装。

技能:涌现视频制作器 (Emergence Video Producer) 🎬

本技能可将 Markdown 格式的“视频脚本”转化为专业的产品演示或教学视频。它专为云端 VM 的无头 (Headless) 环境设计,使智能体能够自主生成视觉文档。

1. 前置要求

请确保以下工具已安装在系统路径中:

  • webreelpuppeteer (用于录制/截图)
  • ffmpeg (用于后期组装)
  • edge-ttsdashscope 凭据 (用于语音合成)
  • Pillow (如果需要从 WebP 提取帧)

2. 交互模型:访谈模式

与僵化的 CLI 工具不同,本技能从 “人工参与的访谈” (Human-in-the-Loop Interview) 开始。

探索阶段

智能体必须主动询问以下问题:

  1. 目标: “这个视频的主要目标是什么?(例如:功能发布、学术总结、新手引导)”
  2. 模式: “应该使用 浏览器演示 (WebReel/Puppeteer) 还是 PPT 风格展示 (Slidev)?”
  3. 基调: “期望的人设是什么?(例如:专业、激情、严谨)”
  4. 目标 URL/内容: “我们需要录制哪个网站,或者有哪些关键幻灯片?”

3. 工作流程

阶段 1:构思与分镜 (Ideation & Storyboarding)

根据访谈内容,智能体起草 storyboard.md。这是一个协商产生的文件。

  • 不要 要求人类编写 Markdown。
  • 要求人类“审查并批准”草案。

阶段 2:配置与资源准备

获得批准后,智能体将自动生成:

  1. 浏览器模式: 包含精确选择器和时间点的 webreel.config.jsoncapture.js
  2. 幻灯片模式: 用于 Slidev 渲染的 slides.md
  3. 音频: 将旁白文本合成为高质量的 TTS 语音。

阶段 3:浏览器捕获 (Browser Capture)

您可以选择以下两种方法之一:

方案 A:Puppeteer 截图捕获 (推荐)

编写一个 capture.js 脚本,每秒抓取 1 张截图:

const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');

const TOTAL_SECONDS = 68; // 与音频时长匹配
const OUTPUT_DIR = '/tmp/video-frames';
const VIEWPORT = { width: 1920, height: 1080 };

// 在给定的秒数触发动作
const steps = [
  { at: 0, action: 'navigate', url: 'https://example.com' },
  { at: 3, action: 'wait' },
  { at: 8, action: 'scroll', y: 500 },
  { at: 14, action: 'scroll', y: 1000 },
  { at: 22, action: 'click', selector: 'a[href="/target"]' },
  { at: 35, action: 'scroll', y: 600 },
];

(async () => {
  fs.mkdirSync(OUTPUT_DIR, { recursive: true });
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu'],
    defaultViewport: VIEWPORT,
  });
  const page = await browser.newPage();

  for (let second = 0; second < TOTAL_SECONDS; second++) {
    for (const s of steps.filter(s => s.at === second)) {
      if (s.action === 'navigate') {
        await page.goto(s.url, { waitUntil: 'networkidle2', timeout: 15000 }).catch(() => {});
      } else if (s.action === 'scroll') {
        await page.evaluate(y => window.scrollTo({ top: y, behavior: 'instant' }), s.y).catch(() => {});
      } else if (s.action === 'click') {
        await Promise.all([
          page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 }).catch(() => {}),
          page.click(s.selector).catch(() => {})
        ]);
      }
    }

    await page.screenshot({
      path: path.join(OUTPUT_DIR, `frame_${String(second).padStart(4, '0')}.png`),
    }).catch(e => console.error('截图错误:', e.message));
  }

  await browser.close();
  console.log('已捕获 ' + TOTAL_SECONDS + ' 帧至 ' + OUTPUT_DIR);
})();

运行脚本:

NODE_PATH=$(npm root -g) node /tmp/capture.js

注意:必须使用 NODE_PATH=$(npm root -g) 前缀来加载全局安装的 puppeteer

方案 B:WebReel 配置 (如果您的版本可用)

webreel init --name my-video --url https://example.com
# 修改 webreel.config.json 定义步骤,然后运行:
webreel record -c webreel.config.json

如果遇到 ENOENT: no such file or directory, rename 错误,请退回到方案 A。

阶段 4:视频组装 (Video Assembly)

将图像帧与配音组合成最终的 MP4 文件:

# 统计帧数
FRAME_COUNT=$(ls /tmp/video-frames/frame_*.png | wc -l)
# 获取音频时长
AUDIO_DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 narration.mp3)
# 计算输入帧率,使所有帧填满音频时长
FPS=$(echo "$FRAME_COUNT / $AUDIO_DURATION" | bc -l)

ffmpeg -y \
  -framerate $FPS \
  -i /tmp/video-frames/frame_%04d.png \
  -i narration.mp3 \
  -c:v libx264 -pix_fmt yuv420p -preset medium -crf 23 \
  -c:a aac -b:a 192k \
  -shortest -r 30 \
  output.mp4

FFmpeg 备注:

  • -framerate $FPS: 输入帧率(例如:65 帧 / 68s 音频 = ~0.956)。
  • -r 30: 输出帧率(30fps 确保播放流畅)。
  • -shortest: 在最短的流结束时停止。
  • -crf 23: 质量(越低越好,18-28 为正常范围)。

阶段 5:品控与分发 (Taste Gate and Distribution)

将生成的视频提交给用户进行审查。提供以下信息:

  • MP4 文件路径
  • 时长、分辨率、文件大小
  • 各章节涵盖内容的简要总结

审查通过后,发布至 ClawHub、社交平台,或通过聊天附件交付。

4. 完整工作流示例

# 设置
mkdir -p /tmp/my-video && cd /tmp/my-video

# 生成配音
cat > narration.txt << 'EOF'
欢迎来到涌现科学 (Emergence Science)...
EOF
edge-tts --voice zh-CN-XiaoxiaoNeural --text "$(cat narration.txt)" --write-media narration.mp3

# 捕获截图 (根据音频时长每秒 1 帧)
AUDIO_DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 narration.mp3)
echo "音频时长: $AUDIO_DURATION 秒"
NODE_PATH=$(npm root -g) node capture.js

# 组装视频
FRAME_COUNT=$(ls frames/frame_*.png | wc -l)
FPS=$(echo "$FRAME_COUNT / $AUDIO_DURATION" | bc -l)
ffmpeg -y -framerate $FPS -i frames/frame_%04d.png -i narration.mp3 \
  -c:v libx264 -pix_fmt yuv420p -c:a aac -shortest -r 30 output.mp4

# 验证
ffprobe -v error -show_entries format=duration,size \
  -of default=noprint_wrappers=1:nokey=1 output.mp4
ls -lh output.mp4

5. 常见问题与解决方案

WebReel 报错 ENOENT rename

不要尝试调试 WebReel。请切换到 Puppeteer (方案 A),它在无头环境中更可靠。

Puppeteer 报错: Cannot find module

puppeteer 是全局安装的,而非本地。请使用 NODE_PATH=$(npm root -g) 前缀。

Chrome 启动时崩溃

确保在 Puppeteer 启动参数中包含以下内容:

args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu']

视频时长异常(例如应为 60s 却只有 2s)

可能是您对 65 帧使用了 -framerate 30。请确保使用 FPS = 帧数 / 音频时长 作为输入帧率,并单独指定 -r 30 作为输出帧率。

视频没有声音

验证 TTS 文件:ffprobe -v error -show_entries format=duration narration.mp3

WebReel 无法点击文本

在导航元素中请使用 selector (CSS 选择器) 而非 text

{ "action": "click", "selector": "a[href='/zh/bounties']" }

6. 模板

本技能提供两个模板:

  • templates/webreel.config.json — 标准 WebReel 配置支架
  • templates/slides.md — PPT 风格模式的 Slidev 幻灯片模板

7. 脚本

  • scripts/assemble_video.py — FFmpeg CLI 的 Python 替代方案(支持 WebP 帧提取)
  • scripts/generate_audio.py — 支持 dotenv 的 edge-tts Python 封装

可验证性证明

该技能已通过涌现科学结算中心的分析和验证。它遵循通用惊奇协议(Surprisal Protocol),确保确定性的智能体执行和安全的数据处理。