/autocut
输入原始录制,输出干净、预剪辑的视频文件。你负责运行每个命令;人类用户批准计划后查看结果。永远不要将命令行交给他们执行。
代码库根目录(脚本存放位置):
THP_HOME=${THP_HOME:-$(cat ~/.config/talking-head-pipeline/root)}
适用范围
| 场景 | 流水线 |
|---|---|
| 原始录制,需修复静默、口误和同步问题 | 本技能 |
| 已剪辑的、面向镜头的人物视频,希望效果更动态 | /dynamic-edit,输入为本技能产生的 clean.mp4 |
本技能不添加特效、字幕或图形。它生成 /dynamic-edit 所需的输入文件。正常流程是链式操作:先 /autocut,再 /dynamic-edit。
原理(以这种方式解释)
两个事实使得简单的自动剪辑工具会“吃掉”单词并造成同步偏移:
- 无线麦克风和采集软件传输音频时存在超前或滞后的时延,且每次录制都会变化(在某个设置下测到+240毫秒)。因此,同步必须逐文件通过嘴唇运动(SyncNet)测量,在一切处理之前应用。永远不应硬编码。
- 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. 验证剪辑(不可省略,按此顺序)
- 首先检查
qa.md中的## 已移除段审计。 每个被移除的间隙都需要检查是否含有残留语音(能量+孤立转录)。FLAGGED行表示该剪辑不可交付:需调查(先检查最响窗口分贝,然后听qa/removed/spanNN.wav),修复keep后重新渲染。单独的、最响窗口分贝低的单词语通常只是点击声或呼吸声,而非语音;请相信能量数值而非转录文本。approved cut行表示正常。 - 像编辑一样从头到尾阅读
qa/verbatim_cut.txt。 它是CrisperWhisper对剪辑后的逐词转录。查找任何存活的重复短语、片段或完整句子重拍。永远不要使用常规Whisper转录来检查剪辑:它恰恰会隐藏这些。 停顿后连续说出的完整句子重拍只能通过这种方式被发现。 ## 剪辑中仍存在的重启和## 边缘剪切中的qa.md:解决每个FLAGGED行(像“928 ... 939”这样的数字序列可能是误报;请阅读它们)。- 脚本无法执行的检查:
- 输出时长与计划时长:差距超过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。