跳至內容

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

參見