Communitygithub.com

ThomasHMD/rough-cut

为 Premiere Pro 自动粗剪人物讲话素材(独白、口播视频)。生成一份 Final Cut Pro 7 XML(XMEML),其时间线已移除重拍、假起始、口吃、填充词和长静音。原始剪辑永不触碰。

rough-cut 是什么?

rough-cut 是一个面向 Premiere Pro 的强大 AI 技能,专门用于自动粗剪人物讲话素材,如独白和口播视频。它能智能识别并移除重拍、假起始、口吃、填充词和长静音,生成一份可直接使用的 Final Cut Pro 7 XML 时间线。该技能的核心原则是永不修改原始剪辑,所有输出(包括 XML、报告和工作文件夹)都生成在剪辑文件旁,并附带版本号(v1、v2 等)。它支持 English 和 French,通过分析 Premiere Pro 项目文件(.prproj)中的转录文本来工作,并利用 Whisper 作为二次验证。对于没有 Premiere 转录的素材,它还提供备用的 v1 流水线。该技能包含一套完善的决策规则(如保留最后一次重拍、给犹豫标记为标志而非直接删除),并提供详细的 QC 检查,确保输出质量。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ThomasHMD/premiere-rough-cut/tree/HEAD/skills/rough-cut

在你喜欢的 AI 中提问

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

文档

rough-cut:为 Premiere Pro 自动粗剪

一次性设置:参见套件根目录下的 INSTALL.md。对于插件,设置行是 bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}";对于手动安装(将四个 skills/ 文件夹并排复制到 ~/.claude/skills/),从套件根目录运行 bash install.sh。脚本位于此技能的 scripts/ 文件夹内。

范围

  • 是:一份 Final Cut Pro 7 XML(XMEML,.xml),其时间线已移除重拍、假起始、口吃、填充词和长静音;一份 Markdown 报告;对需要决定的部分显示红色标记。
  • 否:修改剪辑、转码、导出视频、调色、混音、在明显改述之外的两个镜头中选择(那是剪辑师的决定)。

核心规则:原始剪辑永不修改

该技能仅在剪辑旁写入:

  • <clip>_Derush_v1.xml:要导入的编辑(FCP7 / XMEML);
  • <clip>_Derush_v1.report.md,<clip>_Derush_v1.log.txt;
  • <clip>_Derush_v1_work/:工作文件夹,保留(转录、中间剪辑)。

