soundcheck 是做什么的?
AI视频在听起来完美之前就已经看起来完美了。TTS(文本转语音)片段以不同的电平拼接在一起,音乐背景从未进行闪避处理,混音被推入限制器以听起来“响亮”,而AI语音则保留了6-10kHz的嘶嘶声和100-300Hz的轰鸣声。
soundcheck将这些问题转化为数字,修复它们,并证明修复有效。
运行它
python scripts/soundcheck.py analyze <file> [--target youtube] [--music music.wav] [--json]
python scripts/soundcheck.py fix <file> [--target youtube] [--music music.wav] [--out out.wav] [--level] [--naturalize]
python scripts/soundcheck.py demo
fix需要ffmpeg在PATH中。analyze和demo只需要Python 3 + numpy(scipy用于更快的滤波,如果存在)。
给fix一个视频,它会返回一个视频:修正后的音频会与原视频流复用(拷贝,从不重新编码)。如果没有指定--out,它会在源文件旁边写入<name>.soundcheck.mp4。
--level在母带处理前匹配单独语音段落的电平。用于逐行录制或合成的对话;不要在音乐主导的内容上使用它,因为其中的起伏是编曲的一部分,而非缺陷。analyze会打印最大电平跳跃的时间戳,供你决定。
先验证再信任
python scripts/verify.py # 20项检查,退出码0表示全部通过
该套件检查我们的计量表是否与ffmpeg的ebur128一致,fix是否在所有特征通过时才退出0,交付文件是否使用独立的计量表重新测量,动态是否没有被压扁,以及静音/短片/单声道24位/mp4/缺失文件等边缘情况是否处理得当。如果它在你的机器上失败,请先修复该问题,然后再处理任何人的音频。
当你处理真实素材时,始终进行A/B对比。测量合规性是必要条件,而非充分条件。
工作流程
- 在处理任何东西之前先测量。 运行
analyze。永远不要从猜测开始做EQ。 - 阅读成绩单,而不是分数。 分数只是一个总结;失败的指标才是你需要处理的问题。
- 修复。 运行
fix --target <platform>。它根据测量结果选择修正EQ的深度,应用处理链,根据我们自己的响度测量计算静态增益,限幅,然后重新测量。 - 验证。 当任何测量指标仍超出规格时,
fix会返回非零退出码。不要报告“完成”并给出非零退出码——而是报告剩余的指标。 - A/B对比。 保留原始文件。如果修复后的声音比问题本身更糟(过度EQ、抽吸感),则降低修正深度并重新运行。测量合规性是必要条件,而非充分条件。
7种AI音频特征
| # | 特征 | 测量方式 | 目标值 | 常见原因 |
|---|---|---|---|---|
| 1 | 段落间电平不匹配 | 语音频段区域电平,相邻段落差值 | <= 3 dB | TTS片段单独渲染 |
| 2 | 无动态余量 | 真实峰值 | <= -1 dBTP | “弄大声点”的母带处理 |
| 3 | 人声/音乐打架 | 人声LUFS - 音乐LUFS | >= 4 dB | 无侧链闪避 |
| 4 | 刺耳齿音 | 6-10 kHz / 1-4 kHz 能量比 | <= 0.45 | 合成的/s/和/sh/音 |
| 5 | 低频中频浑浊 | 100-300 Hz / 300-3k 能量比 | <= 0.40 | 近距离增强的轰鸣感,响亮的低频背景 |
| 6 | 无底噪,无空间感 | 噪底与节目电平之比 | >= 45 dB以下 | 降噪伪影,多层环境音 |
| 7 | 相位/直流问题 | 左右声道相关性,直流偏移 | 相关性 >= 0.2 | 拼接片段,重采样 |
特征3仅在传递--music参数并附带独立的音乐分轨时运行。特征6在素材没有静音段落时报告n/a——安静的音乐不是噪音,诚实的“无法评估”不是通过。特征1会报告最大跳跃的位置,以便人类监听。
响度阶梯
| 交付平台 | 综合响度 | 真实峰值 | 备注 |
|---|---|---|---|
| YouTube / TikTok / Reels | -14 LUFS | -1 dBTP | 平台在此归一化 |
| Spotify | -14 LUFS | -1 dBTP | |
| Apple Music | -16 LUFS | -1 dBTP | |
| 播客(立体声/单声道) | -16 / -19 LUFS | -1 dBTP | |
| 广播(EBU R128) | -23 LUFS | -1 dBTP | |
| 短剧 / OTT(中国) | -24 LKFS | -1 dBTP | |
| 影院 | -27 LUFS | -2 dBTP | 以对白为锚点 |
处理链顺序(很重要)
高通滤波 70 Hz -> 减法EQ(先处理浑浊,再处理齿音) -> 轻柔压缩 -> 限幅 -> 静态增益 -> 限幅
- 修正EQ的深度源自测量到的特征,而不是固定的预设。
- 压缩是有意为之的轻柔(2.5:1,约3-6 dB增益衰减)。这是后期处理,不是声音设计。
- 增益在修正链之后应用,并根据链输出的测量结果计算,这样即使EQ改变了响度,交付的文件也能符合规格。
- 限幅器设置在0.79(-2 dBFS采样峰值),以承受真实峰值-1 dBTP时的采样间过冲。
安全护栏
- 在没有新的测量结果之前,永远不要声称成功。 脚本的退出码是真相的来源。
- 不要对有损格式进行两次重新编码。 解压为WAV一次,在WAV中工作,最后编码一次。
- 不要通过升采样来假装高质量。 输出48 kHz;loudnorm的192 kHz内部采样率不是一个优点。
- 不要为了达到数字而压扁动态。 如果达到-14 LUFS需要超过6 dB的限幅,请说明情况,改为交付-16——一个被压扁的混音比一个安静混音更糟糕。
- 音乐分轨保持独立。 对混合音轨进行闪避会破坏人声;请索取分轨。
- 保留原始文件。 始终写入新文件。
这无法修复的问题
当源文件在8 kHz以上几乎没有能量时,analyze会打印一个警告——这是16/22 kHz的TTS通过48 kHz采样率工程传输的标志。这种沉闷感不是母带处理问题,任何EQ都无法恢复。如果触发了该警告,请如实说明,而不是报告“已修复”:使用神经TTS重新渲染语音,然后再进行母带处理。
--naturalize会添加一个小房间、一个呼吸/环境音底噪以及一些高频空气感。它移除了“干燥、数字化的寂静”提示;但它无法创造语调,也无法挽救一个机械化的来源。切勿在音乐主导的内容上默认启用它。
限制
- 需要“音乐背景”特征的分轨;没有分轨,则无法测量人声/音乐平衡。
- 噪底只有在存在真实的安静段落时才有意义。
- 真实峰值是4倍过采样的;需要8倍过采样的广播机构应使用自己的计量表进行验证。
- 这是一个交付工具,不是创意混音。它不会让糟糕的表演变好。