TL/DR
If you are using a Debian based distro and don't care about the details of how this works, then you can simply install the .deb file I've prepared here. After that finishes installing you should be good to go - attach your HDMI cable and the system should automatically switch from playing over the speakers/headphones to piping audio over the HDMI.
The Details or How we make things work on not Debian
How this works is a combination of PulseAudio, Bash, and a little bit of udev.
First things first, we need a bash script that with switch between PulseAudio outputs for us. Save the following bit of code to /usr/bin/hdmi_sound_toggle :
First things first, we need a bash script that with switch between PulseAudio outputs for us. Save the following bit of code to /usr/bin/hdmi_sound_toggle :
#!/bin/bash # Switches between soundcards when run. All streams are moved to the new default sound-card. # $totalsc: Number of sound cards available totalsc=$(pacmd "list-sinks" | grep card: | wc -l) # total of sound cards: $totalsc if [ $totalsc -le 1 ]; then # Check whether there are actually multiple cards available exit fi # $scindex: The Pulseaudio index of the current default sound card scindex=$(pacmd list-sinks | awk '$1 == "*" && $2 == "index:" {print $3}') # $cards: A list of card Pulseaudio indexes cards=$(pacmd list-sinks | sed 's|*||' | awk '$1 == "index:" {print $2}') PICKNEXTCARD=1 # Is true when the previous card is default count=0 # count of number of iterations for CARD in $cards; do if [ $PICKNEXTCARD == 1 ]; then # $nextsc: The pulseaudio index of the next sound card (to be switched to) nextsc=$CARD PICKNEXTCARD=0 # $nextind: The numerical index (1 to totalsc) of the next card nextind=$count fi if [ $CARD == $scindex ]; then # Choose the next card as default PICKNEXTCARD=1 fi count=$((count+1)) done pacmd "set-default-sink $nextsc" # switch default sound card to next # $inputs: A list of currently playing inputs inputs=$(pacmd list-sink-inputs | awk '$1 == "index:" {print $2}') for INPUT in $inputs; do # Move all current inputs to the new default sound card pacmd move-sink-input $INPUT $nextsc done exit
Make our script executable with the command:
sudo chmod +x /usr/bin/hdmi_sound_toggle
Before moving on, confirm the script works as intended. While your HDMI cable is active run the command hdmi_sound_toggle and you should start hearing sound pipe out of the HDMI output.
Next, because PulseAudio is almost always run as a user level daemon, we need something that will move all users' Pulse sessions over to the new output when the HDMI is attached/detached. To do this we create the script /usr/bin/hdmi_sound_toggle_all with the contents:
#!/bin/bash for dir in /home/*/ do dir=${dir%*/} sudo -u ${dir##*/} /usr/bin/hdmi_sound_toggle done
Make this script executable as well:
sudo chmod +x /usr/bin/hdmi_sound_toggle_all
Confirm this script works as well, it needs to be run as root though, so run sudo hdmi_sound_toggle_all while your HDMI is attached - it should switch your output.
Finally, we need to create a udev rule that triggers our scripts when an HDMI cable is attached/detached. To do this we create the file /lib/udev/rules.d/hdmi_sound.rules with the contents:
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/bin/hdmi_sound_toggle_all"
Note that having the full file path in the execute part is important. So if you placed your scripts somewhere other than /usr/bin like I recommended above - adjust this part accordingly.
You should be good to go, enjoy having audio over your HDMI happen automatically like it should by default. Have any questions, feel free to post a comment below and I'll do my best to help.
~Jeff Hoogland
thanks for sharing
ReplyDeleterunning the command hdmi_sound_toggle is not working. I'm an Ubuntu user.
ReplyDeleteCan you toggle audio over your HDMI using another method?
DeleteWhen I run the command in Terminal I get this:
Delete/usr/bin/hdmi_sound_toggle: 16: [: 1: unexpected operator
/usr/bin/hdmi_sound_toggle: 23: [: 0: unexpected operator
/usr/bin/hdmi_sound_toggle: 16: [: 1: unexpected operator
/usr/bin/hdmi_sound_toggle: 23: [: 1: unexpected operator
Welcome to PulseAudio! Use "help" for usage information.
>>> You need to specify a sink either by its name or its index.
>>> Welcome to PulseAudio! Use "help" for usage information.
>>> You need to specify a sink.
That implies there is something wrong with your bash. Did you copy the line #!/bin/bash at the top of the script?
DeleteYes I did. and I tried to install the .deb package with the same rezult
DeleteI think is a problem in the script to count/set/switch the sound card because if I run these commands:
pacmd set-default-sink 1 & pacmd move-sink-input 2 1
pacmd set-default-sink 0 & pacmd move-sink-input 2 0
they toggle the output and is working.
Unfortunately I do not know bash to bedbug this.
What about if you explicitly tell the system to run the script using bash.
DeleteEG: bash /usr/bin/hdmi_sound_toggle
That error message you are getting is from your bash being messed up.
ok using your command is working. Thanks!
DeleteAnd now how do i make this script working without running this command in terminal?
Having #!/bin/bash as the first line of the script SHOULD tell your system to use bash to run this script. For whatever reason it isn't - you likely want to look into fixing why your system isn't handling bash files properly.
DeleteThe command hdmi_sound_toggle_all is working also but is not trigged by udev rule that I created.
DeleteI maked an all day research. Your solution works just when attaching/detaching of HDMI cable triggers an UDEV event. in my case i have installed Nvidia drivers and they DON'T trigger an udev event (i don't even have an /sys/class/drm directory and that means that there is no drm SUBSYSTEM need to create a udev rule). I searched everywhere and I didn't found a good solution in my case. If someone has an idea I would be thankfully.
DeleteI've tried doing this, is whenn run it gives the message 'Welcome to PulseAudio! Use "help" for usage information.
ReplyDelete>>> >>> Welcome to PulseAudio! Use "help" for usage information' and my laptops speakers mute but the sound does not come via the TV. It's a new HDMI cable so I guess the next check is does it work with Windows.
Likely means your hardware isn't being detected as an audio output device. Have you successfully piped audio over your HDMI on Linux before?
DeleteNo I've not, I came across this post as top of my Google search.
DeleteLooks like you missed the first paragraph of the post then. You should always be sure to read a HOWTO in its entirety before you start blindly copy and pasting commands.
DeleteGlad you have the HDMI audio working for us all. I am using an acer c720 installed with bodhi 2.4.0 and I can't get the HDMI video Out to work. I pull HDMI to chromebook and the tv screen is balnk saying no signal. Without Chrome OS - video works with no issues.
ReplyDeleteCAN ANYONE PLEASE HELP ME HDMI Video Out not working?? I really don't want to switch back to chrome os or re-installed Bodhi on a usb 3.0 flashdrive after I have all the software installed.
After plugging in the HDMI cable open the "screen setup" tool and turn on the second screen.
DeleteThank you so much for these scripts!
ReplyDeleteIt didn't work at first, but after some hours working on it, it finally works!
For information (I'm on linux mint 16) :
My HDMI cable doesn't correspond to the rule "SUBSYSTEM=="drm", ACTION=="change"
But instead there is a connection and disconnection (both everytime!) when I plug/unplug it ...
And i had to change the run cmd : RUN+="/bin/su my_user -c my_toggle_script"
The scripts work, but the udev rule does not trigger the scripts. Any suggestion? I'm running Manjaro Linux, most recent updates, kernel 4.3.
ReplyDeleteudev must be messed up on your distro to not be triggering for this event. Might also be triggering a slightly different event name.
DeleteActually, when looking in journalctl -b I found that udev does trigger the script but returns and exit code 1 error. If I run the script manually as [user] it works, but if I run it as [root] via su or sudo, it returns "No PulseAudio daemon running, or not running as session daemon." I seem to be having the issue of PulseAudio as a per user session that root cannot access and udev runs as root. Any suggestions?
Delete