在 Fedora 35 中,WirePlumber 取代了 pipeline-media-session 作为音频会话管理器。 Linux 上的许多内置声卡上的音频存在一个非常烦人的问题,即在 3 秒内没有播放任何内容后,音频接收器会暂停。 3 秒后恢复播放时,音频会延迟或弹出。我们如何修复此默认行为?
答案1
相关的配置文件是/usr/share/wireplumber/main.lua.d/50-alsa-config.lua
,但不要编辑它的系统版本!
您需要将其复制到/etc/wireplumber/main.lua.d/
(全局配置)或~/.config/wireplumber/main.lua.d/
(用户配置)并进行必要的更改。
最简单的方法是将其复制到全局配置位置,以便它适用于所有用户帐户:
sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua
sudo nano /etc/wireplumber/main.lua.d/50-alsa-config.lua
然后,您需要向下滚动到文件底部的该apply_properties
部分,并在其中添加一行:
["session.suspend-timeout-seconds"] = 0
我做了更多的改变并为我自己的个人硬件定制了它。这是我的配置供参考,但此配置仅对我的确切设备有用。实际上,您只需要上面的行即可禁用自动挂起。将其添加到您自己的默认配置中。不要复制我的配置。我所做的其他更改是无关的。
alsa_monitor.properties = {
["alsa.jack-device"] = true,
["alsa.reserve"] = true,
["alsa.midi.monitoring"] = true
}
alsa_monitor.rules = {
{
matches = {
{
{ "device.name", "matches", "alsa_card.*" }
}
},
apply_properties = {
["api.alsa.use-acp"] = true,
["api.acp.auto-profile"] = false,
["api.acp.auto-port"] = false
}
},
{
matches = {
{
{ "node.name", "matches", "alsa_output.pci-0000_0c_00.4.iec958-ac3-surround-51" }
}
},
apply_properties = {
["api.alsa.period-size"] = 128,
["api.alsa.headroom"] = 2048,
["session.suspend-timeout-seconds"] = 0
}
},
{
matches = {
{
{ "node.name", "matches", "alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-mono" }
}
},
apply_properties = {
["api.alsa.period-size"] = 128
}
}
}
设置该session.suspend-timeout-seconds
属性以0
防止挂起/睡眠行为。它完全禁用了该行为,如 WirePlumber 的源代码中所示。
必须重新启动 WirePlumber 才能使更改生效:
systemctl --user restart wireplumber
答案2
session.suspend-timeout-seconds
在运行没有 WirePlumber 的 PipeWire 且使用 pipeline-media-session 的系统中,通常可以通过将 的底部部分更改为 0 来修复此问题/etc/pipewire/media-session.d/alsa-monitor.conf
。但是,在 Fedora 35 安装中找不到此目录或任何会话监视器配置文件。实际上没有文档显示如何防止接收器在 3 秒内挂起,所以我必须自己解决这个问题。相反,我们必须修改 WirePlumber 脚本目录中的 Lua 脚本。导航至/usr/share/wireplumber/scripts/
并为其创建备份副本suspend-node.lua
。然后使用 sudo 权限在文本编辑器或终端中打开suspend-node.lua
,并注释掉负责接收器超时和挂起接收器的代码块,使文件如下所示:
-- WirePlumber
--
-- Copyright © 2021 Collabora Ltd.
-- @author George Kiagiadakis <[email protected]>
--
-- SPDX-License-Identifier: MIT
om = ObjectManager {
Interest { type = "node",
Constraint { "media.class", "matches", "Audio/*" }
},
Interest { type = "node",
Constraint { "media.class", "matches", "Video/*" }
},
}
sources = {}
om:connect("object-added", function (om, node)
node:connect("state-changed", function (node, old_state, cur_state)
-- Always clear the current source if any
local id = node["bound-id"]
if sources[id] then
sources[id]:destroy()
sources[id] = nil
end
-- -- Add a timeout source if idle for at least 3 seconds
-- if cur_state == "idle" then
-- -- honor "session.suspend-timeout-seconds" if specified
-- local timeout =
-- tonumber(node.properties["session.suspend-timeout-seconds"]) or 3
-- if timeout == 0 then
-- return
-- end
-- -- add idle timeout; multiply by 1000, timeout_add() expects ms
-- sources[id] = Core.timeout_add(timeout * 1000, function()
-- -- Suspend the node
-- Log.info(node, "was idle for a while; suspending ...")
-- node:send_command("Suspend")
-- -- Unref the source
-- sources[id] = nil
-- -- false (== G_SOURCE_REMOVE) destroys the source so that this
-- -- function does not get fired again after 3 seconds
-- return false
-- end)
-- end
end)
end)
om:activate()
可能有比注释掉整个块更好的方法来做到这一点,但至少这种方式不会浪费处理时间来检查接收器的状态是否空闲。现在,在接收器闲置几秒钟后恢复播放音乐和视频时,不会出现烦人的音频延迟或爆音。我希望这对在 Fedora 35 上使用 WirePlumber 的人有所帮助。
答案3
我花了很多时间谷歌搜索并做这里描述的事情。
我将把整个算法留在这里(在 Ubuntu 23.04 上就像一个魅力)
将配置移至全局范围并更改其
session.suspend-timeout-seconds
参数:# Main config sudo mkdir -p /etc/wireplumber/main.lua.d sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua # Bluetooth config sudo mkdir -p /etc/wireplumber/bluetooth.lua.d/ sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua # Change the needed settings in both config files # Pay attention to `--` in the beggining. It's a line comment in Lua. And we must remove it sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/main.lua.d/50-alsa-config.lua sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
然后重新加载服务:
systemctl --user restart pipewire wireplumber
然后,您可以在播放和停止音频时通过此命令测试所有音频设备的状态,然后观察状态变化:
watch -cd -n .1 pactl list short sinks
它显示状态:
- RUNNING — 设备当前正在播放或上次播放后不到 10 秒
- IDLE — 设备未播放但准备立即播放(需要什么!)
- 挂起 — 在此状态下,设备将延迟唤醒(不需要)
会话中第一次播放后,不得再出现 SUSPENDED 状态。
恭喜!现在您的音频将无缝播放。
答案4
相关配置文件为/usr/share/wireplumber/main.lua.d/50-alsa-config.lua,但不要编辑它的系统版本
此解决方案不适用于蓝牙设备。要使其正常工作,请复制蓝牙文件并更改属性session.suspend-timeout-seconds
。
sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
sudo vi /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
50-bluez-config.lua:
apply_properties = {
--["node.nick"] = "My Node",
--["priority.driver"] = 100,
--["priority.session"] = 100,
--["node.pause-on-idle"] = false,
--["resample.quality"] = 4,
--["channelmix.normalize"] = false,
--["channelmix.mix-lfe"] = false,
["session.suspend-timeout-seconds"] = 0, -- 0 disables suspend
--["monitor.channel-volumes"] = false,
-- Media source role, "input" or "playback"
-- Defaults to "playback", playing stream to speakers
-- Set to "input" to use as an input for apps
--["bluez5.media-source-role"] = "input",
},