Applescript iTunes Commands

Applescript icon

For some time I've been both frustrated and fascinated by Apple's Applescript technology. On one side Applescript seems very powerful and a really cool way to drive the Mac using automation or scripts. But it is poorly documented, often buggy, and each version of OSX brings a lot of change to the "specification".

First off, the best documentation of the support for Applescript is third party hackers out there like Doug Adams' pages. Doug seems to be making a bit a living off the fact that Apple supports Applescript so poorly. Good for him. Another site I used a lot was Alvin's iTunes Applescript examples.

I'm been meaning for some time to work on a jukebox program that could drive my iTunes on my Mac during our neighborhood dance parties that we have now and then. The idea is that everyone could use their phones to interact with the server, vote up tracks, see what's next, etc, etc.. Pretty simple application but the trick is how to drive iTunes. Enter Applescript.

Applescript is a scripting language written by Apple which allows you to drive many of the stuff on your Mac with a script. My program is going to be using something like the osascript program to get information from iTunes and drive the playing of tracks and the like. I'm still not 100% sure which Applescript commands that I will be using but it took me a while to come up with the below so I thought I'd document them for posterity.

In Java I'm executing the osascript -e ... program which executes Applescript and (I guess) Javascript scripts.

Applescript Commands to Drive iTunes

Some of these I got from other places. Most I had to figure out on my own by looking at various webpages and Stackoverflow answers. They seem to be working as of January 2016 in OSX 10.10.5.

All of the following examples need to be wrapped in something like the following. Read you basic Applescript docs for more info.

tell application "iTunes" ... end tell

Create a blank playlist of clear it if it exists

if user playlist "myPlaylist" exists then try delete tracks of user playlist "myPlaylist" -- could also be: delete of (every track of playlist "myPlaylist") end try else make new user playlist with properties {name:"myPlaylist"} end if

Find a track in your collection or a playlist:

So a track is an iTunes object. It has an internal id (like #29431) as well as the name, artist, genre, year, etc. fields that you can see in iTunes by getting track info. To copy a track into a playlist, delete it, play it, etc. you need to be able to get the track object. Since track is a reserved word, we are setting the trk variable here.

Get the track object associated with its id.

set trk to track id 12693

This also seems to work.

set trk to (first track whose id is 12693)

Get the first track in a playlist.

set trk to track 1 of user playlist "myPlaylist"

Search for a track in your collection or playlist.

set trk to (first track whose name is "Waterloo" and artist is "ABBA") set trk to (first track in playlist "tmp" whose name is "Waterloo" and artist is "ABBA")

Add a track to a playlist:

Here we are copying a track object into the playlist.

duplicate trk to the end of user playlist "tmpList" duplicate track id 12693 to end of user playlist "tmpList"

I'm not sure what this does without the "the end of" part. "copy" also seems to work but maybe creates a full track copy?

Delete tracks from a playlist:

Remove the first track in a playlist.

delete track 1 of user playlist "myPlayList"

Same thing.

set trk to track 1 of playlist "tmpList" delete trk

Remove the first track in a playlist if it is not playing:

set curr to the current track set trk to track 1 of playlist "myPlayList" if curr is not equal to trk then delete trk

Interestingly, this doesn't work or maybe I'm confusing library track ids with playlist track ids.

delete track id 12693 of user playlist "myPlayList" -- ENOWORK

Get information from tracks:

Get the current track id. Other fields include: id, name, artist, album artist, year, genre, rating, time, duration,

get the id of the current track

Get the ids of all of the tracks in a playlist.

get the id of (every track in playlist "myPlayList")

Get other information from a track. This might take a while.

get the {id, name, artist} of (every track)

Get information from a playlist.

get the {name, artist, album artist, year} of (every track in playlist "myPlayList")

Get information from a particular track id.

get the {id, name, artist} of track id 12693

Move tracks around in a playlist:

This takes the 3rd track in the playlist and moves it to the end of the playlist.

set trk to track 3 of playlist "myPlayList" move trk to end of playlist "myPlayList"

I've not found any other mechanism to change a playlist order unfortunately.

Get current playing track status:

Gets the playlist-index, track id, start time (not sure when not 0.0, duration in seconds (not sure when not equal to the finish), finish in seconds, current player position in seconds.

{index, id, start, duration, finish} of current track & {player position}

Get the rating of the current track in stars:

set stars to round (rating of current track) / 20

Copy all tracks from one playlist to another:

copy (every track in playlist "sourcePlaylist") to playlist "destinationPlaylist"

Delete playlist:

delete playlist "tmpList"

Get the artwork for the current track:

Got this from this great StackOverflow post which extracts the artwork from the current track and writes it to the file specified.

tell artwork 1 of current track -- get the bytes of the artwork set srcBytes to raw data -- set the file extension based on the type if format is <> then set ext to "png" else set ext to "jpg" end if end tell -- get the destination filename as cover.ext in a temporary folder set fileName to (path to temporary items folder from user domain as string) & "cover." & ext) -- start the output file set outFile to open for access file fileName with write permission -- truncate it set eof outFile to 0 -- write the bytes of the image to the file write srcBytes to outFile close access outFile -- get and return the posix (i.e. unix) path and extension set posixFilename to POSIX path of filename {posixFilename, ext}

This allows me to get the ~Unix path of the temporary file and read in into my Java program.

Free Spam Protection   Eggnog Recipe   Android ORM   Simple Java Magic   JMX using HTTP   OAuth 2.0 Simple Example   Great Eggnog Recipe