跳至內容

PipeWire/故障排除

出自 Arch Linux 中文维基

繼續之前,請先檢查以下最基本的事項:

  1. 是否選擇了正確的音效卡?
  2. 軟體和硬體音量是否已調高?
  3. 線纜是否連接到了正確的埠?
  4. USB 音效卡是否直接連接到計算機?
  5. 是否已調高麥克風音量、連接麥克風並開啟 XLR 幻象供電?
  6. 環繞聲是否異常?如果是,首先嘗試卸載 UCM 配置軟體包 alsa-ucm-conf包。參見 PulseAudio/Examples#Disabling UCM/"HiFi"。
  7. 重啟 pipewire.service 和 pipewire-pulse.service 用戶單元。

音量

多種應用程式沒有聲音,但瀏覽器有聲音

本文或本章節的事實準確性存在爭議。

原因: 問題的根本原因僅為猜測,尚未得到驗證。是否只是應用程式被靜音?(在 Talk:PipeWire/故障排除 中討論)


使用 mpv 檢查已安裝的編解碼器是否正常工作:

$ mpv --ao=alsa test_file.mpv
$ mpv --ao=pcm test_file.mpv
$ mpv --ao=jack test_file.mpv
$ mpv --ao=pulse test_file.mpv
$ mpv --ao=openal test_file.mpv

如果上述部分或全部測試能夠發出聲音,而以下命令不能:

$ mpv --ao=pipewire test_file.mpv

則可能是 pipewire 通道被靜音。安裝並運行 pavucontrol。

在「配置」選項卡中選擇適當的設備,然後在「輸出設備」選項卡中再次選中它。在播放 mpv --ao=pipewire test.mp4 視頻的同時,使用「靜音」按鈕先靜音再取消靜音。

或者刪除 ~/.local/state/wireplumber/,再通過 systemctl --user restart pipewire pipewire-pulse wireplumber.service 重啟 PipeWire。

音量過低

將 PulseAudio 替換為 PipeWire 後,聲音可能起初正常,但重啟後音量變得低得難以接受。

打開 alsamixer,按 F6 選擇正確的音效卡,並確保 ALSA 音量為 100%。alsactl 應在重啟後保留此設置。

SDDM 和 LightDM 用戶登錄後設備音量未恢復

如果使用 SDDM 或 LightDM,並發現登錄後音量未正確恢復,可以屏蔽顯示管理器用戶的 PipeWire,因為顯示管理器帳戶下運行的 WirePlumber 可能干擾當前用戶的 WirePlumber 會話。

# systemctl --user -M user@ mask pipewire.socket

對於 SDDM,將 user 替換為 sddm;對於 LightDM,則替換為 lightdm。

更多詳細信息參見Debian Wiki 文章。

麥克風

PipeWire 無法檢測麥克風

如果使用筆記本內置麥克風,或通過耳機插孔連接的麥克風,首先確保當前使用的配置文件已啟用模擬輸入。可以在 pavucontrol包 中(也可能在桌面環境的聲音設置中)查看。在 pavucontrol 的「配置」選項卡中,確保「內置音頻」(或類似名稱)選擇了「模擬立體聲雙工」。如果使用 5.1 聲道、HDMI 音頻等高級音頻配置,請選擇包含「+ 模擬立體聲輸入」的配置文件。

PipeWire 的 alsa-monitor 模塊默認使用 alsa-card-profiles包 檢測設備。如果無法正常工作,嘗試禁用 api.alsa.use-acp,或者在 wireplumber包 中啟用 api.alsa.use-ucm:

/etc/wireplumber/wireplumber.conf.d/alsa-config.conf (or ~/.config/wireplumber/wireplumber.conf.d/alsa-config.conf)
monitor.alsa.properties = {
  # 使用 ALSA-Card-Profile 設備。它們通過 UCM 或 profile
  # 配置來設置設備和混音器參數。
  # alsa.use-acp = true
  # 如果可用,使用 UCM 代替 profile。也可以禁用此項,
  # 以跳過使用 UCM 配置文件的嘗試。
  alsa.use-ucm = true
}

