Communitygithub.com

vincesector/talking-head-pipeline

将原始人物讲话录音处理为干净、预剪辑的视频文件。通过嘴唇运动测量并修正音视频同步,逐词转录,发现口误、假起始和重复,移除静默,提出重拍建议,确保单词边界完整,并重新验证剪辑。当用户说“剪切这个”、“清理这段录音”、“去除静默和错误”、“自动剪辑”或要求准备素材时使用。先制定计划,待人工批准后再渲染。

talking-head-pipeline 是什么?

该技能(/autocut)是一个自动化视频预处理流水线,专为处理原始人物讲话录制而设计。其核心功能包括:通过SyncNet从嘴唇运动逐文件测量音视频同步偏移量并自动修正,解决无线麦克风和采集软件导致的延迟问题;使用CrisperWhisper进行逐词转录,保留所有口误、重复和填充词,避免标准Whisper模型平滑处理带来的遗漏;检测并自动剪除重复和假起始,同时智能处理有意修辞性重复(如列举),并将误切风险降至最低(保持“精确优于召回”原则)。支持macOS和Linux平台,Python 3环境。用户只需提供原始录制文件,技能会自动创建工作目录,制定剪辑计划(以表格形式呈现,包含同步信息、剪辑点、口误处理和候选修正),等待人工批准后才执行渲染。渲染后执行严格的六步质量检查,包括移除段语音回放、逐词转录验证、边角剪切检查、时间完整性校验等,生成clean.mp4文件,可直接作为/dynamic-edit等下游效果的输入。工作流严谨:计划门禁、逐文件同步测量、原始文件只读、精确时间戳操作(而非依赖记忆或模糊定位),确保输出内容的高质量和可靠性。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vincesector/talking-head-pipeline/tree/HEAD/skills/autocut

在你喜欢的 AI 中提问

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

文档

/autocut

输入原始录制,输出干净、预剪辑的视频文件。你负责运行每个命令;人类用户批准计划后查看结果。永远不要将命令行交给他们执行。

代码库根目录(脚本存放位置):

THP_HOME=${THP_HOME:-$(cat ~/.config/talking-head-pipeline/root)}

适用范围

场景流水线
原始录制,需修复静默、口误和同步问题本技能
已剪辑的、面向镜头的人物视频,希望效果更动态/dynamic-edit,输入为本技能产生的 clean.mp4

本技能不添加特效、字幕或图形。它生成 /dynamic-edit 所需的输入文件。正常流程是链式操作:先 /autocut,再 /dynamic-edit。

原理(以这种方式解释)

两个事实使得简单的自动剪辑工具会“吃掉”单词并造成同步偏移:

  1. 无线麦克风和采集软件传输音频时存在超前或滞后的时延,且每次录制都会变化(在某个设置下测到+240毫秒)。因此,同步必须逐文件通过嘴唇运动(SyncNet)测量,在一切处理之前应用。永远不应硬编码。
  2. Whisper 的词时间戳只有大约每12次中2次落在真正的词边界上。 围绕错误的时间戳进行填充仍然会剪掉部分单词。因此,每个词都需要使用强制对齐器重新计时,渲染时每个剪切边缘都会与波形本身对齐。

还有一个事实导致它们遗漏错误:Whisper 会平滑掉重复。 “让我们来谈谈,那么让我们来谈谈发生了什么”会被呈现为一个干净的句子。第二次使用逐词转录(CrisperWhisper)可以保留每一次假起始、重复和填充词;口误和重启正是在这次转录中被发现的。

工作流程

1. 找到文件,绝不修改它

使用用户命名的文件,或者他们采集文件夹中最新的录制(问一次文件夹位置)。用一行确认文件名和时长。整个任务期间原始文件只读;所有输出均生成在 <原始文件目录>/<原始文件名>_autocut/ 下。

2. 计划模式

python3 "$THP_HOME/scripts/autocut/autocut.py" "<raw.mp4>"

