Toggle between two Audio Output Sources (Airplay Speakers)

I often plug my MacBook into a secondary display using HDMI (Samsung TV). While working, I like to popup a BTT Webview of a streaming video site, but the audio was always stuck to my MacBook and not playing through TV Speakers.
Screen Shot 2020-02-25 at 8.50.15 AM
I would then select the Output device from the volume menu bar to change audio to Samsung TV. I decided to write a toggle for the Touch Bar to complete this audio output selection for me. Enjoy!

-- Applescript to toggle between two sound outputs by Line number, as they appear in the System Prefs. Sound Control Panel.

set output1 to 1 --change this to the actual 'line number' of your first output speaker
set output2 to 2 --change this to the actual 'line number' of your second output speaker selection
--the rest of the script will use these vales to toggle between the two

tell application "System Preferences"
reveal anchor "output" of pane id "com.apple.preference.sound"
end tell

tell application "System Events"
tell application process "System Preferences"
repeat until exists tab group 1 of window "Sound"
end repeat
tell tab group 1 of window "Sound"
if (selected of row output1 of table 1 of scroll area 1) then
set selected of row output2 of table 1 of scroll area 1 to true
else
set selected of row output1 of table 1 of scroll area 1 to true
end if
end tell
end tell
end tell
quit application "System Preferences"

Enjoying This Preset? PayPal.me/K2DesignLab

This is amazing, thank you!!

1 Like

This is amazing and I love it. Slight problem though, if I have my Mac plugged into a display with speakers it kind of ruins this by making:
output 1- Mac
output 2- Display
output 3- Headphones
Is there some fancy scripting magic to make this IF statement apply to 3 variables?

This is gold! Thank you!

To @mvonb and to whoever finds it useful, I adapted it to cycle between 3 devices

-- Applescript to toggle between two sound outputs by Line number, as they appear in the System Prefs. Sound Control Panel.

set output1 to 4 --change this to the actual 'line number' of your first output speaker
set output2 to 5 --change this to the actual 'line number' of your second output speaker selection
set output3 to 1 --change this to the actual 'line number' of your second output speaker selection
--the rest of the script will use these vales to toggle between the two

tell application "System Preferences"
reveal anchor "output" of pane id "com.apple.preference.sound"
end tell

tell application "System Events"
tell application process "System Preferences"
repeat until exists tab group 1 of window "Sound"
end repeat
tell tab group 1 of window "Sound"
if (selected of row output1 of table 1 of scroll area 1) then
set selected of row output2 of table 1 of scroll area 1 to true
else if (selected of row output2 of table 1 of scroll area 1) then
set selected of row output3 of table 1 of scroll area 1 to true
else
set selected of row output1 of table 1 of scroll area 1 to true
end if
end tell
end tell
end tell
quit application "System Preferences"
1 Like

Adapted it so it works with Mac OS Monterey (June 2022), assuming you only have 2 outputs (Macbook Speakers & Airplay).

-- Applescript to toggle between two sound outputs by Line number, as they appear in the System Prefs. Sound Control Panel.
set output1 to 1 --change this to the actual 'line number' of your first output speaker
set output2 to 3 --change this to the actual 'line number' of your second output speaker selection
--the rest of the script will use these vales to toggle between the two
tell application "System Preferences"
reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events"
tell application process "System Preferences"
repeat until exists tab group 1 of window "Sound"
end repeat
tell tab group 1 of window "Sound"
if (selected of row output1 of table 1 of scroll area 1) then
set selected of row output2 of table 1 of scroll area 1 to true
else
set selected of row output1 of table 1 of scroll area 1 to true
end if
end tell
end tell
end tell
quit application "System Preferences"

`The Apple Shortcuts has a Set Audio Output shortcut now.

If the gui coding changes in the future, you could set up three Set Audio Output shortcuts and trigger them with BTT.

You might even use the new BTT action Cycle Through Multiple Actions (on repeated trigger) to put it all on one button.

Your script works better, i see that Shortcuts doesn't give access to all audio output options.

Stopped working (for me) in Ventura 13.0. Played around with it (not familiar with applescript) but didn't get it to work. ?

You can use a command line tool called SwitchAudio

Or you can install with homebrew

Once installed you run switchaudiosource -a to list all the devices

(note: the path to the executable is because I installed with homebrew, your path may differ is installing manually (I am assuming readers have some command line experience and understand paths etc in the terminal))

~ % switchaudiosource
Please specify audio device.
Usage: /opt/homebrew/Cellar/switchaudio-osx/1.1.0/SwitchAudioSource [-a] [-c] [-t type] [-n] -s device_name | -i device_id | -u device_uid
  -a             : shows all devices
  -c             : shows current device

  -f format      : output format (cli/human/json). Defaults to human.
  -t type        : device type (input/output/system).  Defaults to output.
  -n             : cycles the audio device to the next one
  -i device_id   : sets the audio device to the given device by id
  -u device_uid  : sets the audio device to the given device by uid or a substring of the uid
  -s device_name : sets the audio device to the given device by name

I only want to toggle between headphones or display audio, so on the BTT action (Run Script - Apple Script) I have

set the currentAudioSource to (do shell script "/opt/homebrew/bin/switchaudiosource -c")
if currentAudioSource is equal to "Display Audio" then
	do shell script "/opt/homebrew/bin/switchaudiosource -s \"External Headphones\""
else
	do shell script "/opt/homebrew/bin/switchaudiosource -s \"Display Audio\""
end if

first line sets the variable currentAudioSource to whatever is currently set

if it is set to Display Audio then switch devices to External Headphones,

f anything else (including headphones) then switch to Display Audio.

But you can be as specific as you like using whatever logic you need :slight_smile:

Thanks for that suggestion! That is helpful. FYI, I tried that first (compiling it that is - supply chain security is a hot topic now a-days - trying to minimize what 3rdparty installers/frameworks pull in), but there are a bunch of deprecated 10.6 warnings on "AudioDeviceGetPropertyInfo" in the C code, not to mention that the macOS deployment target has been set to 10.6. Tried looking at the docs to change that call and target to what is now supported (in Ventura), but that step was into a space that I'm not familiar with. But it sounds like this is the way to go.

1 Like