Jump to content

Toggle sound output on hotkey with Notification Center output


Recommended Posts

Hello everyone,

 

here is my first post on this forum.

 

I know there is some other similar posts on the forum... I've read them... but they don't do exactly what I'm looking for. Let me explain myself clearly and you will understand :

 

I have an "old" applescript which toggle the sound output on a press of a hotkey (F7) between 2 different outputs : my display's speakers or my headset. As a result it also send a notification to Growl saying something like "Sound output changed to...".

 

Here is the actual AppleScript :

 

tell application "System Preferences"
	activate
	set current pane to pane "com.apple.preference.sound"
end tell

tell application "System Events"
	tell application process "System Preferences"
		tell tab group 1 of window "Son"
			click radio button "Sortie"
			if (selected of row 2 of table 1 of scroll area 1) then
				set selected of row 3 of table 1 of scroll area 1 to true
				set deviceselected to "HEADSET"
			else
				set selected of row 2 of table 1 of scroll area 1 to true
				set deviceselected to "MAC"
			end if
		end tell
	end tell
end tell

tell application "System Preferences" to quit

tell application "Growl"
	set the allNotificationsList to {"Sound Notification"}
	set the enabledNotificationsList to {"Sound Notification"}
	
	register as application "Toggle Sound Output" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "System Events"
	
	notify with name "Sound Notification" title "Audio Output" description deviceselected application name "Toggle Sound Output"
	
end tell

 

 

 

This script worked well in Alfred 1 as a "trigger" but today I'm a proud new owner of the great Alfred V2 and I'd like to directly integrate this script into a Workflow. And here starts my problems :

 

- I can integrate the script to activate after the press of an hotkey... but I'm unable to output a notification center visual result

or

- I can output a notification center result but without any {query} (of course) so without any usefull information.

 

I tried some of the workflows I've found on your nice forum (Next Audio Output Device...) but what they do is that they ask me to type "o u t p u t"... then to use my keyboard or mouse to choose which sound output I want. It's "long" ! I'd like to press my hotkey and "boum" automatically switch from headsets to display's speakers and vice-versa ! 

 

As you understood at this point, I define myself as "noob" concerning scripting/programming. I usually succeed to get my solution by copying/pasting parts of codes from different scripts... Alfred is so cool I'd like to have more learning about that, that's also the reason I post here :-)

 

 

Sorry for the long message. Hope someone would give me some solution.

 

Thanks

Link to comment

my last post was done during the night and I was missing some sleep. This morning I found the solution to my issue. If anyone have suggestions to simplify that I would be pleased to know :

 

fqRUhEx.png

 

and here is the correct code of the first script :

 

 

tell application "System Preferences"
activate
	set current pane to pane "com.apple.preference.sound"
end tell

tell application "System Events"
	tell application process "System Preferences"
		tell tab group 1 of window "Son"
			click radio button "Sortie"
			if (selected of row 3 of table 1 of scroll area 1) then
				set selected of row 4 of table 1 of scroll area 1 to true
				set deviceselected to "HEADSET"
return "HEADSET"
			else
				set selected of row 3 of table 1 of scroll area 1 to true
				set deviceselected to "MAC"
return "MAC"
			end if
		end tell
	end tell
end tell
tell application "System Preferences" to quit

 

As you can see my error of yesterday night was in forgetting the 2 "return" ... so the script didn't send any information to Notification Center ! (When awake it's obvious).

 

You should wonder why I have a second script inside the workflow ? The reason is because when running my workflow it seems that the first script stop to answer after the "end if" line. So it never quit the "System Preferences" pane ! (maybe I'm not totally awake and I'm missing something obvious ?).

So that's why I have a second script... just having :

 

tell application "System Preferences" to quit

 

That's it.

 

So what this simple workflow do exactly :

 

- I press on F6

- System Preferences open briefly on my display and automatically change the sound output from my Mac's speaker to my headset (or vice-versa)

- System Preferences close and I get a nice looking Notification Center pop-up saying "TOGGLE SOUND OUTPUT : HEADSET" (or "MAC")

 

 

 

 

And here is my questions for you :

 

- Do you see any way to simplify everything ? 