同步检测是耗时部分(3到10分钟,在繁忙机器或仅CPU的Linux上可能更久)。在开始前告知用户。计划模式的其余部分在模型缓存后大约需要一分钟;首次运行每个语言时需要下载模型(数分钟)。仅当检测到的语言错误时添加 --lang en|pt|it|es|fr|de|nl。如果偏移量已知,使用 --offset SECONDS 跳过检测;对于纯屏幕录制(无面部画面),使用 --no-sync。

如果检测失败(未检测到面部、置信度低),脚本会提示并继续以偏移量0处理。不要虚构数字。告知用户无法测量并询问:继续不同步处理,或使用用户提供的值。

3. 以紧凑表格展示计划,然后 STOP

读取工作目录下的 plan.md 文件并以精简形式呈现(切勿粘贴原始文件):

  源文件    take-01.mp4   01:47.9
  同步      +240 ms (音频提前),置信度 5.5,扩散 0 ms
  结果      计划 01:40.5,移除 7.3 秒,5 处剪切

  00:00.0-00:02.8   剪切   静默 3.0 秒          2.8 秒
  00:23.6-00:24.9   剪切   静默 2.0 秒          1.3 秒

  口误(已应用):  "所以我们谈谈,| 所以我们谈谈"   保留第二次
  重启(建议): 01:12.4 "会有损失在" x2 ...      apply_spans 命令已列出
  重拍建议(未应用):
  1  01:45.9-01:47.0  "所以"  ->  保留 01:47.0-01:48.1 "所以"

在同一块中标记:同步扩散超过 40 毫秒或置信度低于 3.5;对齐起始偏移 p90 超过 500 毫秒(转录不稳定);任何标记为 Whisper 解码循环的重拍行。

重复和假起始默认被剪除。 这就是逐词通道的目的。精确性仍优于召回率:一次错误剪切会导致需要重拍,而遗漏一次口误只需要多一次剪切。置信匹配(立即重复、无标点符号切换的放弃片段)被应用;含糊的会被列为 restart? 候选。逐字审阅每个候选。拒绝任何有意的修辞性重复(如“低于60、低于70、低于80”)。填充词(um, uh)会被列出,但永远不自动剪切。保留最后一次;当两个片段之间有停顿,停顿标志着第二个片段的开始。

提出一个问题:批准当前计划,或指定要恢复的内容。如果某个短语有歧义,请具体询问;不要猜测。在收到回答前绝不渲染。

4. 根据数字应用编辑,而非依赖记忆

  • 通过单词(而非手动输入的时间戳)接受重拍或重启:
    python3 "$THP_HOME/scripts/autocut/apply_spans.py" <工作目录> --drop "[email protected]"   # 最接近22秒的短语
    python3 "$THP_HOME/scripts/autocut/apply_spans.py" <工作目录> --span 71.20:74.85     # 复制自 plan.md 中列出的命令
    
    读取它回显的每一行上下文。
  • 在渲染前从磁盘重新读取 plan.json;人类用户可能已编辑过它。被编辑过的计划会自动重新剪切。
  • 脚本化停顿是内容的一部分:有意的停顿(如“答案是... [停顿] 什么都没有”)应在 plan.json 中记录为keep_silences: [[s, e]](源文件秒数),这样剪辑器不会缩短它。

5. 渲染

python3 "$THP_HOME/scripts/autocut/autocut.py" "<raw.mp4>" --render

渲染的具体步骤,以便你解释失败原因:

  • 09p 长片段(超过3分钟):将超过0.65秒的停顿缩短为最后一个声音后0.30秒加下一个声音前0.20秒。这里的静默定义为每5毫秒帧低于-55 dB。永远不要提高这个阈值:单词尾音会衰减到-42到-55 dB,更高的阈值会吃掉最后的辅音。
  • 09a 将每个剪切边缘从声音段弹出,并至少与它移除的声音保持50毫秒距离;将头尾修剪到第一个和最后一个真实单词;在0.4秒或更长的间隙中剪切掉括号内的噪声([UH], [lipsmack])。
  • 09b 如果保留的起始点与声音重叠,则将其移回静默处(修复被剪掉的起始部分)。
  • 剪辑器会丢弃任何长度小于1秒且无声音的片段(两个跳剪之间的“静默碎片”),并为保留的小于1秒的片段打印 CHECK 含声音的短片段。逐个听一遍。

