PipeWire
PipeWire 是一个新的底层多媒体框架。 它旨在以最低的延迟为音频和视频提供录制和播放功能,并支持基于 PulseAudio、JACK、ALSA 和 GStreamer 的应用程序。
基于该框架的守护进程可以配置为音频服务器(具有 PulseAudio 和 JACK 特性)和视频录制服务器。
PipeWire 还支持像 Flatpak 这样的容器,不依赖于 audio
和 video
用户组。 相反,它采用了类似于 Polkit的安全模式,向 Flatpak 或 Wayland 请求许可以录制屏幕或音频。
安装[编辑 | 编辑源代码]
可以从官方软件库安装 pipewire包 程序。 也有lib32-pipewire包 的32位库对于 multilib 进行支持
Pipewire 使用 systemd/用户管理服务器并自动激活socket。
可以选择安装 pipewire-docs包 来查看文档。
Pipewire 可以作为其他音频服务器的直接替代品。参见 #Audio 详细信息。
会话(Session)管理[编辑 | 编辑源代码]
像 JACK一样,PipeWire 内部没有实现连接逻辑。 监视新 streams 并将其连接到适当的输出设备或应用程序的负担留给称为会话管理器的外部组件。
目前,唯一推荐的会话管理器是:
- WirePlumber — 一个当前比较推荐的更强大的管理器。它基于模块化设计,使用 Lua 插件实现实际的管理功能。
以下会话管理器已被弃用,取而代之的是 WirePlumber:
- PipeWire Media Session — 一个非常简单的会话管理器,可以满足一些基本的桌面用例。它主要是为了测试和作为构建新会话管理器的示例而实现的。
在安装 PipeWire 时,您将被要求在其中之一进行选择。只需安装适当的软件包即可在会话管理器之间切换,这将与其他选项发生冲突并替换其他选项。
GUI图形界面[编辑 | 编辑源代码]
- Helvum — 基于GTK patchbay for PipeWire, 灵感来自JACK工具catia.
- qpwgraph — 基于Qt的Graph/Patchbay for PipeWire,灵感来自JACK工具 QjackCtl.
配置[编辑 | 编辑源代码]
PipeWire 软件包在 /usr/share/pipewire
中提供了一组初始配置文件。不应直接编辑这些文件,因为包更新将覆盖所做的更改。要配置 PipeWire,可以将文件从 /usr/share/pipewire
复制到备用系统配置目录位置 /etc/pipewire
或用户目录 ~/.config/pipewire
。具有较高优先级的目录中的同名文件会使类似文件被忽略。 [1]
Profiles[编辑 | 编辑源代码]
Pipewire 带来了一个PulseAudio 配置以外的自定义的 "Pro Audio" 配置文件, 可通过 pavucontrol进行选择。其效果如下所述:https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#what-is-the-pro-audio-profile
用法[编辑 | 编辑源代码]
声音[编辑 | 编辑源代码]
PipeWire 可以用作音频服务器,类似于 PulseAudio 和 JACK,它旨在通过为JACK客户端提供PulseAudio兼容的服务器实现和ABI兼容库来取代PulseAudio和JACK。有关详细信息,请参阅博客文章PipeWire Late Summer Update 2020。
首先,安装 pipewire-audio包。然后根据音频客户端的类型,可能还需要执行一些额外的步骤。
ALSA 客户端[编辑 | 编辑源代码]
安装 pipewire-alsa包 (如果安装了pulseaudio-alsa包需要删掉它) 以使用 ALSA API 通过 PipeWire 路由所有应用程序。
PulseAudio 客户端[编辑 | 编辑源代码]
安装 pipewire-pulse包。它将代替 pulseaudio包 和 pulseaudio-bluetooth包。重新启动、重新登录或 start pipewire-pulse.service
user unit 以查看效果。
通常,不需要进一步的操作,应用应作为用户服务自动启用pipewire-pulse.socket
。要检查替换是否正常工作,请运行以下命令并查看输出:
$ pactl info
... Server Name: PulseAudio (on PipeWire 0.3.32) ...
对于进一步的配置(例如关于模块),请查看官方上游 Wiki Migration from PulseAudio 和 Configuration of Pipewire-Pulse。
JACK 客户端[编辑 | 编辑源代码]
安装 pipewire-jack包 以获取 JACK 支持。还有 lib32-pipewire-jack包 用于 multilib 支持。
pw-jack(1) 可以用来启动 JACK 客户端, 但从技术上讲它不是必需的, 因为它只用作 PIPEWIRE_REMOTE
、PIPEWIRE_DEBUG
和 PIPEWIRE_LATENCY
环境变量的包装器。
可以通过设置 缓冲区大小/采样率 的商(等于以秒为单位的块延迟)来请求自定义缓冲区大小:
PIPEWIRE_LATENCY="128/48000" application
蓝牙设备[编辑 | 编辑源代码]
如果安装了 pipewire-pulse包 软件包,PipeWire 将自动处理蓝牙音频设备。 该软件包包含 /etc/pipewire/media-session.d/with-pulseaudio
文件,该文件的存在会提示媒体会话守护程序启用 bluez5
模块
自动化 profile 切换[编辑 | 编辑源代码]
pipewire-media-session包 和 WirePlumber 都可以在检测到输入流时自动在 HSP/HFP 和 A2DP 配置文件之间切换。
WirePlumber 默认启用了配置文件自动切换。每当检测到输入流时,它可以自动在 HSP/HFP 和 A2DP 配置文件之间切换。可以使用以下命令禁用它:
/etc/wireplumber/policy.lua.d/11-bluetooth-policy.lua (or ~/.config/wireplumber/policy.lua.d/11-bluetooth-policy.lua)
bluetooth_policy.policy["media-role.use-headset-profile"] = false
pipewire-media-session包 默认禁用,可以设置 bluez5.autoswitch-profile
属性为 true
以启用他:
/etc/pipewire/media-session.d/bluez-monitor.conf (or ~/.config/pipewire/media-session.d/bluez-monitor.conf)
... rules = [ { ... actions = { update-props = { ... bluez5.autoswitch-profile = true ...
用于命令行的 PipeWire 补丁集[编辑 | 编辑源代码]
qpwgraph包 可用于可视化和创建连接,以及保存和加载补丁集。 对于非 GUI 需求,以下是用于保存线集、加载线集和解除所有连接的 bash 脚本。 要保存和加载,请使用命令行参数作为文件名。
pw-savewires
#!/bin/bash if [[ "$#" -ne 1 ]]; then echo echo 'usage: pw-savewires filename' echo exit 0 fi rm $1 &> /dev/null while IFS= read -r line; do link_on=`echo $line | cut -f 4 -d '"'` link_op=`echo $line | cut -f 6 -d '"'` link_in=`echo $line | cut -f 8 -d '"'` link_ip=`echo $line | cut -f 10 -d '"'` echo "Saving: " "'"$link_on:$link_op"','"$link_in:$link_ip"'" echo "'"$link_on:$link_op"','"$link_in:$link_ip"'" >> $1 done < <(pw-cli dump short link)
pw-loadwires
#!/bin/python import sys import csv import os if len(sys.argv) < 2: print('\n usage: pw-loadwires filename\n') quit() with open(sys.argv[1], newline='') as csvfile: pwwreader = csv.reader(csvfile, delimiter=',', quotechar='"') for row in pwwreader: print('Loading: ' + row[0] + ' --> ' + row[1]) process = os.popen('pw-link ' + row[0] + ' ' + row[1])
pw-dewire
#!/bin/bash while read -r line; do echo 'Dewiring: ' $line '...' pw-link -d $line done < <(pw-cli dump short link {{!}} grep -Eo '^[0-9]+')
与网络上的计算机共享音频设备[编辑 | 编辑源代码]
虽然 PipeWire 本身不是网络透明的,但其pulse实现支持网络串流。在网络上的计算机之间共享音频的一种简单方法是使用 Avahi 守护程序进行发现。要启用此功能,请安装 pipewire-zeroconf包 软件包。
确保所有要共享声音的计算机上的 avahi-daemon.service
正在运行(如果使用 firewall,则要保证 UDP 端口 5353
已打开)。
要共享本地音频设备,在主机上加载适当的模块(确保使用本地 IP 地址):
$ pactl load-module module-native-protocol-tcp listen=192.168.1.10 $ pactl load-module module-zeroconf-publish
然后在客户端上加载发现模块:
$ pactl load-module module-zeroconf-discover
还可以通过创建专用配置文件自动加载模块:
/etc/pipewire/pipewire-pulse.conf.d/50-network-party.conf
context.exec = [ { path = "pactl" args = "load-module module-native-protocol-tcp" } { path = "pactl" args = "load-module module-zeroconf-discover" } { path = "pactl" args = "load-module module-zeroconf-publish" } ]
将音频串流到 AirPlay 接收器[编辑 | 编辑源代码]
可以将音频串流到冒充 AirPlay 接收器的设备。 要启用此功能,请加载 RAOP Discover 模块:
$ pactl load-module module-raop-discover
还可以通过创建专用配置文件自动加载此模块:
/etc/pipewire/pipewire.conf.d/raop-discover.conf (or ~/.config/pipewire/pipewire.conf.d/raop-discover.conf)
context.modules = [ { name = libpipewire-module-raop-discover args = { } } ]
某些扬声器的 AirPlay 实现(例如 Sonos AirPlay 2 扬声器)可能需要为源设备上的传入 UDP 流量打开端口 6001 和 6002。
在本地 JACK 上运行 PipeWire[编辑 | 编辑源代码]
如果需要,PipeWire 也可以作为 JACK 客户端在本机 JACK 守护程序之上运行。
请参阅 JACK 和 PipeWire (PipeWire wiki) 和 -JACK#jack-bridge JACK 桥(PipeWire wiki) 了解更多信息和附加配置(例如可用通道)。
要使用它,请安装 pipewire-jack-client包 并启动 JACK。Pipewire 应该会被自动桥接。
它可以在启动 jack 之前像 PulseAudio 模块一样手动加载(在pactl(1)解释):pactl load-module module-jackdbus-detect
。
使用 ALSA dmix 设备作为 PipeWire 接收器[编辑 | 编辑源代码]
可以通过 ALSA dmix devices 将 PipeWire 服务器(或每个用户多个)输出到 ALSA。这允许您使用 ALSA 作为主要音频输出系统,同时能够使用非 ALSA 设备,例如蓝牙耳机。
ALSA dmix 设置[编辑 | 编辑源代码]
假设您有两张卡:PCH
和 HDMI
:
/proc/asound/cards
0 [PCH ]: HDA-Intel - HDA Intel PCH HDA Intel PCH at 0xdff40000 irq 146 1 [HDMI ]: HDA-Intel - HDA ATI HDMI HDA ATI HDMI at 0xdfe60000 irq 147
你的 PCM 看起来长这样:
/proc/asound/pcm
00-00: ALC1220 Analog : ALC1220 Analog : playback 1 : capture 1 00-02: ALC1220 Alt Analog : ALC1220 Alt Analog : capture 1 01-03: HDMI 0 : HDMI 0 : playback 1 01-07: HDMI 1 : HDMI 1 : playback 1 01-08: HDMI 2 : HDMI 2 : playback 1 01-09: HDMI 3 : HDMI 3 : playback 1 01-10: HDMI 4 : HDMI 4 : playback 1 01-11: HDMI 5 : HDMI 5 : playback 1
假设您的 ALSA 配置如下所示:
/etc/asound.conf
ctl.!default { type hw card PCH } pcm.!default { type plug slave.pcm "dmix:PCH,0" } pcm.dhdmi { type plug slave.pcm "dmix:HDMI,9" }
在此特定示例中,dmix 设备为 dmix:PCH,0
和 dmix:HDMI,9
。
PipeWire dmix 设置[编辑 | 编辑源代码]
首先,通过注释掉 alsa_monitor.enable()
来阻止 wireplumber
监控和添加硬件 ALSA 设备:
/etc/wireplumber/main.lua.d/90-enable-all.lua (or ~/.config/wireplumber/main.lua.d/90-enable-all.lua)
... -- Load devices -- alsa_monitor.enable() v4l2_monitor.enable() libcamera_monitor.enable() ...
现在,配置 pipewire
以使用 dmix 设备。 默认配置文件(/usr/share/pipewire/pipewire.conf
)包含一个注释掉了的示例,您可以将其用作模板。
将您自己的元素添加到 context.objects
数组中:
/etc/pipewire/pipewire.conf.d/alsa-dmix.conf (or ~/.config/pipewire/pipewire.conf.d/alsa-dmix.conf)
context.objects = [ # We do not start with dmix, but with an input device. # Do not forget to add an input device. # On a friend's Laptop, I saw Zoom having a nervous # breakdown and endlessly crying because no input device # was configured! You have been warned. { factory = adapter args = { factory.name = api.alsa.pcm.source node.name = "alsa-mic-internal" # name of pulse device (mpv) node.description = "Mic Internal" # name of pulse device (pavucontrol) media.class = "Audio/Source" api.alsa.path = "hw:PCH,0" } } # Okay, now we add our dmix PCMs { factory = adapter args = { factory.name = api.alsa.pcm.sink # sink for dmix node.name = "alsa-dmix-internal" # name of pulse device (mpv) node.description = "PCM Internal" # name of pulse device (pavucontrol) media.class = "Audio/Sink" # Sink for dmix api.alsa.path = "dmix:PCH,0" } } { factory = adapter args = { factory.name = api.alsa.pcm.sink # sink for dmix node.name = "alsa-dmix-hdmi" # name of pulse device (mpv) node.description = "PCM HDMI" # name of pulse device (pavucontrol) media.class = "Audio/Sink" # Sink for dmix # remember this is a non-default dmix from /etc/asound.conf api.alsa.path = "dmix:HDMI,9" } } ]
作为用户(非 root),检查 wpctl status
的输出,并使用wpctl set-default ID
根据您的喜好设置默认输入(源)和输出(接收器)设备。ID
是接收器/源名称之前的数字。
现在,您可以全面测试您的配置。
在设备配置之间切换[编辑 | 编辑源代码]
某些硬件音频设备(例如 snd_hda_intel
)的功能会有所不同,具体取决于设备运行的配置文件。对于 snd_hda_intel
,HDMI 和模拟输出有单独的配置文件。
使用 WirePlumber 切换到 HDMI:
$ wpctl set-profile <device-ID> 3 $ wpctl status
... ├─ Sinks: │ * 53. Built-in Audio Digital Stereo (HDMI) [vol: 1.00] ...
使用 WirePlumber 切换到模拟:
$ wpctl set-profile <device-ID> 1 $ wpctl status
... ├─ Sinks: │ * 51. Built-in Audio Analog Stereo [vol: 0.60] ...
WebRTC 屏幕共享[编辑 | 编辑源代码]
大多数应用程序过去依赖 X11 来捕获桌面(或单个应用程序),例如在网络浏览器中使用 WebRTC 时(例如在 Google Hangouts 上)。在 Wayland 上,出于安全原因,共享机制的处理方式有所不同。PipeWire 可以通过细粒度的访问控制在 Wayland 下共享内容。
这需要 xdg-desktop-portal包 及其后端之一被安装。可用的后端有:
- xdg-desktop-portal-gnome包 对应 GNOME。
- xdg-desktop-portal-kde包 对应 KDE。
- xdg-desktop-portal-wlr包 对应 基于 wlroots 的 Wayland 合成器 (例如 Sway, dwl)
Firefox (84+) 默认支持此方法,而在 Chromium (73+) 上,需要通过设置启用 WebRTC PipeWire 支持 URL chrome://flags/#enable-webrtc-pipewire-capturer
处的相应(实验)标志。
obs-studio包 (27+) 通过使用新的 PipeWire 捕获源支持此方法。
请注意,唯一支持的功能是共享整个桌面,而不是特定的应用程序/窗口 -individual-windows[4]。
xdg-desktop-portal-wlr[编辑 | 编辑源代码]
为了使 xdg-desktop-portal-wlr
正常工作,必须在 [[Systemd/用户] 中设置 XDG_CURRENT_DESKTOP
和 WAYLAND_DISPLAY
环境变量#环境变量|systemd用户会话]]。XDG_CURRENT_DESKTOP
必须设置为您的合成器的名称,例如 XDG_CURRENT_DESKTOP=sway
。WAYLAND_DISPLAY
由合成器自动设置。将这些环境变量引入 systemd 用户会话的推荐方法是在启动合成器后运行 systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
,例如使用合成器配置文件。有关更多详细信息,请参阅 [5] 和 [6]。
xdg-desktop-portal-wlr
共享监视器,请安装 slurp包 并添加以下配置(请参阅 xdg-desktop-portal-wlr(5) § 屏幕播放选项):
~/.config/xdg-desktop-portal-wlr/config
chooser_type = simple chooser_cmd = slurp -f %o -ro
当请求共享屏幕时,slurp
会向您显示十字光标,您需要单击要共享的屏幕。选择后,xdg-desktop-portal-wlr
将允许共享该屏幕。
视频[编辑 | 编辑源代码]
尽管该软件尚未准备好投入生产,但可以安全地使用。大多数依赖 GStreamer 处理视频流的应用程序应该使用 PipeWire GStreamer 插件开箱即用,请参阅 GStreamer#PipeWire。因此,像 cheese包 这样的应用程序已经能够使用它来共享视频输入。
使用 pipewire-v4l2包,还应该可以使用 pw-v4l2
脚本来预加载库 (/lib/pipewire-0.3/v4l2/libpw-v4l2 .so
)拦截 v4l2 调用并通过管道路由视频。
音频后期处理[编辑 | 编辑源代码]
Pipewire 模块过滤链(module-filter-chain)[编辑 | 编辑源代码]
Pipewire 有一个名为过滤链(filter-chain)的内部模块,可以创建节点来处理音频输入和输出。有关均衡、虚拟环绕声、LADSPA 插件和通道混合的示例,请参阅 /usr/share/pipewire/filter-chain/
。
全系统参数均衡[编辑 | 编辑源代码]
将配置文件复制到您的 .config
文件夹:
$ mkdir -p ~/.config/pipewire/pipewire.conf.d $ cp /usr/share/pipewire/filter-chain/sink-eq6.conf ~/.config/pipewire/pipewire.conf.d/
然后编辑 sink-eq6.conf
以合并所需的参数。对于耳机,可以从 Oratory1990 的数据库获取,或者,如果没有列出,则参考 AutoEQ 项目。
如果您需要前置放大器,请修改 eq_band_1
以在频率 0Hz 处应用具有负增益的 bq_highshelf
滤波器(支持 -120 至 +20dB 的增益):
label = bq_highshelf control = { "Freq" = 0 "Q" = 1.0 "Gain" = -7.5 }
对于超过 6 个频段,请向 nodes
列表和相应的 links
添加更多条目,将一个过滤器“:Out”连接到下一个过滤器“:In”,例如增加到 11频段(前置放大器 + 10):
{ output = "eq_band_6:Out" input = "eq_band_7:In" } { output = "eq_band_7:Out" input = "eq_band_8:In" } { output = "eq_band_8:Out" input = "eq_band_9:In" } { output = "eq_band_9:Out" input = "eq_band_10:In" } { output = "eq_band_10:Out" input = "eq_band_11:In" }
重新启动Pipewire,选择“Equalizer Sink”作为默认声音输出设备; 这应该适用于所有应用程序。
EasyEffects[编辑 | 编辑源代码]
EasyEffects(以前的 PulseEffects)是一个 GTK 实用程序,它为各个应用程序输出流和麦克风输入流提供大量音频效果和滤波器。值得注意的效果包括输入/输出均衡器、输出响度均衡和低音增强、输入嘶声消除器和降噪插件。有关效果的完整列表,请参阅 GitHub 页面。
为了使用 EasyEffects,请安装 easyeffects包。有关预设配置的集合,请参阅社区预设。对于算法生成的耳机 EQ 预设的集合,请参阅 AutoEq。
NoiseTorch[编辑 | 编辑源代码]
NoiseTorch 是一种噪声抑制的替代方法,与 noisetorchAUR 打包在一起。另外还有-git版本noisetorch-gitAUR。
启动后,可以为所选麦克风加载模块。可以调整语音激活阈值,应将其设置为最高级别,而不是过滤掉任何实际语音。
您可以使用 systemd 自动启动音频处理,请参阅 [7]。请注意,如果从 AUR 安装,noisetorch 二进制路径会有所不同。
语音噪声抑制[编辑 | 编辑源代码]
安装 noise-suppression-for-voice包 并进行下列操作之一:
- 在
context.exec
添加以下内容:
/etc/pipewire/pipewire.conf (or ~/.config/pipewire/pipewire.conf)
... context.exec = [ ... { path = "/usr/bin/pipewire" args = "-c /usr/share/pipewire/filter-chain/source-rnnoise.conf" } ...
然后将降噪后的音频源作为音频的默认选项。您可能需要先重启应用才能使用新的音频源。
JamesDSP[编辑 | 编辑源代码]
JamesDSP for Linux (jamesdspAUR) 为 PipeWire 和 PulseAudio 提供开源的音效实现。JamesDSP 使用自己的效果引擎,不依赖 LADSPA 或是 Calf 之类的东西。起初它被用于安卓设备的音效处理。
LADSPA, LV2 和 VST 插件[编辑 | 编辑源代码]
您可以创建将 PulseAudio 连接到 Carla 音频插件的输入/输出目标位置。
如果您想在所有可用的 LADSPA、LV2 和 VST 中选择的话,可以使用自定义的 Pulseaudio null sink 和 Carla Jack 来应用这些插件。安装 pipewire-pulse包、pipewire-jack包 和 carla包。首先,创建一个名为 default_null_sink
的 PulseAudio null sink。 .
pactl load-module module-null-sink object.linger=1 media.class=Audio/Sink sink_name=default_null_sink channel_map=FL,FR
从 Pipewire 启动 Carla:pw-jack carla-rack
。在 Rack(机架) 页面添加您想使用的插件,确保它们的类型都是 stereo(立体声)。您可以改变插件间的顺序,处理顺序由上至下(最上面的会最先接收到音频流),就跟 EasyEffects 一样。随后,在 Patchbay(跳线槽) 页面将 default_null_sink
的左右监听(L/R monitor)连接到 Carla 的输入,然后将 Carla 的输出连接到回放设备(音响、耳机、HDMI...)。将配置文件保存到一个本地位置,比如 ~/Documents/carla_sink_effects.carxp
。
您可以在多媒体应用发声的时候测试这些效果,比如用 Firefox 看视频。有两种测试方式。第一种:在 Carla 的 Patchbay,断开 Firefox 的所有连线,然后把它的左右声道输出连接到 default_null_sink
的 playback。第二种:使用 pavucontrol包 找到 Firefox 的音频流,然后将其重定向到 default_null_sink
(这应该会记住连接方式,在下次启动的时候自动重定向)。
若想在启动时应用这些设置,创建两个 systemd 用户服务:
~/.config/systemd/user/jack-carla-rack.service
[Unit] Description=Load Carla Rack JACK host [Service] PassEnvironment="PIPEWIRE_LINK_PASSIVE=true" Type=exec ExecStart=/usr/bin/pw-jack carla-rack -n [Install] WantedBy=default.target
~/.config/systemd/user/pulseaudio-null-sink@.service
[Unit] Description=Load %i Pulseaudio null sink Before=jack-carla-rack.service After=pipewire-pulse.service [Service] Type=oneshot ExecStart=/usr/bin/pactl load-module module-null-sink object.linger=1 media.class=Audio/Sink sink_name=%i channel_map=FL,FR ExecStop=/usr/bin/pactl unload-module module-null-sink RemainAfterExit=yes [Install] WantedBy=default.target
然后覆盖 jack-carla-rack 服务,并在 Environment 部分写明 Carla 配置的完整路径。
~/.config/systemd/user/jack-carla-rack.service.d/override.conf
[Service] Environment="CARLA_CONFIG_FILE=/home/username/Documents/carla_sink_effects.carxp" ExecStart= ExecStart=/usr/bin/pw-jack carla-rack -n $CARLA_CONFIG_FILE
最后,启用 pulseaudio-null-sink@default_null_sink.service
和 jack-carla-rack.service
用户单元。
注意,如果你将 default_null_sink
设置为了系统默认设备,所有的应用声音都会被重定向至它,并且音量键也会改变它的音量而不是回放设备的。如果想控制回放设备的音量,需要把回放设备设成默认设备,然后将所需应用在 pavucontrol 里重定向到 default_null_sink
(PipeWire兼容层应该会记住应用的连接关系)。
故障排除[编辑 | 编辑源代码]
音频[编辑 | 编辑源代码]
PipeWire 检测不到麦克风[编辑 | 编辑源代码]
PipeWire 的 alsa-monitor
模块默认使用 alsa-card-profiles包 来检测设备。如果在您的设备上没有效果,可以试着关闭 api.alsa.use-acp
,或是启用 api.alsa.use-ucm
。
如果使用的是 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包:
/etc/wireplumber/main.lua.d/50-alsa-config.lua (or ~/.config/wireplumber/main.lua.d/50-alsa-config.lua)
... alsa_monitor.rules = { { ... apply_properties = { -- Use ALSA-Card-Profile devices. They use UCM or the profile -- configuration to configure the device and mixer settings. -- ["api.alsa.use-acp"] = true, -- Use UCM instead of profile when available. Can be -- disabled to skip trying to use the UCM profile. ["api.alsa.use-ucm"] = true, ...
然后重启 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
在这个 issue 中提到的另一种解决方案是手动添加麦克风。首先,确保麦克风能被 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 # record from the mic $ aplay test-mic.wav # play it
如果 arecode 测试麦克风工作正常但是却没被 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 = "Undetected Microphone" media.class = "Audio/Source" api.alsa.path = "hw:card_number,device_number" } } ]
重启 PipeWire 来重载配置。
连接到新设备时声音输出不会自动切换[编辑 | 编辑源代码]
若想自动切换到新连接的设备,创建以下文件:
/etc/pipewire/pipewire-pulse.conf.d/switch-on-connect.conf (or ~/.config/pipewire/pipewire-pulse.conf.d/switch-on-connect.conf)
# override for pipewire-pulse.conf file pulse.cmd = [ { cmd = "load-module" args = "module-always-sink" flags = [ ] } { cmd = "load-module" args = "module-switch-on-connect" } ]
声音输出不会自动切换到蓝牙耳机[编辑 | 编辑源代码]
运行 pactl load-module module-switch-on-connect
,同时配置您的桌面环境在登录时自动运行这个命令。你可能会需要执行 wpctl set-default <id>
。<id>
可以在 wpctl status
的输出中找到。具体请参见wireplumber issue #89。
连接到蓝牙设备后没有声音[编辑 | 编辑源代码]
截至 2020-12-07,如果连接上蓝牙设备却没有声音,您可能需要切换默认输出设备(sink)与/或是将 sink 输入移动到正确的 sink 位置。使用 pactl list sinks
列出所有可用的 sink 并通过 pactl set-default-sink
将默认 sink 切换为蓝牙设备。这可以使用类似这样的脚本通过 udev 自动化。
参见这个 Reddit 讨论串关于这一问题的探讨。根据脚本作者所言,耳机配置(the headset profile,HSP)可能仍有问题。
音量过低[编辑 | 编辑源代码]
在将 PulseAudio 换成 Pipewire 后,声音可能一开始正常,但一重启就变得超级小。
打开 alsamixer
,使用 F6
选择正确的声卡并且确保 ALSA 音量为 100%。alsactl
会在重启后保持设置。
提升 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 从 64kB 提升至 128kB 似乎足以解决问题。如果你是在 systemd/User 下使用 pipewire-pulse
,向 /etc/security/limits.d/username.conf
添加:
username soft memlock 64 username hard memlock 128
修改默认采样率[编辑 | 编辑源代码]
默认 PipeWire 使用 48kHz 的全局采样率。如果您想更改此值(比如您有个支持更高采样率的 DAC),则可以设置一个更高的默认值:
/etc/pipewire/pipewire.conf (or ~/.config/pipewire/pipewire.conf)
... context.properties = { ... default.clock.rate = sample_rate ...
修改允许的采样率[编辑 | 编辑源代码]
只要 DAC 支持,PipeWire 可以动态更改采样率。所选的采样率会跟随当前正在播放的音频流。
/etc/pipewire/pipewire.conf (or ~/.config/pipewire/pipewire.conf)
... context.properties = { ... default.clock.allowed-rates = [ sample_rate_1 sample_rate_2 sample_rate_3 ... ] ...
举个例子: [ 44100 48000 88200 96000 ]
.
据开发者所言,“PipeWire 支持至多 16 种不同的采样率,并且会在允许的时候进行切换”。也就是说,在受支持的设备按照以上内容配置不会发生重采样。在 PipeWire 0.3.61 之后,最多可以配置 32 种不同的采样率。
请参照您 DAC 的硬件手册来查看受支持的采样率。内核驱动编码器支持的采样率可以通过以下命令查看:
$ grep -E 'Codec|Audio Output|rates' /proc/asound/card*/codec#*
要想查看当前某声卡配置的采样率,请运行:
$ 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
同样会显示每张声卡与每条音频流的采样率。
音质 (重采样质量)[编辑 | 编辑源代码]
如果之前使用 PulseAudio 时用了 resample-method = speex-float-10
或是 soxr-vhq
,那么您可能会想将 /etc/pipewire/client.conf
和 /etc/pipewire/pipewire-pulse.conf
两个配置文件中 stream.properties
部分的 resample.quality = 4
取消注释并修改成 10
或是最大值 15
(如果配置文件不存在请从 /usr/share/pipewire/
复制过来)。不要忘记重启 pipewire.service
和 pipewire-pulse.socket
这两个用户单元(如果想要应用配置千万不能把后者忘了)。
在 10
与 15
之间音质差距很小,但是 CPU 负载会差两到三倍。同时,4
、10
与 15
对延迟影响的差距还有待探索。resample.quality = 15
在 Ryzen 2600 和 44100→48000 Hz 的条件下会让 pipewire
或是 pipewire-pulse
产生 4.0% 的单核负载。
您可以在 https://src.infinitewave.ca/ 比较重采样器(不要关注任何超过 18KHz,超过 120dB 的内容)。speex 被列为 "Xiph.org Speex"。
PipeWire 使用它自己的被称为 Spa 的重采样算法。与 SoX 的 sox
和 Speex 的 speexenc
一样,PipeWire 同样有这个重采样器的单独版本 spa-resample
。使用方法如下:
$ spa-resample -q 15 -f s24 -r 48000 input16bit44100orAnythingElse.wav output24bit48000hz.wav
通过创建自己的 sink 并且使用其他重采样器应该是可能的。或者你也可以使用音乐播放器的插件,比如 Qmmp 就有个 SoX 插件。
外部声卡在重连后不会激活[编辑 | 编辑源代码]
检查 ~/.config/pipewire/media-session.d/default-profile
看看有没有默认配置是 "off" 的条目并将其移除。如果不管用,移除 ~/.config/pipewire/media-session.d/
中的所有文件并重启 pipewire.service
用户单元。
没有声音或 pactl info shows 执行失败:Connection refused[编辑 | 编辑源代码]
这意味着应用无法连接到 PipeWire-Pulse 服务。请确认 /etc/pipewire/pipewire-pulse.conf
存在且非空并重启 pipewire-pulse.service
用户单元。
如果没有修复问题,运行 strace -f -o /tmp/pipe.txt pactl info
并将 /tmp/pipe.txt
上传到 pastebin,之后在 IRC(#pipewire on OFTC) 或邮件列表寻求帮助。
蓝牙音质低[编辑 | 编辑源代码]
如果蓝牙回放卡顿,检查 pipewire.service
的 unit status,看看有没有类似以下的错误:
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.codecs
修改为 sbc aac ldac aptx aptx_hd
其中之一。你也可以尝试 mSBC 支持(修复了 Sony 1000XM3 系列,比如 WH-1000XM3 和 WF-1000XM3 的麦克风)以及 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] ...
在 wireplumber包 下:
/etc/wireplumber/bluetooth.lua.d/51-bluez-config.lua (or ~/.config/wireplumber/bluetooth.lua.d/51-bluez-config.lua)
bluez_monitor.properties = { ["bluez5.enable-sbc-xq"] = true, ["bluez5.enable-msbc"] = true, ["bluez5.codecs"] = "[sbc sbc_xq]", }
重启 pipewire.service
用户单元来使修改生效。
在播放时有可觉察的音频延迟或是爆裂声[编辑 | 编辑源代码]
这是由不活跃时的节点暂停(node suspension)造成的。
在 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
以应用更改,或者你也可以直接重启整个计算机。
在 wireplumber包 下,创建一个新文件来覆盖默认配置:
~/.config/wireplumber/main.lua.d/51-disable-suspension.lua (or /etc/wireplumber/main.lua.d/51-disable-suspension.lua)
table.insert (alsa_monitor.rules, { matches = { { -- Matches all sources. { "node.name", "matches", "alsa_input.*" }, }, { -- Matches all sinks. { "node.name", "matches", "alsa_output.*" }, }, }, apply_properties = { ["session.suspend-timeout-seconds"] = 0, -- 0 disables suspend }, })
对于蓝牙设备,同时使用以下配置(注意不同的文件位置):
~/.config/wireplumber/bluetooth.lua.d/51-disable-suspension.lua (or /etc/wireplumber/bluetooth.lua.d/51-disable-suspension.lua)
-- Note: bluez_monitor, not alsa_monitor table.insert (bluez_monitor.rules, { matches = { { -- Matches all sources. -- Note: bluez_input, not alsa_input { "node.name", "matches", "bluez_input.*" }, }, { -- Matches all sinks. -- Note: bluez_output, not alsa_output { "node.name", "matches", "bluez_output.*" }, }, }, apply_properties = { ["session.suspend-timeout-seconds"] = 0, -- 0 disables suspend }, })
重启 pipewire.service
和 wireplumber.service
以应用更改。
如果不想完全禁用节点暂停(suspension),你也可以将源暂停的超时延迟改为自己想要的值。
多个流同时播放时音频被切断[编辑 | 编辑源代码]
此问题通常可以通过阅读 pipewire-pulse.service
用户单元的 journal 检测出来。您会看到类似以下内容:
pipewire-pulse[21740]: pulse-server 0x56009b9d5de0: [Nightly] UNDERFLOW channel:0 offset:370676 underrun:940
根据官方 PipeWire 除错指南,在 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包 下:
/etc/wireplumber/main.lua.d/50-alsa-config.lua (or ~/.config/wireplumber/main.lua.d/50-alsa-config.lua)
apply_properties = { ["api.alsa.headroom"] = 1024, },
如果您经历了由内核页锁定(page locking)与延迟调度(late scheduling)导致的音频卡顿,请参考游戏#调整内核参数以实现响应时间一致性。
音频失真[编辑 | 编辑源代码]
- 对于麦克风,试着运行
alsamixer
并切换到有问题的声卡,然后使用方向键降低所有 "Mic Boost" 与 "Internal Mic Boost" 选项,For microphones, - 参照#修改默认采样率将采样率降至
44100
(44.1 kHz)。
在待机后出现音频问题[编辑 | 编辑源代码]
如果将机器从睡眠中唤醒后音频出现缺失或是其他状况,重新初始化 ALSA 可能有帮助:
# alsactl init
USB DAC 延迟高 (比如 Schiit DACs)[编辑 | 编辑源代码]
修改采样率可能有助于某些 DAC 的延迟,例如 Schiit Hel 2。[8] 使用 pipewire-media-session 的匹配规则,我们可以为设备设置属性。[9]
将默认的配置文件 /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 # Following value should be doubled until audio does not cut out or other issues stop occurring api.alsa.period-size = 128 ...
alsa_output.name-of-node
中的 node 可以使用 pw-top
获得。
你的 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 ...
在这个例子中是 card 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
是所有格式都支持的采样率。
将音量升至 30% USB DAC 才出声[编辑 | 编辑源代码]
某些 USB DAC 在音量达到一定值前不会有输出 [10]。通常这个值是 25% - 30%,而此时多半声音已经过响,还没法调小。解决方法是忽略硬件混音器的音量控制:将 ["api.alsa.soft-mixer"]
设为 true
。
在wireplumber包 下,你可以使用 table.insert
在 /usr/share/wireplumber/main.lua.d/50-alsa-config.lua
中加入以下配置片段。
~/.config/wireplumber/main.lua.d/51-volume-fix.lua
table.insert (alsa_monitor.rules, { matches = { { -- This matches all cards. { "device.name", "matches", "alsa_card.*" }, }, }, -- Apply properties on the matched object. apply_properties = { -- Do not use the hardware mixer for volume control. It -- will only use software volume. The mixer is still used -- to mute unused paths based on the selected port. ["api.alsa.soft-mixer"] = true, } })
然后重启 pipewire。将 alsamixer
的主音量设定好,随后使用 # alsactl store
保存设置。您现在应该可以正常使用音量调节了。
实时音频不起作用[编辑 | 编辑源代码]
如果 pipewire.service
用户单元的 status 出现了 RTKit error: org.freedesktop.DBus.Error.AccessDenied
,这意味着 pipewire 守护进程的优先级不是实时。对于此问题,参见 [11]。
同时输出到同一声卡的多个 sink[编辑 | 编辑源代码]
复制一份 /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 = Digital Stereo (HDMI) device-strings = hdmi:%f paths-output = hdmi-output-0 channel-map = left,right priority = 9 direction = output [Profile multiple] description = Analog Stereo Duplex + Digital Stereo (HDMI) Output output-mappings = analog-stereo hdmi-stereo input-mappings = analog-stereo
接着,配置 PipeWire 的 media-session,对匹配设备使用新的声卡配置。识别声卡信息可以使用 $ pw-cli dump device
。
/etc/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 } } } ]
Discord 没有提示音[编辑 | 编辑源代码]
这可能是由于 min.quantum 设置得过低,尝试将其修改到 700 以上。您可以为 Discord 专门写一个覆盖用的配置,只需在 pipewire-pulse.conf 的 pulse.rules 部分添加如下规则:
/etc/pipewire/pipewire-pulse.conf (or ~/.config/pipewire/pipewire-pulse.conf)
... pulse.rules = [ ... { # Discord notification sounds fix matches = [ { application.process.binary = "Discord" } ] actions = { update-props = { pulse.min.quantum = 1024/48000 # 21ms } } } ...
FMOD 游戏在 PipeWire 下崩溃[编辑 | 编辑源代码]
某些使用旧版 FMOD 音频引擎的游戏(譬如 Pillars of Eternity)会运行 pulseaudio --check
并且在 PulseAudio 的二进制文件不存在的情形下崩溃。可以通过将 /bin/pulseaudio
链接至 /bin/true
来绕过这个问题。[12]
# ln -s /bin/true /bin/pulseaudio
注意:重新安装 PulseAudio 需要移除此符号链接。
自动切换不起作用[编辑 | 编辑源代码]
自动切换不起作用可能是由于 WirePlumber 状态有问题。这条评论指出可以删除 WirePlumber 的本地状态并重启守护进程看看有没有用:
$ rm -r ~/.local/state/wireplumber/
然后重启 wireplumber.service
用户单元。
从待机状态恢复时失去实时优先级/负载下音频爆裂[编辑 | 编辑源代码]
由于 rtkit 2011 年的一个 bug,待机事件会取消 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
,以及 media session 服务。
在向 RAOP 设备推流时没有声音 (例如 Sonos)[编辑 | 编辑源代码]
使用 Avahi 或 systemd-resolved 设置 mDNS 域名解析。
视频[编辑 | 编辑源代码]
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包 可以用于捕获所有屏幕。
参阅[编辑 | 编辑源代码]
- Wiki——Freedesktop GitLab 上的 PipeWire Wiki
- Pipewire Update Blog Post——一篇 2018 年 1 月的描述当时 PipeWire 状态的博文
- PipeWire Late Summer Update 2020——2020 年 9 月的一篇博文