You are not logged in.
Hi all
I'm trying to change audio output (Pulseaudio on Pipewire), when HDMI cable is connected. I got myself nice udev rule and bash script. Script works from command line, but when running as udev rule, configuration returned by
pactl list
will update only after all udev rules will finish processing So after my awesome script will finish running, I still get in logs:
May 17 14:24:42 host (udev-worker)[23011]: card1: Process '/usr/bin/su user -c /home/user/shell_scripts/hdmi.sh' succeeded.
May 17 14:24:42 host (udev-worker)[23011]: card1: Running built-in command "uaccess"
May 17 14:24:42 host (udev-worker)[23011]: card1: Device processed (SEQNUM=5376, ACTION=change)
May 17 14:24:42 host (udev-worker)[23011]: card1: sd-device-monitor(worker): Passed 594 byte to netlink monitor.
May 17 14:24:42 host systemd-udevd[335]: No events are queued, removing /run/udev/queue.
May 17 14:24:45 host systemd-udevd[335]: Cleanup idle workers
May 17 14:24:45 host systemd-udevd[335]: Worker [23011] exited.
May 17 14:24:49 host systemd-udevd[335]: Cleanup idle workers
At which point script finished but if invoked again, will now work properly - both from cmd line and by udev rule.
pactl info
shows correct info about connection to Pulseuadio, so this does not look like user/permissions issue. Also experimented by triggering udev rule with some sleep and running script in parallel from cli - same stuff.
At this point I wonder - can I force udev rule, to really run after *uaccess* and *sd-device-monitor*? Or should I ask Pipewire people about it? Maybe this is on purpose, as pactl works in user space, so it can only be updated after udev will finish ?
I tried to send udev task into background to wait, by adding
/hdmi.sh > /dev/null &
to run command, but udev still waits for such task to finish.
At this point I'm like - I should schedule one time cron task from udev rule, but it is not elegant.
100-hdmi-plug.rules
:
ACTION=="change", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/user/.Xauthority", RUN+="/usr/bin/su user -c /home/user/shell_scripts/hdmi.sh"
which triggers this script:
#!/bin/sh
export XAUTHORITY=/home/user/.Xauthority
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
export XDG_RUNTIME_DIR="/run/user/1000"
if pactl list | grep "available: yes" | grep hdmi
then
echo "HDMI connected"
pactl set-card-profile alsa_card.pci-0000_00_1f.3 output:hdmi-stereo+input:analog-stereo
else
echo "HDMI disconnected"
pactl set-card-profile alsa_card.pci-0000_00_1f.3 output:analog-stereo+input:analog-stereo
fi
Last edited by gladykov (2024-05-17 19:29:44)
Offline
Pulseaudio/pipewire/wireplumber should have native support for a switch based on a device becoming available. e.g. https://wiki.archlinux.org/title/PipeWi … new_device
Though your case looks like a port switch and from what I'm finding wireplumber should do the logistics of that by default already anyway.
Offline
OK, after tinkering more, using | at to send bash script into background as one time task with some delay inside script, was the solution. Put whole solution here: https://github.com/gladykov/hdmi-audio- … ch-on-arch
Offline
Pulseaudio/pipewire/wireplumber should have native support for a switch based on a device becoming available. e.g. https://wiki.archlinux.org/title/PipeWi … new_device
Though your case looks like a port switch and from what I'm finding wireplumber should do the logistics of that by default already anyway.
It is broken for HMDI since 5.x
Offline