Last active
May 11, 2024 07:04
-
-
Save RobTrew/2a57cd45fae7162ddf40 to your computer and use it in GitHub Desktop.
Toggling OS X Sound Output Devices with JXA Javascript for Automation (OS X 10.10)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Rob Trew @complexpoint 2015 | |
function run() { | |
"use strict"; | |
var blnUseKeyboardMaestro = false; | |
// EDIT TO NAMES OF TWO ALTERNATIVE SOUND OUTPUT DEVICES | |
var dctSources = { // A unique substring for each is enough | |
primary: "Internal", | |
secondary: "Elgato" | |
} | |
if (blnUseKeyboardMaestro) { | |
// NB if you are using KeyBoard Maestro, the values of the KM variables, | |
var strVarNameONE = "soundDeviceONE" | |
var strVarNameTWO = "soundDeviceTWO" | |
// take precedence (as long as they are both set, | |
// and different from the strings above) | |
// Otherwise, [blnUseKeyboardMaestro = false] | |
// the dctSources setting above will be used | |
var oPrimary = findOrMakeKMVar(strVarNameONE), | |
oSecondary = findOrMakeKMVar(strVarNameTWO), | |
kmvarPrimary = oPrimary.value(), | |
kmvarSecondary = oSecondary.value(); | |
if (kmvarPrimary) dctSources.primary = kmvarPrimary; | |
else oPrimary.value = dctSources.primary; | |
if (kmvarSecondary) dctSources.secondary = kmvarSecondary; | |
else oSecondary.value = dctSources.secondary; | |
} | |
// ASSUMING / CREATING TWO KEYBOARD MAESTRO VARIABLES | |
// Get a reference to a Keyboard Maestro variable | |
function findOrMakeKMVar(strName) { | |
var appKM = Application("Keyboard Maestro Engine"), | |
oVars = appKM.variables; | |
try { | |
oVars[strName].name(); | |
} catch (e) { | |
oVars.push(appKM.Variable({ | |
'name': strName | |
})); | |
} | |
return oVars[strName]; | |
} | |
var appPrefs = Application("System Preferences"), | |
blnFound = false, | |
strLegend, strMsg; | |
// FIND SOUND TAB OF SYS PREFS | |
appPrefs.panes[ | |
"com.apple.preference.sound" | |
].anchors["output"].reveal(); | |
// FIND CURRENT DEVICE SELECTION | |
var rows = Application("System Events").processes[ | |
"System Preferences" | |
].windows[0].tabGroups[0].scrollAreas[0].tables[0].rows, | |
strSeln = rows.where({ | |
"selected": true | |
})[0].textFields[0].value(); | |
// CHOOSE NEW TARGET BY TOGGLING | |
var strTarget = (strSeln.indexOf(dctSources.primary) !== -1) ? | |
dctSources.secondary : | |
dctSources.primary; | |
// FIND AND AND SELECT THE FIRST MATCHING LINE | |
rows().forEach(function (oRow) { | |
if (!blnFound) { | |
strLegend = oRow.textFields[0].value(); | |
if (strLegend.indexOf(strTarget) !== -1) { | |
oRow.select(); | |
blnFound = true; | |
} | |
} | |
}); | |
// NOTIFY FAILURE OR NEW SETTING | |
var app = Application.currentApplication(); | |
app.includeStandardAdditions = true; | |
app.activate(); | |
app.displayNotification( | |
blnFound ? | |
"→ " + strLegend : | |
"Couldn't find a sound device containing this string: \"" + strTarget + | |
'\"', { | |
withTitle: "Sound Output Device " + | |
(blnFound ? '' : 'NOT ') + "Changed" | |
} | |
); | |
// AND TIDY UP | |
appPrefs.quit(); | |
return blnFound; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment