虽然 AirPods 或 AirPlay 技术已经很好地解决了音频设备配对繁琐的问题,但是在 Mac 上切换输出依然不便。每当用触控板或鼠标费力地点选音量图标时,我常常感到总有一天我会忍不住去简化一下这个过程,like today。
当然 App Store 上已经有了很好的解决方案: Tooth Fairy 。不过如果需求比较简单,只是希望便捷地在常用设备间切换(通过快捷键、Touch Bar 或者绑定其它的工作流),那么用 macOS 上的万能胶水 AppleScript 就可以做到
通过点选菜单栏音量图标进行切换
最简单的,就是跟我们平常操作方式一样,点击音量图标,选中设备,只不过我们用脚本来自动执行,以 Keyboard Maestro 为例,绑定快捷键即可
需要给 Keyboard Maestro Engine 赋予辅助功能权限,其它工具同
脚本如下:
tell application "System Events" to tell process "SystemUIServer"
tell (menu bar item 1 of menu bar 1 whose description contains "volume")
click
set target to "Jay's AirPods" -- 修改为自己设备的名称
set alternative to "内置扬声器" -- 相互切换设备名称
set retry to 1 -- 重试次数,可为 0
set interval to 1 -- 重试间隔(秒),可为小数
if exists (menu item 1 of menu 1 whose title is target and value of attribute "AXMenuItemMarkChar" is "✓") then
set target to alternative
end if
repeat with counter from 0 to retry
try
click (menu item target of menu 1)
exit repeat
end try
if counter < retry then
delay (interval)
else
key code 53
end if
end repeat
end tell
end tell
- 需要在「系统偏好设置」->「声音」中勾选「在菜单栏中显示音量」
- 脚本中只要指定 target 设备名称即可。默认与系统内建设备相互切换,可以修改 alternative 为其它设备名称
- 因为蓝牙设备的发现需要时间,有时菜单会有少许延迟,因此增加了一个未发现设备时延时重选的机制,默认 1 次,可以修改 retry 为其它值,可为 0。默认间隔 1 秒,可由 interval 指定
- 如果用 Bartender 隐藏了音量图标,脚本仍然可以正常工作,同时屏幕上不会显示操作过程
通过「系统偏好设置」进行切换
上个方法很直观,但是对视线的干扰比较大(可以用 Bartender 隐藏,但通常我们并不想这么做),另外如果在脚本执行的同时我们操作了鼠标,可能会导致脚本点选设备失败
所以还可以有另外一种思路,就是使用「系统偏好设置」,而且不必在前台显示,隐藏状态下操作后自动退出,这样就只会在 Dock 栏跳一下图标
为演示方便,在前台显示了切换过程,并加入了一些延时,实际只有 Dock 栏跳动图标的效果
脚本如下:
tell application "System Preferences"
reveal anchor "output" of pane "com.apple.preference.sound"
end tell
tell application "System Events"
tell application process "System Preferences"
repeat until exists tab group 1 of window 1
end repeat
tell table 1 of scroll area 1 of tab group 1 of window 1
set target to "Jay's AirPods" -- 修改为自己设备的名称
# 相互切换设备名称,默认用了第一行设备的名称
set alternative to value of text field 1 of row 1
set retry to 1 -- 重试次数,可为 0
set interval to 1 -- 重试间隔(秒),可为小数
if value of text field 1 of (row 1 whose selected is true) is target then
set target to alternative
end if
repeat with counter from 0 to retry
try
select (row 1 whose value of text field 1 is target)
exit repeat
end try
if counter < retry then
delay (interval)
end if
end repeat
end tell
end tell
end tell
tell application "System Preferences" to quit
特殊情况
如果使用了 Boom 3D 之类的音效增强类 App,输出设备会被固定为一个聚集设备,用以上两种方法无从判断当前实际连接设备,就不能在设备间双向切换,不过单向切换到 target 设备总是可行的(如果 target 是 AirPlay 则不受影响,嗯,就是「隔空播放」)