You know how when you plug headphones into your laptop's aux jack, the internal speakers are automatically muted and the sounds comes out of your headphones? I want exactly that for HDMI.
I connect a monitor with built-in speakers to my laptop to watch videos, sometimes. It's very weird when the video is on the monitor (which is placed 3 m away from my desk) but the sound comes out of my laptop's internal speakers (laptop sits on the desk).
Of course, I can just go to the sound settings and switch the output channel to HDMI. But then, later on, when I removed the HDMI cable hours ago and might even be in a totally different location, the sound won't play because the sound server still tries to play it via HDMI but there isn't anything connected to it.
Automatically switching back to the internal speakers when no device is connected via HDMI is more important but switching to sound output via HDMI when a device is connected would still be very nice.
This apparently worked with 11.10 but it doesn't work with 16.04.
I had a similar problem during suspend/resume when sound would switch from HDMI TV to laptop speakers. Upon resume sound would stay on Laptop speakers and I would have to manually reset output device to TV in
This was one of my first annoying experiences with upgrade from Ubuntu 14.04 to 16.04 and the root was upgrade to PulseAudio 8 that comes with 16.04 LTS
After much searching I created a script called
TV-sound. Although I don't plug and unplug the TV like yourself, I did some google searches and create a variation of the script to work in your situation. I've tested it and it works.
Step 1: Create script to switch audio between connected devices
We'll create a script called
hotplugtvwhich udev calls. This same script can be called in many places though. For example, during testing I used it in
lock-screen-timerwhere sound reverted back to Laptop during screen lock.
When the editor opens with a blank screen, copy and paste the following into it:
You will need to replace the two occurrences of
rickwith your own user id, ie
I know this can be more professional with user name automatically set to a bash variable but I'm not that skilled yet :( Anyway, save the file and exit
Step 2: Create udev rules
udev monitors hotplug events when you plug in and unplug your HDMI monitor. Type the following to create a new rule.
NOTE: If the file
70-persistent-net.rulesdoesn't exist in your directory copy any other file there. We don't need the file contents, just the file permissions to ensure ours are the same.
The editor will show a bunch of irrelevant text, highlight it and delete it. Then highlight the code below and paste it into the editor:
Save the file and exit.
To enable the rule (without rebooting) we need to reload udev:
Now you can plug and unplug your HDMI monitor / TV and the sound switches appropriately.
On my system the sound automatically reverts to the Laptop speakers when HDMI is unplugged. On your system it did not. Further enhancements to the code may be required if sound doesn't go to your Laptop speakers when HDMI is unplugged. Please reply via comment below how things work / don't work out.
Quick testing in CLI
You can quickly test the code at the terminal by using:
Switch to HDMI / TV:
Switch back to built in speakers:
Remember to replace
rickwith your user name.
exportline probably isn't necessary but I've included it just to be safe.
hdmi-stereotweaks are obviously needed to find out the correct parameters before writing your script.
Deciphering your device name within PulseAudio
The code below uses the same command twice. Once when the sound is set to external HDMI TV. A second time when the sound is set to the Laptop's built in speakers. Each time you see the name PulseAudio uses:
When you have multiple sound cards
Use the command
aplay -lto see if you have cards greater than number 0. If so you will need to use appropriate card number in your scripts. For example:
In the above example all card numbers are 0 with different output sources. If you have USB speakers they can have a different card number than 0.
Edit December 2, 2016
For some unknown reason the script was broken today. Above code used to read: "$(cat /sys/class/drm/card0-HDMI-A-1/status" but I had to change
card1and the code above has been revised as such. I can't explain what changed on my system other than regular Ubuntu updates since November 26, 2016.
Edit December 14, 2016
Above code needed to be switched again back to: "$(cat /sys/class/drm/card0-HDMI-A-1/status". Instead of revising code between
card1depending on boot, revise program to reference
card*to capture both scenarios.