Community编程与开发github.com

JZnebel/AutoDemo

自动创建带有旁白的Web应用演示视频的Agent技能。通过一条命令完成探索、录制、旁白和渲染全流程。

AutoDemo 是什么?

AutoDemo 是一个AI Agent技能,旨在自动化创建Web应用演示视频的完整流程。它通过单条命令协调四个阶段:首先是“侦察”阶段,Agent会打开目标URL、处理登录、识别品牌元素(Logo和主题色)并规划演示段落;然后是“录制”阶段,Agent自然浏览应用并录制屏幕,同时智能处理暂停和加载;接着是“旁白”阶段,Agent根据录制内容生成结构化的narration.json文件,包含字幕样式、语音选择、段落文本和提示标签;最后是“自定义合成”阶段,Agent会编写一个独特的Remotion组合组件(composition.tsx),利用预定义的React构建块(如DeviceMockup、IntroCard、LowerThird等)创建定制视频。该技能支持灵活的输入方式——用户可以通过参数或自然语言指定URL、登录凭据、演示方向和时长。它适用于任何需要快速生成高质量产品演示或启动视频的场景,支持所有主流AI编码代理平台(如Claude Code、Codex、Cursor等)。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/JZnebel/AutoDemo/tree/main/.claude/skills/demo

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

/demo — 自动化演示视频流水线

您正在创建一个带有旁白的Web应用演示视频。整个流程——探索、录制、旁白和渲染——都通过这一条命令完成。

参数

从 $ARGUMENTS 解析:

  • 第一个位置参数:要演示的 URL(必填)
  • --login <credentials>:登录凭据,格式为 email:password。如果提供,则在录制前登录。
  • --brief <"要展示的内容">:演示应涵盖内容的自然语言描述。可以很短——例如“展示仪表盘并创建一个项目”。如果省略,则自由探索。
  • --name <名称>:输出名称(默认从URL主机名派生)
  • --duration <秒数>:目标视频时长(默认60秒)
  • --voice <语音>:TTS语音(默认 en-US-GuyNeural)
  • --preset <draft|production>:质量预设(默认 draft)

参数也可以在URL之后作为自然语言传递。以下所有方式都是等效的:

/demo https://app.com --login [email protected]:pass123 --brief "显示计费页面并添加支付方式"
/demo https://app.com — 以 [email protected] / pass123 登录,显示计费页面并添加支付方式
/demo https://app.com 登录:[email protected] pass123。显示计费页面。

尽你所能进行解析。如果用户用简单英语给你提供凭据和指令,请使用它们。

流水线

阶段 1:侦察应用

在录制之前,先了解你要处理的对象:

  1. 通过 new_page 或 navigate_page 打开URL
  2. 如果提供了凭据(--login),找到登录表单并先登录。寻找常见模式:/login、/sign-in、"Sign In"链接等。使用 fill 填写邮箱/密码字段,然后点击提交。等待仪表盘/主页加载完成后再继续。
  3. 截取屏幕截图并快照以了解应用
  4. 捕捉品牌:识别应用的Logo和强调色/品牌色。
    • 尝试将Logo图片下载到输出目录(在阶段2中确定),命名为 logo.png(或 .svg/.webp)。在侦察期间,先将其保存到临时位置,然后在唯一名称确定后移动到最终输出目录。使用 evaluate_script 查找Logo <img> 的src URL,然后使用Bash的 curl 或 wget 保存。流水线会自动检测它并在介绍卡片中使用。
    • 从应用的主按钮/品牌颜色中选取强调色,并在narration.json中将其用作 accentColor(rgba格式)。
  5. 如果提供了简要说明(--brief),用它来指导你的探索。简要说明告诉你用户关心什么——优先展示这些功能。如果没有简要说明,则自由探索。
  6. 识别关键功能、导航和有趣的流程
  7. 规划3-6个演示片段,在约 duration 秒的旁白时间内展示应用

思考如何制作一个引人注目的演示:

  • 如果有简要说明,遵循它——用户知道他们想展示什么
  • 从视觉上最令人印象深刻或独特的功能开始
  • 展示广度(导航不同部分)而非深度(不要在一个表单上卡住)
  • 以能总结整体的内容结束(仪表盘、设置、结果)
  • 在录制中跳过登录屏幕、加载旋转器和错误状态——在 screencast_start 之前的设置中处理这些

