problema ao criar regras do udev para executar o script que faz um loopback de um microfone na tomada

0

Eu tenho tentado configurar meu microfone USB para alternar para o padrão e fazer o loopback automaticamente com o udev.

Minhas regras atuais são:

ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/micunplug"

O script do micplug é:

#!/bin/bash

echo "setting source mic" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono
echo "loopback mic" >> /home/wanderingconfused/test
pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo

Que define o microfone como a fonte padrão e faz um loopback.

O script do micunplug é:

#!/bin/bash

echo "turn off loopback" >> /home/wanderingconfused/test
pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
echo "setting source webcam" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono

O que desativa o loopback e retorna a fonte padrão para minha webcam.

Os scripts funcionam exatamente como planejados por conta própria. No entanto, quando o udev os executa, meu tudo ecoa no arquivo de teste, mas o pulseaudio ignora os comandos.

Eu estava pensando que tinha algo a ver com permissões, e é por isso que adicionei GROUP. Eu tentei alguns grupos e proprietários e tentei MODE =="0660", mas neste momento estou perplexo.

Editar 3/3/2017 Então agora meu / usr / bin / pulse_events_wrapper é:

#!/bin/bash

# Get UID of user running pulseaudio (uses the first if more than one)
PUID='ps -C pulseaudio -o ruid= | awk '{print $1}''

if [ ! -z "$PUID" ]; then
  # environment variables to export
  export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
  export HOME='getent passwd $PUID | cut -d: -f6'

  if [ -x "$HOME/.pulse_events" ]; then
    # Pass single command line arg to user script
    nohup sudo -u "#$PUID" -E $HOME/.pulse_events $1 >/dev/null 2>&1 &
  fi
fi

e o script home / .pulse_events é

!/bin/bash

case $1 in
    micplug)
      echo "setting source mic" >> /home/wanderingconfused/test
      pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono >>/home/wanderingconfused/test 2>&1
      echo "loopback mic" >> /home/wanderingconfused/test
      pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo$
    ;;

    micunplug)
      echo "turn off loopback" >> /home/wanderingconfused/test
      pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - ) >>/home/wanderingconfused/test 2>&1
      echo "setting source webcam" >> /home/wanderingconfused/test
      pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono >>/home/wanderingconfused/test 2>&1
    ;;
esac

Funciona, mas eu prefiro não colocar tudo isso em um arquivo. Eu tentei remover os ecos e rotear tudo para null, mas depois ele parou de funcionar.

Além disso, o microfone desconecta-se quando eu olho para o arquivo de teste:

setting source mic
loopback mic
68
turn off loopback
setting source webcam
turn off loopback
turn off loopback
You have to specify a module index or name
setting source webcam
You have to specify a module index or name
setting source webcam
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
70
Failure: No such entity
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
78
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
80
turn off loopback
turn off loopback
setting source webcam
Failure: No such entity
setting source webcam
setting source mic
loopback mic
82
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
84
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
loopback mic
87
turn off loopback
setting source webcam
turn off loopback
You have to specify a module index or name
setting source webcam

Outra coisa estranha, apesar de dizer: "Fonte alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono não existe." Ainda funciona.

    
por wanderingconfused 01.03.2017 / 21:56

2 respostas

0

Minha solução final de trabalho principal.

Regras do Udev:

ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/pulse_event_wrapper micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/pulse_event_wrapper micunplug"

/ usr / bin / pulse_events_wrapper

#!/bin/bash

# Get UID of user running pulseaudio (uses the first if more than one)
PUID='ps -C pulseaudio -o ruid= | awk '{print $1}''

if [ ! -z "$PUID" ]; then
  # environment variables to export
  export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
  export HOME='getent passwd $PUID | cut -d: -f6'

  if [ -x "$HOME/.pulse_events" ]; then
    # Pass single command line arg to user script
    nohup sudo -u "#$PUID" -E $HOME/.pulse_events $1 >/dev/null 2>&1 &
  fi

fi

home / .pulse_events

#!/bin/bash
n=0
case $1 in
    micplug)
      while ! $(pactl list sources|grep -q 'Logitech USB Microphone Analog Mono')
        do let "n += 1"
        sleep 1
        if [ "$n" -eq 10 ]
          then break
        fi
      done
      pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono
      pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo
    ;;

    micunplug)
      pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
      pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono
    ;;
esac

Eu adicionei um loop while para verificar meu microfone na lista de fontes pulseaudio e tudo funciona bem sem preencher meu arquivo de teste. A regra de remoção ainda dispara duas vezes. Tentei assistir aos eventos do udev para encontrar IDs de conjuntos exclusivos que correspondem apenas a um evento, mas que tentei violar a regra. Enquanto que o evento só precisa ser executado uma vez em execução duas vezes não vai doer nada e fico feliz que não corra mais do que isso. Então ... por enquanto ... eu terminei.

    
por wanderingconfused 06.03.2017 / 19:31
1

O servidor pulseaudio normalmente é executado como seu usuário regular (pelo menos na 16.10 da qual estou digitando), no entanto o udev executa seu script como root, sem as variáveis de ambiente normais que o seu usuário regular possui. Você provavelmente poderia executar o sistema pulseaudio wide (nunca fiz isso, mas o link indica que isso pode ser feito), ou você precisará modificar seu script para executar o pacmd como o usuário em questão.

Talvez mude seu script para um wrapper para executar um script por usuário como:

/ usr / bin / pulse_event_wrapper:

#!/bin/bash

# Get UID of user running pulseaudio (uses the first if more than one)
PUID='ps -C pulseaudio -o ruid= | awk '{print $1}''

if [ ! -z "$PUID" ]; then
  # environment variables to export
  export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
  export HOME='getent passwd $PUID | cut -d: -f6'

  if [ -x "$HOME/.pulse_events" ]; then
    # Pass single command line arg to user script
    sudo -u "#$PUID" -E "$HOME/.pulse_events $1" >/dev/null 2>&1
  fi
fi

coloque seu script em .pulse_events em seu diretório pessoal (certifique-se de torná-lo executável, por exemplo, chmod 755 /home/wanderingconfused/.pulse_events)

/home/wanderingconfused/.pulse_events:

#!/bin/bash

case $1 in
    micplug)
      echo "setting source mic" >> /home/wanderingconfused/test
      pacmd set-default-source alsa_input.usb Logitech_Logitech_USB_Microphone-00.analog-mono
      echo "loopback mic" >> /home/wanderingconfused/test
      pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo
    ;;

    micunplug)
      echo "turn off loopback" >> /home/wanderingconfused/test
      pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
      echo "setting source webcam" >> /home/wanderingconfused/test
      pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono
    ;;
esac

finalmente, faça com que o udev chame o wrapper com o argumento de evento desejado:

ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/pulse_event_wrapper micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/pulse_event_wrapper micunplug"
    
por 1crackedbell 02.03.2017 / 03:26