Communitygithub.com

every-app/video-skills

从真实产品截图和用户的网络摄像头叙述中制作一款带旁白的产品视频(发布视频、产品演示或教程)。捕捉产品、构建故事板进行录制、编辑录制的片段(包括重录、死寂、可选填充词)、将每个场景、点击和按键与口语单词同步,然后渲染并验证一个带有圆形摄像头气泡的1080p MP4文件。

video-skills 是什么?

该技能“Narrated video”使AI代理能够从真实产品截图和用户的网络摄像头叙述中自动生成带旁白的产品视频。它支持发布视频、功能演示和教程三种格式。整个过程包括:简短确认需求,使用Playwright捕获真实产品截图,构建故事板,用户录制单次旁白,代理自动编辑(移除重录、死寂,可选减少填充词),利用Whisper进行本地语音识别,基于HyperFrames框架将文字叙述与截图动画同步(点击、输入等操作精确匹配口语单词),最后渲染并验证1080p MP4视频。技能支持macOS、Linux和Windows平台,但Whisper在Apple Silicon上使用mlx-whisper,其他平台使用faster-whisper。编辑器未打开的情况下,每次编辑都会在能量轨迹上定位并测试剪切点,确保音频平滑。最终视频会通过多步检查,包括画面完整性、音频电平等。该技能特别适合需要自行录制旁白来制作产品演示、操作指南或发布视频的场景。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/every-app/video-skills/tree/HEAD/skills/narrated-video

在你喜欢的 AI 中提问

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

文档

旁白视频

用户录制一段自己根据故事板讲述的旁白。代理编辑该片段,并将真实的产品截图动画化以匹配旁白:每个场景开始时,每次点击的位置,以及每次搜索时输入的单词都与旁白的发音同步。整个视频由代码构成(一个HyperFrames合成加一个编辑列表),因此重新录制、更换截图或调整顺序只需重新运行,无需重新编辑。

视频始终适应旁白,而非相反。用户决定风格;代理负责剪辑、显示帧并进行询问。

设置

  • 路径中需包含 ffmpeg、uv、Node 20+ 和 npx(HyperFrames 0.8.62 通过 npx 运行),以及用于捕获的 Playwright 和 Chromium。支持 macOS、Linux 和 Windows。
  • Whisper 本地运行:Apple Silicon 上使用 mlx-whisper,其他平台使用 faster-whisper。uv run 会自动安装正确的版本。
  • SK=<此技能目录>/scripts。所有工具均以 uv run $SK/<tool>.py 形式运行;每个工具声明自己的依赖。
  • 在仓库追踪文件之外的文件夹中工作(例如 .logs/<video>/ 或临时文件夹):
<work>/
  assets/            捕获文件、背景、结束卡片
  storyboard.json    场景 -> storyboard/index.html
  takes/<name>/      每个录制的片段文件夹:探测输出、转录、edit.json、剪辑后的旁白和摄像头视频
  video.py           合成脚本 -> comp/ (index.html, renders/)
  NOTES.md           所有决定:剪辑及其原因、场景开始时间、重建命令

1. 简要确认

通过一次简短交流确认,并提供默认值:

  • 格式:发布视频、功能演示或教程(references/formats.md)。发布视频时长需控制在2分钟以内(含结束卡片)。
  • 目标受众、视频必须传达的三到四个要点以及行动召唤(CTA)。
  • 适合演示的示例数据:一个示例业务或搜索,能让受众一眼理解。
  • 品牌:背景图片(或默认渐变)、结束卡片(产品OG图效果不错)、窗口标题栏中显示的URL。

2. 捕获

基于 $SK/capture.mjs 构建的 Playwright 脚本,以1440x900、2x分辨率捕获运行中的产品真实截图:为屏幕上输入的任何内容生成逐帧帧序列(每个按键对应一帧),为点击操作生成前后状态,为滚动操作生成高截图,以及为指针生成测量好的点击目标。如果应用需要登录,传递 login 参数,首次运行时会打开一个浏览器窗口供用户一次登录。切勿绘制UI或编辑像素。使用前仔细检查每个捕获结果。详情及隐私说明:references/capture.md。

3. 故事板

编写 storyboard.json,每个场景一张卡片:截图、屏幕上显示的内容、三到六条讲述要点(简短笔记,非完整句子)、大致时长。构建并展示:

uv run $SK/storyboard.py storyboard.json storyboard/

这是一个简单的页面,每个场景一个区块。当工具可以发布页面时,发布 storyboard/(index.html 加上 frames/),否则在本地打开。反复迭代直到用户准备好录制,然后提供录制说明(参见 references/storyboard-and-recording.md)。一旦用户开始据此录制,未经询问不得修改故事板。

4. 录制

用户录制一次单个片段,摄像头和声音合在一个文件(任何网络摄像头录制工具:QuickTime、Photo Booth、Windows Camera、OBS),对着故事板讲述。口误没关系:重新开始句子继续即可。允许多次录制;每次录制会放在一个单独的文件夹中。

