Minha solução de trabalho
-
Modifique
a2dp.py
substituindo todas as instâncias depacmd
porpactl
adjustingpacmd list-sinks
apactl list sinks
(no meu caso, salvo como/usr/local/bin/a2dp_2.sh
). -
Crie um script de wrapper
/usr/local/bin/a2dp-wrapper.sh
#!/bin/bash MAC=$1 MACMOD=$(echo $MAC | sed 's/:/_/g') PID=$(pgrep pulseaudio) USER=$(grep -z USER= /proc/$PID/environ | sed 's/.*=//') export DISPLAY=:0 export XAUTHORITY=/home/$USER/.Xauthority if pactl list sinks short | grep "bluez_sink\.$MACMOD.*SUSPENDED" then sudo -u $USER /usr/local/bin/a2dp_2.py $MAC fi
-
Adicione a seguinte linha a
/etc/udev/rules.d/80-bt-headset.rules
:ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="00:22:37:3D:DA:50" RUN+="/usr/local/bin/a2dp-wrapper.sh $attr{name}"
Este script de wrapper realiza o seguinte:
-
Ele descobre que
$USER
possui a instância em execução de pulseaudio, depois define as variáveis de ambienteDISPLAY=:0
eXAUTHORITY=/home/$USER/.Xauthority
necessárias para quepactl
funcione. Isso deve fazer com que funcione para todos os usuários em uma máquina. (Eu não testei os efeitos de vários usuários conectados ao mesmo tempo.) -
Verifica se o coletor correspondente está suspenso e só então executa
a2dp_2.py
. Isso é necessário para evitar um loop infinito causado pora2dp_2.py
reconectando o dispositivo e, assim, acionando a regra. -
Ele executa
a2dp_2.py
como $ USER. Se for executado como root,a2dp_2.py
deixará o pulseaudio e, portanto, qualquer configuração de áudio, inacessível sem privilégios de root.
Alternativas: loop dbus / pacote fixo
-
Uma solução alternativa usando um loop dbus pode ser encontrada na página do desenvolvedor do sript .
-
Uma correção para o bug original já está disponível aqui e pode ser facilmente instalado adicionando
ppa:ubuntu-audio-dev/pulse-testing
e atualizando os pacotes disponíveis.
Dica: encontrar o endereço MAC do seu dispositivo
Não é estritamente parte do problema original, mas isso pode ser útil para referência futura. Existem várias maneiras de encontrar o endereço MAC do seu dispositivo. O que segue é o que considero mais útil para as regras do udev:
-
Encontre o caminho do dispositivo executando
udevadm monitor
e conectando seu dispositivo. Sua saída deve ser algo como isto:USER@MACHINE:~$ udevadm monitor monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL[123043.617276] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/bluetooth/hci0/hci0:256 (bluetooth) UDEV [123043.647291] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/bluetooth/hci0/hci0:256 (bluetooth) KERNEL[123044.153776] add /devices/virtual/input/input68 (input) KERNEL[123044.153911] add /devices/virtual/input/input68/event17 (input) UDEV [123044.193415] add /devices/virtual/input/input68 (input) UDEV [123044.213213] add /devices/virtual/input/input68/event17 (input)
Pare o monitor com
Ctrl+C
. Encontramos três caminhos de dispositivos. O que é relevante para nós é/devices/virtual/input/input68
. -
Conecte o caminho obtido em
udevadm info
:USER@MACHINE:~$ udevadm info -a -p /devices/virtual/input/input68 Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/virtual/input/input68': KERNEL=="input68" SUBSYSTEM=="input" DRIVER=="" ATTR{name}=="00:22:37:3D:DA:50" ATTR{phys}=="" ATTR{properties}=="0" ATTR{uniq}==""
Aprendemos que o endereço MAC é
00:22:37:3D:DA:50
e também que é armazenado comoATTR{name}
.
Mesmo que a saída pareça completamente diferente, esses dois comandos serão um bom começo para procurar as condições relevantes para uma regra do udev.
Experimental: captura de dispositivos de áudio Bluetooth arbitrários
A regra:
ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="??:??:??:??:??:??" RUN+="/usr/local/bin/a2dp-wrapper.sh $attr{name}"
será acionado para qualquer dispositivo de entrada que tenha um atributo de nome que se pareça com um endereço MAC, e o condicional no script de wrapper deve garantir que nenhuma ação indesejada seja tomada.
Eu não tenho nenhum outro dispositivo de áudio Bluetooth disponível para testar isso, mas vejo diversos problemas em potencial:
-
Isso funcionará apenas para um dispositivo Bluetooth reconhecido como um dispositivo de entrada contendo o endereço MAC no atributo name. Nem todo dispositivo pode ser reconhecido como tal.
-
Esta solução não é muito elegante, pois a regra será acionada para qualquer dispositivo de entrada. No entanto, não consegui encontrar indicadores claros para identificar um dispositivo de áudio bluetooth. (Como visto acima, o dispositivo de entrada não tem atributos adicionais, e o dispositivo bluetooth não mostra nenhuma indicação de ser um dispositivo de áudio, nem contém o endereço MAC. Talvez o ACPI seja melhor para isso.)
-
Você pode não querer tratar todos os dispositivos de áudio bluetooth da mesma forma: você pode usar o protocolo HSP para o seu fone de ouvido ou pode não querer alternar automaticamente para os alto-falantes do seu housemate, emparelhados algum ponto, sempre que estiverem disponíveis. Nesses casos, é preferível ter uma regra separada para cada dispositivo.
Vou continuar atualizando esta postagem enquanto aprendo mais.