Macros with AppleScript for Video Editing

Macros are a simple way of saving you time while you’re editing, but I don’t think many editors take advantage of them. If you don’t know, a macro is a short script that makes the computer automatically execute a series of keyboard commands to help make repetitive tasks much simpler. They can be particularly useful for assistant editors, where you often have to perform a predictable and repetitive series of keystrokes over and over. By using a macro, not only can you save time, you can also eliminate some of the inevitable human error that can arise by having to repeat a complex series of keystrokes many times. There are even health benefits. I worked as an assistant on a show a couple years ago and after a few days of syncing dailies and grouping in the Avid, my left pinkie was beginning to hurt quite a bit from all the reaching for the control key. By writing a macro for the repetitive tasks, I was able to save myself from a lot of pain and my hand lived to fight (well, edit) another day!

In this post, I’m going to use a recent real-life task as an example to show the steps required to create a macro using AppleScript. While the actual macro that I’m writing is specific to completing one task on Final Cut Pro 7, these same techniques can be applied to any repetitive task on any editing system. As best as I can, I’ll try to explain the few simple AppleScript commands you need to be able to macro-ize anything that can be accomplished with a keyboard.

There are several programs out there that will let you create macros. For the Mac, I haven’t been able to find a free one. One of the more popular pay programs is QuicKeys, which I have used (the PC version, actually), and it’s quite good. The other main program for Macs is Keyboard Maestro, which I haven’t used. Fortunately, on the Mac, we can get pretty much everything we need out of a macro using AppleScript, which is included free with any Mac. Obviously, AppleScript is Mac only. On the PC side, I’ve used a free program called AutoHotkey, but that’s outside the scope of this post.

The Task: Recently, I was working on a program where we had to create international textless versions for distribution abroad. The spec I was given required having the whole show as-is, after that, take each shot that had text in it from the show and append a textless version to the end, starting a minute after the end of the main program. They requested a spreadsheet to accompany the program that listed where each textless clip went in the main program. It seemed like a perfect opportunity to create a macro. A few more details: I decided to put three seconds (a number I chose rather arbitrarily) between each textless clip at the end. I also wanted to have a marker at the beginning of each textless clip. Each marker’s name would be the timecode in the main program where that clip began. That way, I could export a marker list when I was done and have the required spreadsheet pretty much already finished.

A picture of my timeline with the textless media

A picture of the end of my timeline with the textless media

The first thing to do when you create a macro is to figure out exactly what keystrokes you need to perform the task at hand. In my specific case, I need to set an in and out point in my timeline around the clip that needs a textless version. I then hit Option-A to highlight everything between the in and out. Then, I need to go to the in point. Then, by pressing tab, I can highlight the current timecode in the timecode box at the top left of the timeline. I then copy that timecode and press tab again to get back to the timeline. Then, I copy the highlighted clips in the timeline. (It turns out, Final Cut 7 can store both a clip and some text, the timecode in this case, in the clipboard at the same time. It knows what to paste based on the context of where you’re trying to paste it.) I then deselect the clips with shift-command-a. Next, I go to the end of the timeline and then use the numeric keypad to type, “+3.” to move three seconds ahead. I press “m” to create a marker at that point and then press “m” again to open the marker edit dialog box. I paste in the timecode and press enter again to close the dialog box. Finally, I paste the highlighted clip. That’s the complete workflow. Not quite all of it will be automated. I need to set the in-out points at the beginning by hand since it will require human judgment as to which clips neede to be made textless. I also want to do the option-a to highlight the clip by hand so I have a clear visual of exactly what will be copied. But every step after that will be done using the macro. I know that’s a bit of a mouthful, so here’s a video of the process I want to recreate with a macro:

 

