无法创建 udev 规则来运行用于在插头上回送麦克风的脚本

无法创建 udev 规则来运行用于在插头上回送麦克风的脚本

我一直在尝试设置我的 USB 麦克风,以切换到默认值并使用 udev 自动环回。

我当前的规则是:

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"

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

将麦克风设置为默认源并将其环回。

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

这会关闭环回并将默认源返回到我的网络摄像头。

这些脚本本身完全按照预期工作。但是,当 udev 执行它们时,所有内容都会回显到测试文件,但 pulseaudio 会忽略这些命令。

我认为这与权限有关,这就是我添加 GROUP 的原因。我尝试了几个组和所有者,并尝试了 MODE=="0660",但此时我不知所措。

编辑 3/3/2017 所以现在我的 /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

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

它确实有效,但我宁愿不将所有内容转储到文件中。我尝试过删除回声并将所有内容路由为空,但随后它就停止工作了。

当我查看测试文件时,麦克风拔出似乎重复发生:

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

另一件奇怪的事情,尽管它说,“源 alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono 不存在。”但它仍然可以工作。

答案1

pulseaudio 服务器通常以普通用户身份运行(至少在我输入此内容的 16.10 上),但是 udev 以 root 身份运行脚本,没有普通用户拥有的正常环境变量。您可能可以在系统范围内运行 pulseaudio(我从未这样做过,但https://community.linuxmint.com/tutorial/view/1137意味着它可以完成,或者您需要修改脚本以以相关用户的身份运行 pacmd。

也许将您的脚本更改为包装器以运行每个用户脚本,例如:

/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

然后将脚本放在主目录中的 .pulse_events 中(确保使其可执行,例如 chmod 755 /home/wanderingconfused/.pulse_events )

/主页/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

最后,让 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"

答案2

我最终最有效的解决方案。

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

主页/.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

我添加了一个 while 循环来检查 pulseaudio 源列表中的麦克风,一切正常,无需填满我的测试文件。删除规则仍然触发两次我曾尝试观察 udev 事件以找到仅与 1 个事件匹配的唯一集合 ID,但我尝试的那些违反了规则。虽然该事件只需要运行一次,但运行两次不会造成任何损害,我很高兴它不会运行超过这个次数。所以...现在...我完成了。

相关内容