6. 验证剪辑(不可省略,按此顺序)

  1. 首先检查 qa.md 中的 ## 已移除段审计。 每个被移除的间隙都需要检查是否含有残留语音(能量+孤立转录)。FLAGGED 行表示该剪辑不可交付:需调查(先检查最响窗口分贝,然后听 qa/removed/spanNN.wav),修复 keep 后重新渲染。单独的、最响窗口分贝低的单词语通常只是点击声或呼吸声,而非语音;请相信能量数值而非转录文本。approved cut 行表示正常。
  2. 像编辑一样从头到尾阅读 qa/verbatim_cut.txt。 它是CrisperWhisper对剪辑后的逐词转录。查找任何存活的重复短语、片段或完整句子重拍。永远不要使用常规Whisper转录来检查剪辑:它恰恰会隐藏这些。 停顿后连续说出的完整句子重拍只能通过这种方式被发现。
  3. ## 剪辑中仍存在的重启 和 ## 边缘剪切 中的 qa.md:解决每个 FLAGGED 行(像“928 ... 939”这样的数字序列可能是误报;请阅读它们)。
  4. 脚本无法执行的检查:
    • 输出时长与计划时长:差距超过0.6秒则存在问题;
    • 以5帧/秒的速度扫描每个连接处(从 timemap.json 中取两侧各0.5秒范围的帧):连接处不得有手势模糊或重复帧;
    • 没有内部停顿超过1.0秒;没有片段的帧低于-45 dB;
    • 恒定帧率:计数的帧数 / 流时长必须精确等于名义帧率(30.0000,而非29.98)。录制设备在负载下会丢帧,如果帧率不准,后续所有基于帧索引的工具都会偏离。

无需重新剪辑即可重新运行QA:autocut.py --qa-only --workdir <目录>。

为用户打开 clean.mp4(macOS 上使用 open,Linux 上使用 xdg-open)。

7. 报告并移交

移除的内容(表格)、clean.mp4 的位置,以及一行提示:这是预剪辑输入;说“让它动态起来”即可继续使用 /dynamic-edit。下一阶段所需的字幕来自逐词转录,并映射到剪辑时间线中:

python3 "$THP_HOME/scripts/autocut/verbatim_cut_words.py" <工作目录> -o words.json

8. 清理,仅在用户说视频已完成时进行

工作目录包含 synced.mp4(录制的完整副本)和 tmp/ 渲染片段。删除前需询问。plan.json、transcript.json、verbatim.json 和 qa.md 体积小;保留它们。

硬性规则

  • 计划门禁是强制性的。 未经人类用户批准,不得渲染。
  • 永远不要硬编码同步偏移量。 逐文件测量,或使用用户提供的值。
  • 原始文件绝不修改。
  • 使用剪辑后的逐词转录来检查剪辑,绝不使用常规Whisper转录。
  • 永远不要固定自动生成的边缘。 _meta.pinned_edges 用于人类针对波形检查过的边缘;固定机器生成的边缘会跳过“对齐器”的间隙检查,导致吃掉单词。
  • 静默仅指低于-55 dB。 在门控麦克风上,-40到-55 dB之间的任何内容都不是静默。
  • 没有语言内容的拼接片段长度不得小于1秒。
  • 当某个单词或指令有歧义时,提出一个具体的问题。

注意事项

  • Whisper 会在结尾的环境音上产生空段幻觉,时间戳会超出文件末尾。这是预期行为;重拍检测器会过滤掉它们。两秒内出现数千个“重拍”是解码循环,不是真实重拍,plan.md 中会明确说明。
  • 同步检测需要屏幕上出现脸部。纯屏幕录制素材:使用 --no-sync,并说明原因。
  • 许多麦克风录音声音较低(约-30 LUFS)。autocut 不做标准化。响度应在最终母带阶段处理(scripts/master/sync_trim.sh --loudnorm);永远不要静默应用。

完整的分阶段参考:$THP_HOME/docs/AGENT_GUIDE.md。

Individual skills in this repo

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

相关技能