使用 pipewire-media-session包 時:

/etc/pipewire/media-session.d/alsa-monitor.conf (or ~/.config/pipewire/media-session.d/alsa-monitor.conf)
...
rules = [
    {
        ...
        actions = {
        update-props = {
            ...
            api.alsa.use-acp = false
...

隨後重啟 WirePlumber 並檢查可用設備:

本文或本節內容已經過時。

原因: 新版本 pw-record 已不再提供 --list-targets 選項;請改用 wpctl status、pw-cli ls 或 pw-dump 列出對象。 (在Talk:PipeWire/故障排除討論)
$ pw-record --list-targets
Available targets ("*" denotes default): 62
	58: description="Built-in Audio" prio=1872
	60: description="Built-in Audio" prio=2000
*	62: description="Built-in Audio (Loopback PCM)" prio=1984

此 PipeWire 問題報告還提出了一種替代方案:手動添加麥克風。首先確保 ALSA 已檢測到麥克風。

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card card_number: card_name, device device_number: device_name
  ...

從列表中選擇麥克風,然後運行以下命令進一步測試:

$ arecord --duration=5 --format=dat --device=hw:card_number,device_number test-mic.wav # 從麥克風錄音
$ aplay test-mic.wav # 播放錄音

如果麥克風可以通過 arecord 正常錄音,卻未被 PipeWire 檢測到,可以嘗試創建配置文件,手動添加該設備。

/etc/pipewire/pipewire.conf.d/microphone.conf (or ~/.config/pipewire/pipewire.conf.d/microphone.conf)
context.objects = [
    { factory = adapter
        args = {
            factory.name           = api.alsa.pcm.source
            node.name              = "microphone"
            node.description       = "未檢測到的麥克風"
            media.class            = "Audio/Source"
            api.alsa.path          = "hw:card_number,device_number"
        }
    }
]

然後重啟 PipeWire 以重新加載配置。

音頻質量

節能機制導致爆音

HECI 控制器受到電源管理影響時可能導致爆音。可以通過 powertop 禁用運行時電源管理(Runtime PM)。

音頻失真

  • 對於麥克風,在運行 alsamixer 後找到存在問題的音效卡,並使用方向鍵降低「Mic Boost」或「Internal Mic Boost」等麥克風增益選項。
  • 參照#更改默認採樣率,將採樣率降低至 44100(44.1 kHz)。

更改默認採樣率

PipeWire 默認使用固定的 48 kHz 全局採樣率。如需更改,可以設置新的默認值(但不推薦):

/etc/pipewire/pipewire.conf.d/sample-rate.conf (or ~/.config/pipewire/pipewire.conf.d/sample-rate.conf)
context.properties = {
    default.clock.rate = sample_rate
}

不過,不建議這樣做,因為這會影響延遲,而 quantum 的數值不會自動重新計算。如果希望保持相同的時間比例,則必須自行調整。引用官方文檔的說明:

默認時鐘採樣率決定了最小、最大和默認 quantum 所對應的實時持續時間。更改默認時鐘採樣率時,你可能需要同時更改 quantum,以保持它們原來的持續時間。

請注意,各音頻流自身的採樣率不會改變。PipeWire 只會進行重採樣,以滿足新的輸出採樣率。因此,原本無需處理的 48 kHz 音頻流現在也會被重新採樣。

如果設備支持多種採樣率,建議保留默認設置,改為按照#更改允許的採樣率進行配置。

更改允許的採樣率

PipeWire 也可以根據 DAC 所支持的採樣率動態改變輸出採樣率,使其跟隨正在播放的音頻流。例如:

/etc/pipewire/pipewire.conf.d/sample-rate.conf (or ~/.config/pipewire/pipewire.conf.d/sample-rate.conf)
context.properties = {
    default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 352800 384000 ]
}

假設默認採樣率為 48000(即默認設置)。通常,如果音頻流以 44100 Hz 輸出(例如播放 CD 音質歌曲),PipeWire 會把它重採樣到 48 kHz。但是,如果允許列表中包含 44100,PipeWire 則會檢查音頻流的 44100 是否在允許列表內,以及接收音頻的輸出設備(例如 DAC)是否支持該採樣率。如果都滿足,DAC 就能在不進行重採樣的情況下播放歌曲。如果採樣率不在列表中,或者 DAC 不支持它,PipeWire 就會退回默認採樣率並進行重採樣。

根據開發者的說法:「PipeWire 最多允許配置 16 種不同採樣率,並會在可能時切換。」這意味著上述配置在設備支持時不會進行重採樣。自 PipeWire 0.3.61 起,最多可配置 32 種採樣率。

獲取允許的採樣率

查閱硬體手冊,確認 DAC 支持的採樣率。內核驅動編解碼器報告的支持採樣率可以通過以下命令查看:

$ grep -E 'Codec|Audio Output|rates' /proc/asound/card*/codec#*

如果 DAC 不報告編解碼器信息,可以嘗試通過以下命令獲取支持的採樣率:

$ grep -m1 -Hn "" /proc/asound/card?/stream? | tee /dev/tty | awk -F':' '{print $1}' | xargs grep 'Rates'
注意:雖然 DAC 晶片可能報告高於產品標稱規格的採樣率,但其中一些僅用於 USB 轉 I2S 等特殊模式。

檢查當前使用的採樣率

運行以下命令,檢查某張音效卡當前使用的輸出採樣率:

$ grep rate: /proc/asound/card?/pcm??/sub?/hw_params
/proc/asound/card1/pcm0p/sub0/hw_params:rate: 96000 (96000/1)

在 pcm0p 或 pcm0c 中,c 表示「capture」(採集),p 表示「playback」(播放)。

命令:

$ pw-top

也會顯示各音效卡和音頻流當前使用的採樣率。

提示:如果在設置 default.clock.allowed-rates 後,DAC 仍不能切換到更高採樣率,可能是系統無法讀取 DAC 支持的採樣率。這時仍可嘗試設置 default.clock.rate。

硬體和音效卡

JBL Quantum 350 Wireless 與 Discord 的兼容問題

症狀:當 Discord 發起音頻輸出或初始化音頻配置時,沒有聲音;如果已經有其他聲音正在播放,Discord 音頻便可正常工作。例如會出現以下錯誤:

spa.alsa: front:0p: (125 suppressed) snd_pcm_avail after recover: Broken pipe

該錯誤會出現在 系統日誌中。

至少有兩種可能的解決方案:提高 api.alsa.headroom(例如設為 512),或設置合適的 api.alsa.start-delay。以下是針對 JBL Quantum 350 無線設備的示例:

~/.config/wireplumber/wireplumber.conf.d/52-jbl-quantum-350-discord-fix.conf
monitor.alsa.rules = [
   {
     matches = [
       {
         node.name = "alsa_output.usb-JBL_JBL_Quantum350_Wireless-00.analog-stereo"
       }
     ]
     actions = {
       update-props = {
         api.alsa.start-delay = 500
       }
     }
   }
 ]

然後在計算機上重啟 wireplumber.service 用戶單元。

XiiSound / HAVIT Fuxi-H3 (040b:0897)

這款 USB 耳機在 PipeWire 和 WirePlumber 下有幾個特殊問題:

  • 僅在音量為 100% 時有聲音——硬體音量範圍過窄(0.00 dB 至 0.39 dB),使得 PipeWire 的分貝映射將較低音量全部轉換為靜音。
  • 左聲道靜音——設備具有一個供左聲道使用的次級 ALSA 混音器控制項(PCM,1,numid=10),WirePlumber 未初始化它,導致音量停留在 0%。
  • 麥克風初始化時被靜音——PipeWire 可能在啟用靜音的狀態下創建採集源。

修複方法 1——強制使用軟體混音器:

創建:

~/.config/wireplumber/wireplumber.conf.d/51-fuxi-h3-fix.conf
monitor.alsa.rules = [
   {
     matches = [
       {
         device.name = "alsa_card.usb-XiiSound_Technology_Corporation_Fuxi-H3-00"
       }
     ]
     actions = {
       update-props = {
         api.alsa.soft-mixer = true
         api.alsa.ignore-dB = true
         api.alsa.split-enable = false
       }
     }
   }
 ]

然後在計算機上重啟 wireplumber.service 用戶單元。

修複方法 2——恢復左聲道:

$ amixer -c 0 cset numid=10 100

修複方法 3——取消麥克風靜音:

$ pactl set-source-mute alsa_input.usb-XiiSound_Technology_Corporation_Fuxi-H3-00.mono-fallback 0

使設置在重啟後仍然有效:

# alsactl store 0

KDE Plasma 中未顯示任何音頻設備

PipeWire 客戶端(包括桌面環境)可能依賴 XDG_RUNTIME_DIR 環境變量來連接 PipeWire 守護進程。[1] 如果登錄後沒有出現音頻設備,原因可能是該變量被手動設置成了錯誤的路徑。

儘管手動重啟 PipeWire 可能暫時解決問題,但仍可能出現其他故障,例如無法在 Chromium 中共享屏幕(提示 pipewire context failed)。XDG_RUNTIME_DIR 會由 pam_systemd(8) 自動設置,因此應刪除初始化文件中對它的所有手動賦值。

向 RAOP 設備(Sonos 等)串流時沒有聲音

使用 Avahi 或 systemd-resolved 配置 mDNS 主機名解析。

從掛起狀態恢復後實時優先級丟失/負載下爆音

這一章節正在考慮移除。

原因: 所述缺陷已於 2023 年遷移到 新的 freedesktop.org 倉庫後得到修復。 (在 Talk:PipeWire/故障排除 討論)


由於 rtkit 中一項2011 年報告的缺陷,系統掛起會導致 PipeWire 的實時優先級被撤銷,且恢復運行後無法重新獲得。若要關閉觸發此問題的保護機制,請編輯 rtkit-daemon.service:

/etc/systemd/system/rtkit-daemon.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/lib/rtkit-daemon --no-canary

然後重啟 rtkit-daemon.service 系統單元、pipewire.service 用戶單元及媒體會話服務。

同一音效卡同時向多個音頻輸出設備輸出

複製 /usr/share/alsa-card-profile/mixer/profile-sets/default.conf,以便更新後仍保留自定義更改。這裡定義一個將模擬輸出與 HDMI 的兩個默認映射合併起來的配置文件。

/usr/share/alsa-card-profile/mixer/profile-sets/multiple.conf
[General]
auto-profiles = no

[Mapping analog-stereo]
device-strings = front:%f
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 15

[Mapping hdmi-stereo]
description = 數字立體聲 (HDMI)
device-strings = hdmi:%f
paths-output = hdmi-output-0
channel-map = left,right
priority = 9
direction = output

[Profile multiple]
description = 模擬立體聲雙工 + 數字立體聲 (HDMI) 輸出
output-mappings = analog-stereo hdmi-stereo
input-mappings = analog-stereo

然後配置會話管理器,為匹配的設備使用新的音效卡配置文件。可以通過 pw-dump 或 wpctl 獲取設備標識信息。

對於 wireplumber包:

/etc/wireplumber/wireplumber.conf.d/alsa-custom.conf (or ~/.config/wireplumber/wireplumber.conf.d/alsa-custom.conf)
monitor.alsa.rules = [
  {
    matches = [
      {
        device.nick = "HDA Intel PCH"
      }
    ]
    actions = {
      update-props = {
        api.alsa.use-acp = true
        api.acp.auto-profile = false
        api.acp.auto-port = false
        device.profile-set = "multiple.conf"
        device.profile = "multiple"
      }
    }
  }
]

對於 pipewire-media-session包:

/etc/pipewire/media-session.d/alsa-monitor.conf (or ~/.config/pipewire/media-session.d/alsa-monitor.conf)
rules = [
    {
        matches = [ { alsa.card_name = "HDA Intel PCH" } ]
        actions = {
            update-props = {
                api.alsa.use-acp = true
                device.profile-set = "multiple.conf"
                device.profile = "multiple"
                api.acp.auto-profile = false
                api.acp.auto-port = false
            }
        }
    }
]

USB DAC 的高延遲問題(例如 Schiit DAC)

更改採樣率或音頻格式可能有助於降低 Schiit Hel 2 等 DAC 的延遲。[2]

對於 pipewire-media-session包:

將默認配置文件 /usr/share/pipewire/media-session.d/alsa-monitor.conf 複製到 /etc/pipewire/media-session.d/(或 ~/.config/pipewire/media-session.d/)。 然後添加類似下面的規則塊:

/etc/pipewire/media-session.d/alsa-monitor.conf (or ~/.config/pipewire/media-session.d/alsa-monitor.conf)
...
rules = {
    ...
    {
        matches = [
            {
                node.name = "alsa_output.name-of-node"
            }
        ]
        actions = {
            update-props = {
                audio.format = "S24_3LE"
                audio.rate = 96000
                # 如果聲音仍有中斷或其他問題,請逐次將以下數值加倍
                api.alsa.period-size = 128
...

對於 wireplumber包:

/etc/wireplumber/wireplumber.conf.d/update-rate-and-format.conf (or ~/.config/wireplumber/wireplumber.conf.d/update-rate-and-format.conf)
monitor.alsa.rules = [
  {
    matches = [
      {
        node.name = "alsa_output.name-of-node"
      }
    ]
    actions = {
      update-props = {
        audio.format = "S24_3LE"
        audio.rate = 96000
        # 如果聲音仍有中斷或其他問題,請逐次將以下數值加倍
        api.alsa.period-size = 128
      }
    }
  }
]

可以用 pw-top 獲取 alsa_output.name-of-node 節點名稱。

你的 DAC 可能支持不同的格式或採樣率。可以通過查詢 ALSA 來檢查 DAC 所支持的參數:

首先獲取 DAC 的音效卡編號:

$ aplay -l
...
card 3: S2 [Schiit Hel 2], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
...

因此,本例中的音效卡編號為 3。 獲取所有受支持的採樣率及格式:

$ cat /proc/asound/cardX/streamX
...
Playback:
  ...
  Interface 1
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 0x05 (5 OUT) (ASYNC)
    Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
    Data packet interval: 125 us
    Bits: 16
    ...
  Interface 1
    Altset 2
    Format: S24_3LE
    Channels: 2
    Endpoint: 0x05 (5 OUT) (ASYNC)
    Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
    Data packet interval: 125 us
    Bits: 24
    ...
  Interface 1
    Altset 3
    Format: S32_LE
    Channels: 2
    Endpoint: 0x05 (5 OUT) (ASYNC)
    Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
    Data packet interval: 125 us
    Bits: 32
    ...
...

本例中,支持的格式為 S16_LE, S24_3LE, S32_LE;所有格式合計支持的採樣率為 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000。

USB DAC 音量達到 30% 後才有聲音

某些 USB DAC 只有在音量達到一定數值後才能輸出聲音[3]。通常閾值在 15% 至 30% 左右,這可能導致初始音量過大,並且無法維持低音量。解決方法是將該設備的 api.alsa.soft-mixer 設為 true,忽略硬體混音器的音量控制。

在 wireplumber包 中可以使用以下配置:

/etc/wireplumber/wireplumber.conf.d/alsa-soft-mixer.conf (or ~/.config/wireplumber/wireplumber.conf.d/alsa-soft-mixer.conf)
monitor.alsa.rules = [
  {
    matches = [
      {
        device.name = "alsa_card.name-of-device"
      }
    ]
    actions = {
      update-props = {
        # 不使用硬體混音器控制音量,僅通過軟體調節音量。
        # 但仍使用混音器,根據所選埠
        # 將未使用的音頻通路靜音。
        api.alsa.soft-mixer = true
      }
    }
  }
]

參見 獲取用於規則匹配的接口名稱,以確定替換 "alsa_card.name-of-device" 所需的正確值。

也可以指定 "~alsa_card.*",將規則應用到所有音頻設備。

然後重啟 PipeWire,例如運行 systemctl --user restart pipewire。在 alsamixer 中設置主音量,然後以 root 身份執行 alsactl store 保存設置。現在應該可以正常使用音量控制器了。

實時音頻無法工作

如果 pipewire.service 用戶單元的狀態中出現 RTKit error: org.freedesktop.DBus.Error.AccessDenied,說明 PipeWire 守護進程未能獲得實時優先級。參見此問題報告。

外接音效卡重新連接後未激活

檢查 ~/.config/pipewire/media-session.d/default-profile 中是否存在默認配置文件為 "off" 的條目,如有則將其刪除。如果仍無法解決,刪除 ~/.config/pipewire/media-session.d/ 內的所有文件並重啟 pipewire.service 用戶單元。

沒有聲音,或 pactl info 顯示 Failure: Connection refused

這意味著應用程式無法連接到 PipeWire-Pulse 服務。請檢查 pipewire-pulse.service 用戶單元是否正在運行。

如果無法解決問題,請運行 strace -f -o /tmp/pipe.txt pactl info,並將 /tmp/pipe.txt 上傳到 pastebin,以便在 IRC(OFTC 上的 #pipewire)或郵件列表上尋求幫助。

連接新設備時聲音未自動切換

若要自動切換到新連接的設備,請創建以下文件:

/etc/pipewire/pipewire-pulse.conf.d/switch-on-connect.conf (or ~/.config/pipewire/pipewire-pulse.conf.d/switch-on-connect.conf)
pulse.cmd = [
    { cmd = "load-module" args = "module-switch-on-connect" }
]

然後使用 systemctl --user 重啟 pipewire-pulse.service,並檢查 module-switch-on-connect 是否已加載。

連接藍牙設備後沒有聲音

截至 2020 年 12 月 7 日,如果連接藍牙設備後沒有聲音,可能需要切換默認輸出設備,或將音頻流輸入移動到正確的輸出設備。使用 pactl list sinks 列出可用輸出設備,再使用 pactl set-default-sink 將默認輸出切換到藍牙設備。也可以藉助 udev,使用類似這個腳本的方式自動完成。

參見此 Reddit 討論。根據腳本作者的說法,耳機配置文件(HSP)仍可能存在問題。

藍牙

藍牙音頻質量低

如果藍牙播放出現卡頓,請檢查 pipewire.service 用戶單元的狀態,尋找類似以下內容的錯誤:

Feb 17 18:23:01 HOST pipewire[249297]: (bluez_input.18:54:CF:04:00:56.a2dp-sink-60) client too slow! rate:512/48000 pos:370688 status:triggered

如果出現這些錯誤,請使用 pactl list sinks 檢查當前選擇的編解碼器,並嘗試將 bluez5.codec 設置為 sbc aac ldac aptx aptx_hd 中的一種。還可以嘗試 mSBC 支持(可修復 Sony 1000XM3,即 WH-1000XM3 耳機和 WF-1000XM3 真無線耳機的麥克風問題),以及 SBC-XQ 編解碼器。

注意:對於 WH-1000XM3 等耳機,如果在配套應用中將「聲音質量模式」設置為「優先穩定連接」而不是「優先音質」,耳機就不會公布 SBC/SBC-XQ 以外的其他編解碼器。

對於 wireplumber包:

/etc/wireplumber/wireplumber.conf.d/bluez-config.conf (or ~/.config/wireplumber/wireplumber.conf.d/bluez-config.conf)
monitor.bluez.properties = {
  bluez5.enable-sbc-xq = true
  bluez5.enable-msbc = true
  bluez5.codecs = [ sbc sbc_xq ]
}

對於 pipewire-media-session包:

/etc/pipewire/media-session.d/bluez-monitor.conf (or ~/.config/pipewire/media-session.d/bluez-monitor.conf)
...
properties = {
  ...
  bluez5.enable-msbc = true
  bluez5.enable-sbc-xq = true
  bluez5.codecs = [sbc sbc_xq]
...

通過重啟 pipewire.service 用戶單元來重啟 PipeWire,使更改生效。

應用程式

終端提示鈴不響

從 PipeWire 的角度來看,必須加載 x11.bell 模塊。該模塊本應在配置中默認啟用(也可以檢查前面提到的配置文件)。檢查是否安裝了 pipewire-x11-bell包 軟體包。窗口管理器也可能影響終端提示鈴,例如在 xfwm 中需要檢查 xfwm-terminal 的設置,確保已啟用「Audible bell」(可聽提示鈴)。然後重啟 PipeWire 服務:

$ systemctl --user restart pipewire

可以運行以下命令測試終端提示鈴是否正常:

$ echo $'\a'

OBS 等應用無法顯示畫面,即使已經請求選擇窗口或屏幕

如果確信已安裝 xdg-desktop-portal包 以及 xdg-desktop-portal-gtk包 或 xdg-desktop-portal-kde包,請檢查相關守護進程是否正在運行。

如果 OBS 正常工作,應該在 stdout 中看到以下內容:

...
info: [pipewire] desktop selected, setting up screencast
info: [pipewire] created stream 0x5632d7456850
info: [pipewire] playing stream…

對於多顯示器設置,slurp包 軟體包可以幫助捕獲所有屏幕。

使用 FMOD 的遊戲在 PipeWire 下崩潰

一些使用舊版本 FMOD 音頻引擎的遊戲(例如 永恆之柱)會調用 pulseaudio --check,並在缺少 PulseAudio 可執行文件時崩潰。一種規避方法是創建從 /bin/pulseaudio 指向 /bin/true 的符號連結。[4]

# ln -s /bin/true /bin/pulseaudio

請注意,如果以後要重新安裝 PulseAudio,需要先刪除該符號連結。

Discord 沒有通知聲音

這可能是由於 min.quantum 太低;可以嘗試將其設置為大於 700 的值。可在 pipewire-pulse.conf 的 pulse.rules 部分添加如下規則,僅覆蓋 Discord 的相關設置。

/etc/pipewire/pipewire-pulse.conf (or ~/.config/pipewire/pipewire-pulse.conf)
...
pulse.rules = [
  ...
    {
        # 修復 Discord 通知聲音
        matches = [ { application.process.binary = "Discord" } ]
        actions = {
            update-props = {
                pulse.min.quantum      = 1024/48000     # 21ms
            }
        }
    }
...

多個音頻流開始播放時聲音中斷

通常可以通過查看 pipewire-pulse.service 用戶單元的日誌來診斷此問題,其中可能出現類似以下的記錄:

pipewire-pulse[21740]: pulse-server 0x56009b9d5de0: [Nightly] UNDERFLOW channel:0 offset:370676 underrun:940

根據 PipeWire 官方故障排除指南,對於 wireplumber包,可使用以下配置解決:

/etc/wireplumber/wireplumber.conf.d/alsa-config.conf (or ~/.config/wireplumber/wireplumber.conf.d/alsa-config.conf)
monitor.alsa.rules = [
  {
    matches = [
      {
        node.name = "~alsa_output.*"
      }
    ]
    actions = {
      update-props = {
        api.alsa.period-size   = 1024
        api.alsa.headroom      = 8192
      }
    }
  }
]

對於 pipewire-media-session包:

/etc/pipewire/media-session.d/alsa-monitor.conf (or ~/.config/pipewire/media-session.d/alsa-monitor.conf
api.alsa.headroom = 1024

如果音頻卡頓是由內核頁面鎖定或調度不及時造成的,請參見 遊戲#調整內核參數以實現響應時間一致性。

其他問題

自動切換功能無法工作

如果自動切換無法正常工作,問題可能出在 WirePlumber 的狀態數據上。按照此評論的建議,可以刪除 WirePlumber 的本地狀態並重啟守護進程,查看是否有所改善:

$ rm -r ~/.local/state/wireplumber/

然後重啟 wireplumber.service 用戶單元。

待機恢復後出現音頻問題

如果計算機從睡眠中喚醒後沒有聲音,或聲音異常失真,可能是音效卡未能正確恢復。臨時解決方法是重啟 PipeWire 和 WirePlumber:

# systemctl --user restart pipewire pipewire-pulse wireplumber

增加 RLIMIT_MEMLOCK

Dec 13 11:11:11 HOST pipewire-pulse[99999]: Failed to mlock memory 0x7f4f659d8000 32832: This is not a problem but for best performance, consider increasing RLIMIT_MEMLOCK

安裝 realtime-privileges包,並將當前用戶加入 realtime 用戶組。

另一種方法是將 memlock 限制從 64 kB 提升到 128 kB,這似乎足以修復問題。如果通過 systemd/用戶 運行 pipewire-pulse,請添加:

username	soft	memlock	64
username	hard	memlock	128

將這些內容寫入 /etc/security/limits.d/username.conf。

開始播放時出現明顯延遲或可聽見的爆音

這是因為節點在空閒時被掛起。

對於 wireplumber包,創建一個新的配置文件覆蓋默認設置:

/etc/wireplumber/wireplumber.conf.d/disable-suspension.conf (or ~/.config/wireplumber/wireplumber.conf.d/disable-suspension.conf)
monitor.alsa.rules = [
  {
    matches = [
      {
        # 匹配所有輸入源
        node.name = "~alsa_input.*"
      },
      {
        # 匹配所有輸出設備
        node.name = "~alsa_output.*"
      }
    ]
    actions = {
      update-props = {
        session.suspend-timeout-seconds = 0
      }
    }
  }
]
# 藍牙設備
monitor.bluez.rules = [
  {
    matches = [
      {
        # 匹配所有輸入源
        node.name = "~bluez_input.*"
      },
      {
        # 匹配所有輸出設備
        node.name = "~bluez_output.*"
      }
    ]
    actions = {
      update-props = {
        session.suspend-timeout-seconds = 0
      }
    }
  }
]

重啟 pipewire.service 和 wireplumber.service 使更改生效。

除了完全禁用掛起,也可以更改超時值,指定音頻源在多少秒無活動後才掛起。

某些設備自行檢測靜音並進入休眠。對於這些設備,僅禁用節點掛起仍無效。可以通過添加少量噪聲來規避靜音檢測,使輸出始終不會完全靜音:

.../disable-suspension.conf
...
    session.suspend-timeout-seconds = 0,  # 0 表示禁用掛起
    dither.method = "wannamaker3", # 添加指定形狀的抖動噪聲
    dither.noise = 2, # 增加額外的噪聲位數
...

可能需要調整 dither.noise 和 dither.method 參數,使噪聲既足夠安靜,又足以防止設備檢測到靜音。參見 PipeWire 文檔。

對於 pipewire-media-session包:

根據延遲發生的位置,編輯 /etc/pipewire/media-session.d/*-monitor.conf,將 session.suspend-timeout-seconds 屬性改為 0 以禁用掛起,或者嘗試其他數值,觀察效果。

也可以在 /etc/pipewire/media-session.d/media-session.conf 中注釋掉 suspend-node 這一行。

重啟 pipewire.service 與 pipewire-pulse.service 以應用更改,或直接重啟計算機。

首次嘗試播放後才有聲音

如果 PipeWire 通過套接字激活啟動,部分原生 PipeWire 應用可能會在 WirePlumber 完成節點配置之前就嘗試播放音頻,從而出現錯誤,例如:

$ mpv -v /path/to/file
[ao/pipewire] PipeWire does not have any audio sinks, skipping
[ao] Failed to initialize audio driver 'pipewire'
$ journalctl --user -u mpd.service
output: Failed to play on "PipeWire" (pipewire): no target node available
exception: Failed to open audio output

規避方法是啟用 pipewire.service 用戶單元。