If you add up all the steps after we’ve selected our clip, it’s 16 keystrokes that need to be done in exactly the right order. This show is an eight-episode series with, on average, about 30 clips that need to be made textless per episode. That’s 240 clips, meaning it takes 3,840 keystrokes to create the textless versions. It’s inevitable that somewhere in there, probably quite a few times, I’ll press the wrong button and screw something up. For example, I could forget to go to the in point of the clip and end up copying the wrong timecode into the marker name, which would make my spreadsheet incorrect and cause (expensive) problems down the line. By creating the macro, it’s guaranteed that my timelines will be accurate. I should also point out that all this does is move a copy of the clip from the episode to the end, it doesn’t actually remove the text. After I’ve been through the whole episode, I’ll need to manually go back to each clip at the end and remove whatever text needs to be removed. Usually, that just means deleting a lower third clip or something simple. For a few graphics, I do need to go back to After Effects and re-render a textless version. Also, I should note that the macro won’t work for the very first clip in the episode that needs to be textless. This is because, at that point, the end of the timeline is just the last frame of the episode and not a minute after the end of the episode as required by the specs. I could mess around with slugs or something to make it work on the first clip, too, but it’s easier to just do the first clip by hand.

Now that I’ve figured out what I need to do, I can write an AppleScript that automates these tasks. We’re going to use something called “User Interface Scripting,” where AppleScript basically simulates a keyboard. Because of that, we need to make a change in System Preferences. Go to System Preferences>Accessibility and then ensure that “Enable access for assistive devices” is checked. If this isn’t checked, the AppleScript won’t work.

Enabling access for assistive devices

This is the Mountain Lion version of this dialog box. It looks different in other versions of OS X.

Once that’s done, open the AppleScript Editor application, which is under Applications>Utilities. We need to begin every macro script we write like this:

Don’t worry about the indentation. AppleScript Editor will indent everything properly for you when you compile or run the script. When you tell FCP to activate, that makes it the front-most app. System Events is the program that will simulate the keystrokes. Obviously, if you’re writing a macro for a different editing application, replace “Final Cut Pro” with the name that appears in your dock when your editing app is open. For example, as of this writing, CS6 is the newest version of Premiere. In the dock, it’s called “Adobe Premiere Pro CS6,” so the first line would say “tell application "Adobe Premiere Pro CS6".” Sorry for the weird double quotes, but it’s important to put the application name in quotes. After these initial setup lines, we’ll write our actual macro. There are only three commands we need to know: delay, key code, and keystroke.

delay: This is a length of time, in seconds, that we want to pause between commands. You can use decimal numbers to indicate a fraction of a second. So, for example, the command “delay 0.5” would make AppleScript wait half a second before executing its next command. I’ve found that I pretty much need to put short delays between every command otherwise the macro executes too quickly for Final Cut to keep up. Depending on how complex the task is, I’ll try to put a 0.1 or 0.2 second delay between commands. If it’s something really hard where it maybe requires the timeline to redraw or something, I’ll do a 0.5 or 1 second delay. This takes a little trial and error. If you find your macro isn’t behaving reliably, it’s likely because it’s sent out a keystroke before the editing application is ready to accept it and the keystroke has gotten lost in the shuffle. In that case, you’ll want to add or lengthen a delay command between the two key commands.

