For No One

RSS

Posts tagged with "Mac"

May 3

Running AppleScripts from Automator

These days, I’ve been using Automator more and more to run AppleScripts (especially since Mountain Lion came out and disallowed Calendar, née iCal, from triggering AppleScripts directly: http://apple.stackexchange.com/questions/59257/ical-no-longer-runs-scripts).

I began copying and pasting scripts into my workflows, which is a messy solution. I kept the scripts around, because it’s easier to write and debug them in AppleScript Editor, and especially since I converted them to plaintext scripts and uploaded them to GitHub, it’s very useful to be able to easily diff them, as well.

But there’s a better way. A much better way, in fact. AppleScripts can call other AppleScripts, and this works from within the Run AppleScript workflow action, as well. The full solution looks like this:

on run {input, parameters}
    
    run script file "Macintosh HD:Some Directory On Disk:a cool script.applescript"
    
end run

Doing it that way, the Automator is a simple wrapper – you can set it and forget it. I’ve even confirmed that this works with scripts in the plain text .applescript format and compiled AppleScripts (.scpt).

Update

You can also pass the input and parameters arguments into your scripts from Automator as well. Just use the same on run handler that the Run AppleScript action defaults to (as shown above) in your script file, and pass the arguments from Automator like so:

run script file "path to script like above" with parameters {input, parameters}
Jan 2

Hi, I am trying to use your HandBrakeCLI code with Automator, but I am getting the following error: "Variable re_compile is not defined". I am using Mountain Lion. Cheers!.

Anonymous

Thanks for pointing that out! I neglected to mention that you need to install the Satimage.osax AppleScript extension. the re_compile you’re seeing is because I use regular expressions to handle the command line output of HandBrake. I’ve updated the post to include information about installing Satimage.

Dec 5

Using HandBrake on a list of files

I download a lot of videos on the web, and most of the time, they don’t come wrapped up as an iTunes-friendly m4v file. Even when they do, they may not necessarily be encoded in a way that plays nicely with all of my iOS devices (AppleTV, iPhone, iPad, etc.). So, for a long time, my download process has gone like this before loading into iTunes:

  1. Download
  2. Transcode
  3. Tag

The tools I use for the first and third steps have not changed for a long time, but there has been a lot of movement in the Mac video transcoding space. What do I mean by transcoding? I take video that arrives in a particular format (let’s say Ogg Theora) and convert it into a format my devices accept (typically some flavor of MPEG-4 my Apple devices).

VisualHub

For years, I used an awesome tool named VisualHub, and it did everything I wanted. I dragged in a list of files, told it which device I wanted to play them on, and let it rip. It even made use of OS X’s Xgrid infrastructure to encode multiple files simultaneously, distributed among my Mac Pro’s 8 cores, as well as any other networked machines I cared to use. But VisualHub died (so to speak).

It was reborn as an open source project named (poorly, in my opinion) FilmRedux. I tried using it, and found it lacking in various regards. Another project forked the code base and went in its own direction, calling itself VideoMonkey. I used it for a while, dealing with its superficial bugs and slow rate of development, simply because I couldn’t find another tool that would (usually) work the way I desired.

HandBrake

Of course, this all applies to lists of files. If I had a single file to transcode, I used HandBrake as soon as it began accepting arbitrary files for input (it originated as a tool for ripping DVDs, for which it still excels). I love HandBrake, and would use it for all my transcoding needs, if only I could use it for a list of files. The interface has been written with ripping DVDs in mind, however, and so you can only select one file at a time. So I set out to fix that, with my tool of choice: automation!

The Solution

I wanted a way to give HandBrake a list of files, and have it transcode all of them to a particular folder, using a particular settings preset. I realized this seems to be an idea ready-made for an OS X Service, and luckily, Automator (bundled with the OS) allows you to easily make Services. But, HandBrake doesn’t support AppleScript and doesn’t export any Automator Actions, so I needed to figure out another way to automate it. Luckily, HandBrake provides a CLI (command line interface) executable for the Mac.

First, you need to install the Satimage AppleScript extension. Follow the link, download the Satimage___.pkg installer, and run it. If you’re on Mountain Lion (with default Gatekeeper settings), you will need to right-click the file and click Open1, since it hasn’t been signed by the developer, but other than that, it works 100% in Mountain Lion. The installer is very basic, only copying the Satimage.osax extension into your /Library/ScriptingAdditions/ folder.

To create your own service, follow these steps:

  1. Launch Automator.app

    Automator

  2. Click File > New (Cmd+N)

  3. Select Service

    Service

  4. Click the Choose button

  5. Set the following two dropdowns at the top of the service’s definition: Service receives selected files or folders in Finder

    Settings

  6. Drag in the Action named Run AppleScript (you can search to find it quickly)

    Action

  7. Copy and paste the script below as the script’s text

  8. Click the Compile button to make sure the AppleScript pasted is valid

    Hammertime

  9. Click File > Save (Cmd+S), and enter a name (I chose “Encode With HandBrake”), which will show up in the Services menu

on run {input, parameters}
    set handbrakeCli to "/Applications/HandBrakeCLI"
    set defaultPreset to 7
    
    -- Make sure HandBrakeCLI is installed
    set handbrakeInstalled to false
    tell application "Finder" to if exists handbrakeCli as POSIX file then set handbrakeInstalled to true
    if not handbrakeInstalled then
        display alert "Install HandBrake CLI" message "Please install HandBrakeCLI into the /Applications directory

The HandBrake CLI can be downloaded at http://handbrake.fr/downloads2.php" as critical
        return
    end if
    
    set the destination to POSIX path of (choose folder with prompt "Select the conversion destination")
    
    set the presetList to do shell script handbrakeCli & " -z"
    
    set eachPreset to every paragraph of presetList
    
    set groupEx to re_compile "<[ ]*(.+)"
    set presetEx to re_compile "[ ]*\\+[ ]*([^:]*):"
    
    set displayNames to {}
    set presetNames to {}
    
    set group to ""
    
    repeat with preset in eachPreset
        if length of preset > 0 then
            if preset starts with "<" then
                -- Pull out the group's name
                set group to find text groupEx in preset using "\\1" with regexp and string result
            else if preset contains "+" then
                set presetName to find text presetEx in preset using "\\1" with regexp and string result
                copy presetName to end of presetNames
                copy group & " > " & presetName to end of displayNames
            end if
        end if
    end repeat
    
    set chosenDisplayPreset to choose from list displayNames with title "HandBrake preset" with prompt "Choose a HandBrake preset" default items {item defaultPreset of displayNames}
    
    if chosenDisplayPreset = false then
        return
    end if
    
    set chosenDisplayPreset to chosenDisplayPreset as text
    
    set presetIndex to 1
    repeat with i from 1 to (count of items in displayNames)
        if item i of displayNames is equal to chosenDisplayPreset then
            set presetIndex to i
            exit repeat
        end if
    end repeat
    
    set chosenPreset to item presetIndex of presetNames
    
    repeat with inputFile in input
        -- Get original file's name
        
        set thePath to POSIX path of inputFile
        set prevTIDs to AppleScript's text item delimiters
        set AppleScript's text item delimiters to "/"
        -- Get the file name
        set inputFileName to (item -1 of (every text item of thePath)) as text
        
        -- Get the file name without an extension
        set AppleScript's text item delimiters to "."
        set inputFileNoExtension to items 1 through -2 of (every text item of inputFileName)
        set AppleScript's text item delimiters to prevTIDs
        
        -- Put back together if file name included periods
        set outputFileName to ""
        repeat with fileNamePart in inputFileNoExtension
            set outputFileName to outputFileName & fileNamePart & "."
        end repeat
        
        -- Put on the preferred extension
        set outputFileName to outputFileName & "m4v"
        
        set handbrakeCommand to "nice " & handbrakeCli & " -i " & quoted form of (POSIX path of inputFile) & " -o " & quoted form of (destination & outputFileName) & " --preset='" & chosenPreset & "'"
        --return handbrakeCommand
        do shell script handbrakeCommand
    end repeat
    return input
end run

To use the service:

  1. Select the files you wish to convert in Finder
  2. Right click (or Control-click) on the selection
  3. Click Services > Encode With HandBrake (or whatever you named your Service in Step 10 above)
  4. The Service will prompt you for an output folder for the conversion. Select the folder you want your converted files to land in
  5. The Service will also prompt you for a HandBrake preset to encode with2. Select the one you wish to use. Unfortunately, the CLI doesn’t support custom presets defined in the GUI app
  6. A spinning gear icon will show up on the Menu Bar at the top of your screen until the job finishes

This script has worked solidly for me for a long time, and I hope you enjoy it. As always, you can let me know if you have any problems or feature requests.

Update

I’ve gotten feedback that the re_compile command is not working for some (all?) of you. D’oh! I forgot to mention you need to install the Satimage.osax AppleScript extension. I’ve had it for a while and forgot that this script uses Regular Expressions. I’ve updated the post to include those instructions.


  1. This is described on the Gatekeeper support page, under the “How to open an app from a unidentified developer and exempt it from Gatekeeper” heading 

  2. I have it defaulting to the Apple > AppleTV 2 preset, which you can change in the following line of AppleScript: set defaultPreset to 7 

littlebigdetails:

iOS - The feature Speak Selection (on Settings &gt; General &gt; Accessibility) shows the characters of the fable The Tortoise and the Hare for the voice speed settings.
/via Victor Boaretto

The original 1984 Mac used the same iconography in its control panel for keyboard repeat rate:



Mac image courtesy of Toasty Tech

littlebigdetails:

iOS - The feature Speak Selection (on Settings > General > Accessibility) shows the characters of the fable The Tortoise and the Hare for the voice speed settings.

/via Victor Boaretto

The original 1984 Mac used the same iconography in its control panel for keyboard repeat rate:

Mac image courtesy of Toasty Tech

littlebigdetails:

Mail - When selecting multiple messages the number of envelopes increases from a couple to many depending on the amount selected.
/via David

littlebigdetails:

Mail - When selecting multiple messages the number of envelopes increases from a couple to many depending on the amount selected.

/via David

➩ Paid Upgrades

Wil Shipley, author of Delicious Library (App Store, direct) wrote a blog post this week, which also got picked up as an Op-Ed on Ars Technica. He calls for Apple to allow paid upgrades for Mac App Store (MAS) apps. I agree with the majority of his post, and since I’m making plans to launch a Mac App Store exclusive title, the subject matters greatly to me. I’d like to some of my own thoughts.

First of all, free upgrades have only been tolerated so far, since both app stores are still so young. The markets are still expanding at such a rapid pace that lone-developer shops like Instapaper can survive on new app sales alone. But what happens when the market gets saturated (or nearly-saturated)? No matter what, this problem will come to a head at some point. Vast as the markets may be, they are far from infinite.

This impacts niche apps more severely. An app like Instapaper could potentially be purchased by every literate person in the world. If you wrote software that competed with Aperture or Final Cut Pro, however, you would have a much smaller target audience. Apple might gladly offer their apps with free updates for life, but, as Shipley points out, we don’t all have $100 billion in the bank. The demand for non-Apple, non-Avid video editing software might be saturated much quicker than those developers would prefer. What then? Charge $80 or $150 for upgrades? With App Store prices lower than prices before it (and Apple leading the way in that regard) this seems more palatable, but users might still resent the developers.

I doubt this point escaped Apple’s notice. And though they tend to respond to an issue more quickly when someone like Shipley brings an issue into public discourse (they specifically have listened to Wil Shipley’s ideas before), it seemed to me that the app stores were designed for paid upgrades from the beginning. The interface has always shown “Free” next to each “Update” button, and I’ve always assumed we would someday see “$4.99” or the like next to it instead.

He vaguely describes a mechanism by which developers would declare upgrade pricing:

The Mac App Store should allow developers to submit, with our applications, a list of our other applications from which the user can upgrade, along with a separate price we’d charge people who already own those applications.

I wonder how this list would look, though. Let’s say you have versions 1, 2, and 3 of your app, all costing $40 when new. Would you be able to charge $30 when upgrading from version 1 and $20 when upgrading from version 2? That would make sense, but it would be more complicated to describe.

He also suggests a way to handle the older versions of apps in the store:

Leave our version ‘2’ page up but don’t allow any new sales of it, and mark it as obsolete.” (In this way existing version “2” customers can still be updated (for free) with bug fixes even if they don’t upgrade to “∞.”)

Certainly, if you offer a paid update to an app you should still be allowed to offer maintenance updates to the older version. I don’t think it would make sense to keep the page for the older version visible, however. Perhaps he meant to keep it available for displaying release notes, which would make sense, but I don’t think it should show up in an App Store search to someone who hasn’t already purchased it, or if you find a link to an app in an old review on the web. In that case, it should take you to the current version, not the old version.

Along different lines, I disagree with a statement he makes early on when describing his split of customers between App Store purchasers and those who purchase directly from his site:

…we assume customers who learn about Delicious Library from our site probably buy it from our site, so customers who buy from Apple probably found out about us through Apple — and Apple deserves a cut.

Here, I think he’s missing some of the advantages of the Mac App Store. I’ve been buying every app I can through the MAS, even when available directly. I like the unified update mechanism, being able to easily install apps on other machines, and would prefer not to be excluded from future App-Store-only features like iCloud interaction, which are beginning to appear in Mountain Lion. I would also imagine a growing segment of users don’t search the web for software anymore. If I told my grandmother about Delicious Library, she would probably search for it on the App Store, since that’s where apps come from (to her).

Finally, to echo John Gruber’s point, Apple should also allow upgrades on the iOS App Store. It would help alleviate the race to the bottom in pricing that makes it difficult to charge significant amounts for software there.

Apple definitely needs to address this, and doing so will help the app stores grow into the mature platforms they must eventually become.

Authentically awesome

Sometimes, a geek such as myself has cause to venture into the thorny underbrush of a Mac; places such as /System and /Library, where regular users have no business mucking around. Often, I’ll need to modify a text file therein, which can be troublesome. If you use the built-in TextPad, or other text editors, they won’t be able to save your changes.

The operating system wants you to authenticate with your username and password, which is your way of telling it “I’m an administrator, I know what I’m doing. Back off”. You can maneuver around this by saving a copy of the file elsewhere (like your Desktop), and then use Finder or Terminal to copy it in, at which point you get prompted for credentials.

I previously used TextWrangler to perform “authenticated saves”, in which the text editor would prompt me for my credentials, so the save would succeed. Much easier. And then I upgraded to BBEdit, purchased from the Mac App Store, which presented me with errors every time I went to save to a protected location. Surely, the paid upgrade from a free app wouldn’t remove a feature, right? There must be more going on here. And, don’t call me Shirley.

It turns out Bare Bones needed to remove this feature to comply with App Store guidelines. And this remained the status quo for a while, until they came up with a rather clever solution. Version 10.1.1 introduced a hook at the point where a file is saved, so that the operation could use an AppleScript delegate, if present. They posted a support article, where users can follow the instructions and get the “authenticated save” feature added back.

This makes a lot of sense, since only an experienced user would need the feature, and would be more than capable of copying a file into the ~/Application Support directory. Best of all, you do it once and the problem is permanently solved (until you install BBEdit on a new machine and forget all about it all, unless you store your BBEdit settings on Dropbox). Good job, Bare Bones!

➩ Dan Dilger discusses the new iPad's name

Daniel Eran Dilger:

By centering on a single brand name for each major product category it sells, Apple spends much less on advertising and promoting new brands and customers find it easier to find what they’re looking for and ask for it by name.

Covers most of the same points I did several days ago, but goes much more deeper into Apple’s own history, and their competitive landscape.

I’ve been following Dan Dilger’s writing for years, first at his Roughly Drafted blog, and more recently at AppleInsider. He knows Apple’s history like no one else I’ve read, and grasps well their competitive advantages.

➩ Mountain Lion drops support for several older Mac models - SHIT!

Both of my Macs (in bold) EOLed at once! This is going to be an expensive year…

This means the following Macs which are supported under OS X Lion will not be able to run Mountain Lion (model identifiers in parentheses):

  • Late 2006 iMacs (iMac5,1, iMac5,2, iMac6,1)
  • All plastic MacBooks that pre-date the aluminum unibody redesign (MacBook2,1, MacBook3,1, MacBook4,1)
  • MacBook Pros released prior to June 2007 (MacBookPro2,1, MacBookPro2,2)
  • The original MacBook Air (MacBookAir1,1)
  • The Mid-2007 Mac mini (Macmini2,1)
  • The original Mac Pro and its 8-core 2007 refresh (MacPro1,1, MacPro2,1)
  • Late 2006 and Early 2008 Xserves (Xserve1,1, Xserve2,1)

➩ Daring Fireball: Mountain Lion

John Gruber, on the just-announced 10.8 Mountain Lion OS X update (and in a typically well-constructed narrative):

Apple is calling it “Gatekeeper”. It’s a system whereby developers can sign up for free-of-charge Apple developer IDs which they can then use to cryptographically sign their applications. If an app is found to be malware, Apple can revoke that developer’s certificate, rendering the app (along with any others from the same developer) inert on any Mac where it’s been installed. In effect, it offers all the security benefits of the App Store, except for the process of approving apps by Apple. Users have three choices which type of apps can run on Mountain Lion:

  • Only those from the App Store
  • Only those from the App Store or which are signed by a developer ID
  • Any app, whether signed or unsigned

I was surprised Apple didn’t do this with Lion, and I remember John Gruber (or someone else, but I think it was him) suggesting this change. The middle option is the default, and I think that’s a perfect balance between security and flexibility.