Switching to HDMI Audio when HDMI is plugged into a laptop (14.04)

16,902

Solution 1

  1. Check for available cards & profiles

    pactl list cards
    
  2. 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 2

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 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

Solution 5

Well, all the provided scripts didn't work for me (Ubuntu 16.04), but I found this app indicator which allows you to change sound output in just one click:

https://github.com/lkettenb/sound-output-switcher

(note: you need to install the appindicator package first: sudo apt-get install python-appindicator )

Just thought I'd leave this here for others who might be in the same situation as me, even though it's an alternative solution... but it makes it pretty easy and it's discrete ;-)

Share:
16,902
Kingamajick
Author by

Kingamajick

Updated on September 18, 2022

Comments

  • Kingamajick
    Kingamajick over 1 year

    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.

  • Joe
    Joe over 7 years
    This doesn't work in 16.04. I'm working on it again.
  • WinEunuuchs2Unix
    WinEunuuchs2Unix over 7 years
    I had similar script that worked using card0 but one day it switched to card1 so I changed the script then the next day it changed back to card0. In the end I changed the code to card* and all is well since then. Just a heads up if something similar happens to you.
  • Arno
    Arno over 3 years
    I followed the advice, the script is called but pactl will not be executed (if typed in at shell it works). My guess: It takes some time to switch on HDMI and sound setting is not possible at that time. I added a sleep 5 before the sudo, but that increases also the time for screen to be switched to HDMI. How to change order ?