- Is there a way to have the "system preferences" pane to be invisible on the display when running the script ?

 

I don't need to change from or to other sound outputs sources. The only other one I would sometimes use is "HDMI" ... but I will think about an other simple workflow using "launch XBMC media center" as a trigger to "Toggle sound output to HDMI". What do you think ? 

Link to comment
  • 2 weeks later...

I'd like a copy of this and would love to see a way to mute the volume included.

 

Ok... not sure how to share things... but I have a try with my Box.com account : https://www.box.com/s/yydcplhdj7vzt3dhqhly

 

That's the "Toggle Sound Output Workflow", hope you like it.

 

Concerning a way to mute the volume that's something to include in the "script"... it's possible and I think it already exist a workflow on the forum concerning that. If you search you will find it I think.

Link to comment

OK, unfortunately with ML we need to use gui scripting for this particular issue because Apple has changed the sound a bit, BUT, you don't HAVE to activate system prefs. That brings it to the front.

 

Check out the last post by "Lri" HERE

where Lri states ... 

  • reveal anchor "" of pane id "" reveals a specific tab

This works for me in selecting a specific output, and yes, System Prefs does show up in the dock, but it is not made active or visible. The script runs, then goes away.

Link to comment

I am doing something much less complex. I just want to be able to mute or unmute the sound. I use a keyword, "mute". If I type "mute on" the sound is muted; "mute off" unmutes, and "mute" toggles the mute status. I don't set sound levels (although it would be pretty easy to modify my workflow so that if you type "mute ##" the sound is set to level "##". Anything argument but "on" or "off" causes the script to just do nothing. Very simple, but meets my needs. 

 

I just use a keyword trigger to fire a bash script, that reads as below. Note that I force the keyword to lowercase in the first line. You could obviously tie this to different triggers if you wanted to. 

 

Hope this is helpful.

 

-----

 

 

 

# If no argument is given, toggle the muted setting.
# If 'on' or 'off' is the argument, set muted setting accordingly.
# If argument is anything else, do nothing.
 
arg=`echo "{query}" | tr "[:upper:]" "[:lower:]"`
muted=`osascript -e "output muted of (get volume settings)"`
 
case "$arg" in
  on)
    setting="with"
    ;;
  off)
    setting="without"
    ;;
  "")
    if [ "$muted" == "false" ]
      then
      setting="with"
    else
      setting="without"
    fi
    ;;
  *)
    setting=""
esac
 
if [ "$setting" != "" ]; then `osascript -e "set volume $setting output muted"` ; fi
Link to comment

Thanks a lot RodgerWW, you gave me the answer I was looking for (and thanks to "Lri" of course). Here is my new version of the script :

 

tell application "System Preferences"
	reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
	tell tab group 1 of window "Son"
		click radio button "Sortie"
		if (selected of row 3 of table 1 of scroll area 1) then
			set selected of row 4 of table 1 of scroll area 1 to true
			set deviceselected to "HEADSET"
return "HEADSET"
		else
			set selected of row 3 of table 1 of scroll area 1 to true
			set deviceselected to "MAC"
return "MAC"
		end if
	end tell
end tell
quit application "System Preferences"

 

- With that I don't need anymore to have a separate script to tell application System Preferences to quit !

- I don't have anymore the System Preferences pane which open and pop-up on the screen !

 

- If you have an english system (like most of you I think), you will have to change "SON" by "SOUND" and "SORTIE" by "OUTPUT"

- Also, you will have to change "ROW 4" by the number corresponding to the sound output you want to be selected. Same thing for the "Else" where you have "ROW 3". You can find which "number" it is for you by "control-click" the sound icon on your menu bar : here you'll find the list of all your sound output options in order (1,2,3...).

 

 

And here is the new link to download the new resulting workflow if you wish : https://www.box.com/s/79iprwo8nehs0v7bzin6

Hope you will like it ;-)

Edited by mtlx
Link to comment

OK, cool. Now I can toggle between my only two used outputs with a shortcut!

 

I needed to do a tiny bit of modification to the scripting, not just French/English translation, but flow overall, because for ME, the System Preferences would not close after run due to the "return" values within the if statements. I have no idea why really, but with farting around in the Applescript Editor, I modified the initial script as shown below. And now everything works for me, as 'mtlx' stated it should.

 

