关于 analyze-video
ButterCut 的素材分析技能,在剪辑前为视频生成转录文本、联系表和片段摘要,并协调处理与素材复核。
主要功能
- 01转录文本与联系表流程
- 02依据视觉联系表生成摘要
- 03可选的转录文本校订
- 04进度跟踪与故障处理
适用场景
- 01为粗剪准备视频素材库
- 02查看片段内容与对白
- 03结合素材库上下文修正转录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ barefootford/ buttercut --skill analyze-video安装后在 Claude Code 中输入/analyze-video确认已加载。
附带文件agent_prompt.md
详细介绍
技能:分析视频(上级说明)
这是主线程中「分析视频」工作流步骤的操作指南。请在完成媒体库设置后、开始任何剪辑工作前运行。本文涵盖每段素材生成的三个产物:音频 transcript、contact_sheet 和 Markdown summary。粗剪 Agent 会在需要时运行 script_extractor.rb,从 transcript JSON 中读取对白——无需单独生成脚本产物。
SKILL.md 是上级的调度说明。子 Agent 的工作提示词位于 agent_prompt.md——启动 Task Agent 时,将其内容内联。不要传入 SKILL.md。
术语
- **面向用户:**称为「素材分析」或「分析素材」。
- **内部/文件名:**使用「转录」(例如,library.yaml 字段
transcript等)。
前提条件
- 媒体库设置已完成(
library.yaml已存在,架构为最新版本——如果不是,请运行 AGENTS.md 中的迁移)。 - 直接读取
libraries/settings.yaml,获取whisper_model。对于媒体库字段,请通过ruby lib/buttercut/library.rb <name> summary读取快照,并从 JSON 中提取所需值——不要直接解析 library.yaml。
此时,创建一个用户可见的待办列表,使用高层次、非技术性的步骤,让用户了解处理媒体库的整体计划。只有用户选择启用时,才加入保持电脑唤醒的步骤。例如:
- [ ] Keep computer awake
- [ ] Create transcripts (0/30)
- [ ] Analyze footage (0/30)
- [ ] Let computer sleep again
- [ ] Review the footage together
这些公开待办事项对应下方的步骤:「保持电脑唤醒」是步骤 1,「让电脑重新休眠」是步骤 6;「创建转录」涵盖步骤 2 中的机械化运行,以及步骤 3 中可选的优化流程(根据步骤 2 的 [transcript …] 进度行更新计数;如果启用了优化,则在步骤 3 期间保持进行中状态);「分析素材」跟踪步骤 4 中的摘要(随着素材完成摘要而更新计数,而不是在生成联系表后更新);「一起查看素材」是步骤 5。
在公开聊天中,使用这些非技术步骤来描述进展。将技术工作(WhisperX、联系表生成、Sonnet 摘要)放在幕后。
步骤 1 — 处理期间防止电脑休眠
开始分析前,通过 AskUserQuestion 询问用户:「处理可能需要一段时间——要我让电脑保持唤醒,直到处理完成吗?」选项:「是(推荐)」和「否」。
如果用户选择是,则在后台启动平台对应的保持唤醒助手,并保存 PID——分析完成后,在步骤 6 中将其终止。(备份由调用此技能的 process-library 技能在此技能返回后处理。)
macOS:
caffeinate -i -w $$ &
KEEPAWAKE_PID=$!
Windows(Git Bash):
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/keep_awake.ps1 &
KEEPAWAKE_PID=$!
这两种方式都会在处理素材期间防止电脑因空闲而休眠(显示器仍可能关闭,这没有问题)。
步骤 2 — 处理素材(先生成转录文本,再生成联系表)
(如果你是直接进入此技能,而非通过 process-library 进入,请先告知用户:“找到 [N] 个视频([total size])。开始分析素材……”)
这是两个机械操作命令,需要依次运行——先生成转录文本,再生成联系表。切勿同时运行:WhisperX 非常占用 RAM,而我们正是要避免两者同时运行。不要通过子 Agent 手动编写这两项操作;每次运行方式都相同,一次处理约 2 个片段,并在每个片段完成后立即将其记录到 library.yaml 中。两项操作均可幂等执行——只会处理仍缺少相应产物的片段——因此重新运行时只会完成剩余部分。它们会在一个类似 Sidekiq 的微型作业服务中运行。你将运行命令,然后查看返回的日志文件以跟踪进度。
步骤 2a — 转录文本。 如果使用 Claude Code,请在 Bash 工具中设置 run_in_background: true 运行。否则,请使用正确的工具和参数在后台运行。
ruby lib/buttercut/process_footage.rb transcripts <library-name>
启动后,立即在日志文件上设置 Monitor 或同等机制,以便每个片段完成或失败时收到通知:
tail -f tmp/logs/processing/<library-name>/$(date +%Y-%m-%d).log | grep --line-buffered -E "TranscribeJob (done|error)|transcript: [0-9]+/[0-9]+|Error|error:|failed|Traceback"
ruby lib/buttercut/library.rb <name> pending transcript # JSON list; done = N − its length
随着片段完成,更新“创建转录文本 5/20”,即已完成片段数/片段总数,让用户能看到进度。后台任务完成时,如果有任何片段失败,退出状态将为非零。失败时,重新运行一次。如果再次失败,请进行调查,然后要么创建修复,以便妥善处理此问题,要么告知用户该片段的问题,并视情况将其从素材库中移除。
等待步骤 2a 完成后再开始步骤 2b。
步骤 2b — 联系表。 转录文本完成后,生成联系表(快速的 ffmpeg 处理,可在前台运行):
ruby lib/buttercut/process_footage.rb contact-sheets <library-name>
联系表仅在后台使用——不要将其作为公开计数展示。步骤 2a 和任何润色(步骤 3)完成后,将“创建转录文本”标记为已完成。
调整(可选):两个步骤都会从 libraries/settings.yaml 读取 parallel_jobs(默认值为 2);可使用 --jobs N 覆盖单次运行的设置。每个步骤都会在 tmp/logs/processing/<library>/ 下写入带时间戳的日志,供事后查看。
重新处理。 每个步骤都会跳过已生成相应产物的片段。若要重新处理某个片段——例如转录文本误听了人名——请使用 --force --clips NAME.mov 重新运行该步骤。单独使用 --force 会重新处理所有片段。
步骤 3 — 润色转录文本(需判断——仅当 transcript_refinement: true 时)
转录流程中唯一需要判断的环节是根据素材库上下文修正误听的专有名词,因此这一步交由模型处理,在机械处理完成后再运行。如果素材库的 transcript_refinement 为 false,请跳过整个步骤。
如果为 true,请对步骤 2a 刚写入的转录文本分批调用润色子 Agent(并行运行 2-4 个,滚动执行)。将 skills/transcribe-audio/refine_instructions.md 的内容直接内联为每个子 Agent 的提示词,并内联传入:
transcript_path— 片段转录 JSON 在libraries/<library>/transcripts/下的绝对路径user_context和footage_summary— 使用ruby lib/buttercut/library.rb <name> summary获取的当前值(可以是空字符串;润色仍会修正无意义词元和自我见证问题)
子 Agent 会就地编辑转录 JSON,并返回一份简短的修正列表。它们不会修改 library.yaml——步骤 2a 已设置 transcript 字段。润色完成后,将公开的“创建转录文本”待办事项标记为已完成。
步骤 4 — 摘要(Sonnet 子 Agent,批量处理,滚动调度)
使用 Sonnet 模型调度 analyze-video 子 Agent。与 Haiku 相比,Sonnet 能从联系表中读出明显更具体的视觉信息(能捕捉服装、建筑和镜头构图)——这很值得,因为摘要会影响之后的每个剪辑决策。
每个子 Agent 处理 10 个片段,最多并行运行 10 个子 Agent,并采用滚动调度。 每个子 Agent 按顺序处理自己的 10 个片段;批量处理可以摊薄每个 Agent 约 5–10 秒的调度开销。对于一个包含 93 个片段的素材库,总共只需约 10 个子 Agent,而不是 93 个。某个子 Agent 一返回,就立即启动下一个;不要等整批 10 个都完成,否则整体耗时会多出约 30%,因为要等该批次中最慢的 Agent。
传给每个子 Agent 一个包含 10 条片段记录的列表。每条片段记录需要包含:
video_filename— 视频的基本文件名(用于摘要标题和回复行)duration— library.yaml 中的时长字符串(例如00:01:19);Agent 会将其写入摘要标题contact_sheet_path—_full.jpg的绝对路径(来自步骤 2)transcript_path— 音频转录 JSON 的绝对路径(来自步骤 2);子 Agent 会按需通过script_extractor.rb提取对白summary_output_path— Agent 应写入摘要 Markdown 文件的绝对路径。不要手动拼出这个文件名;通过以下命令让素材库返回规范路径:ruby lib/buttercut/library.rb <name> field_path summary <clip>(会自动处理summaries/summary_<clip>.md命名约定,无论文件扩展名是否存在)
每个子 Agent 返回一批结果后,更新 library.yaml,为该批中的每个片段添加 summary:
ruby lib/buttercut/library.rb <name> complete summary <filename> [<filename>...]
contact_sheet 字段已在步骤 2 中填写,因此子 Agent 返回的内容只需包含摘要。
如果子 Agent 将摘要直接返回,而不是写入磁盘(有时 Sonnet 会臆测“写入工具被阻止”,然后在回复中直接输出 Markdown),不要盲目重试——只需从 Agent 的回复中提取每份摘要,并在父线程中用 Write 将其写入对应的 summary_output_path。然后照常运行 complete summary 命令。这样比重新调度更快,而且内容已经有了。
(长片段的分段联系表会生成在磁盘上 _full 联系表旁边,可按约定查找——它们不会列在 library.yaml 中。)
摘要全部完成之前不要继续。随着片段摘要完成,更新“分析素材”的计数;全部完成后将其标记为完成。
图像。 静态图像完全跳过步骤 2–3(无需转录音频,也无需构建联系表)——它们只需要一份 summary,而且会和视频一起显示在 ruby lib/buttercut/library.rb <name> pending summary 的结果中。图像本身就是要查看的内容,因此请直接为其撰写摘要:在主线程或 Sonnet 子 Agent 中读取图像文件(文件很小),然后写一段 3–4 句的描述,说明主体、场景、构图以及图像上的文字,并保存到 ruby lib/buttercut/library.rb <name> field_path summary <image-filename> 返回的规范路径。请注意,图像片段键包含扩展名(title-card.png → summaries/summary_title-card_png.md),field_path 会自动处理。然后按相同方式记录:ruby lib/buttercut/library.rb <name> complete summary <image-filename>。
第 5 步 — 与用户确认对素材的理解
(这是“共同回顾素材”待办事项。)所有摘要都写好后,与用户一起梳理素材实际展示的内容——确认人物姓名、地点、叙事主线、任何无关或偏离主题的片段,以及用户对这个素材库的创作意图。使用普通对话;只有在提供明确选项时才使用 AskUserQuestion。了解情况后,更新:
- 通过
ruby lib/buttercut/library.rb <name> update_metadata footage_summary "..."更新footage_summary和user_context(user_context也使用同样的命令) - 如果摘要误标了某人或遗漏了关键信息(例如,“一个穿棕褐色夹克的男人”→用户的姓名),请修改相应的
summary_*.md文件
这是唯一一次进行如此全面梳理的环节。之后每次规划粗剪时,都会继承由此形成的上下文,而不是重新询问素材库的情况。
第 6 步 — 停止防休眠辅助程序
如果你在第 1 步启动了辅助程序,现在将其关闭(两个平台均适用):
kill $KEEPAWAKE_PID 2>/dev/null
并行子 Agent 模式(参考)
用于第 3 步和第 4 步。
父 Agent 的职责:
- 读取一次
library.yaml和settings.yaml,收集子 Agent 所需的所有值。 - 启动 Task Agent,并在提示词中内联传入所有所需值。
- 随着 Agent 完成,按顺序更新 library.yaml(通过
LibraryAPI——参见 AGENTS.md)。 - 处理错误并重试。
子 Agent 的职责:
- 仅使用父 Agent 内联传入的输入,处理分配给自己的片段。
- 原地完善转录 JSON(refinement),或读取预生成的联系表,通过
script_extractor.rb从转录中提取对话,并在一次 Write 调用中写入摘要 Markdown(analyze-video)。(WhisperX 不再作为子 Agent 运行——process_footage.rb transcripts会在第 2a 步运行它。) - 返回简短的结构化回复,其中包含文件路径。
每个技能的 agent_prompt.md 都记录了其自身的 IO 合约,包括子 Agent 是否读取或写入 library.yaml。(剧透:它绝不会写入 library.yaml。只有父 Agent 会通过 Library API 写入。)
如果用户在分析完成前请求粗剪
提醒用户:“我现在可以制作粗剪,但分析完所有素材后,效果会更好。仍要继续吗?”如果用户确认,就继续;否则,等分析完成后再进行。