Автоматическое переключение звука на Bluetooth-наушники в Linux с помощью udev и wpctl

Вступление

В Linux есть два популярных звуковых сервиса: PulseAudio и PipeWire. PipeWire постепенно становится стандартом, и в сочетании с WirePlumber можно настроить автоматическое переключение. Но иногда WirePlumber не срабатывает, или событие обрабатывается с задержкой. Решение — использовать udev, который отслеживает события подключения устройств и запускает скрипт.

Шаг 1: Проверяем PipeWire и wpctl

Убедитесь, что PipeWire и WirePlumber запущены:

systemctl --user status pipewire
systemctl --user status wireplumber

Также полезно посмотреть список аудиоустройств:

wpctl status

Вы увидите свои колонки и Bluetooth-устройства:

Audio
 ├─ Sinks:
 │  * 136. alsa_output.usb-ARTURIA_ArturiaMsd-00.analog-stereo
 │    55. bluez_output.XX_XX_XX_XX_XX_XX.a2dp-sink

Шаг 2: Создаём скрипт для переключения звука

Создаём скрипт /usr/local/bin/bt-audio-autoswitch.sh:

#!/bin/bash
ACTION=$1
STATEFILE="/run/user/$(id -u)/bt-audio-last-sink"
LOGTAG="bt-audio-autoswitch"

# Текущее устройство вывода
get_default_sink() {
    wpctl status | awk '/\*.*sink/ {print $2; exit}' | tr -d '[]'
}

# Идентификатор первого Bluetooth sink
get_bt_sink() {
    wpctl status | awk '/bluez_output/ {print $2; exit}' | tr -d '[]'
}

# Ждём обновления PipeWire
sleep 2

if [ "$ACTION" = "add" ]; then
    CURRENT=$(get_default_sink)
    if [ -n "$CURRENT" ]; then
        echo "$CURRENT" > "$STATEFILE"
        logger "$LOGTAG: сохранил текущее устройство $CURRENT"
    fi
    BT_ID=$(get_bt_sink)
    if [ -n "$BT_ID" ]; then
        wpctl set-default "$BT_ID"
        logger "$LOGTAG: переключил звук на $BT_ID"
    fi
elif [ "$ACTION" = "remove" ]; then
    if [ -f "$STATEFILE" ]; then
        PREV=$(cat "$STATEFILE")
        if [ -n "$PREV" ]; then
            wpctl set-default "$PREV"
            logger "$LOGTAG: вернул звук на $PREV"
        fi
        rm -f "$STATEFILE"
    fi
fi

Делаем скрипт исполняемым:

sudo chmod +x /usr/local/bin/bt-audio-autoswitch.sh

Шаг 3: Создаём udev-правило

# Подключение Bluetooth аудио
ACTION=="add", SUBSYSTEM=="sound", KERNEL=="card*", RUN+="/usr/local/bin/bt-audio-autoswitch.sh add"

# Отключение Bluetooth аудио
ACTION=="remove", SUBSYSTEM=="sound", KERNEL=="card*", RUN+="/usr/local/bin/bt-audio-autoswitch.sh remove"

Применяем новые правила:

sudo udevadm control --reload-rules
sudo udevadm trigger

Шаг 4: Проверяем работу

Подключаем Bluetooth-наушники. Скрипт автоматически сохранит текущее устройство и переключит звук на наушники.

Отключаем наушники. Скрипт вернёт звук на сохранённое устройство (например, ваши колонки).

Проверить работу можно через journalctl:

journalctl -f -t bt-audio-autoswitch

Заключение

Использование udev + wpctl позволяет надёжно автоматизировать переключение аудио на Bluetooth-наушники даже в случае, если WirePlumber не успевает сработать. Этот подход легко настраивается и не требует ручного выбора устройства при каждом подключении.