mpv 音频滤镜(--af)完全指南:从格式转换到变调变速的源码级解析
本文以 mpv 官方手册中的 AUDIO FILTERS 章节(DOCS/man/af.rst)为主体,系统讲解 mpv 音频滤镜链的语法、全部内置滤镜(lavcac3enc、format、scaletempo、scaletempo2、lavfi-tempo、rubberband、lavfi、drop)及其参数细节,并结合 audio/filter/ 目录下的实际实现,说明每个滤镜的默认值、适用场景与底层工作原理。读完后你可以正确搭建音频滤镜链、控制采样格式与声道、完成变速不变调的播放,并理解 mpv 在速度变化时如何自动插入变速滤镜。
1. 滤镜链语法:--af 是什么
音频滤镜用于修改音频流及其属性。mpv 通过 --af=... 选项挂载一条滤镜链。该选项在源码中注册为 object settings list(对象设置列表):
// options/options.c
{"af", OPT_SETTINGSLIST(af_settings, &af_obj_list)},
见 options/options.c#L703。这意味着 --af 的完整语法(链式组合、每段 name=opt1:v1:opt2:v2 的写法、如何引用上一段等)与视频滤镜 --vf 完全一致,详细说明见 DOCS/man/vf.rst 中 VIDEO FILTERS 一节。
两个实用要点:
- 使用
--af=help可以列出当前构建可用的全部音频滤镜; - 大多数实际的音频滤镜并不需要 mpv 自带实现,而是通过
lavfi包装器直接使用 FFmpeg libavfilter 中的滤镜(包括所有从 MPlayer 移植到 libavfilter 的滤镜)。--vf文档中描述的 libavfilter 用法以及“如何用 lavfi 替代已弃用 mpv 滤镜”的说明,同样适用于音频侧。
除 --af 外,还有以下辅助选项(语义同 --vf 组):
| 选项 | 作用 |
|---|---|
--af-add |
在滤镜链末尾追加滤镜 |
--af-pre |
在滤镜链开头插入滤镜 |
--af-clr |
清空滤镜链 |
2. lavcac3enc:运行时把多声道音频编码为 AC-3
lavcac3enc[=options] 使用 libavcodec 在运行时把多声道音频实时编码为 AC-3,典型用途是向只支持 AC-3 的数字接收设备(AVR/功放)输出环绕声。实现位于 audio/filter/af_lavcac3enc.c。
限制条件(来自文档):
- 仅支持 16-bit 本机字节序输入格式,最多 6 个声道;
- 输出原始 AC-3 流时为大端字节序,输出到 S/PDIF 时为本机字节序;
- 若输入采样率不是 48 kHz、44.1 kHz 或 32 kHz,会先重采样到 48 kHz。
参数:
-
tospdif=<yes|no>:yes(默认)输出到 S/PDIF 以便 passthrough 直通;no则输出裸 AC-3 流。 -
bitrate=<rate>:AC-3 码率,单位 kbps。默认为 640(部分接收器可能无法处理)。合法取值:32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640。特殊值auto按输入声道数选择:声道数 码率 (kbps) 1 96 2 192 3 224 4 384 5 448 6 448 -
minch=<n>:若输入声道数小于<minch>,滤镜会自行从链上摘除(detach)。默认 3——单/双声道输入时不会做无谓的 AC-3 编码。 -
encoder=<name>:选择 libavcodec 编码器。应当是 AC-3 编码器,指定其它编解码器会导致失败。
示例:--af=lavcac3enc=bitrate=384 将 5.1 音源以 384 kbps 实时编码后走 S/PDIF 直通。
3. format:声明式地控制“进入/流出某滤镜的音频格式”
format=format:srate:channels:out-srate:out-channels 本身不做任何格式转换。它的作用是向滤镜系统声明约束:滤镜系统会在需要时,在该滤镜前后自动插入必要的转换滤镜。因此它主要用于控制流入后续其它滤镜的音频格式。实现见 audio/filter/af_format.c。
文档明确区分了它与 --audio-* 系列选项的分工:
- 控制音频输出格式,应使用
--audio-format、--audio-samplerate、--audio-channels; - 这些
--audio-*选项可能被音频输出后端(ao)根据输出设备兼容性而覆盖;而format滤镜能够强制某种格式,不会被 ao 改写。
四个参数全部可选,语义分两组:
- 前 3 个参数(
<format>、<srate>、<channels>)限制该滤镜接受的输入格式,因而会触发在该滤镜之前插入转换滤镜:<format>:强制转换到该采样格式,--af=format=format=help可列出合法格式名;<srate>:强制转换到指定采样率,为整数(如 48000);<channels>:强制混音到指定声道布局,取值参见--audio-channels。
- 后 2 个参数(
<out-srate>、<out-channels>)不做转换,只是告诉该滤镜之后的滤镜或音频输出如何“解释”数据。文档警告:除非你确实在做测试或处理损坏的媒体文件,否则设置这些参数“大概率会弄坏一切”。
历史沿革:该滤镜旧名 force;旧的 format 滤镜自己执行转换,而现在的 format 把转换交给滤镜系统统一调度。
4. scaletempo:经典 WSOLA 变速不变调
scaletempo[=option1:option2:...] 在不改变音高的前提下调节音频节奏(tempo),并可选择与播放速度联动。实现位于 audio/filter/af_scaletempo.c。
工作原理:以“stride”为节拍——按正常速度播放 stride 毫秒音频,然后消耗 stride*scale 毫秒的输入音频;通过把相邻 stride 的 overlap% 内容混合来拼接;还会对接下来 search 毫秒的音频做简短统计分析,以寻找最佳重叠位置。
参数(含默认值):
| 参数 | 默认 | 说明 |
|---|---|---|
scale=<amount> |
1.0 | 名义节奏缩放倍数,叠加在 speed 之上 |
stride=<amount> |
60 | 每个 stride 输出的毫秒长度。过高:高速率下跳变明显、低速率下有回声;过低:会改变音高。增大可降低开销 |
overlap=<factor> |
0.20 | stride 的重叠比例,减小可提升性能 |
search=<amount> |
14 | 寻找最佳重叠位置的搜索毫秒数,减小可大幅提升性能。慢速机器上建议设得很低 |
| `speed=<tempo | pitch | both |
speed 的四种取值:
-
tempo:节奏跟随 speed 联动(默认); -
pitch:滤镜效果反转——变为变速不变节奏(改变音高)。文档给出按半音步进播放的input.conf绑定:[ multiply speed 0.9438743126816935 ] multiply speed 1.059463094352953注意(原文警告):此模式会失去与视频的同步;
-
both:节奏与音高同时缩放; -
none:忽略速度变化。
文档给出的四个典型用法,全部保留:
mpv --af=scaletempo --speed=1.2 media.ogg:以 1.2 倍速播放,音频音高不变;此后改变播放速度会同步改变音频节奏。mpv --af=scaletempo=scale=1.2:speed=none --speed=1.2 media.ogg:1.2 倍速且音高不变,但之后改变播放速度对音频节奏无影响。mpv --af=scaletempo=stride=30:overlap=.50:search=10 media.ogg:手动微调质量与性能参数。mpv --af=scaletempo=scale=1.2:speed=pitch audio.ogg:1.2 倍速且音高不变;之后改变播放速度只会改变音高,节奏保持在 1.2 倍。
5. scaletempo2:更高质量的 WSOLA 实现(也是自动变调的默认引擎)
scaletempo2[=option1:option2:...] 同样在不改变音高的前提下缩放节奏。算法移植自 Chromium,使用 Waveform Similarity Overlap-and-add(WSOLA)方法,见 audio/filter/af_scaletempo2.c 与 audio/filter/af_scaletempo2_internals.c。文档认为其音质优于 scaletempo 和 rubberband 的 R2 引擎(engine=faster)。
关键机制:当启用 audio-pitch-correction 选项(默认开启)且播放速度变化时,mpv 会自动插入该滤镜——这一行为在自动滤镜链中实现,见 filters/f_auto_filters.c#L506-L508(日志中可见 "adding scaletempo2")。
参数(含默认值,默认 search-interval 与 window-size 与 Chromium 相同):
| 参数 | 默认 | 说明 |
|---|---|---|
min-speed=<speed> |
0.25 | 播放速度低于该值时静音 |
max-speed=<speed> |
8.0 | 播放速度高于该值且该值非 0 时静音 |
search-interval=<amount> |
40 | 寻找最佳重叠位置的搜索毫秒数 |
window-size=<amount> |
12 | overlap-and-add 窗口的毫秒长度 |
6. lavfi-tempo:借道 libavfilter 的 atempo / ascale
lavfi-tempo[=[filter=]<filter_name>] 使用 FFmpeg libavfilter 的 atempo 或 ascale 滤镜来缩放节奏,可作为 scaletempo / scaletempo2 的替代。实现见 audio/filter/af_lavfi_tempo.c。
源码印证了文档描述的“回退”行为:初始化时若指定的 ascale 滤镜在当前 libavfilter 中不可用,会打印警告并自动改用 atempo:
// audio/filter/af_lavfi_tempo.c
if (!mp_lavfi_is_usable(p->opts->filter, AVMEDIA_TYPE_AUDIO)) {
MP_WARN(f, "%s filter is not available, using atempo instead.\n", p->opts->filter);
p->opts->filter = "atempo";
p->fall_backed = true;
}
(audio/filter/af_lavfi_tempo.c#L81-L85;filter 选项默认值即 atempo,见同文件 L223-L225。)速度变化时,该滤镜通过向内部 lavfi 滤镜下发 tempo 命令动态更新倍速(set_speed(),L48-L67)。
文档示例(原样保留):
mpv --af=lavfi-tempo --speed=1.2 media.ogg:1.2 倍速、音高不变,节奏由 lavfi 的atempo缩放。mpv --af=lavfi-tempo=atempo --speed=1.2 media.ogg:同上(直接指定名字)。mpv --af=lavfi-tempo=filter=atempo --speed=1.2 media.ogg:同上(用filter=显式命名)。mpv --af=lavfi-tempo=ascale --speed=1.2 media.ogg:由ascale缩放节奏;若ascale不可用则回退到atempo。mpv --af=lavfi-tempo=filter=ascale --speed=1.2 media.ogg:同上。
注意 ascale 仅在 Librempeg 构建的 libavfilter 中提供。
7. rubberband:基于 librubberband 的高质量变调
rubberband 提供由 librubberband 驱动的高质量音高校正,实现见 audio/filter/af_rubberband.c。它可替代 scaletempo/scaletempo2:播放速度与正常速度不同时会用它调整音频音高;也可以在不改变播放速度的情况下单独调整音高。
参数:
pitch-scale=<amount>(默认 1.0):音高缩放因子,频率乘以该值。engine=<faster|finer>:选择核心引擎。Faster:Rubberband R2 引擎,CPU 占用显著低于 R3;Finer:Rubberband R3 引擎,需要 librubberband 3.0 及以上,输出质量显著提高但 CPU 更高(可用时作为默认)。
该滤镜还有大量未在此处逐一列出的子选项(它们只是透传给 librubberband),可用 mpv --af=rubberband=help 列出全部子选项及其默认值,各选项含义需查阅 librubberband 官方文档(RubberBandStretcher 类)。注意某些选项只对 R2(faster)或 R3(finer)之一生效。mpv 子选项到 librubberband 选项的映射遵循简单规则:"Option" + Name + Value。
运行时控制:该滤镜支持以下 af-command 命令:
set-pitch:动态设置pitch-scale,可在播放中实时改变音高。注意 speed 本身用标准的speed属性控制,不走af-command;multiply-pitch <factor>:动态地把当前pitch-scale乘以某个系数。
8. lavfi:把任意 libavfilter 图接到音频链上
lavfi=graph 用 FFmpeg 的 libavfilter 处理音频,<graph> 为 libavfilter 图,语法与 lavfi 视频滤镜完全相同(同样要注意给 libavfilter 图加引号,见 --vf 文档中的 lavfi 一节)。另有 o=<string> 用于传递 AVOptions。
重点参数 fix-pts=<yes|no>(默认 no):
- 启用后,播放器不再依赖 libavfilter 准确透传 PTS,而是把样本计数作为 PTS 传给 libavfilter,并据此加输入 PTS 反推 mpv 使用的 PTS;
- 这对那些“输出重算 PTS 而非原始 PTS”(包括要求 PTS 从 0 开始)的滤镜是必需的。mpv 默认假定滤镜不动 PTS,因此
fix-pts不是默认行为,但用它修复“坏滤镜”时:不加会出现缓慢的 A/V 失步(部分文件),或者在 seek / 从文件中间开始播放时直接破坏播放。
9. drop:为 SPDIF 而生的低质量兜底滤镜(不推荐使用)
drop 通过丢弃或重复音频帧来适配播放速度。它始终按完整音频帧操作,因为它是为处理 SPDIF(压缩音频 passthrough)而设计的;当使用 --video-sync=display-adrop 选项时会自动启用。文档直接给出结论:不要使用这个滤镜(或该选项),质量极差。实现见 audio/filter/af_drop.c。
10. 实践建议:如何选择变速滤镜
结合本文档与源码结构,可以给出一个清晰的决策路径:
- 日常变速(默认场景):什么都不用做。
audio-pitch-correction默认开启,speed 改变时 mpv 会自动插入scaletempo2(WSOLA,filters/f_auto_filters.c); - 显式对比各引擎音质/性能:
--af=scaletempo2、--af=scaletempo(可调stride/overlap/search换性能)、--af=lavfi-tempo(借atempo/ascale); - 追求最高变调质量且 CPU 富余:
--af=rubberband=engine=finer,并用af-command的set-pitch/multiply-pitch在播放中实时微调; - 向功放/接收器输出 5.1 AC-3:
--af=lavcac3enc(注意bitrate默认 640 可能超出接收器能力,可用auto); - 需要精确控制某段滤镜输入/输出格式:
format滤镜做声明式约束,真正的转换交给滤镜系统自动插入。
最后提醒:本文档描述的行为以当前仓库为准(如 scaletempo2 默认由 audio-pitch-correction 自动启用、fix-pts 默认关闭等);滤镜的完整列表随构建时链接的 libavfilter 版本而异,最可靠的清单永远是运行时执行 mpv --af=help 的输出。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00