Video Audio Editor
本地音频处理 Skill。基于 FFmpeg 实现气口分析、人声优化、降噪去闷、混音归一化,无需调用任何 AI 生成模型。
前置条件
FFmpeg
本 Skill 依赖 FFmpeg 二进制文件。优先使用系统已安装的 FFmpeg,否则使用 npm 包 @ffmpeg-installer/ffmpeg 提供的静态二进制。
检测 FFmpeg 路径的优先顺序:
1. which ffmpeg(系统安装)
2. /Users/imac/.workbuddy/binaries/node/workspace/node_modules/@ffmpeg-installer/darwin-x64/ffmpeg(npm 包)
如果两者都不可用,执行以下命令安装:
cd /Users/imac/.workbuddy/binaries/node/workspace && /Users/imac/.workbuddy/binaries/node/versions/22.22.2/bin/npm install @ffmpeg-installer/ffmpeg @ffmpeg-installer/darwin-x64
安装后给二进制加执行权限:
chmod +x /Users/imac/.workbuddy/binaries/node/workspace/node_modules/@ffmpeg-installer/darwin-x64/ffmpeg
Python
脚本使用 Python 3,优先使用:
- /Users/imac/.workbuddy/binaries/python/envs/default/bin/python
核心经验
afftdn FFT 降噪的 musical noise 陷阱
afftdn FFT 降噪在原片底噪干净时会产生 musical noise(音乐噪声伪音),表现为词尾"刺啦刺啦"声。
- 原因:afftdn 在频谱上一块块削减噪声,残留频率成分形成有规律的伪音。词尾信号变弱时最明显(此时信号接近噪声底,FFT 判噪最激进)。压缩器 makeup gain + loudnorm 会把这些伪音抬到可闻范围。
- 判断方法:原片听起来干净、没有明显底噪/空调声/环境噪声 -> 不要用 afftdn
- 解决方案:用
--mode light单链轻处理路径,彻底跳过 afftdn
默认模式已从 full 改为 light。 只在原片底噪明显(空调声、风声、环境嘈杂)时才用 --mode full。
filter 顺序:loudnorm 必须在 alimiter 之前
否则 loudnorm 会把信号顶过 TP 天花板,导致 True Peak 超标。
AAC 编码会产生 inter-sample peak
limiter 只管 sample peak,AAC 编码可能让 True Peak 超过 0 dBTP。若输出 True Peak >0,用 --aac-trim 1.0 在编码前额外衰减 -1dB 修复。
大动态范围需加强压缩
原片 LRA >= 8 LU 属于大动态(音量忽大忽小),默认 ratio 2.5 压不住,需调到 3.5 + threshold 0.15 + loudnorm LRA 降到 7。
工作流程
阶段 1:气口分析
使用 scripts/analyze_silence.py 分析音频参数和气口分布:
python scripts/analyze_silence.py --input input.mp4
输出内容:
1. 音频参数:均值音量、峰值音量、整合响度(LUFS)、True Peak、动态范围(LRA)
2. 气口检测:自动阈值检测所有静音段,分类为首部/尾部/长气口/短气口
3. 动态范围评估:LRA >= 8 时自动给出强压缩参数建议
4. 气口均匀化建议:长气口数量、可节省时长、推荐使用 video-editor 技能处理
可选参数:
- --threshold:手动指定静音检测阈值 dB(不填则自动 mean_volume+3dB)
- --min-dur:最短静音时长 s,默认 0.2
- --max-air:长气口判定阈值 s,默认 0.6
- --json:输出 JSON 报告到指定路径
阶段 2:判断处理模式
根据气口分析结果判断:
| 条件 | 模式 | 说明 |
|---|---|---|
| 原片底噪干净 | light |
单链轻处理,不用 afftdn |
| 原片底噪明显(空调声、风声、环境嘈杂) | full |
人声分离 + FFT 降噪 |
| LRA >= 8 LU | light + 强压缩 | 见下方参数表 |
| LRA < 6 LU | light + 标准压缩 | 默认参数即可 |
阶段 3:音频处理
执行 scripts/process_audio.py,根据分析结果选择模式和参数。
模式 light(推荐,原片底噪干净时)
单链轻处理,不做人声/环境音分离,不用 afftdn:
高通120Hz -> 压缩 -> EQ(300Hz +2dB暖度, 3000Hz +4dB清晰度) -> loudnorm -> alimiter -> [可选] AAC安全衰减
- 不碰 6500Hz(不放大高频齿音/空气感)
- loudnorm 在前,alimiter 在后(防止 loudnorm 把信号顶过 TP 天花板)
- 压缩参数和 LRA 目标可调,原片动态大时加强
# 标准轻处理(原片动态正常,LRA < 8)
python scripts/process_audio.py --input input.mp4 --output output.mp4 --mode light --target-lufs -12
# 强压缩(原片动态大,LRA >= 8,音量忽大忽小)
python scripts/process_audio.py --input input.mp4 --output output.mp4 --mode light --target-lufs -12 --comp-ratio 3.5 --comp-threshold 0.15 --comp-makeup 1.8 --lra 7 --aac-trim 1.0
light 模式动态范围应对表:
| 原片 LRA | 压缩 ratio | 压缩 threshold | 压缩 makeup | loudnorm LRA | aac_trim |
|---|---|---|---|---|---|
| < 6 LU(正常) | 2.5(默认) | 0.22(默认) | 1.4(默认) | 9(默认) | 0 |
| 6-8 LU(偏大) | 3.0 | 0.18 | 1.6 | 8 | 0 |
| >= 8 LU(忽大忽小) | 3.5 | 0.15 | 1.8 | 7 | 1.0 |
模式 full(原片底噪明显时)
人声分离 + FFT 降噪 + 混音:
分离阶段:
- 人声轨:highpass=f=120 -> afftdn=nr=20:nf=-30:tn=1:rf=-55:om=o(默认 nr 降至 20)
- 环境音轨:highpass=f=150 -> afftdn=nr=20:nf=-30:tn=1:rf=-55:om=n -> 去闷 EQ
人声轨处理:
- 噪声门:agate=threshold=0.015:range=0.12:attack=2:release=50
- 压缩:acompressor=threshold=0.22:ratio=3:attack=4:release=70:makeup=1.6
- 三段 EQ:300Hz +3dB、3000Hz +5dB、6500Hz +0dB(默认不放大空气感)
- 去齿音(可选):5500Hz -5dB + 7500Hz -2.5dB + 8kHz highshelf -2dB
混音与母带:
- 混音:amix + volume 预补偿
- 响度归一化 + 限幅:loudnorm -> alimiter(顺序不可反)
阶段 4:合成输出
- 视频流直接 copy(
-c:v copy),不重编码,保持原始画质 - 替换音频流为处理后的 AAC 192kbps
- 添加
+faststart标志,支持流式播放 - 输出到指定目录
脚本使用
scripts/analyze_silence.py
气口分析 + 音频参数分析脚本。检测静音段(气口)、分析音量/响度/动态范围、给出处理参数建议。
# 基本分析
python scripts/analyze_silence.py --input input.mp4
# 手动指定阈值
python scripts/analyze_silence.py --input input.mp4 --threshold -20 --min-dur 0.2
# 输出 JSON 报告
python scripts/analyze_silence.py --input input.mp4 --json report.json
参数说明:
- --input:输入视频/音频路径(必填)
- --threshold:静音检测阈值 dB,不填则自动检测(mean_volume+3dB)
- --min-dur:最短静音时长 s,默认 0.2
- --max-air:长气口判定阈值 s,默认 0.6
- --json:输出 JSON 报告到指定路径
scripts/process_audio.py
音频处理主脚本,支持 light(单链轻处理)和 full(人声分离)两种模式。
# light 模式(推荐,原片底噪干净时)
python scripts/process_audio.py \
--input <输入视频路径> \
--output <输出视频路径> \
--mode light \
--target-lufs -14
# full 模式(原片底噪明显时)
python scripts/process_audio.py \
--input <输入视频路径> \
--output <输出视频路径> \
--mode full \
--env-volume 0.4 \
--denoise-nr 20
参数说明:
- --mode:处理模式,light(默认)或 full
- --input:输入视频文件路径(必填)
- --output:输出视频文件路径(必填)
- --target-lufs:目标响度,默认 -14(短视频平台可拉到 -12)
- --true-peak:目标 True Peak,默认 -1.0 dBTP
- --highpass:高通频率(light 模式),默认 120Hz
- --vocal-presence:3kHz 清晰度提升量,默认 4(light)/ 5(full)
- --lra:loudnorm 目标动态范围 LU(light 模式),默认 9。原片 LRA>=8 时降到 7
- --comp-ratio:压缩器比率(light 模式),默认 2.5。动态大时调到 3.5
- --comp-threshold:压缩器阈值(light 模式),默认 0.22。动态大时降到 0.15
- --comp-makeup:压缩器增益(light 模式),默认 1.4。ratio 提高时相应提高
- --aac-trim:AAC 编码前额外衰减 dB(light 模式),默认 0。输出 True Peak>0 时设为 1.0
- --env-volume:环境音音量比例(full 模式),默认 0.4
- --vocal-highpass:人声轨高通频率(full 模式),默认 120Hz
- --env-highpass:环境音轨高通频率(full 模式),默认 150Hz
- --denoise-nr:FFT 降噪强度(full 模式),默认 20(降低以防 musical noise)
- --deesser:去齿音开关(full 模式),默认 on
- --gate-release:噪声门释放时间(full 模式),默认 50ms
- --air-boost:6500Hz 空气感提升(full 模式),默认 0dB(不放大)
- --deess-gain:去齿音衰减量(full 模式),默认 -5dB
可调参数参考
目标响度(平台参考)
- -14 LUFS:微信视频号/公众号(保守,平台限流严格)
- -12 LUFS:抖音/小红书/快手(更冲,短视频推荐)
环境音音量比例(full 模式)
- 0.3:环境音很弱,几乎只听人声
- 0.4:环境音轻微保留,不抢戏
- 0.55:环境音适中,有氛围感(餐厅探店推荐)
- 0.7:环境音明显,保留现场感
降噪强度(full 模式 afftdn nr)
- 10-15:轻度降噪,保留更多原始音质
- 20:中度降噪(默认值,降低 musical noise 风险)
- 28-30:重度降噪,警告:高风险产生 musical noise 伪音
注意事项
- 全程不调用任何 AI 生成模型,零额外积分消耗
- 视频流使用
-c:v copy保持原始画质,不重编码 - 音频处理为有损操作,不可逆,建议保留原始文件
- 如果素材为竖屏(如手机拍摄),输出保持竖屏比例(1080x1920)
- HEVC/H.265 编码的素材可直接 copy,无需转码
amix滤镜会自动归一化音量,必须用volume=2.0预补偿(full 模式)afftdn的om=o输出降噪后信号(人声),om=n输出被去除的噪声成分(环境音)- 处理完毕后清理 /tmp 下的中间文件
- filter 顺序:loudnorm 必须在 alimiter 之前
- 原片底噪干净时绝不用 afftdn FFT 降噪
- FFmpeg 4.x 无
deesser滤镜(5.0+ 才有),用窄EQ衰减替代 - AAC 编码会产生 inter-sample peak:limiter 只管 sample peak,AAC 编码可能让 True Peak 超过 0 dBTP
- 大动态范围(LRA >= 8 LU)需加强压缩
- 气口均匀化(视频重剪)由 video-editor 技能负责:本技能检测到长气口时,建议用户使用 video-editor 技能的 recut_video.py 处理