关于 capture-video-frames
capture-video-frames 按时间间隔截取 YouTube 视频帧,并引导 Agent 描述、去重和筛选画面,适合制作视频内容的视觉记录。
主要功能
- 01按间隔截取视频帧
- 02生成带时间戳的清单
- 03调用子 Agent 描述画面
- 04去除视觉相似的帧
- 05按说话者面部状态筛选
适用场景
- 01制作视频的视觉摘要
- 02为文档选择代表性画面
- 03检查截取帧中的说话者状态
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pamelafox/ presentation-skills --skill capture-video-frames安装后在 Claude Code 中输入/capture-video-frames确认已加载。
附带文件capture_video_frames.py
详细介绍
捕获并描述视频帧
第 1 步:捕获帧
运行 capture_video_frames.py 脚本:
uv run .agents/skills/capture-video-frames/capture_video_frames.py <youtube_url> <output_dir> [--interval SECONDS]
参数
youtube_url(必需):YouTube 视频 URL(接受的格式与 extract-transcript 技能相同)。output_dir(必需):用于保存帧和清单文件的目录。如果目录不存在,则会创建。--interval(可选):捕获帧之间的秒数。默认为 30。
输出
- frame_0000.png、frame_0030.png、…… — 按时间戳(秒)命名的 PNG 图像,时间戳补零至 4 位。
- frames_manifest.md — 一个 Markdown 文件,列出每一帧及其时间戳,并为描述预留占位内容。
frames_manifest.md 示例:
| File | Timestamp | Description |
|------|-----------|-------------|
| frame_0000.png | [00:00] | |
| frame_0030.png | [00:30] | |
| frame_0060.png | [01:00] | |
前提条件
- yt-dlp:
brew install yt-dlp或pip install yt-dlp - ffmpeg:
brew install ffmpeg或apt-get install ffmpeg
第 2 步:使用 describe-frame 子 Agent 描述帧
捕获帧后,将 describe-frame 自定义 Agent 作为子 Agent 运行,为每一帧添加描述。每次调用子 Agent 都会获得独立的上下文,因此帧图像不会不断累积并耗尽上下文窗口。
describe-frame Agent 定义在 .github/agents/describe-frame.md 中。
操作步骤
- 从输出目录读取 frames_manifest.md,获取完整的帧列表。
- 对于每一帧,将
describe-frameAgent 作为子 Agent 运行,并在提示词中包含:- 要查看的当前帧图像的绝对路径。
- 要查看的上一帧图像的绝对路径(如果存在)。
- 上一帧的文字描述(如果存在)。
- 子 Agent 将返回纯文本描述(如果该帧与上一帧基本相同,则返回
(same as previous))。 - 每次子 Agent 返回后,立即更新 frames_manifest.md 中该行的 Description 列。
- 继续操作,直到所有帧都添加了描述。
子 Agent 提示词模板
调用 describe-frame 子 Agent 时使用此提示词(填写方括号中的值):
Describe the current frame image at: [CURRENT_FRAME_ABSOLUTE_PATH]
[If previous frame exists, include these two lines:]
The previous frame image is at: [PREVIOUS_FRAME_ABSOLUTE_PATH]
The previous frame was described as: "[PREVIOUS_DESCRIPTION]"
输出示例
描述完所有帧后,frames_manifest.md 应如下所示:
| File | Timestamp | Description |
|------|-----------|-------------|
| frame_0000.png | [00:00] | Title slide introducing "Building RAG apps with Python" |
| frame_0030.png | [00:30] | Speaker showing the agenda with four main topics |
| frame_0060.png | [01:00] | (same as previous) |
| frame_0090.png | [01:30] | Architecture diagram of a retrieval-augmented generation pipeline |
第 3 步:去重帧并挑选效果最佳的演讲者面部画面
为所有帧添加描述后,连续的 (same as previous) 行表示在不同时间捕获到相同的视觉内容。在每组中,演讲者的面部状态可能不同——眼睛睁开或闭合、嘴巴张开或闭合、面向镜头或转向一旁。
目标
对于每组重复帧,只保留一帧——即演讲者面部效果最佳的一帧——并删除其余帧。
面部效果最佳的判断标准(按优先级排序)
- 当前演讲者的嘴巴应张开(正在说话)。如果你知道该时间戳正在发言的人是谁(可从转录稿中得知),则优先选择该演讲者。
- 眼睛睁开——避免选择眨眼过程中的帧。
- 面向镜头——没有侧身或低头。
- 如果没有可见的演讲者(例如全屏演示或不含摄像头画面的幻灯片),则该组中的所有帧都视为相同,保留第一帧。
操作步骤
- 找出所有描述为
(same as previous)的连续行组。每组都以“锚点”帧(带有实际描述的帧)开头,后接一行或多行(same as previous)。 - 对于每组,将
describe-frame子 Agent 作为子 Agent 运行,比较锚点帧与每个重复帧的人脸。使用此提示词模板:
Compare these two frames focusing ONLY on the speaker faces visible in webcam feeds. Which frame has better speaker faces — eyes open, facing camera, mouth open (mid-speech), not mid-blink or turned away?
Frame A: [ANCHOR_FRAME_ABSOLUTE_PATH]
Frame B: [DUPLICATE_FRAME_ABSOLUTE_PATH]
Reply with ONLY one of:
- "A BETTER" if the anchor frame has better speaker faces
- "B BETTER" if the duplicate frame has better speaker faces
- "EQUAL" if both are equivalent
- "NO SPEAKERS" if no speaker faces are visible in either frame
Then add a brief reason.
- 将该组中的所有重复帧都与锚点帧(以及当前效果最佳的帧)比较后,确定唯一的最佳帧。
- 如果最佳帧不是锚点帧:
- 将锚点帧的描述移到最佳帧对应的行。
- 在描述中添加面部效果说明,例如
(better speaker faces than frame_XXXX: eyes open, facing camera)
- 从清单中删除所有其他
(same as previous)行。 - 如果锚点帧本来就是最佳帧,则只需删除重复行。
重新捕获闭嘴的画面
去重后,如果某组中最佳画面里说话者仍然闭着嘴(两位说话者都闭着嘴),请尝试在附近时间点重新捕获:
- 如果尚未下载视频,请先下载:
yt-dlp -f "bestvideo[height<=720]" --no-playlist -o "<output_dir>/video.%(ext)s" "<youtube_url>" - 在该画面时间戳之后的 +2 秒、+5 秒、+8 秒和 +10 秒处捕获替代画面:
ffmpeg -ss <SECONDS> -i <output_dir>/video.mp4 -frames:v 1 -q:v 2 <output_dir>/alt_<FRAME>_<SECONDS>.png -y - 使用
describe-frame子 Agent 检查任一替代画面中说话者是否张开了嘴,并确认幻灯片/演示内容仍然相同。 - 如果找到更好的替代画面,请替换画面文件(
cp alt_XXXX.png frame_XXXX.png)。 - 清理:
rm -f <output_dir>/alt_*.png <output_dir>/video.mp4
评论
支持 Markdown