5. 编辑片段

uv run $SK/probe.py <recording> takes/<name>       # take.wav, cam.mp4, take.json; 检查 still.jpg,如果需要裁剪则添加 --crop 重新运行
uv run $SK/transcribe.py takes/<name>              # 两次转录:普通版,以及将填充词写出的版本
uv run $SK/analyze.py takes/<name>                 # 候选:长停顿(含剪切点)、填充词、重录、杂音
uv run $SK/trace.py takes/<name> <a>:<b>           # 将每个剪切点定位到能量轨迹上(添加 --fine 以获得5毫秒精度)
uv run $SK/splicetest.py takes/<name> c1=<a>:<cut start>,<cut end>:<b>   # 试听剪切效果:必须听上去是预期的句子
uv run $SK/jump.py takes/<name> <cut start>:<cut end> --slide 0.3        # 检查剪切点在摄像头气泡中的可见程度
# 编写 takes/<name>/edit.json,然后:
uv run $SK/edit.py takes/<name>                    # edl.json;输出编辑后的旁白和保留的填充词:完整朗读一遍
uv run $SK/build.py takes/<name>                   # narration-edit.wav, cam-edit.mp4(每次剪切处包含交叉淡入淡出和摄像头溶解效果)
uv run $SK/master.py takes/<name>                  # 生成 -16 LUFS 的 narration.wav

两种编辑级别(references/editing.md):

  • 轻度编辑(默认):删除重录和假开始,修剪死寂(超过约1.1秒的停顿保留0.7秒,场景切换处保留0.9秒)。每个“嗯”和短暂犹豫保留。
  • 减少填充词(应要求):额外删除大多数独立于短语之间的“嗯”,并将超过约0.8秒的停顿修剪至约0.55秒。保留任何与相邻词语粘合的填充词。
  • 每个剪切点必须位于能量轨迹中的房间噪音区内,并且在纳入前必须通过拼接测试。重录剪切点尽可能在场景切换处进行,以便画面剪切隐藏气泡中的跳动。

6. 根据文字合成

uv run $SK/cues.py takes/<name>       # words.json,提示表(最终旁白的片段级转录)
NV_SCRIPTS=$SK ASSETS=assets uv run --with numpy python video.py   # 合成脚本 -> comp/;在上下文中打印每个提示
uv run $SK/render.py comp lint
uv run $SK/render.py comp snapshot 1,14.2,22.5,40.1

基于示例编写 video.py(examples/openseo-launch/video.py):从提示表中获取场景开始时间和提示时间(cue times),将摄像头层叠加在捕获之上,并创建与文字同步的编排。示例中的提示位置仅适用于其自己的编辑:需要重新定位每个提示,并在每次编辑更改后读取打印出的提示表。时间规则参见 references/composition.md;最重要的几条:

  • 场景在其第一个词语前0.3秒开始,或恰好在该词之前的停顿中的剪切点处开始。
  • 每个动作落在命名它的词语上:点击在“复制”一词上,打字在说出搜索词时,缩放数字在其被说出时,指针在命名每个项目时指向它。
  • 第一帧是海报帧:整个应用,无淡入。每帧都有内容在移动。
  • 每个节拍一个简短标签。对每个场景开始、点击和标签进行截图,并在渲染前查看它们。

7. 渲染并验证

uv run $SK/render.py comp render
uv run $SK/composite.py comp takes/<name> comp/renders/<video>-1080p.mp4
uv run $SK/check.py comp/renders/<video>-1080p.mp4 comp takes/<name>
uv run $SK/filmstrip.py comp/renders/<video>-1080p.mp4 comp/renders/filmstrip.png

在满足以下条件之前,不要将结果交给用户:检查显示每一帧都有窗口、每个摄像头点位于帧偏移0处、音频中位数为0毫秒、音频电平约为 -16 LUFS,并且你已阅读转录并查看了胶片条(references/verification.md)。

8. 审阅与迭代

  • 向用户提供 MP4 路径、被剪辑的内容以及需要留意的地方。
  • 保持 NOTES.md 最新:每个剪辑及其原因、场景开始时间、重建命令。预期会经历多轮修改。
  • 变体成本很低:另一种录制、一种轻度或减少填充词的编辑、不同的场景顺序。每个都是独立的编辑文件夹或合成脚本;使用子代理时,以独立文件名并行构建,避免冲突。

硬性规则

  • 仅使用真实截图。隐藏不属于故事的部分(如横幅、Cookie 通知);切勿覆盖像素。
  • 在渲染前检查捕获和录制内容是否包含秘密或个人数据(API 密钥、他人的邮件和姓名、客户数据、localhost URL);通过画面裁剪或重新捕获来规避,并撤销任何出现在屏幕上的密钥。用户自己的姓名或邮件出现在应用中可以,但需经其确认。
  • 用户的录制和登录会话保留在其计算机上。未经要求不得发布任何内容。

常见陷阱:references/gotchas.md。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能