MY script looks like this:

 

 

tell application "System Preferences"
   reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
   tell tab group 1 of window "Sound"
   click radio button "Output"
      if (selected of row 1 of table 1 of scroll area 1) then
      set selected of row 2 of table 1 of scroll area 1 to true
      set deviceselected to "Shure SRH440 Headphones"
      else
      set selected of row 1 of table 1 of scroll area 1 to true
      set deviceselected to "Internal Speakers"
      end if
   end tell
end tell
quit application "System Preferences"
return deviceselected
 

Basically, I removed the two named returns, and at the end of the script simply returned the value set with deviceselected. As far as I know, the value will only be one thing due to the if/else. Now on my system, the hotkey press will simply toggle between my 2 outputs (flashing System Prefs only in the dock for a second, then quitting), and once switched, I get the notification telling me which is active [or selected].

Edited by RodgerWW
Link to comment

Nice !!!  :)  I also like the fact that it saves one line of code... I know it's not a lot but even without being a "coder" I know that if you can do at least the same or better with less code then you will have a more beautiful code. 

Link to comment
  • 1 month later...
  • 1 year later...

Hello, 

 

Thank you for the script: it is working!

 

One question: I have tried to attach a Hotkey and when pressed, instead of directly running the script, it opens the Alfred window and I have to click the workflow for it to work (the action selected for the Hotkey is "Pass through the workflow"). Any ideas? 

 

All the best, 

Tudor

Link to comment
  • 1 year later...

Hi,

 

First, thanks to everyone who contributed to this.

 

I'm hoping someone can help me with this. I've followed the steps on this thread, but I'm running into an inconsistent issue. Sometimes when I hit my hotkey, the notification comes up blank (does not reference an output), AND the output does not change. Anyone else run into this issue? Here is my script:

 

tell application "System Preferences"

   reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
   tell tab group 1 of window "Sound"
   click radio button "Output"
      if (selected of row 1 of table 1 of scroll area 1) then
      set selected of row 3 of table 1 of scroll area 1 to true
      set deviceselected to "Logitech USB Headset"
      else
      set selected of row 1 of table 1 of scroll area 1 to true
      set deviceselected to "Speakers"
      end if
   end tell
end tell
quit application "System Preferences"
return deviceselected
Link to comment
  • 1 month later...
  • 3 years later...

When I upgraded from Sierra to Mojave, I had to hit my keystroke twice for it to change the sound output. My brother, Justin Mayer, helped me create this to fix the issue. If this helps anyone out there, awesome!

 

tell application "System Preferences"
	reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
	repeat until exists tab group 1 of window "Sound"
	end repeat
	tell tab group 1 of window "Sound"
		click radio button "Output"
		if (selected of row 3 of table 1 of scroll area 1) then
			set selected of row 4 of table 1 of scroll area 1 to true
			set deviceselected to "Headphones"
		else
			set selected of row 3 of table 1 of scroll area 1 to true
			set deviceselected to "Speakers"
		end if
	end tell
end tell
quit application "System Preferences"
return deviceselected

 

Link to comment
  • 1 year later...

Long dead thread but I'm wondering if anyone has this working on Catalina and Big Sur? Perhaps this is an issue connecting to Airplay speakers but it does work with a different workflow. I would just prefer to be able to use a hotkey to set the output specifically. I get the notification as if it's completed the script but the output source doesn't actually change. I've tried both the packaged workflow that @ssent1 provided as well as the updated script from @morgdaddy

 

Edit: it also seems to be playing/pausing Apple Music.

Edited by getthething
Link to comment
  • 2 months later...
On 1/5/2021 at 12:57 PM, getthething said:

Long dead thread but I'm wondering if anyone has this working on Catalina and Big Sur? Perhaps this is an issue connecting to Airplay speakers but it does work with a different workflow. I would just prefer to be able to use a hotkey to set the output specifically. I get the notification as if it's completed the script but the output source doesn't actually change. I've tried both the packaged workflow that @ssent1 provided as well as the updated script from @morgdaddy

 

