跳转到内容

WirePlumber

来自 Arch Linux 中文维基

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
注意:只有在输出节点处于静音状态时,才会显示静音状态。

禁用蓝牙配置文件自动切换

参见 PipeWire#自动化 profile 切换。

注销后保持蓝牙运行/无头蓝牙

注意:还需要为运行 PipeWire/WirePlumber 的用户启用 用户驻留。

自 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/故障排除中找到。

参见