Ubuntu – Set HDMI sound output automatically on connect/disconnect


I have a dual screen setup on my laptop (using 12.04 LTS) using a HDMI connected display. Everything works fine, but everytime I connect/disconnect the cable I have to go to Sound preferences and change the sound output device manually.

Is there any way to change the sound output device on connect/disconnection of cable, so when I connect my display the sound output is set to HDMI and when I disconnect it the sound goes back to laptop speakers?

Best Answer

For the benefit of people who stumble upon this question - Salem's solution almost worked for me in 13.04, I ended up gathering bits and pieces from all around the web, I think the deal breaker for me was the lack of the environment variable PULSE_SERVER

Here is my full solution, which is basically repeating Salem's solution with the few missing pieces. I also redid it as a shell script (despite my love for Python) because I was afraid at first that my Python script is running into import path issues:

(same as Salem's answer) Create a file /etc/udev/rules.d/hdmi_sound.rules as root with the content:

SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"

Create a file /usr/local/bin/hdmi_sound_toggle as root with the content:

USER_NAME=`who | grep "(:0)" | cut -f 1 -d ' '`
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`

export PULSE_SERVER="unix:/run/user/"$USER_ID"/pulse/native"

if [ $HDMI_STATUS = "connected" ]
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:hdmi-stereo+input:analog-stereo
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo

Then make it executable with chmod 0755 /usr/local/bin/hdmi_sound_toggle

I tried to make this script as generic as possible, but you still might need to change some lines, such as the HDMI_STATUS file path or the profiles used. You can see a list of profiles by running pactl list cards and looking under Profiles.

Note that the script failed for me when I removed the keyword "export" when setting PULSE_SERVER, I think pactl is looking for the env variable

Don't forget to reload your udev rules: sudo udevadm control --reload-rules

Update this script is updated for 14.04. Before that, you would use USER_NAME instead of USER_ID everywhere