阶段 2:录制

设置输出目录并开始录制:

输出目录:screencast-output/<名称>/
录制文件:screencast-output/<名称>/recording.mp4
  1. 选择一个唯一的输出目录。 在创建目录之前,检查 screencast-output/<名称>/ 是否已存在。如果存在,则追加递增的后缀:<名称>-v2、<名称>-v3 等。使用第一个可用的名称。例如:
    # 检查并找到下一个可用名称
    NAME="trafficstores"
    DIR="screencast-output/$NAME"
    if [ -d "$DIR" ]; then
      V=2; while [ -d "screencast-output/${NAME}-v${V}" ]; do V=$((V+1)); done
      NAME="${NAME}-v${V}"
      DIR="screencast-output/$NAME"
    fi
    mkdir -p "$DIR"
    
    在本次运行中使用解析后的 <名称>(如果需要带后缀)——用于录制、narration.json、合成、渲染输出等所有后续路径。
  2. 创建输出目录
  3. 调用 screencast_start,路径为 screencast-output/<名称>/recording.mp4
  4. 自然地与应用交互——点击你规划的功能
    • 在每个重要屏幕上短暂暂停(1-2秒),让观众可以阅读
    • 点击按钮,用真实数据填充表单,在部分之间导航
    • MCP分支会自动处理光标动画和自动分段
  5. 完成后调用 screencast_stop

录制提示:

  • 不要着急——流水线会自动加速无聊的部分
  • 在视觉上有趣的屏幕上暂停(流水线会减慢这些部分以匹配旁白)
  • 避免在跨源iframe内滚动——直接导航到其他地方
  • 如果某个内容加载时间很长,自动分段器会裁剪掉等待时间

阶段 3:编写旁白

根据你刚刚录制的内容编写 screencast-output/<名称>/narration.json。你知道发生了什么,因为你刚刚做了这些事。

{
  "introTagline": "简短有力的标题",
  "introSubtitle": "产品或公司名称",
  "outroHeading": "行动号召问题",
  "outroUrl": "website.com",
  "outroCtaText": "开始使用",
  "accentColor": "rgba(59, 130, 246, 1)",
  "captionStyle": "pop",
  "voice": "en-US-AndrewNeural",
  "introLogoSrc": "screencast-output/<名称>/logo.png",
  "segments": [
    {
      "text": "此片段的旁白。像人类演示一样对话式地写。",
      "sceneIndex": 0,
      "sceneLabel": "功能名称"
    }
  ],
  "fullText": "所有片段文本用空格连接。"
}

旁白指南:

  • 像你在旁边给人演示一样写,而不是读文档
  • 使用现在时态:"这里我们看到……"而不是"这里我们看到了……"
  • 指出观众应该注意的特定UI元素
  • 保持总旁白时长接近 --duration 目标
  • 每个片段应为5-20秒的语音(约15-50个单词)
  • accentColor 应与应用的品牌颜色匹配(从你所见的颜色中选取)
  • 每个片段的 sceneLabel 在视频中成为一个动画下部三分之一——保持简短(最多2-3个单词):"注册"、"AI构建器"、"实时网站"
  • 将 introLogoSrc 设置为你在阶段1下载的Logo文件——它会在介绍卡片中以弹簧动画显示
  • 设置 captionStyle 以匹配应用的感觉:"pop"(活泼俏皮)、"clean"(磨砂玻璃、优雅)、"bold"(大而有力)、"minimal"(微妙)、"karaoke"(无背景)或 "outline"(发光阴影)
  • 选择与应用基调匹配的 voice:
    • en-US-AndrewNeural — 温暖自信(好的默认选项)
    • en-US-BrianNeural — 平易近人、随意(初创公司、友好应用)
    • en-US-ChristopherNeural — 可靠、权威(企业、金融科技)
    • en-US-AriaNeural — 积极、自信(营销、消费应用)
    • en-US-EmmaNeural — 愉快、清晰(电商、社交)
    • en-US-AvaNeural — 富有表现力、关怀(健康、保健、社区)
    • en-US-JennyNeural — 友好、体贴(教育、支持)
    • en-US-EricNeural — 理性(分析、数据工具)
    • en-US-GuyNeural — 充满激情(创意工具、媒体)
    • en-GB-RyanNeural / en-GB-SoniaNeural — 英式(国际、奢华)

