WirePlumber
WirePlumber 是一款强大的PipeWire 会话和策略管理器。其采用模块化设计,使用 Lua 插件进行管理,具有高度可配置性及可扩展性。
安装
安装 wireplumber包。任何冲突的 PipeWire 会话管理器会被卸载。
WirePlumber 使用 systemd 用户单元管理 PipeWire 服务。
配置
配置文件布局
WirePlumber 的配置使用 PipeWire 的 JSON 对象如 context 和 alsa_monitor,通过修改这些对象来控制其行为。配置文件位于 ~/.config/wireplumber/(用户配置)、/etc/wireplumber/(全局配置)以及 /usr/share/wireplumber/(默认配置)。
WirePlumber 启动时首先会读取主配置文件。这是一个类 JSON 文件,用于设定 PipeWire 上下文环境(context)、SPA 插件、模块以及组件。
默认配置文件位于 /usr/share/wireplumber/wireplumber.conf,其是一个单实例配置文件,集成其他配置到一个进程中。请参阅文档 ALSA 对象、"access" 对象和蓝牙对象。
修改配置
推荐向 /etc/wireplumber/ 或 ~/.config/wireplumber/ 目录下的 wireplumber.conf.d/ 文件夹内添加 SPA-JSON 文件来配置 WirePlumber。
用户配置较系统配置具有更高优先级,低优先级的同名配置文件会被忽略。在配置目录中,各文件按照字母数字顺序被读取,请参阅文档以了解详细信息。
获取用于规则匹配的接口名称
在配置文件中,需要指定 matches 规则,并使用要配置的接口对应对象的某项属性进行匹配。
使用 wpctl status 命令显示 WirePlumber 管理的所有对象。找到分配给目标接口的 ID,然后运行 wpctl inspect ID 获取所需的属性。
例如,如果目标接口是 HD Audio Controller Analog Stereo,可以参考以下输出:
$ wpctl status
PipeWire 'pipewire-0' [0.3.56, user@hostname, cookie:1163266174] Audio ├─ Devices: │ 42. HD Audio Controller [alsa] │ 105. USB PnP Audio Device [alsa] │ ├─ Sinks: │ * 48. HD Audio Controller Analog Stereo [vol: 0.50] │ ├─ ... │ ├─ Sources: │ * 101. USB PnP Audio Device Mono [vol: 0.74] │ └─ ...
该接口的 ID 为 48。
接下来使用 inspect 命令查看该对象的详细信息及其全部属性:
$ wpctl inspect 48
id 48, type PipeWire:Interface:Node
...
device.api = "alsa"
device.class = "sound"
* device.id = "42"
device.profile.description = "Analog Stereo"
device.profile.name = "analog-stereo"
...
* factory.id = "18"
factory.mode = "merge"
factory.name = "api.alsa.pcm.sink"
...
* media.class = "Audio/Sink"
* node.description = "HD Audio Controller Analog Stereo"
* node.name = "alsa_output.pci-0000_08_00.4.analog-stereo"
* node.nick = "ALC1220 Analog"
...
* object.path = "alsa:pcm:1:front:1:playback"
* object.serial = "49"
...
请选择具有唯一性且稳定的属性用于 matches 规则。推荐使用 device.name 或 node.name 属性。
避免使用 device.id,因为它是动态分配的,可能在不同会话之间发生变化。
规则支持正则表达式和多个属性的 matches 匹配;详情参见官方文档中的“Working with rules”一节。
- 对大多数用户来说,有两种重要的对象类型:
- Device 对象相当于一个 ALSA 声卡(ALSA Card)。
- Node 对象相当于一个 ALSA 设备(ALSA Device)。
-
PipeWire 虚拟设备的流类别由
media.class属性指示。分类逻辑参见 WirePlumber 链接策略简介。 - WirePlumber 使用 PCM 名称填充
node.nick属性。在使用 UCM 的 HDA 声卡上,即使模拟输出、HDMI 等不同输出共用同一个配置文件,也能将它们作为独立的Nodes暴露出来,并为其提供有描述性的昵称。
- 如果难以找到目标接口,可以使用 PipeWire 命令
pw-top查看当前处于活动状态的devices和nodes列表。 - PipeWire 中类似的检查命令是
pw-cli info ID。
修改设备/节点属性
要修改设备或节点的属性,例如描述或昵称,需要创建一个 SPA-JSON 文件,并按照正确的路径和文件名将其放在 /etc/wireplumber/ 或 ~/.config/wireplumber/ 下。
例如,要修改 ALSA 节点的描述,可以创建如下文件:
/etc/wireplumber/wireplumber.conf.d/device-rename.conf(或 ~/.config/wireplumber/wireplumber.conf.d/device-rename.conf)
monitor.alsa.rules = [
{
matches = [
{
node.name = "alsa_output.pci-0000_00_1f.3.output_analog-stereo"
}
]
actions = {
update-props = {
node.description = "Laptop"
}
}
}
]
如果要修改蓝牙节点或设备的属性,可以创建如下文件:
/etc/wireplumber/wireplumber.conf.d/bluez-rename.conf(或 ~/.config/wireplumber/wireplumber.conf.d/bluez-rename.conf)
monitor.bluez.rules = [
{
matches = [
{
node.name = "bluez_output.02_11_45_A0_B3_27.a2dp-sink"
}
]
actions = {
update-props = {
node.nick = "Headphones"
}
}
}
]
可修改的属性以及用于选择设备或节点的匹配规则,详见 ALSA 配置和蓝牙配置文档。
禁用设备/节点
任何设备或节点都可以被禁用:对于设备,设置 device.disabled 属性;对于节点,设置 node.disabled 属性:
/etc/wireplumber/wireplumber.conf.d/alsa-disable.conf(或 ~/.config/wireplumber/wireplumber.conf.d/alsa-disable.conf)
monitor.alsa.rules = [
{
matches = [
{
device.name = "alsa_card.pci-0000_08_00.4"
}
]
actions = {
update-props = {
device.disabled = true
}
}
}
]
按照#获取用于规则匹配的接口名称中的说明,找到设备或节点的唯一标识符。
本例使用 device.name 进行匹配,也可以使用 node.nick 等其他标识属性。
node.disabled,而不是 device.disabled。一种常见用途是禁用显卡的 HDMI 音频输出。
这种方式也可以通过匹配特定节点(例如 node.nick)来只禁用指定显示器的 HDMI 音频,因为该属性可能随连接的设备而变化。
设置节点优先级
要改变自动选择的音频输出节点(sink)或输入节点(source),需要设置其 priority.session 值:
/etc/wireplumber/wireplumber.conf.d/set-priorities.conf
monitor.alsa.rules = [
{
matches = [
{
node.name = "alsa_output.usb-Generic_USB_Audio-00.HiFi__Speaker__sink"
}
]
actions = {
update-props = {
priority.session = 100
}
}
}
]
本例将华硕 B650E-F 主板板载音频的扬声器输出节点优先级从原来的 1000 降至 100。这样,其他具有更高优先级的输出节点,例如板载音频设备的 S/PDIF 输出或已连接的耳机,就会被选为默认输出,而不是模拟扬声器输出。
需要注意,默认情况下,优先级的实际影响可能比预期更小。WirePlumber 在计算机启动或设备拔出时,默认会优先恢复之前选择过的设备。若要让这些情况下的选择遵循优先级,应禁用对先前选择的记忆:
/etc/wireplumber/wireplumber.conf.d/no-restore-default.conf
wireplumber.settings = {
node.restore-default-targets = false
}
同一声卡上的多个输出节点同时输出
参见 PipeWire/故障排除#同一声卡同时向多个音频输出设备输出。
向临时连接的设备同时输出
你可能希望同时向板载设备和外部设备输出声音,即使外部设备并非始终连接。 为实现这一点,我们先创建一个始终存在的虚拟节点,使其不受硬件是否连接的影响。然后,每当临时设备(本例为 USB 耳机)接入时,就将其连接至该虚拟节点。
首先,创建一个在登录时运行的脚本。通常最简单的方式是使用窗口管理器的启动项功能。
/usr/local/bin/create-virtual-sink.sh
#!/bin/bash
# Create a new sink called Simultaneous Output
pw-cli create-node adapter '{ factory.name=support.null-audio-sink node.name="Simultaneous Output" node.description="Simultaneous Output" media.class=Audio/Sink object.linger=true audio.position=[FL FR] }'
# Connect the normal permanent sound card output to the new sink
pw-link "Simultaneous Output:monitor_FL" alsa_output.pci-0000_05_04.0.analog-stereo:playback_FL
pw-link "Simultaneous Output:monitor_FR" alsa_output.pci-0000_05_04.0.analog-stereo:playback_FR
# Switch the default output to the new virtual sink
wpctl set-default `wpctl status | grep "\. Simultaneous Output" | egrep '^ │( )*[0-9]*' -o | cut -c6-55 | egrep -o '[0-9]*'`
在上面的示例中,最初唯一的输出设备是“普通”板载声卡(alsa_output.pci-0000_05_04.0.analog-stereo)。可以运行 wpctl status 和 wpctl inspect 来确定自己声卡的标识符。
插入 USB 耳机时,运行以下脚本,将耳机连接到虚拟输出节点:
link-virtual-sink-headphones.sh
#!/bin/bash # link the virtual sync to your headphones should run when detected by UDEV # wait a second for the drivers to load sleep 1s # link the headphones to your virtual sink sudo -u user1 env XDG_RUNTIME_DIR=/run/user/1000 pw-link "Simultaneous Output:monitor_FL" alsa_output.usb-Kingston_HyperX_Cloud_Flight_S_000000000001-00.analog-stereo:playback_FL sudo -u user1 env XDG_RUNTIME_DIR=/run/user/1000 pw-link "Simultaneous Output:monitor_FR" alsa_output.usb-Kingston_HyperX_Cloud_Flight_S_000000000001-00.analog-stereo:playback_FR # finish and return the code for success exit 0
理想情况下,应在耳机插入时自动运行该脚本。udev 页面介绍了如何为此创建自定义规则。(不过要注意,不能直接通过 udev 运行此脚本,因为 udev 要在指定脚本执行之后才会加载驱动程序。因此需要使用中间脚本,并借助 nohup 等方式间接启动。) 此外,需要修改上述脚本,使 XDG_RUNTIME_DIR 与自己的用户 ID 对应,并将 user1 替换为自己的用户名。
可以用相同的方法将任意数量的设备添加到这个虚拟输出节点。
如果难以弄清各设备之间的连接关系,可以使用 qpwgraph包 工具,以图形方式直观查看设备之间的连接。
提示与技巧
删除损坏的设置
如果 WirePlumber 的设置损坏,可以删除所有用户设置。先停止 wireplumber.service 用户单元,再使用以下命令删除设置:
$ rm -r ~/.local/state/wireplumber
然后可以重新启动 wireplumber.service 用户单元。
键盘控制音量
参见 快捷键#Xorg,了解如何将以下命令绑定到音量按键:XF86AudioRaiseVolume、XF86AudioLowerVolume、XF86AudioMute 和 XF86AudioMicMute。
提高音量,上限为 150%:
$ wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+
降低音量:
$ wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
静音/取消静音:
$ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
将麦克风静音/取消静音:
$ wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
wpctl status 列出所有可用的输出节点,并使用相应的输出或输入节点编号替换 @DEFAULT_AUDIO_SINK@ 或 _SOURCE@。显示音量级别
查看默认输出节点的音量级别和静音状态:
$ wpctl get-volume @DEFAULT_AUDIO_SINK@
Volume: 0.45
禁用蓝牙配置文件自动切换
注销后保持蓝牙运行/无头蓝牙
自 0.4.8 版本起,需要禁用 BlueZ 座席监控(seat-monitoring)对 support.logind 的要求。
~/.config/wireplumber/wireplumber.conf.d/disable-logind.conf
wireplumber.profiles = {
main = {
monitor.bluez.seat-monitoring = disabled
}
}
禁用音频栈集成
如果你打算使用另一套音频解决方案(例如 PulseAudio、JACK 或 ALSA),不希望 PipeWire/WirePlumber 接管音频设备,但仍希望保留其屏幕共享或视频相关功能,可以使用 wireplumber@.service 模板单元启用另一组默认配置文件。WirePlumber 提供了一个仅启用视频相关部分、禁用音频集成(包括蓝牙音频)的配置文件,可以通过启用 video-only 模板用户单元使用它。
禁用 wireplumber.service 用户单元,并启用 wireplumber@video-only.service 用户单元。
调整当前未播放音频的应用程序音量
有些应用程序(例如启动器)发声时间太短,无法使用图形混音器及时调整音量。WirePlumber 将每个应用程序和每个节点的音量及静音状态保存在文本文件 $HOME/.local/state/wireplumber/stream-properties 中。可以手动编辑该文件以修改设置。编辑时请确保 WirePlumber 没有运行,否则它可能会覆盖所做的修改。
故障排除
由于 WirePlumber 只负责管理 PipeWire 会话,因此 WirePlumber 相关问题的解决方法也可以在 PipeWire/故障排除中找到。
参见
- 文档 — 官方文档
- WirePlumber,PipeWire 会话管理器 — George Kiagiadakis(Collabora)于 2020 年 5 月发表的博客文章,详细介绍 WirePlumber 的工作原理