SuperAPI AI 工具集

filler-removal

设计与创作

查看项目

更新于 10-15 10:11

技能介绍

填充词去除(filler-removal)

目标:剪掉填充词,让结果听起来自然——不出现被切断的辅音、不出现突兀的音频跳变,也不丢失真实语音。这是一个迭代过程,不要在第一遍就停下。

步骤 0(关键):获取逐字稿

mlx-whisper 默认会静默清理不流畅词——它会从转写中丢弃大部分“um/uh”,导致无内容可剪。这是过去一次失败的根因:填充词在编辑后仍然存活。

transcribe 现在默认逐字输出:它用一段简短的迟疑提示(Um, uh, er, hmm...)作为解码种子,并设置 condition_on_previous_text=False,因此 um/uh 会被保留。只需运行:

uv run video-agent transcribe video.mp4 --words -o words.txt # start_sec end_sec word

这里不要传 --clean——那会恢复 whisper 丢弃填充词的行为,与目标相反。

种子提示被刻意设计得很窄(只包含短促的迟疑),以避免把 like/so 这类真实用词过度转写。如果用户反馈仍有填充词未出现在列表中,先直接听对应音频片段确认实际说了什么,再下结论说那里没有内容。

步骤 0.5(关键):把词边界与静音交叉核对

Whisper 的词时间戳抖动大、对实际剪切不可靠——可能偏差 0.3–0.7 秒,且重新运行转写会为同一个词给出不同位置。直接按原始词时间戳剪切曾导致真实编辑落在错误位置(填充词存活,反而剪掉了一段静音)。剪切前务必先校验边界:

uv run video-agent speech-segments video.mp4 # 语音/静音区间,原始时间线

像孤立的“um”这样的填充词,几乎总是位于两段静音之间的一个独立短语音爆发——该爆发的起止才是真相,而不是 whisper 给出的数字。把每个 whisper 填充词映射到它的爆发区间,剪掉这个爆发,而不是那个时间戳。

这也能揭示自然节奏:如果填充词位于一段长停顿内,只剪掉爆发区间会留下一个拖沓的空洞。要匹配说话者自己的句子边界停顿(从静音图上读取——通常 0.4–0.7 秒),把周围的死气沉沉合并成一个自然的节拍。“听起来像我从未说过”意味着无缝衔接,而不是在词的位置留一个沉默的间隙。

(speech-segments 包装了 ffmpeg silencedetect 并将其反转为语音区间。如需调整阈值,可用原始形式:ffmpeg -i in.mp4 -af silencedetect=noise=-30dB:d=0.15 -f null - 并从 stderr 读取 silence_start/silence_end。)

剪切规则(严格遵循)

  • 从 word_start − 0.05s 剪到 word_end + 0.15s(50ms 前置、150ms 后置)——后置可防止切断填充词后面的辅音。
  • 任意一侧非填充词的距离都不得近于 0.1s。
  • 若两个填充词相距在 0.3s 以内,合并为一次剪切。
  • 常见填充词:um, uh, er, like, you know, I mean, so, basically, literally, right, well。仅当它们作为不流畅词时才剪——“like”和“so”常常是真实用词,需结合上下文判断。

迭代循环——不清干净就不要停

  1. 从逐字稿中列出所有填充词及其精确起止时间。

  2. 构建保留片段(各剪切之间的所有内容),用 filter_complex concat 拼接(重编码——避免非关键帧接缝处出现冻结帧):

ffmpeg -i a.mp4 -i b.mp4 -i c.mp4
-filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]"
-map "[v]" -map "[a]" -c:v h264_videotoolbox -b:v 8M -c:a aac -ar 44100 out.mp4

  1. 对每一次剪切,抽取接缝前后 3 秒的拼接预览:

ffmpeg -i out.mp4 -ss <join_time-1.5> -t 3 -c:v h264_videotoolbox -c:a aac preview_cut_N.mp4

  1. 逐个观看/听取预览。调整并重做有问题的剪切:
  • 音频突兀跳变 → 后置填充增加 0.05s
  • 词首缺失 → 前置减少 0.05s
  • 听起来自然 → 通过
  1. 拼接后,重新对输出转写(同样逐字)并确认没有剪掉非填充词的真实语音——同时用 grep 在重新转写结果中查找 um/uh,确认填充词确实已消失(这是验证剪切落点是否正确的最强内容级检查)。

  2. 若真实语音缺失 → 从原始素材恢复该次剪切并迭代。

完成标准:每个预览都听起来自然,且重新转写结果符合意图。

填充词去除之后:节奏

去掉 um/uh 后,它们原来所在的位置留下了空隙。如果结果仍然拖沓,那是节奏问题,而不是填充词问题——运行 tighten(把长停顿压缩成自然节拍,并写出 EDL)并添加分离编辑。两者都在 cutting-rhythm 技能中。顺序很重要:先 filler-removal,再 tighten,否则你会围绕即将被剪掉的词做节奏调整。

参考

  • 词时间戳输出格式:start_sec end_sec word(制表符分隔,每行一个)。
  • 对 B 帧源,-ss 必须放在 -i 之后才能获得准确的剪切点(参见 CLAUDE.md 帧抽取的坑)。
  • 如果同一视频还需要特效,参见 video-overlay 和 grok-video-edit 技能。