Switching to HDMI Audio when HDMI is plugged into a laptop (14.04)
I'm trying to get my laptop to switch the audio to HDMI when it's plugged in, and back to standard analog when it's removed.
I set up a udev rule to trigger a script to perform the switching, however I'm having problems getting it to work:
- It appears that until I select the HDMI Audio output in the Sound Settings, it is not recognised as a available sink, also once the HDMI Audio output is selected, the analog output is no longer listed.
See the below:
# HDMI plugged in, not selected in Sound settings.
$ pactl list short sinks
5 alsa_output.pci-0000_00_1b.0.analog-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
kingamajick@kingamajick-laptop: ~
# HDMI selected in sound settings
$ pactl list short sinks
7 alsa_output.pci-0000_00_1b.0.hdmi-stereo module-alsa-card.c s16le 2ch 48000Hz SUSPENDED
kingamajick@kingamajick-laptop: ~
# HDMI removed
$ pactl list short sinks
9 alsa_output.pci-0000_00_1b.0.analog-stereo module-alsa-card.c s16le 2ch 48000Hz SUSPENDED
The script I'm using the toggle the output is as follows:
#!/bin/bash
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))
if [ $HDMI_STATUS = "connected" ]
then
pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo &> /dev/null; done
else
pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo &> /dev/null; done-server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi
The script gives an error about no such sink when I trigger it before I select HDMI in the sound settings.
Solution 1:
Based in this link and this link ...i tested and WORKS FINE ubuntu 14.04
you should create a rule in /etc/udev/rules.d/100-hdmi_sound.rules
whith this content
SUBSYSTEM=="drm", ACTION=="change", RUN+="/lib/udev/hdmi_sound_toggle.sh"
then create
sudo -H gedit /lib/udev/hdmi_sound_toggle.sh
whith your content
#!/bin/bash
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))
if [ $HDMI_STATUS = "connected" ]
then
pactl set-card-profile 0 output:hdmi-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo &> /dev/null; done
else
pactl set-card-profile 0 output:analog-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo &> /dev/null; done
fi
I Hope can help ..sorry for my english i spoke spanish
Solution 2:
-
Check for available cards & profiles
pactl list cards
-
Add following command to the script to change profile before setting default sink & moving streams
pactl [options] set-card-profile CARD PROFILE
(So no need to switch it manually from Sound Settings)
Reference:
pactl -h
& man pactl
Solution 3:
I had a bit of trouble following this. I copied the original script and modified it as suggested and now it works.
I am including it here to make it easier for someone else to use.
#!/bin/bash
## From: https://askubuntu.com/questions/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now
##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))
if [ $HDMI_STATUS = "connected" ]
then
pactl set-card-profile 0 output:hdmi-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo &> /dev/null; done
else
pactl set-card-profile 0 output:analog-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo &> /dev/null; done
fi
Now, I'd just like to trigger it with udev, but I'm clueless as to how to do that.
Solution 4:
The provided scripts didn't work for me with udev out of the box on Ubuntu 14.04, I had to add:
export DISPLAY=:0
at the beginning, convert the two pacmd commands to pactl and finally run the script using sudo -s -u (user) from the udev rule.
#!/bin/bash
## From: https://askubuntu.com/questions/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now
export DISPLAY=:0
##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pactl list sink-inputs | grep Input | awk '{print $3}' | sed -r 's/^.{1}//')
if [ $HDMI_STATUS = "connected" ]
then
pactl set-card-profile 0 output:hdmi-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo &> /dev/null; done
else
pactl set-card-profile 0 output:analog-stereo
pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo &> /dev/null; done
fi