Audio Hijacking Automation 4 with Shortcuts and JavaScript – Six Colors

0
An Audio Hijack 4 automation turns blocks on and off and starts a session.

Rogue Amoeba’s Audio Hijack 4 is here, and while it has a bunch of cool new features, my favorite is its support for automation via JavaScript and hotkeys. Although not everything is (yet) controllable in Audio Hijack, most of it is, and it offers some really interesting possibilities for users.

Audio Hijack can be controlled by scripts saved in the app itself (the app includes several built-in scripts as samples, and more are available on the Rogue Amoeba website), via scripts saved as .ahcommand text files on your Mac and via scripts sent directly from Shortcuts. Individual sessions can run scripts through the new Script tab for each session; automations can trigger when a recording, session, or timer stops or starts. A script provided by Rogue Amoeba, Discard Small Files, will delete any recording under five seconds. It’s a perfect match for the Session Stop event.

But Audio Hijack really happens when you integrate it into Shortcuts. Currently, the application offers three shortcut actions: run script, run JavaScript, and run/stop session. Run Script will run a script stored in the Audio Hijack application; Run JavaScript will run a script passed to the app from the shortcut, and Run/Stop Session lets you enable or disable a particular session. (There is an “Allow execution of external scripts” setting in the Audio Hijack preferences that you need to enable first.)

It is a very limited set of actions. But even if only Run Javascript in Audio Hijack were available, anything would be possible. Indeed, the initial JavaScript implementation of Audio Hijack 4 allows you to detect the state of sessions and individual blocks within sessions, and then activate and deactivate them. You can also assign some, but not all, variables within a block. You can set the filename and destination of a recording block, for example, so that a shortcut or script can name and place a file adaptively.

Simple examples

Here’s a simple example: I’ve created a shortcut that enables or disables a particular audio hijacking session. The Run/Stop Session action has no knowledge of the current session state, so the shortcut first runs a one-line JavaScript:

return (app.sessionWithName('Podcast lossless').running)

When Audio Hijack runs this script, it will return a result of true if the session is running, and false if it’s not the case. At this point my shortcut can handle what happens next.

Or let’s say you want to create a shortcut that requires a list of running sessions. You would use this script:

var sessionNames = [ ];
try {
app.runningSessions.forEach( session =>
{
    console.log(session.name);
    sessionNames.push(session.name);
})
return sessionNames;
}
catch(err){
return '';
}

What your shortcut does with this information is up to you.

Three way switch

I wrote a shortcut that creates a three-way switch when I record and live stream The Incomparable. The shortcut detects the current state of the Incomparable session, whether it’s not running, streaming live music before the show starts, or streaming and recording our voices .

Each time the shortcut is activated, it updates the Audio Hijack session so that everything is in the right position for the next step in the workflow. If the shortcut runs when nothing is happening, it activates the session, turns off my microphone and makes sure recording is off, and flips an A/B switch to the music streaming part of the session. This script looks like this:

app.sessionWithName("Live - Incomparable").blocks.forEach( block =>
{
    if (block.name == "Recorder") {
block.disabled = true;
}
}
)
app.sessionWithName("Live - Incomparable").blockWithName("musicapp").disabled = false;
app.sessionWithName("Live - Incomparable").blockWithName("USBPre").disabled = true;
app.sessionWithName("Live - Incomparable").blockWithName("Switch").switchPosition = 'A';
app.sessionWithName("Live - Incomparable").start()

If the shortcut detects that the session is running in music mode, it runs a different script that turns on my microphone and all recording blocks and turns off the music.

app.sessionWithName("Live - Incomparable").blocks.forEach( block =>
{
    if (block.name == "Recorder"){
        block.disabled = false;
}
    if (block.name == "musicapp"){
        block.disabled = true;
}
    if (block.name == "USBPre"){
        block.disabled = false;
}
})
app.sessionWithName("Live - Incomparable").blockWithName("Switch").switchPosition = 'B';

And of course, if the session is live streamed and recorded, the next execution of the shortcut deactivates the session. If the Audio Hijack session window is open when scripts are running – this is no longer needed in Audio Hijack 4! – the application puts on quite a show. Blocks turn on and off and switches toggle, all without me doing anything (except running the shortcut).

Integration with Stream Deck

A part of the Keyboard Maestro macro that updates a Stream Deck button.

I built my Incomparable three-way shortcut to be connected to a Stream Deck button, of course. But the problem with most Stream Deck buttons is that they don’t change based on the current state. So I changed my shortcut to show a variable called status at the end of its execution, indicating the current state of my recording session.

Then in Keyboard Maestro I created a macro that runs my shortcut when I press the right button. This macro update the image on the button depending on the variable returned by the shortcut. Now when my live stream is in music mode, there is a music note overlay. And when we live broadcast, a broadcast symbol appears. When we’re off the air, there’s no overlap.

I also created a Keyboard Maestro macro for the simple on/off hotkey I mentioned at the top of this article. The shortcut asks Audio Hijack for the current state of the session and sends this information to the Keyboard Maestro macro. The Keyboard Maestro macro updates the Stream Deck button accordingly. Now when I press that record button it turns red when recording and goes black when not.

Fit in…anything, really

Since the Audio Hijack 4 JavaScript API includes app.runShortcut() and app.runShellCommand() commands, and since the app will run arbitrary JavaScript scripts from the filesystem, there’s almost nothing you can not embed Audio Hijack 4. Run a python script from Audio Hijack. Run an AppleScript that tells Audio Hijack to open a specific script file. Yes, everything has to go through JavaScript (and no, JavaScript isn’t my favorite), but if you can work your way through some basic scripting, you can do just about any job.

That said, there is still work to be done. I would like to see Rogue Amoeba add JavaScript access to all variables in all blocks. (I wish a script could provide metadata to a broadcast block, for example.) And there should be more shortcut actions for the app. Yes, you can do almost anything through the Run JavaScript command, but not everyone is comfortable with JavaScript. It’s good that Rogue Amoeba added Run/Stop Session as an action, rather than forcing everyone to use app.sessionWithName("session").start() every time, but there are probably other common use cases that could be made a little friendlier to people who think in shortcuts, not JavaScript.

Always! Audio Hijack was already one of my most vital Mac utilities, and now, with scripting support, it’s already even more useful. I can’t wait to see what Audio Hijack 4 users build with the new automation tools.

If you enjoy articles like this, support us by becoming a Six Colors subscriber. Subscribers get access to an exclusive podcast, members-only stories, and a special community.

Share.

About Author

Comments are closed.