key code: Each key on your keyboard has a number, or key code, associated with it. These key codes might vary from country to country, so it’s a good idea to figure out exactly what key codes your keyboard uses. There’s a very nice free app on the Mac App Store called “Key Codes” that does just this. I’ll use several key codes in the finished macro script in a moment, just be aware that your keyboard might have different codes. On my keyboard, the “i” key has a key code of 34. So if I want the macro to include a press of the “i” button, “key code 34” would be the proper command. Maybe you want to use shift-i to go to an in point. In that case, “key code 34 using {shift down}” would be the way to go. shift, command, control, or option are all valid keywords to represent the corresponding modifier keys on the keyboard. You can also use multiple modifier keys. Say you wanted to do shift-command-a to deselect all. The keycode for “a” is 0 on my computer, so “key code 0 using {command down, shift down}” is the way to do that. Finally, one other note about key codes. It’s a real pain to have to remember them all and you don’t want to come back to a macro you wrote a year later and have a bunch of random 34s and 76s (the enter key) lying around, so it’s a good idea to assign all these numbers to descriptive variable names, so that you know what they mean. Then, any time in the script that you’d want to use a number, you can use the variable name instead. So, for example, say I want to copy something using command-c. It would be a good idea to have a variable called, perhaps, btnC, which equals 8, the key code for “c” on my keyboard. In AppleScript, just say “set btnC to 8” and then any time you use btnC in your code, AppleScript will interpret it as 8. So I could then say, “key code btnC using {command down}” and that is much more descriptive and easy to understand than just having a random “8″ in the middle of the line. The AppleScript executes sequentially and you can’t use a variable before you’ve set its value, so be sure to place the “set to” line above any of the places you use the variable. I have a place at the top of my AppleScript macro where I set all my variable names that I’ll use later. You can even do this before the first “tell application” line if you like.

keystroke: This is similar to the key code command, but instead of having to use key code numbers, you can just use a line of text enclosed in quotes. For example, say I wanted the marker name to be “Hello” instead of a timecode number. When I had the marker dialog box open, I could use the command, “keystroke "Hello"” and that text would appear in the dialog box. The temptation may be strong to use keystroke instead of key code since it’s much more user friendly. But I recommend using key code for most of your commands. I find that Final Cut doesn’t always behave as reliably with keystroke. I think it’s because all the text just gets spit out at once with keystroke, almost as if it’s been pasted instead of typed one character at a time. Say, for some reason you want to set an out point and then go to an in point in the timeline. You could do “keystroke "oI"” but you sort of have to imagine that you’ve just pasted the text “oI” rather than pressed those individual keys. A good rule of thumb is to use keystroke any time you could paste text somewhere and use key code when pasting might overwhelm the application. In my macro, I only use key code except when I want to move ahead by three seconds. There, I tell it to “keystroke "+3."” and since it’s entered into a text prompt, it is akin to pasting text and it works with no problems. When in doubt, use key code; it’s just safer that way.

And that’s really all you need to know. At the end of your macro, you need to include the following few lines of code which close the “tell” blocks you opened at the beginning:

I’ll say a few words about running the macros and then I’ll end with the code for the specific case I described above. The easiest way to run an AppleScript macro is to have the AppleScript Editor open and just quickly switch over to it and hit command-R to run the macro. If you’ve made any errors, it will let you know with an error message and you’ll have to examine your code to see where you went wrong. Once you start a macro, they’re difficult to stop, so it’s a good idea to up your undo level in Final Cut Pro, especially for a longer string of commands. Be sure to test the macro out on a test sequence before you mess with the real thing. Also, since the macro is just blindly simulating key presses, if you switch away from your editing app midway through the macro’s execution, whatever app you switch to will then receive those key presses instead of your editing app, so you can’t check your email or something while a macro is executing.

There are ways to assign a keyboard shortcut to an AppleScript. The easiest that I know of is using a free program called Quicksilver. I won’t go into details about how to do that here, but there’s a good write-up over at Lifehacker that explains the steps. Unfortunately, I’ve found that when I try to set the macro up through Quicksilver, it doesn’t always behave reliably, meaning that sometimes it will miss a step, which causes the whole operation to mess up. So I know it’s a bit of a pain, but I think it’s probably safer to just switch over to AppleScript editor and run the macro. It’s two keyboard commands (command-tab then command-r) to do the switchover versus just one keyboard command if you assign it in Quicksilver, so it’s not like you’re taking a huge productivity hit by switching over to the editor first. This may be an area where paying for a macro program will yield better performance than doing it the free way with AppleScript.

So that just about wraps it up. Here’s the complete code for the textless versioning task I described above. Note that I’ve also included quite a few comments in the code to explain what I’m doing. If you put a number sign on a line of AppleScript code, anything after that number sign is a comment and will be ignored by the compiler.

Leave a Reply