Workflow to switch between audio devices

I have a Hammerspoon script which contains a whitelist of audio in and out devices, and I use this to switch between the audio devices I want to use. This works well with directly connected devices, but has some bugs with normal bluetooth devices, and doesn’t work at all with AirPods.

So I’m looking for a new solution. Something that with one simple [shortcut|click|something I can automate] will allow me to switch audio so that whatever I’m listening actually comes out through what I want to listen to it with.

(Hammespoon script included for fun)

outputArray = {}
-- outputArray["Speaker"] = "Impresario"
outputArray["Astro A50 Game"] = "Astro A50"
outputArray["Built-in Output"] = "Internal Speaker"
outputArray["MacBook Pro Speakers"] = "Internal Speaker"
outputArray["FiiO USB DAC-E10"] = "FiiO"
outputArray["Logitech G930 Headset"] = "G930"
outputArray["Tom’s AirPods Pro"] = "Airpods"
outputArray["WH-1000XM3"] = "Sony"
-- outputArray["CalDigit Thunderbolt 3 Audio"] = "Thunderbolt"
outputArray["Jabra Link 380"] = "Jabra"

inputArray = {}
-- inputArray["CalDigit Thunderbolt 3 Audio"] = "Thunderbolt"
inputArray["WH-1000XM3"] = "Sony"
inputArray["MacBook Pro Microphone"] = "Internal Microphone"
inputArray["Tom’s AirPods Pro"] = "Airpods"
inputArray["Jabra Link 380"] = Jabra

current_output = hs.audiodevice.defaultOutputDevice()
current_input = hs.audiodevice.defaultInputDevice()

function switch_output()
    for _, device in pairs(hs.audiodevice.allOutputDevices()) do
        if device and device ~= current_output and outputArray[device:name()] then
            hs.alert.show("Audio out: " .. outputArray[device:name()])
            current_output = device
            device:setDefaultOutputDevice()
            break
        end
    end
end

function switch_input()
    for _, device in pairs(hs.audiodevice.allInputDevices()) do
        if device and device ~= current and inputArray[device:name()] then
            hs.alert.show("Audio in: " .. inputArray[device:name()])
            current = device
            device:setDefaultInputDevice()
            break
        end
    end
end

There’s some prior art here that might be helpful.

I do love me some Alfred :slight_smile:
Edit: Turns out https://github.com/sampayo/Alfred-WorkFlows still works, 8 years after creation! I might edit the applescripts to add whitelisting of devices, but since I can just write “input jabra”, that doesn’t seem like it would save me that much time…

1 Like

Wow - with GUI scripting no less!

I use Ears by ClickOnTyler.
Its a pretty simple and straightforward interface. Once the window pops up, outputs are mapped to numbers and inputs are mapped to letters. Two keypresses + enter and the pathways are all set.
Its fully keyboard shortcut enabled. I have (hyper = CTRL-SHIFT-OPT-CMD and mapped to CAPS LOCK):

  • hyper-F12 - brings up Ears interface
  • hyper-F11- auto-connect to my Bose QC’s (set as “favorite”)
  • hyper-backtick - auto-mute all inputs (at the system level, so independent of the conferencing app being used).

It’s a slick little app.

2 Likes

This is at least as good, and of course far better if you don’t want to rely on Alfred.
I do rely on Alfred, and hate learning new keyboard combos, but I’m trying Ears now.