/bb:edit
目标
将原始素材剪辑成一个能让陌生人驻足、产生共鸣并采取行动的短视频:一个1080x1920的主版本和一个标准的1080x1350信息流主版本,两者都大约在-14 LUFS,并附带一个说明每处剪切为何在彼的剪辑方案。
在此之前:检查此Mac
python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" --data "${CLAUDE_PLUGIN_DATA}"
它会为每个工具打印一行状态,附带精确的修复方法,然后输出 READY 或 NOT READY。可以安全地重复运行,一旦所有工具就绪只需几秒钟。首次运行会构建Python工具,这需要几分钟。
如果返回 NOT READY,将修复指令提供给用户并停止。如果仅缺少模型,告知用户大约需要490 MB,在用户同意后添加 --download-models 参数重新运行同一命令。OPTIONAL 状态的行不会阻塞任何操作。
然后:询问我们要做什么
运行此命令的人掌握上下文,他们提供的信息是保证工作质量的关键。我们曾因为没提问而导致一个广告失败;又因为有人提供了真实背景而成功制作了一个Reel。
先查看已有内容(素材、脚本、简报、笔记)并重述,以便用户确认而不是重新输入。在一次简短的对话中提问(如果知道答案,使用AskUserQuestion;否则在消息中提问)。
始终要先提问,除非用户已经告知:
- 我们要做什么?这是什么类型的视频? 品牌宣传视频、展示Reel、销售付费广告、UGC或创始人讲话、幕后花絮,还是其他类型?
然后只询问缺失的信息:
- 目标受众是谁?看完后希望他们产生什么感受或采取什么行动?
- 风格如何?哪个参考最接近?然后你将基于实际素材展示可选的风格选项。
- 素材、声音或音乐、时长,以及发布平台。
如果是广告,脚本的购买者和阶段信息需保持一致,或者先运行 /bb:script。剪辑绝不可替换创意或产品声明;这需要回到脚本阶段处理。
将答案写入 job/brief.md,然后一直工作到完成。唯一的额外停顿是步骤2中的选项提供。如果用户已提供所有信息,或说直接开始,则无需提问。如果无人能回答(无头运行),请说明你会问什么问题,并做出合理的判断。
审美取决于任务
问题1确定了任务:将其写入 job/brief.md 的第一行。一个视频中某人的喜好不适用于另一个视频。有机运营的Reel和广告是不同任务:广告的目的是销售。因此广告的评判标准是目标受众、产品卖点、证据和购买理由,而不是有机内容中的笑话或感觉。从有机运营剪辑中学到的教训不约束广告,反之亦然。
为什么
通用AI剪辑会在每个音乐节拍处剪切,给每个镜头相同的时长,对一切进行推拉,并在最后一句话结束的瞬间停止。这里每一个做法都曾被否决(参见 lessons.md)。剪辑书籍能更好地回答同样的问题,因此我们在每个决策时咨询它们:Murch用于思考何时结束;Pearlman用于节奏和开放式问题;Block用于视线引导。书籍提供的只是问题和段落,而非具体声音。
好作品的标准
- 第0帧在静音状态下就已经是一张有效的静止画面:展示产品、结果或惊喜,而不是Logo或问候语。
- 在钩子部分提出一个问题,并在回报部分之前保持开放。
- 剪切落在一个思考或动作完成处,而不是在固定节拍上。至少有一个镜头在快速剪辑中保持较长,以表明是有意的停顿。
- 每个镜头中最亮或运动的部分应该是视觉焦点。文字位于下巴下方或天空区域,绝不要在嘴巴上,也不要堆叠另一行相同含义的文字。
- 结尾比前一帧更平静,诉求明确。结局自然:音乐在自身结尾或真实乐句处结束,绝不要在一片仍在进行的歌声上渐弱,也不要覆盖自己的最后强拍。
- 真实声音包含在内。画面中的人物声音高于音乐,歌曲的最高点与画面的最高点同步。
- 素材保持原始拍摄状态:iPhone的自然色彩、固定的构图,只对产品进行轻微的推近,无动态缩放、无镜像填充、无黑边。
- 4:5版本基于相同的EDL重新布局,使字幕和面部保持在画面内。
命令
引用文件写得很简短。Shell状态不会在命令之间保持,因此始终使用完整形式,并且也要给评审代理使用完整形式。
PY代表"${CLAUDE_PLUGIN_DATA}/venv/bin/python",即setup构建的Python。所有Python脚本均使用它运行。scripts/...代表${CLAUDE_SKILL_DIR}/scripts/...。references/...代表${CLAUDE_SKILL_DIR}/references/...。search.py代表python3 "${CLAUDE_PLUGIN_ROOT}/skills/books/scripts/search.py"。
工作流程
任务文件夹:用户当前文件夹中的 <客户端>-<任务>/,或简报中命名的文件夹(job/)。素材保持原位;只写入渲染文件。
- 读取和聆听。 在规划之前运行
PY scripts/listen.py clips <素材> --out job/sound:它会转录每个片段,并找出语音、笑声、喊叫和电平峰值。阅读全部内容。画外音往往是创意所在,并且它们告诉你镜头的真实含义(一个广告中的“应用”镜头实际上是导演在说“你不需要应用任何东西”)。同时运行PY scripts/listen.py song <音轨>并阅读歌词:它们可能与画面冲突或相得益彰。然后阅读任何客户笔记、lessons.md、客户自己的历史剪辑文件夹(仅该客户,参见examples/README.md)、脚本或简报。运行scripts/probe.sh <素材> > job/footage-log.md,然后观看片段并添加最佳时刻的时间码。在转换HDR之前使用scripts/proxies.sh。别人写的素材日志只是线索,不是事实:在每个挑选的片段进入EDL之前,查看其帧画面(scripts/sheet.sh <片段> <开始> <长度> job/sheets,这样除了素材本身之外没有其他内容)。将脚本或简报中的每个主张与显示该主张的片段时刻逐一对照;没有任何片段展示的主张现在就需要修改或删除,而不是由评审代理来做。用用户自己的话,用一句话描述氛围。 - 规划。 加载
references/plan.md、rhythm.md、eye.md、sound.md。使用PY scripts/beats.py <音轨>对音乐进行测量:节奏、第一拍和响度映射,显示音轨在music.start处已有动态的部分。针对每个节拍(钩子、转折、回报、结尾):要传达的感觉、节奏、视线落点、声音。每列进行一次搜索。撰写job/plan.md,每行附有段落ID。 - 提供选项。 每个部分大约三种处理方案(平缓、中等、激进),以缩略图形式呈现:每个方案一张画面和一行描述。由用户选择。如果用户不在场,或说直接开始,由你选择,在
options.md中记录理由,并保持其他选项可见;有一个选项表格就已足够。 - 粗剪。 加载
references/formats.md。编写job/edl.json,然后使用mix.py(声音)和cut.py --draft(在代理文件上)进行操作。对结果运行scripts/sheet.sh和listen.py cut,并阅读报告及其波形图片。自行查看画面、钩子条和第0帧,并在静音状态下观看一次。 - 评审。 一个新的独立代理获取
job/brief.md(以便根据任务进行评判)、全尺寸的第0帧、所有画面、条状图、聆听报告、混音日志、主张列表、references/critic.md以及完整的search.py命令。第0帧优先处理,因为缩略图可能产生误解。不包含你的笔记或本对话。它返回每个节拍的评审意见,最多三个修复建议并附有段落ID,以及一个最终判决。 - 最终输出。 修复评审发现的问题(或写下为什么简报更合理)。将EDL指向全质量SDR文件,运行无
--draft的渲染,然后为4:5版本运行reframe.py,再对结果运行check_cut.py和listen.py cut。修复所有 FAIL;阅读所有 WARN。明确说明尚未有人听过它: 报告只是测量,并不聆听,因此语音线路和混音需要交给用户自己的耳朵。两个主版本各生成画面。按照formats.md处理README.txt和交付文件。
回复时附带两个文件、第0帧、评审后每个节拍变化的简要说明,以及一句引用书籍的话。所有引用保留在 plan.md 中,绝不要出现在视频上。
硬性限制
- 修改后的主张或创意必须回到
/bb:script。如果素材或声音导致创意无法实现,停止执行,与评审代理一起重新进行诊断和脚本撰写;绝不要在剪辑过程中替换台词。我们曾有一个广告在剪辑中替换了台词,最终发布后没有观众,也没有存在的理由。 - 在粗剪之前必须提供选项。如果用户不在场,由你选择并记录;绝不可跳过。
- 绝不可减慢或加快人声。当镜头的速度不是1时,
cut.py会静音该镜头自己的音频。 - 无降噪、无模糊、无动态缩放、无镜像填充、无黑边。HDR首先通过avconvert转换为SDR。对讲话镜头和UGC不做调色。只有在简报要求时才能应用轻微调色(在EDL中设置
look),并在回复中明确说明。 - 绝不可在关闭片头声音且未在计划中记录理由的情况下交付视频。
- 一个镜头绝不可证明比实际发生的情况更多:如果音频显示是口型同步,那它就不是证据。
- 字幕使用口语语言,每个重要词汇都需添加,绝不要覆盖嘴巴,绝不要与标注文字堆叠。
- 屏幕上的主张、价格和优惠必须来自简报或客户的实时网站,绝不可凭空捏造。
- 未经用户同意,任何内容不得发送给客户、发布或产生费用。交付到客户的Drive以及任何消息均为用户草拟;由用户自己发送。
实用知识
- 文字: Homebrew的ffmpeg没有
drawtext和 libass,因此文字由scripts/text_png.swift(CoreText,由cut.py编译一次)渲染为PNG图片,并通过overlay叠加。字体位于assets/fonts/(Geist Black、Geist Bold、Playfair Display Italic);客户自己的字体通过路径在EDL的styles块中设定。 - Whisper是英语模型,可能误听画外音。
listen.py使用小型英语模型。检查你添加字幕的每一行,通过阅读对应帧来确认;如果需要更清晰地识别可疑行,setup.py --download-large可添加一个更大的模型(1.6 GB),listen.py clips --large会使用该模型。 - 速度: 最终渲染速度大约为每秒3到5帧(从1080p源输出1080x1920,同时运行其他编码任务);一个30秒的广告需要3到5分钟。粗剪时使用
--draft参数。将长时间的渲染作为后台任务运行。 - 节拍对齐的剪切:
beats.py从文件中测量bpm和offset。测量整个音轨:它会检查两半是否一致,而在一个引子上的短窗口可能会锁定错误的脉冲。为音乐提供bpm和offset(文件开头到第一个重拍之间的秒数),或提供一个beats列表。将那些应该落在节拍上的镜头结尾标记为"snap": true;默认只捕捉这些镜头。cut.py --beats会显示当前剪切对应的节拍网格。只在转折和回报处对齐节拍,而非每个剪切点:check_cut.py会在超过80%的剪切点落在节拍上时发出警告。 - 文字时间: 将文字与镜头关联(
"shot": 2, "at": 0.3, "dur": 1.2),而不是绝对秒数,这样当节拍对齐导致剪切移动时,文字会跟随镜头。 - 响度: 使用线性模式的两遍
loudnorm标准化到-14 LUFS,然后以4倍采样率使用限制器;cut.py会测量文件,并在AAC将其推高到-1 dBTP以上时以较低上限重新编码。在镜头保留自身声音时,音乐默认比素材音频低14 dB;设置music.gain_db可更改。 - 4:5:
reframe.py精确按照9:16的方式为每个镜头取帧,并为每个镜头提取一个1350行高的窗口(y45,默认285)。文字保持其在画面中的位置,并向内收缩40像素。将9:16的文字保持在行330至行1590之间,4:5版本无需额外工作。 - 安全区(9:16): 除全屏卡片外,任何内容不得高于行270或低于行1590;底部12%为Meta的按钮区域。
- 画面:
sheet.sh <视频> [开始] [长度]写入一个40帧的画面(时间码在其旁边的.txt文件中),钩子区域(或任意窗口)的10fps条状图以及第0帧。闪帧会在条状图中显示,而非画面中。 - 片段结尾: 当镜头的
out超过图片的最后一帧时,cut.py会发出警告并保持该帧,确保主版本不会因音频而变短。如果出现冻结帧,请将out拉回。 - 手持拍摄和推近:
x每个镜头只有一个数值,因此手持拍摄中的主体移动会超出窗口,而推近会放大这种移动。在信任构图之前,观看该镜头窗口的运动画面(sheet.sh <渲染> <镜头开始> <长度>给出10fps的条状图)。 - 单词时间漂移: Whisper的逐词时间偏差可达2秒。在台词加入之前,单独转录该片段;任何一端丢失的单词都意味着剪切错误。
- 唇音同步: 手机拷贝的音频可能比画面提前约0.1秒。在剪辑之前检查一个片段;如果语音超前,在画面上微调
in,绝不要调整单词。 - 书籍搜索:
search.py "<字面单词>" --job feel|rhythm|eye --book murch|pearlman|block --k 6,然后使用--show <id>阅读一条笔记。使用字面单词;问题形式无效。
参考文件(按决策加载)
references/plan.md:四节拍方案,每节拍每列一行,以及每列的查询。references/rhythm.md:剪切、保持、模式变化、开放问题的位置。references/eye.md:视线落点、文字位置、安全区、4:5波段。references/sound.md:聆听步骤、语音、音乐、效果、响度、结尾。references/critic.md:评审标准,仅由评审代理加载。references/formats.md:EDL格式、脚本顺序、输出、最终文件存放位置。references/drawings.md:手绘动画叠加在剪切上,当简报需要时。
经验教训
lessons.md 存储来自真实反馈和结果、带有日期标记的经验。在步骤0时阅读;评审代理会根据最近五条来检查剪辑。此文件夹在每次更新时被替换,因此客户自己的经验教训存储在该客户的文件夹中,而面向所有人的经验教训通过代码仓库(CONTRIBUTING.md)引入。