Edit: it also seems to be playing/pausing Apple Music.

 

The issue is that in Catalina, as far as I can tell, the table divider is considered a "row" so when numerically identifying your output devices you need to take this into consideration and modify the script. For example, if you have two devices, like I do, you toggle between rows 1 and 3, not rows 1 and 2. Try the following and make sure to change the 'deviceselected' to names of your devices.

 

tell application "System Preferences"
	reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
	tell tab group 1 of window "Sound"
		click radio button "Output"
		if (selected of row 1 of table 1 of scroll area 1) then
			set selected of row 3 of table 1 of scroll area 1 to true
			set deviceselected to "Gulliver HomePod"
		else
			set selected of row 1 of table 1 of scroll area 1 to true
			set deviceselected to "Internal Speakers"
		end if
		
	end tell
end tell
quit application "System Preferences"
return deviceselected

 

sound-script.jpg

Edited by patgilmour
Link to comment
  • 1 year later...

I am now revisiting this for MacOS Ventura.

My current script does not after the upgrade. I kind of expected that.

I have issues fixing this myself though, so maybe someone is able to help.

 

This is my current script and below is the debug log.

 

tell application "System Preferences"
   reveal anchor "output" of pane id "com.apple.preference.sound"
end tell
tell application "System Events" to tell process "System Preferences"
   tell tab group 1 of window "Sound"
   click radio button "Output"
      if (selected of row 4 of table 1 of scroll area 1) then
      set selected of row 3 of table 1 of scroll area 1 to true
      set deviceselected to "External Headphones"
      else
      set selected of row 4 of table 1 of scroll area 1 to true
      set deviceselected to "Mac Pro Speakers"
      end if
   end tell
end tell
quit application "System Preferences"
return deviceselected

 

Debug log:

[09:06:35.425] Toggle Output Device[Hotkey] Processing complete
[09:06:35.425] Toggle Output Device[Hotkey] Passing output '' to Run Script
[09:06:35.564] ERROR: Toggle Output Device[Run Script] 36:104: execution error: System Settings got an error: AppleEvent handler failed. (-10000)
[09:06:35.570] Toggle Output Device[Run Script] Processing complete
[09:06:35.571] Toggle Output Device[Run Script] Passing output '' to Run Script
[09:06:35.571] Toggle Output Device[Run Script] Passing output '' to Post Notification
[09:06:35.697] ERROR: Toggle Output Device[Run Script] 36:104: execution error: System Settings got an error: AppleEvent handler failed. (-10000)

 

Plus attached is a screenshot of my system settings and alfred workflow

 

image.png.31f11a527deb262bfee7c53e5870e895.png

image.png.0b0d2a649beec3f06d1f7a369e411313.png

 

Link to comment
  • 4 weeks later...

Here's the script I use on my Ventura.
please refer.

if (system attribute "sys1") is not 13 then return

open location "x-apple.systempreferences:com.apple.Sound-Settings.extension"
delay 2

tell application "System Settings"
	tell application "System Events" to tell application process "System Settings"
		tell window "Sound" to tell group 1's splitter group 1's group 2's group 1's scroll area 1's group 2
			click tab group 1's radio button 1 --Output tab
			tell scroll area 1's table 1
				set RowsList to every row
				set devList to {}
				repeat with i in RowsList
					set devName to i's UI element 1's group 1's static text's name
					if i's selected then set defaultName to devName
					set end of devList to devName
				end repeat
			end tell
		end tell
	end tell
end tell

tell application "Finder"
	activate
	set devSel to (choose from list devList default items defaultName with prompt "Select Device...") as string
end tell

tell application "System Settings"
	tell application "System Events" to tell application process "System Settings"
		tell window "Sound" to tell group 1's splitter group 1's group 2's group 1's scroll area 1's group 2
			click tab group 1's radio button 1 --Output tab
			tell scroll area 1's table 1
				set RowsList to every row
				set devList to {}
				repeat with i in RowsList
					set devName to i's UI element 1's group 1's static text's name
					if devName contains devSel then
						set i's selected to true
						delay 1
						exit repeat
					end if
				end repeat
			end tell
		end tell
	end tell
	quit
end tell

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...