自动演示制作器
自动为任何 Web 应用程序生成专业的、带配音的视频演示。
流水线概述
用户上下文 → 演示脚本 → 幻灯片 → TTS 旁白 → 浏览器录制 → 最终 MP4
三个阶段,全自动完成:
- 旁白 — edge-tts(免费微软神经语音)为每个场景生成音频
- 录制 — Playwright 驱动带视频捕获的无头 Chromium
- 合成 — ffmpeg 将视频和音频合并为精美的 MP4
何时激活
- 用户要求“创建演示”、“录制演练”、“制作视频演示”
- 用户提供 URL 和要展示内容的描述
- 用户想要一个自动化的带旁白的录屏
分步工作流程
第一步:收集上下文
向用户询问:
- 目标 URL — 要演示的 Web 应用程序(例如,
https://myapp.azurewebsites.net) - 要展示的内容 — 关键功能、用户流程或场景
- 受众 — 谁将观看?(高管、开发者、客户)
- 时长目标 — 演示应该多长?(通常 1-5 分钟)
- 语音偏好 — 语言和性别(默认:
en-US-JennyNeural) - 品牌信息 — 产品名称、副标题、组织、开头/结尾幻灯片强调色
第二步:创建演示脚本
使用以下格式生成 demo_script.md:
# 演示:{产品名称}
## intro | 5
> slide 开头
欢迎观看产品名称的演示。今天我们将介绍其关键功能。
## login | 8
> goto {base_url}
> fill 用户名 [email protected]
> fill 密码 ****
> click 按钮 登录
现在我们使用演示凭据登录应用程序。
## dashboard | 10
> wait 2
> scroll down 300
仪表板显示了所有活动项目的实时概览。
## feature_one | 12
> click 链接 功能一
> wait 1
> scroll down 200
让我们探索功能一,它允许您创建和管理工作流。
## outro | 5
> slide 结尾
感谢观看!如需更多信息,请访问 contoso.com。
脚本格式规则:
## 场景ID | 最小持续时间(秒)— 场景标题> 动作 参数...— Playwright 动作(见下文动作参考)- 纯文本行 = 旁白(由 TTS 语音朗读)
- 旁白决定实际场景时长(填充以匹配音频长度)
第三步:生成幻灯片
运行幻灯片生成器以创建开头/结尾 HTML 文件:
python generate_slides.py `
--title "产品名称" `
--subtitle "您的标语" `
--org "Contoso" `
--badge "由 Azure 提供支持" `
--accent "#60a5fa" `
--out-dir ./slides
第四步:安装依赖项
pip install edge-tts playwright
playwright install chromium
# 确保 ffmpeg 可用:
# Windows: winget install Gyan.FFmpeg
# macOS: brew install ffmpeg
# Linux: sudo apt install ffmpeg
第五步:运行录制器
python record_demo.py `
--script demo_script.md `
--base-url "https://myapp.azurewebsites.net" `
--voice en-US-JennyNeural `
--slides-dir ./slides `
--output demo_final.mp4
其他选项:
--resolution 1280x720用于更小的文件大小--var project_id=abc123用于脚本中的自定义变量--var [email protected]用于参数化流程
第六步:审查与迭代
录制后,审查输出视频。常见调整:
- 太快了? 增加场景标题中的
min_duration - 时间点不对? 在步骤之间添加
> wait N动作 - 缺少步骤? 向脚本中添加更多场景
- 语音不对? 尝试不同的 edge-tts 语音
动作参考
| 动作 | 语法 | 描述 |
|---|---|---|
goto | > goto https://url.com | 导航到 URL |
slide | > slide intro | 显示来自幻灯片目录的 HTML 幻灯片 |
click | > click 链接 链接文本 | 点击文本链接 |
click | > click 按钮 按钮文本 | 点击文本按钮 |
click | > click 文本 任意文本 | 点击任意文本元素 |
fill | > fill 标签 值 | 填写表单文本框 |
type | > type #选择器 值 | 通过 CSS 选择器输入到元素 |
hover | > hover 元素文本 | 悬停在元素上 |
select | > select 标签 选项 | 选择下拉列表选项 |
scroll | > scroll down 300 | 向下滚动指定像素 |
scroll | > scroll up 200 | 向上滚动指定像素 |
wait | > wait 2 | 暂停 N 秒 |
screenshot | > screenshot 名称.png | 保存屏幕截图 |
语音选择
流行的 edge-tts 语音(全部免费,无需 API 密钥):
| 语音 | 语言 | 风格 |
|---|---|---|
en-US-JennyNeural | 英语(美国) | 温暖,对话式 |
en-US-GuyNeural | 英语(美国) | 专业,清晰 |
en-US-AriaNeural | 英语(美国) | 自然,多用途 |
en-GB-SoniaNeural | 英语(英国) | 精致,专业 |
it-IT-IsabellaNeural | 意大利语 | 自然,清晰 |
de-DE-KatjaNeural | 德语 | 专业 |
fr-FR-DeniseNeural | 法语 | 优雅 |
es-ES-ElviraNeural | 西班牙语 | 清晰 |
ja-JP-NanamiNeural | 日语 | 自然 |
zh-CN-XiaoxiaoNeural | 中文 | 多用途 |
完整列表:edge-tts --list-voices
变量
在脚本中使用 {变量名}。内置变量:
{base_url}— 通过--base-url参数设置
通过 --var key=value 自定义变量:
> goto {base_url}/projects/{project_id}
> fill 搜索 {search_term}
输出
此技能生成:
demo_final.mp4— H.264 视频,AAC 音频,Web 优化(faststart)- 分辨率:1920×1080(默认)或自定义
- 质量:CRF 18(高质量),AAC 192kbps
制作精彩演示的提示
- 先写脚本 — 在动作之前编写旁白。故事驱动节奏。
- 短场景 — 每个场景 8-15 秒。保持紧凑。
- 充裕的等待时间 — 在导航后添加
> wait 1-2,以获得视觉呼吸空间。 - 使旁白与动作匹配 — 描述屏幕上正在发生的事情。
- 开头/结尾幻灯片 — 始终使用它们以获得专业效果。
- 增量测试 — 先录制一个场景以检查时机,然后添加更多。
- 品牌一致性 — 开头/结尾幻灯片的颜色必须与 PoC 的品牌调色板匹配(来自
threadlight-design跨切面模式 1)。不要为红色品牌的客户使用默认的蓝色/紫色渐变。将 PoC 的demo-deck.html中的 CSS 自定义属性复制到幻灯片 HTML 文件中。 - 字幕 — 从旁白文本生成 WebVTT 文件。不要使用外部
<track src="file.vtt">— Edge 会阻止file://协议上的 CORS。相反,将 VTT 内联嵌入为 JS blob URL:var blob = new Blob([vttData], {type:'text/vtt'}); track.src = URL.createObjectURL(blob);并动态追加<track>元素。时间戳必须使用HH:MM:SS.mmm格式(不是MM:SS.mm— Edge 会拒绝)。 - 嵌入到演示卡片中 — 如果 PoC 提供了
demo-deck.html,将视频作为实时演示预留卡片上的回退方案嵌入。连接一个V键切换:按 V 在.is-cue幻灯片上内联播放视频,再次按 V 停止。添加可见的控制栏(播放/暂停按钮 + 可点击进度条 + 时间显示),以便演示者不依赖键盘快捷键。在ended事件时自动停止。回退提示(“按 V 播放预先录制的回退视频”)以低透明度显示在提示文本下方。
录制 Agent 演示(经过实战检验的模式)
本节内容来自对一个 Foundry 托管 Agent PoC 的 6 次失败录制尝试。 当 Agent 响应时间不可预测(10–50 秒)时,以下模式是唯一能够可靠生成可观看视频的方法。
问题
AI Agent 演示无法实时录制。Agent 需要 10–50 秒来响应。如果连续录制浏览器并叠加预先生成的旁白音频,当屏幕仍显示“工作中...”时,语音就已经在描述答案了。任何后期制作的加速或音频偏移都无法可靠地解决这个问题——两条时间线从根本上不同步。
解决方案:逐场景截图跳切
切勿在视频中显示“工作中...”。从“问题已输入”直接跳切到“答案已渲染”。Agent 等待发生在屏幕之外(截图之间)。
逐场景工作流程:
- 输入提示词 → 截图输入状态(旁白在此帧上介绍问题)
- 点击“提问” → 轮询直到响应完全渲染(屏幕外——不录制)
- 截图完成的答案(旁白在此帧上描述响应)
- 构建片段:静态图像 + 匹配的旁白音频片段(精确时长匹配)
- 连接所有片段:开头 → K1已输入 → K1已完成 → K2已输入 → K2已完成 → … → 结尾
智能等待——出现/消失轮询:
# 阶段 1:等待加载指示器出现(确认 API 调用已开始)
for _ in range(30):
if await page.evaluate("() => !!document.body.innerText.match(/工作中/)"):
break
await page.wait_for_timeout(500)
# 阶段 2:等待加载指示器消失(确认响应已渲染)
for _ in range(120):
if not await page.evaluate("() => !!document.body.innerText.match(/工作中/)"):
break
await page.wait_for_timeout(1000)
await page.wait_for_timeout(2000) # 让 DOM 稳定
将正则表达式(/工作中/)调整为匹配工作区使用的任何加载指示器。两阶段模式防止了常见的错误,即脚本在“工作中...”出现之前进行检查并立即继续。
从静态图像和音频构建片段:
def make_segment(image_path, audio_path, output_path):
audio_dur = ffprobe_duration(audio_path)
subprocess.run([
"ffmpeg", "-y",
"-loop", "1", "-i", str(image_path),
"-i", str(audio_path),
"-c:v", "libx264", "-preset", "fast", "-crf", "18",
"-c:a", "aac", "-b:a", "192k",
"-t", str(audio_dur),
"-pix_fmt", "yuv420p",
"-movflags", "+faststart", str(output_path),
], check=True)
每个片段的时长等于其旁白音频时长——旁白始终描述屏幕上显示的内容。
反模式(来自对一个 Foundry 托管 Agent PoC 的 6 次失败录制尝试)
| ❌ 方法 | 失败原因 |
|---|---|
| 连续录制,之后叠加音频 | 音频和视频时间线永远无法对齐——屏幕显示“工作中...”时,旁白却在谈论引用 |
使用 setpts 加速“工作中...”视频部分 | 看起来很糟糕;加速因子取决于不可预测的 Agent 响应时间 |
脚本中固定的 > wait 35 定时器 | Agent 响应时间为 10–50 秒;固定定时器要么截断答案,要么浪费 30 秒什么也不显示 |
| 实时同时录制视频和音频 | Playwright 无法捕获系统音频;无头 Chromium 没有音频设备 |
| 用音频偏移检测进行后处理 | 太脆弱;“工作中...”文本出现在 DOM 中,但视觉加载微调器因工作区而异 |
Agent 演示的语音选择
对于面向英国受众的 PoC,使用英式语音(en-GB-SoniaNeural)——它以演示节奏自然地朗读,并与专业语气匹配。对于受监管行业的演示(FSI、电信、医疗保健),避免使用美式休闲语音。
文件位置
当作为全局 Copilot CLI 技能激活时,脚本位于:
~/.copilot/skills/auto-demo-producer/scripts/record_demo.py~/.copilot/skills/auto-demo-producer/scripts/generate_slides.py
在运行之前将它们复制到您的项目目录,或直接引用。
先决条件
- Python 3.10+ 与
pip - edge-tts —
pip install edge-tts(免费微软神经语音) - Playwright —
pip install playwright && playwright install chromium - ffmpeg — 系统二进制文件(请参阅上面的安装命令)