阶段 3.5:设计自定义视频合成

为此特定视频编写一个自定义的Remotion组合组件。将其保存为 screencast-output/<名称>/composition.tsx。流水线将使用它,而不是默认的MarketingDemo模板。

首先加载Remotion技能: 从 demo-render/.agents/skills/remotion-best-practices/rules/ 读取规则——特别是 animations.md、timing.md、text-animations.md、transitions.md 和 sequencing.md。

你的合成组件必须:

  1. 导出 VideoComposition(React组件)和 calculateMarketingDemoDuration(时长函数)
  2. 导出 MarketingDemoProps 类型(从 ./MarketingDemo 重新导出)
  3. 接受与MarketingDemo相同的props——流水线传递相同的JSON

可用的构建块(从 ./components/ 导入):

  • DeviceMockup — 浏览器框架中的屏幕录制(videoSrc、accentColor、displayUrl、zoomRegions、layout)
  • IntroCard / OutroCard — 默认介绍/结尾模板(tagline、subtitle、accentColor、logoSrc)
  • WordHighlightCaptions — 逐字字幕(wordTimings、style、accentColor)
  • LowerThird — 场景标签叠加(label、accentColor、leftOffset)
  • ProgressBar — 进度指示器(accentColor)
  • AudioWaveform — 音频反应可视化器(variant、accentColor、samples)
  • FeatureCallout — 标注注释(label、side、y、accentColor)
  • ChapterCard — 场景分隔卡片(chapterNumber、title、accentColor)
  • Presenter — 带有唇形同步的2D角色(mouthCues、side)
  • AvatarPip — 画中画头像
  • SceneBreak — 场景边界处的短暂视觉闪动

你也可以在组合文件中内联编写自定义组件。

每个视频要做出的设计决策:

  • 介绍风格: 编写自定义介绍或使用IntroCard。匹配应用的个性——乡土/有机、科技/干净、温暖/邀请、大胆/有力。
  • 结尾风格: 编写自定义结尾或使用OutroCard。同样的个性匹配。
  • 包含哪些叠加元素: 并非每个视频都需要所有叠加元素。对于简洁的SaaS演示,跳过AudioWaveform。对于短视频,跳过ProgressBar。如果片段很明显,跳过LowerThird。
  • 叠加位置: LowerThird不一定非得在左上角。字幕不一定非得在底部居中。选择不与录制中重要的UI元素重叠的位置。
  • 动画多样性: 不要总是使用同样的弹簧入场。混合淡入、滑动、擦除、打字机、交错效果。Remotion技能展示了这些模式。
  • 介绍→内容→结尾之间的过渡: 淡入、滑动、擦除或光泄漏。选择适合的。

composition.tsx的模板文字示例:

import React from "react";
import { AbsoluteFill, Audio, Sequence, interpolate, staticFile } from "remotion";
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
// 导入构建块
import { DeviceMockup } from "./components/DeviceMockup";
import { WordHighlightCaptions } from "./components/WordHighlightCaptions";
import { ProgressBar } from "./components/ProgressBar";
// 导入你的自定义介绍/结尾(内联编写或作为单独组件)
// 导入类型
import type { MarketingDemoProps } from "./MarketingDemo";
export type { MarketingDemoProps };

export function calculateMarketingDemoDuration(props: MarketingDemoProps) {
  return props.introDurationFrames + props.videoDurationFrames + props.outroDurationFrames - 20;
}

// 你的自定义介绍组件(内联)
const MyIntro: React.FC<{...}> = (...) => { ... };

export const VideoComposition: React.FC<MarketingDemoProps> = (props) => {
  // 你独特的合成布局在这里
};

要遵循的Remotion规则:

  • 所有动画由 useCurrentFrame() 驱动——不要使用CSS动画或transition属性。

相关技能