让 udev 检查音频设备

让 udev 检查音频设备

我正在尝试为我的蓝牙接收器编写一条 udev 规则,当它连接时,它会运行一个脚本来检查是否还添加了相应的音频设备,如果没有,则重新连接。出于某种原因,当我打开接收器并自动连接时,最初没有添加任何音频设备。我使用 pipewire-pulse。

问题是我不知道如何让 udev 检查音频设备。pactl list无法以 root 身份运行,但没关系,因为理论上pw-cli list-objects应该可以运行。所以我的脚本如下所示:

#!/bin/bash

sleep 3

# JR-CB1 connected but not available as audio device
if bluetoothctl devices Connected | grep "25:4E:4A:C7:43:C4" && ! pw-cli list-objects | grep "25_4E_4A_C7_43_C4"; then
    # Reconnect
    bluetoothctl disconnect 25:4E:4A:C7:43:C4
    bluetoothctl connect 25:4E:4A:C7:43:C4
fi

su终端中,这很好用。如果没有音频设备,它会重新连接,如果有,则不执行任何操作。pw-cli list-objects | grep "25_4E_4A_C7_43_C4"添加音频设备后的输出是

object.path = "bluez_output.25_4E_4A_C7_43_C4.1:monitor_0"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:monitor_1"
node.name = "bluez_output.25_4E_4A_C7_43_C4.1"
device.name = "bluez_card.25_4E_4A_C7_43_C4"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:playback_1"
object.path = "bluez_output.25_4E_4A_C7_43_C4.1:playback_0"

并且 grep 返回值为 0,因此不应运行 if 语句。但是,虽然这在终端中有效,但在 udev 中由于某种原因不起作用。当记录由 udev 运行时脚本的输出时,输出为pw-cli list-objects | grep "25_4E_4A_C7_43_C4"空,返回值为 1,这意味着执行了重新连接,我得到了一个无限的重新连接循环。

为什么 udev 无法列出 pipewire 音频设备?还有其他方法吗?

答案1

我想我找到了解决方案。根据评论的建议,我研究了使用服务来启动脚本。为了让 systemd 知道设备事件,我使用了以下 udev 规则:

/etc/udev/rules.d/60-bluetooth-add-event.rules

CTION=="add", SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}="bluetooth-add-event.service"

(我试图确定特定于我的蓝牙设备的属性,但是没有 pipewire 设备,udev 似乎没有可用的唯一属性,因此每当任何 bt 设备连接时我都会启动该服务并让脚本处理识别。)

该服务如下所示:

/etc/systemd/system/bluetooth-add-event.service

[Unit]
Description=Runs when bluetooth connection is added
Requires=bluetooth.target
After=bluetooth.target

[Service]
ExecStart=/usr/bin/bluetooth-add-event.sh
Type=exec
Restart=no

[Install]
WantedBy=multi-user.target

这不是用户服务,因为pw-cli可以由 root 使用,只是不能由 udev 运行时使用。

(我对 systemd 单元选项的理解还很初级,因此欢迎提出任何改进建议。)

脚本和以前一样:

/usr/bin/bluetooth-add-event.sh

#!/bin/bash

sleep 3

# JR-CB1 connected but not available as audio device
if bluetoothctl devices Connected | grep "25:4E:4A:C7:43:C4" && ! pw-cli list-objects | grep "25_4E_4A_C7_43_C4"; then
    # Reconnect
    bluetoothctl disconnect 25:4E:4A:C7:43:C4
    bluetoothctl connect 25:4E:4A:C7:43:C4
fi

现在,当我连接设备时,脚本运行一次,找不到音频设备,重新连接 bt 设备,然后再次运行但不执行任何操作,因为它在 中找到了音频设备pw-cli list-objects

相关内容