To switch to HDMI audio output (of monitor) and back to normal audio output from system audio jack (for headphones, as my monitor doesn't have audio out), I find myself opening up sound preferences and selecting the right channel everytime. Is there any way I can create a toggle button in the panel or assign some shortcut key to toggle since I do the switching so often.
:aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: STAC92xx Analog [STAC92xx Analog] Subdevices: 1/1 Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 3: HDMI 0 [HDMI 0] Subdevices: 0/1 Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 7: STAC92xx Digital [STAC92xx Digital] Subdevices: 1/1 Subdevice #0: subdevice #010 Answers
With pulseaudio we are able to select the output sink from the command line:
pacmd set-default-sink "SINKNAME"This command can be used in a launcher, script or even assigned to a keyboard shortcut for fast switching between different sinks. Please replace "SINKNAME" by the name or number of your desired sink. A list of known sinks with their associated numbers and names is given by the command:
pacmd list-sinksNote: Changing the output sink through the command line interface can only take effect if stream target device reading is disabled. This can be done by editing the corresponing line in /etc/pulse/default.pa to:
load-module module-stream-restore restore_device=falseAlternatively we could run pulseaudio to simultaneously output sound to the internal audio device, and to the hdmi-device by running paprefs with the option to add a virtual output device:
I found this very annoying myself and wrote a script to toggle the output:
#!/bin/bash
CURRENT_PROFILE=$(pacmd list-cards | grep "active profile" | cut -d ' ' -f 3-)
if [ "$CURRENT_PROFILE" = "<output:hdmi-stereo+input:analog-stereo>" ] ; then pacmd set-card-profile 0 "output:analog-stereo+input:analog-stereo"
else pacmd set-card-profile 0 "output:hdmi-stereo+input:analog-stereo"
fiAnd then bound an unused key on my keyboard to execute it (see this).
2An alternative to Sound Switcher Indicator (which requires adding a PPA) is to create a command (or a script) and call it with a shortcut:
In my case was hdmi-stereo-extra1+input profile, so in one line would be:
[[ $(pacmd list-cards | grep "active profile" | cut -d " " -f 3-) = "<output:hdmi-stereo-extra1+input:analog-stereo>" ]] && \ pacmd set-card-profile 0 "output:analog-stereo+input:analog-stereo" || \ pacmd set-card-profile 0 "output:hdmi-stereo-extra1+input:analog-stereo"You can use a custom shortcut (gnome-control-center keyboard) to execute it with bash -c (will warn you if there is any conflict with other shortcut):
I use:
- Super + Alt + o: Toggle the output between headphones and HDMI.
- Super + Alt + Up: Vol Up
- Super + Alt + Down: Vol Down
Also, you can add an alias to your .bashrc.
Tested on Ubuntu 16.04 and 18.04
If you want above behavior on a script, I made some changes based on @user829996 answer:
#!/bin/bash
set -euo pipefail # strict mode
activeProfile() { pacmd list-cards | grep "active profile" | cut -d " " -f 3-; }
CURRENT_PROFILE="$(eval activeProfile)"
# If it doesn't work run pacmd list-cards and try the other outputs from profile section
ANALOG_PROFILE="output:analog-stereo+input:analog-stereo"
HDMI_PROFILE="output:hdmi-stereo-extra1+input:analog-stereo"
if [ "$CURRENT_PROFILE" = "<output:hdmi-stereo-extra1+input:analog-stereo>" ] ; then pacmd set-card-profile 0 "$ANALOG_PROFILE"
else pacmd set-card-profile 0 "$HDMI_PROFILE"
fi
activeProfile Edit
the code for this answer/explanation is outdated and has some bugs. I'm keeping this Up-to-date here:
Yet Another Sink Switcher Script
tested on Ubuntu 16 and 18
But this one lets you switch only the audio of the application you want.
USAGE: Focus the application you want to change its sink and run this script. That's it!!!
This script detects the application that is on focus, finds all audios playing from it, and switch them to the next available sink.
Explaining the script
We need to find the PID of the application on focus
But first we need the xid
xprop -root _NET_ACTIVE_WINDOW Then insert it here $xid to get the pid of the application
xprop -id $xid _NET_WM_PIDNow we need find the sink-inputs related to that PID
First let's linearize the output of the command pacmd list-sink-inputs to list one sink-input per line, showing its index, sink and pid on the same line
pacmd list-sink-inputs | grep -E 'index:|sink:|process.id' | tr '\n' ' ' | tr -d '"' | sed -e 's/index:/\n/g' | tail -n +2let's analyze it step by step:
grep -E 'index:|sink:|process.id only keep lines that contain index:, sink: or process.id
tr '\n' ' ' joins all lines
tr -d '"' removes all " characters. Necessary to get the pid without quotes
sed -e 's/index:/\n/g' replaces all index: occurrences with a new line character \n
tail -n +2 removes the first line because it's empty
And the result is something like this:
180 sink: 0 <alsa_output.pci-0000_00_00.1.hdmi-stereo-extra1> application.process.id = 3521 181 sink: 1 <alsa_output.pci-0000_00_01.0.analog-stereo> application.process.id = 2733 182 sink: 0 <alsa_output.pci-0000_00_00.1.hdmi-stereo-extra1> application.process.id = 13752
Let's analyze one line to understand what it means:
# 182 sink: 0 <alsa_output.pci-0000_00_00.1.hdmi-stereo-extra1> application.process.id = 13752
182 is the sink-input index, 0 is the sink index, and 13752 at the end, is the pid of the belonging application
Then we iterate through each line
... | while IFS= read -r line || [ -n "$line" ]; do sink_input_pid=$(echo $line | awk '{print $NF}')And finally filter only the sink-input's pid that matches the focused app's pid
if [ $sink_input_pid = $app_pid ]; thenExtracting data
With awk we can get the elements we need
sink_input_index=$(echo $sink_input | awk '{print $1}')
current_sink_index=$(echo $sink_input | awk '{print $3}')Get numbers of sinks, to know when the rotation of sinks should restart from 0.
sink_list_size=${#sink_list_array[@]}Finding next sink, we have to iterate through the list of sinks, to know which one matches current_sink_index and to know the index of the next sink.
i=0
for sink in "${sink_list_array[@]}"; do i=$((($i+1)%sink_list_size)) # i++ mod(#sinks) if [ $sink = $current_sink_index ]; then next_sink_index=${sink_list_array[i]} break fi
doneAnd finally, we move the sink-input to play in next_sink_index
pacmd move-sink-input $sink_input_index $next_sink_indexNote on Ubuntu 16.04:
When configuring the shortcut key, I couldn't make it work with ubuntu's shortcut manager. So I had to install compizconfig-settings-manager
sudo apt-get install compizconfig-settings-manager 2 If you are using Gnome Shell instead of Unity you can install the extension below. You'll then be able to switch from the volume short-cut in the top panel.
Since there is only one soundcard visible in the screenshot, I think the output of this soundcard should be switched.
For example: I have a Notebook with one integrated soundcard, but it has a digital output (SPDIF) when docked.
So what I wanted to do is switch the active output or "Profile" in pulseaudio.
I found the commands that do exactly that:
pacmd set-card-profile 0 output:analog-stereo
pacmd set-card-profile 0 output:iec958-stereo+input:analog-stereoWhat I did to get the correct names for my desired output-setting--here, digital output, but analog (micro) input--was:
pacmd list | grep output I've been trying to find a solution to this problem as well. As of Ubuntu 11.04 this does not seem to be possible directly, I only found this guide to add both HDMI and Analog as separate outputs, so pacmd shows 3 sinks now. Then it is possible to switch between sinks using the above commands. (see also)
But apparently Ubuntu 11.11 will get a PulseAudio with jack detection system. According to the website below, David Henningsson has coded a detection via udev so pulse audio automatically gets switched to the last added output, including switching between different profiles of the same soundcard (as is the case with your and my setup). (see here)
So I'm hoping this will work, when I try the final version next Friday.
Based on many of the previous answers, I wrote a script that sets the playback sink alternating between the available ones.
The best way to use it is by creating a keyboard shortcut to run it, so every time you press that key combination the audio is redirected to the next available sink.
The code is available here:
In my case the analog options where not in the list. Install pavucontrol:sudo apt install pavucontrol
Could fix the issue, by starting the application:
- Start the app via terminal, by entering:
pavucontrol(enter) - Go to the 'Configuration' tab.
- Select Analoge stereo output profile at Intern Sound
Now I could here sound and select different profiles (under Linux Mint):
Is there any way I can create a toggle button in the panel
I wrote an indicator applet that lets you switch the sound output.
1