I like to switch the sound output from Speaker to USB headphone with a Shortcut. Is there a way to accomplish this?
-
1Closely related: http://askubuntu.com/questions/41858/shortcut-to-switch-between-analog-stereo-output-hdmi-audio-output – Takkat Jun 28 '12 at 06:16
9 Answers
Automated solution https://ubuntuforums.org/showthread.php?t=1370383 It works on Ubuntu 18.04
Open the terminal and type:
sudoedit /usr/local/bin/audio-device-switch.shCopy and paste the below code in nano editor
Save it and close nano editor.
sudo chmod 755 /usr/local/bin/audio-device-switch.shSystem -> Preferences -> Keyboard Shortcuts
Press Add and enter Switch between audio devices as name and audio-device-switch.sh as command and press Apply.
Select the newly added shortcut row and click on the shortcut column. 8. Choose a shortcut combination – e.g. Win + F12.
That's all - now you can plug in your plug in your HDMI device and switch the audio output by pressing the chosen shortcut combination.
Code:
#!/bin/bash
declare -i sinks_count=pacmd list-sinks | grep -c index:[[:space:]][[:digit:]]
declare -i active_sink_index=pacmd list-sinks | sed -n -e 's/\*[[:space:]]index:[[:space:]]\([[:digit:]]\)/\1/p'
declare -i major_sink_index=$sinks_count-1
declare -i next_sink_index=0
if [ $active_sink_index -ne $major_sink_index ] ; then
next_sink_index=active_sink_index+1
fi
#change the default sink
pacmd "set-default-sink ${next_sink_index}"
#move all inputs to the new sink
for app in $(pacmd list-sink-inputs | sed -n -e 's/index:[[:space:]]([[:digit:]])/\1/p');
do
pacmd "move-sink-input $app $next_sink_index"
done
#display notification
declare -i ndx=0
pacmd list-sinks | sed -n -e 's/device.description[[:space:]]=[[:space:]]"(.*)"/\1/p' | while read line;
do
if [ $next_sink_index -eq $ndx ] ; then
notify-send -i notification-audio-volume-high "Sound output switched to" "$line"
exit
fi
done
- 103
- 181
-
great work! don't try to run the script as root (e.g. with sudo), it will not work. just run as normal user – sotix Nov 30 '20 at 16:44
-
I had to fix the last if and do to match the bash syntax. The script works perfectly!. – Gor Stepanyan Dec 22 '20 at 14:39
-
I just realized, that the indices of sinks are not necessarily counted from 0 to COUNT-1, so you have to get list of indices and then move to the next one from the list – fairtrax Jan 02 '21 at 09:53
Check for port names
pactl list sinks(I remove non needed sinks output):Sink #1 State: RUNNING Name: alsa_output.pci-0000_00_1b.0.analog-stereo Description: Built-in Audio Analog Stereo Driver: module-alsa-card.c ... Ports: analog-output-speaker: Speakers (priority: 10000, not available) analog-output-headphones: Headphones (priority: 9000, available) Active Port: analog-output-headphones Formats: pcmSet sink port using
pactl set-sink-port:pactl set-sink-port 1 analog-output-speakeror
pactl set-sink-port 1 analog-output-headphonesIf you are using a removable device (Example: USB devices), it's better to use sink
nameinstead ofid. For example:pactl set-sink-port alsa_output.pci-0000_00_1b.0.analog-stereo analog-output-headphones
Reference: man pactl
- 49,295
-
1
-
1Come'n :) you were still waiting, I just fill it in case someone need it come by. – user.dz Feb 15 '14 at 20:00
-
Really. I haven't found a solution for that. But i stopped trying to find one a long time ago. – Evenbit GmbH Feb 15 '14 at 20:04
-
1
Since everyone's been adding their solutions, here's mine.
#!/bin/sh
currentline=$(pactl list short sinks | grep -n "$(pactl get-default-sink)" | cut -d: -f 1)
lastline=$(pactl list short sinks | wc -l)
nextline=$(($currentline % $lastline + 1))
nextsink=$(pactl list short sinks | head "-n$nextline" | tail -1 | cut -f 1)
pactl set-default-sink $nextsink
for sinkinput in $(pactl list short sink-inputs | cut -f 1); do
pactl move-sink-input $sinkinput "@DEFAULT_SINK@"
done
edit: My new motherboard comes with ALC4080. pactl now lists both the front and the rear output jack as available, although only one of them can actually be in use at the same time. Hence, cycling through the outputs with this script no longer works. The loop gets stuck at the last available output.
- 210
I have Ubuntu 20, and realized, that the indices of devices are not counted from 0 to COUNT-1. So I had to modify the script. This one works now:
#!/bin/bash
declare -i sinks_count=pacmd list-sinks | grep -c index:[[:space:]][[:digit:]]
if [ $sinks_count -eq 0 ] ; then
exit
fi
declare -i active_sink_index=pacmd list-sinks | sed -n -e 's/\*[[:space:]]index: [[:space:]]\([[:digit:]]\)/\1/p'
active_index_position_found=0
let next_sink_index=-1
while read index ;
do
declare -i ind=($(echo $index | tr -dc '[0-9]+'))
if [ $next_sink_index -lt 0 ] ; then
export next_sink_index=$ind
fi
if [ $active_index_position_found -eq 1 ] ; then
export next_sink_index=$ind
break;
fi
if [ $active_sink_index -eq $ind ] ; then
export active_index_position_found=1
fi
done < <(pacmd list-sinks | grep index:[[:space:]][[:digit:]])
#change the default sink
pacmd "set-default-sink ${next_sink_index}"
#move all inputs to the new sink
for app in $(pacmd list-sink-inputs | sed -n -e 's/index:[[:space:]]([[:digit:]] )/\1/p');
do
pacmd "move-sink-input $app $next_sink_index"
done
#display notification
declare -i ndx=0
pacmd list-sinks | sed -n -e 's/device.description[[:space:]]=[[:space:]]"(.*)" /\1/p' | while read line;
do
if [ $next_sink_index -eq $ndx ] ; then
notify-send -i notification-audio-volume-high "Sound output switched to" "$line"
exit
fi
ndx+=1
done;
- 111
-
This still didn't work for me. I got the following error when I tried to run the script.
Sink 2945029504090482540 does not exist– Heisenberg Sep 20 '21 at 13:52
It was not working with two digit indices. In my case Nvidia HDMI sink was with index 23. Here is a working solution :)
#!/bin/bash
declare -i sinks_count=pacmd list-sinks | grep -Pc 'index:\s+\d+'
if [ $sinks_count -eq 0 ] ; then
exit
fi
declare -i active_sink_index=pacmd list-sinks | grep -Po '\*\s+index:\s+\K\d+'
active_index_position_found=0
let next_sink_index=-1
while read index ;
do
declare -i ind=($(echo $index | tr -dc '[0-9]+'))
if [ $next_sink_index -lt 0 ] ; then
export next_sink_index=$ind
fi
if [ $active_index_position_found -eq 1 ] ; then
export next_sink_index=$ind
break;
fi
if [ $active_sink_index -eq $ind ] ; then
export active_index_position_found=1
fi
done < <(pacmd list-sinks | grep -Po 'index:\s+\K\d+')
#change the default sink
pacmd "set-default-sink ${next_sink_index}"
#move all inputs to the new sink
for app in $(pacmd list-sink-inputs | grep -Po 'index:\s+\K\d+');
do
pacmd "move-sink-input $app $next_sink_index"
done
The only script version that worked for me was thew one @rosetta-stoned shared above. Scripts from other comments did not. [OS: Ubuntu Mate 22.04 LTS (Jammy Jellyfish) 64-bit]
I further extended the script with a line to play a sound. This way you can hear sound in the devices as you keep switching output devices. Hearing sound in the desired device will mean you don't need to swap around anymore.
#!/bin/bash
declare -i sinks_count=pacmd list-sinks | grep -Pc 'index:\s+\d+'
if [ $sinks_count -eq 0 ] ; then
exit
fi
declare -i active_sink_index=pacmd list-sinks | grep -Po '\*\s+index:\s+\K\d+'
active_index_position_found=0
let next_sink_index=-1
while read index ;
do
declare -i ind=($(echo $index | tr -dc '[0-9]+'))
if [ $next_sink_index -lt 0 ] ; then
export next_sink_index=$ind
fi
if [ $active_index_position_found -eq 1 ] ; then
export next_sink_index=$ind
break;
fi
if [ $active_sink_index -eq $ind ] ; then
export active_index_position_found=1
fi
done < <(pacmd list-sinks | grep -Po 'index:\s+\K\d+')
#change the default sink
pacmd "set-default-sink ${next_sink_index}"
#move all inputs to the new sink
for app in $(pacmd list-sink-inputs | grep -Po 'index:\s+\K\d+');
do
pacmd "move-sink-input $app $next_sink_index"
done
paplay /usr/share/sounds/mate/default/alerts/sonar.ogg
- 11
-
Worked perfectly for me on KDE Neon, just had to adapt the audio path to
/usr/share/sounds/gnome/default/alerts/sonar.ogg– Lauloque Feb 29 '24 at 15:55
I added support for "prev" and "next" arguments, since I have quite a few devices to choose from. Just bind 2 keys.
#!/bin/bash
declare direction="$1"
declare -i sinks_count=pacmd list-sinks | grep -Pc 'index:\s+\d+'
if [ $sinks_count -eq 0 ] ; then
exit
fi
declare -i active_sink_index=pacmd list-sinks | grep -Po '\*\s+index:\s+\K\d+'
readarray -t indexes < <(pacmd list-sinks | grep -Po 'index:\s+\K\d+')
declare indexes_count=${#indexes[@]}
declare active_index=-1
for i in "${!indexes[@]}"; do
if [[ "${indexes[$i]}" = "${active_sink_index}" ]]; then
active_index=$i;
fi
done
declare next_index=$((( $active_index + 1 ) % $indexes_count))
declare prev_index=$((( $active_index - 1 ) % $indexes_count))
declare next_sink_index=${indexes[$next_index]}
declare prev_sink_index=${indexes[$prev_index]}
declare sink_to_use="${next_sink_index}"
if [ "$direction" = "prev" ] ; then
sink_to_use="${prev_sink_index}"
fi
Change the default sink
pacmd "set-default-sink ${sink_to_use}"
Move all inputs to the new sink
for app in $(pacmd list-sink-inputs | grep -Po 'index:\s+\K\d+');
do
pacmd "move-sink-input $app $sink_to_use"
done
- 1
Error: No PulseAudio daemon running, or not running as session daemon.
If you see this you are using pacmd,which no longer works for me.You need to use pactl instead.
Here is how:
Copy this :
#!/bin/sh
currentline=$(pactl list short sinks | grep -n "$(pactl get-default-sink)" | cut -d: -f 1)
lastline=$(pactl list short sinks | wc -l)
nextline=$(($currentline % $lastline + 1))
nextsink=$(pactl list short sinks | head "-n$nextline" | tail -1 | cut -f 1)
pactl set-default-sink $nextsink
for sinkinput in $(pactl list short sink-inputs | cut -f 1); do
pactl move-sink-input $sinkinput "@DEFAULT_SINK@"
done
paplay /usr/share/sounds/mate/default/alerts/sonar.ogg
Open an editor and paste . Save it as
audio-device-switch.shcopy it to
/usr/local/bin/open a terminal and type
sudo chmod 755 /usr/local/bin/audio-device-switch.shGo to System -> Preferences -> Keyboard Shortcutsclick
Addand to command enteraudio-device-switch.sh. give it a name likeSwitch AudioClickApply.Select the newly added shortcut row and click on the shortcut column and choose a shortcut key combination.
My system: Ubuntu Mate 24.04.1 LTS (Noble Numbat) 64-bit. Updating from Ubuntu Mate 22.04 LTS (Jammy Jellyfish) broke the pacmd based script for me.
Honourable mentions: This solution is a merge of previous solutions in this thread. Code is based on what user j2l4e shared, I only added the last line so you can hear a sound as you keep switching output devices. Hearing the sound in the desired device will mean you don't need to swap around anymore. steps to add keyboard shortcuts are based on matreshkin's post above.
- 11
Do this in 2 steps:
Find a command line setting to change back/forth between these settings.
Add these to some key combinations. Systems Settings >> Keyboard >> Shortcuts
- 14,538
-
How can one find out, what command line setting is needed to switch the sound output? Is there a way to trace what happens, when I do it with the GUI? – Evenbit GmbH Jun 28 '12 at 05:43
-
No, you need to use amixer (command line) and/or alsamixer (char-mode) in a terminal. These are old-school, and require some effort to master. Start by adding output from amixer -c 0 to your question .. – david6 Jun 28 '12 at 07:16
-
1I find that command and successfully run a shortcut to switch between analog and HDMI output, see my answer here. – Pablo Bianchi Mar 30 '17 at 22:40