XML 通过绝对路径(file://localhost/...)引用剪辑:Premiere 仅引用它。新的一次运行会创建 v2、v3……而不会覆盖任何内容。

用户操作(3 步)

  1. 在 Premiere 中:导入剪辑,运行转录(文本面板 > 转录),保存项目。转录随后位于 .prproj 内部:永远不要要求用户导出它。
  2. 给 Claude 剪辑的路径,以及视频的参考脚本(如果有的话)(纯文本、Markdown、Google 文档、Notion 页面,任何可读格式)。脚本仅用于判断重复是否是故意的。没有脚本,流水线仍能工作;故意的重复随后被标记为标志而非直接剪切。
  3. 导入 .xml(文件 > 导入)。出现一个 Derush_vN 序列,已经编辑好:剪切从时间线中移除(剪辑首尾相接,无需闭合间隙),存疑部分作为带有红色标记的活动剪辑保留。

不要询问其他内容:语言、剪辑类型和选项会被推断(见下文),只有在剪辑类型真正模糊时才值得提问。

语言

所有语言相关的内容(填充词、假起始短语、拍板模式、孤立连接词、要剪掉的开场白、耳语幻觉、标记的理由文本)都位于 languages/<code>.json 中,而非代码中。内置了法语(fr)和英语(en)。语言通过 --lang <code> 选择,否则使用转录中记录的语言,否则使用 en。详情及如何添加新语言:references/languages.md。

流水线 v2:镜头选择(正常路线)

仅检测缺陷(下面的 v1)的召回率最多在 57% 左右,因为 Whisper 会静默地去重重复的镜头:其反循环解码器会将逐字重复的句子视为幻觉并仅转录一次。这无法通过配置修复。Premiere 的转录会逐字保留每个镜头,并且其单词开始时间在长静音后不会漂移(Whisper 会)。因此:

步骤工具角色
1extract_prproj_transcript.py project.prproj words_premiere.json [--rush CLIP.MOV].prproj 到 words_premiere.json(主要来源)。如果项目没有转录,退出码为 2:要求用户运行转录并保存项目。后备:在手动 JSON 导出上运行 parse_premiere_transcript.py
2extract_audio.py + transcribe.pyWhisper = 二次意见(交叉检查文本,从不检查边界)
2bcalibrate_premiere_times.py将 Premiere 的转录与音频重新对齐。在每个粗剪后立即运行(当转录按时时,它不进行任何修改)。通过互相关、逐窗口测量偏移;在 21 分钟剪辑的末尾观察到 1.8 秒的漂移。如果忘记,症状:silence_cuts.py 报告数十个“可疑噪音”
3Claude 在上下文中语义分析:通过将 Premiere 的转录与脚本和 Whisper 进行比较,发现重拍、假起始和口吃。规则如下
4silence_cuts.pyPremiere 单词之间 >= 1.0 秒的静音,单词结束重新对齐到声音电平,枚举保护(两个短块之间的短暂停 = 故意节奏),噪音区域:标记或剪切(见下文)。默认值针对已完成的剪辑进行了校准:未经重新测量不要更改它们(参见 references/lessons.md,“测量”)
5apply_takes.py <work>步骤 3 中决定的镜头写入 takes.json(单词索引;可选的手动设置边界或以秒为单位的剪切)。脚本将边界放置在能量谷中,与静音合并,融合两次剪切之间留下的静音片段,将每个剪辑边缘重新对齐到真实声音,并标记剪辑边缘处小于 0.25 秒的孤立声音,写入 cuts_final.json。仅当用户要求时 protect(保留静音)
6build_premiere_xml.pyXMEML。选项 meta["audio_file"]:将音频指向完整长度的处理过的 WAV(参见已知限制)。多个剪辑:每个剪辑一个 XML,然后 merge_xml.py output.xml "name" a.xml b.xml = 一个单一的序列,首尾相接
6b编辑,再次转录端到端检查:连接 audio.wav 的保留区间,在上面运行 Whisper,并使用剪切点 阅读 文本。捕获其他检查遗漏的内容:编辑中留下的静音(3 个单词的 8 秒剪辑)、被剪切的单词、幸存的失败镜头
7qc_repeat_scan.py确定性检查:如果编辑中保留有在 30 秒内重复的 5-gram,或者如果在暂停或剪切之后的两个单词在早些时候的 8 秒编辑内已经说过(一个带有变体的重复镜头),则退出码为 2。每个命中都对照脚本和通过耳朵(hear.py)检查:幸存的重复镜头(保留最后一个)或故意的修辞(首语重复、枚举)
7bmontage_qc.py <work>编辑的音频被逐剪辑转录和阅读,Premiere 单词(P)对比 Whisper(W):空白的时长 > 1.6 秒或片段 < 1 秒时退出码为 2。可疑的边缘用 hear.py audio.wav 12.3-14.0 ...(在隔离片段上的 Whisper)检查
8report_v2.py报告:编辑和剪辑的时长、镜头、疑虑;--notes 用于“故意保留”和触及脚本敏感点的段落

步骤 3,决策规则

硬性规则:

  • 重复文本:保留 最后一个 镜头(即使它不如较早的镜头干净);
  • 口吃:保留 最长的连续片段;
  • 疑虑:flag,永远不要 disable。低切总是优于高切:添加一个剪切很容易,恢复一个缺失的段落是地狱。
  • 剪切边界对齐到 Premiere 单词,在保留的第一个单词之前留出大约 0.15 秒的空隙。

从真实编辑中学习的规则:

  • 任何在两次镜头剪切之间被夹在中间的、时长小于 2 秒的孤岛都会被监听(hear.py)。几乎总是假起始。永远不要仅凭 Premiere 的文本来判断:一次呼吸可以在 Premiere 中承载单词,而“感谢观看”类别的幻听意味着根本没有单词。
  • 带有噪音但非脚本句子的静音(旁白、“开始了”、操作相机)被剪切,而非标记。
  • 句子开头的填充性开场白(语言文件的“openers”列表,例如“So,”或“Well,”)被剪切。
  • 句子内的逐字口吃(“It's it's”)被禁用。但是在一个句号两侧重复的名字(“less documented than Nikon. Nikon has plenty of docs”)不是口吃:Premiere 可能将其写为双份。在任何单字剪切之前用 hear.py 检查该片段。
  • 孤立连接词(一个孤立的“And / So / But”)紧接在剪切静音之前,包含在剪切中。对于 任何在剪切和暂停之间被夹在中间的孤立假起始单词,也是如此。
  • 在 Premiere 转录中的无意义单词,且没有 Whisper 对应物,在冗余旁白中,是一个口吃:至少标记它。
  • 不携带信息的填充短语,重复了整个下一句:仅标记(这是编辑性的)。
  • 一个“重拍”可能是前一句的结尾,被 Premiere 错误计时(一个单词持续 5 秒)。编辑的 Whisper 文本会显示这一点。
  • Premiere 有时将一个句子分成两半:一个两个单词的“假起始”可能是下一句的开头。
  • Premiere 会漏掉小的嘟囔词:剪切一个重复的句子可能留下一个孤立的引导词。首先用 hear.py 检查该片段;手动设置边界(takes.json 中条目的第 6 个元素)。
  • 一个单一的双字重复(“the the”):边界可能会吃掉它前面的单词,因为 Premiere 将两者都标注在同一个呼吸中。收听连接处(先 ffmpeg atrim 两个保留片段,然后 hear.py)。
  • 两个剪辑之间的接缝:剪辑 1 的结尾和剪辑 2 的开头被一起收听。一个在剪辑 1 结尾开始并在剪辑 2 开头重复的句子从其第一个单词开始被剪切。
  • 对相机说给剪辑师听的指令(“这是给你的,在这里放些图形”)作为指令被剪切,并在报告中列出,因为它们指示了在哪里进行说明。
  • 在剪切一个镜头后,收听保留镜头的攻击(当 Premiere 有两个单词时,第一个单词可能被吃掉)。

Premiere 转录位于 .prproj 内部

.prproj 是 gzipped XML,包含一个块 <ExternallyProvidedTranscriptDocument><TranscriptData Encoding="base64">,其有效载荷是一个 FlatBuffers 缓冲区。extract_prproj_transcript.py 解码它:

Segment -> f0 i64 start_ticks, f3 vector<Word>, f4 string language
Word    -> f0 i64 start_ticks, f1 i64 duration_ticks, f2 string text, f3 f32 confidence
Premiere ticks = 254016000000 每秒

空文本的项是 Premiere 标记的暂停(其持续时间覆盖整个静音)。脚本会丢弃它们;否则单词之间的每个间隙都是 0,silence_cuts.py 找不到任何内容(症状:“gaps > 1s: 0”并且单词长达 39 秒)。

一个项目中的多个剪辑:.prproj 为每个剪辑保存一个转录。--rush NAME.MOV 会选择与剪辑时长匹配的那个(没有它,会选择最长的一个,并带有警告)。它比较最后一个单词的开始时间,漂移余量为时长的 0.3%。检查两个剪辑之间的单词数量是否不同。每个剪辑一个工作文件夹,然后 merge_xml.py。

这个转录中的 两个陷阱:

  1. 它可能相对于文件漂移:步骤 2b。剪切是基于文件时间的(XML 读取的就是这个),所以单词会被校正,而不是反过来。
  2. 单词时长可能会吞掉其后的静音:静音不再存在于单词之间,也不会被剪切。silence_cuts.py 将这些单词恢复到其真实结束位置(trim_overflow)。永远不要信任 Premiere 单词的结束点;只有开始点是可靠的。

更多陷阱(在静音内计时的单词、静音片段、微小孤岛):references/lessons.md。

镜头剪辑边界:位于单词开始点的最近 能量谷,在保留单词的攻击之前留出 0.12 秒的空隙。通过 单词索引 描述剪切,而非秒数:它们在重新对齐后仍然有效。

下面的 v1 流水线在 没有 Premiere 转录时作为后备(警告:逐字重拍可能被错过)。

机器要求

在启动时检查;如果有缺失,指向 INSTALL.md(仅关于 Whisper 的部分在 references/whisper-setup.md 中)。

brew install whisper-cpp ffmpeg
mkdir -p ~/Models/whisper
curl -L -o ~/Models/whisper/ggml-large-v3-turbo.bin \
  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin

Python 3,带有 numpy(没有其他依赖)。无需 API 密钥,无需账户,模型下载完成后没有任何东西离开机器。

流水线 v1(后备,8 个阶段)

由 scripts/derush.py 运行。每个阶段写入 <clip>_Derush_vN_work/,位于剪辑旁,永不删除(可以恢复和检查)。

#脚本角色
1derush.py(入口点)ffprobe 元数据,版本号
2extract_audio.pyffmpeg 转为 audio.wav 16 kHz 单声道
3transcribe.pywhisper.cpp 转为 transcript.json
4mechanical_cuts.py语言文件的单词列表和模式转为 cuts_mechanical.json
5语义分析(Claude)转为 cuts_semantic.json(见下文)
6merge_cuts.py合并,对齐到单词,得分转为 cuts_final.json
7build_premiere_xml.py转为 .xml(XMEML / FCP7)
8build_report.py转为 .report.md

阶段 5:语义分析

脚本写入 prompt_semantic.txt 并停止。这是正常路线:运行技能的 Claude 然后执行以下操作。

  1. 完整读取 prompt_semantic.txt;
  2. 按照提示中的规则分析转录;
  3. 将 JSON 写入 cuts_semantic.json(路径在提示中给出);
  4. 恢复:derush.py <clip> --resume-from=6 --work-dir=<work>。

如果 cuts_semantic.json 已存在,则跳过此阶段。

三级决策(技能的理念)

每个提议的剪切都有 0 到 1 之间的置信度。

  • disable:该段落 从时间线中移除,而非停用。build_spine_clips() 通过减法构建序列:仅保留的区间保留,首尾相接,序列时长是保留区间的总和。相当于“波纹删除”已应用。阈值:机械剪切 >= 0.85,语义剪切 >= 0.92(LLM 经常超出其边界)。
  • flag(0.6 到 0.85):不剪切。该段落作为 活动剪辑 保留,带有一个红色序列标记(“DOUBT <类型> (conf X):原因”)在正确的位置。由用户决定。
  • ignore(< 0.6):不处理,以避免淹没时间线。

永远不要反转这些语义。交付停用、灰色的剪辑让用户手动删除,会将工作转移到用户身上,而非移除它:承诺的是一个可直接使用的序列。

剪切类型

  • filler:填充词(“um”、“uh”……)和句子开头的填充性开场白。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相关技能