Friday, December 15, 2017
  • Index
  •  » unScripted
  •  » Do-It-Yourself Time Machine for iTunes (Building year-based playlists)

#1 2009-12-05 04:48:51 pm

Kevin Bradley
Administrator
From:: Independence, MO
Registered: 2006-03-13
Posts: 548
Website

Do-It-Yourself Time Machine for iTunes (Building year-based playlists)

Build Your Own Time Machine

No, I'm not talking about Apple's Time Machine, which helps you backup your files.  No, the time machine I'm talking about is a musical time machine. If, like me, you keep close track of the "year" field in your iTunes tracks, wouldn't it be nice if you could just run an Applescript and have it randomly select a year and play some tracks?  Or maybe you'd prefer to select a year yourself?  For those that are familiar with a TV program called "Doctor Who," you know that his time machine is called the TARDIS.  If you have never seen "Doctor Who", then just know that the TARDIS looks like a british police call box (phone booth) and is larger on the inside than it is on the outside.  And sometimes it goes astray and winds up someplace the Doctor didn't intend.

With that out of the way, let's get to work building our time travel script.  First, we need to survey your iTunes tracks and find out what years are available. Compiling this list is fairly easy, we simple ask for "set trackyears to year of file tracks of playlist 'Music'."  This list will have lots of duplicates in it, which would bias the following selection of tracks toward those years with lots of tracks.  We prefer a fairer distribution, so we create a repeat loop and a new list, adding only those years that aren't already in the list.  After this, we use the "some item" command to randomly select a year from our list.

That done, we need to check and see if the playlist we're about to use exists already or if we need to create it.  I've got several scripts that use that functionality in iTunes, so I've written a separate handler that I can just cut and paste into my iTunes scripts. "CreateList('TARDIS','')" tells the handler we want a playlist named 'TARDIS' but the empty quotes tells the handler we don't want it placed in a folder, otherwise we'd supply the name of the folder.

Just for fun, I've set the script to start by playing the first 10 seconds of the Doctor Who theme to set the mood. If you're a fan of the old TV series "Time Tunnel" you can use that theme instead and change the playlist name.  Playing the music also helps fill the time it takes to sort the year list and select the tracks, so it's also a useful diversion.

Since we build the list of available years instead of just picking a year that you might not have in your iTunes library, we're assured of getting at least one track for the specified year.  I've set my script to try and get ten unique tracks. But if the library has less than ten tracks, we just duplicate them to the playlist.

If we have more than ten tracks to choose from, we again use the "some item" command to randomly select tracks.  Since we don't want ten instances of the same track we need to check the track list to make sure the new track isn't already there. If it is, we keep iterating the "repeat" loop until we get ten tracks that are unique. When finished, we duplicate the tracks to the playlist "TARDIS."

At this point, we're ready to play the list. Let's stop the TV show theme and announce the year we've landed in! As a nice touch, let's also show the user the playlist by revealing track 1 of the list.

You've successfully built your own musical time machine!  Here's the completed script:

Applescript:

tell application "iTunes"
   --For fun!
   play file track "Doctor Who Theme"
   --compile list of available years
   set tracklist to {}
   set trackyears to year of file tracks of playlist "Music"
   --cull out the duplicates
   repeat with aYear in trackyears
       if tracklist does not contain aYear then set end of tracklist to aYear
   end repeat
   set theYear to some item of tracklist
end tell
--if playlist exists, wipe it
--else create it
createList("TARDIS", "")
--populate list with songs from target year
tell application "iTunes"
   set tracklist to every file track of playlist "Music" whose year is theYear and kind is not "PDF Document"
   --if more than ten tracks, we'll randomly pick 10
   --otherwise we'll skip the repeat loop and just load the few tracks we have
   if length of tracklist > 10 then
       set done to false
       repeat until done
           set theTrack to some item of tracklist
           set theName to name of theTrack
           set theTest to every file track of playlist "TARDIS" whose name is theName
           if length of theTest = 0 then duplicate theTrack to playlist "TARDIS"
           set testTracks to count tracks of playlist "TARDIS"
           if testTracks = 10 then set done to true
       end repeat
   else
       duplicate every file track of tracklist to playlist "TARDIS"
   end if
   repeat until player position ≥ 10
   end repeat
end tell
tell application "iTunes" to stop
say "The Tardis has landed in the year " & theYear & "."
tell application "iTunes"
   play playlist "TARDIS"
   reveal track 1 of user playlist "TARDIS"
end tell


on createList(newlist, folderlist)
   -- check for my playlist and create if necessary
   tell application "iTunes"
       if exists playlist newlist then
           delete every file track of playlist newlist
       else
           if length of folderlist > 0 then
               make new user playlist at (folder playlist folderlist) with properties {name:newlist}
           else
               make new user playlist with properties {name:newlist}
           end if
       end if
   end tell
end createList

Building an Accurate Time Machine
Now, let's look at another sort of time machine - one which you control.  Rather than choosing a year randomly, you can input a year you would like to hear.  Given that we already have the mechanics of choosing tracks based on the year, all we need to do is rewrite the beginning of the script so that instead it accepts a typed year from the user.  I've put in some "try" statements to avoid any conversion error, faulty input, or years that don't exist in the library.  Here's the finished script:

Applescript:

set theYear to (year of (current date)) --the default year
set success to false
tell application "iTunes"
   activate
   repeat until success
       display dialog "Set the WABAC Machine to year:" default answer theYear buttons {"Cancel", "Go!"} default button 2
       try
           --first see if it's a valid number
           set theYear to (text returned of the result) as integer
           set success to true
       on error
           display dialog "That wasn't a valid year."
           set success to false
       end try
       try
           --now see if we can find any tracks for that year
           set tracklist to every file track of playlist "Music" whose year is theYear
           if (length of tracklist) > 0 then
               set success to true
           else
               set success to false
               display dialog "No tracks for that year."
           end if
           
       on error
           display alert "Error reading tracks from iTunes."
           set success to false
       end try
   end repeat
end tell
if success then
   --if playlist exists, wipe it
   --else create it
   createList("WABAC Machine", "")
   --populate list with songs from target year
   tell application "iTunes"
       --use the tracklist to select some tracks
       set sometracks to true
       if length of tracklist ≥ 10 then
           set done to false
           repeat until done
               set theTrack to some item of tracklist
               set theName to name of theTrack
               set theTest to every file track of playlist "WABAC Machine" whose name is theName
               if length of theTest = 0 then duplicate theTrack to playlist "WABAC Machine"
               set testTracks to count tracks of playlist "WABAC Machine"
               --say (testTracks & " tracks") as text
               if testTracks = 10 then set done to true
           end repeat
       else if length of tracklist = 0 then
           display dialog "No tracks for this year."
           set sometracks to false
       else
           repeat with aTrack in tracklist
               duplicate aTrack to playlist "WABAC Machine"
           end repeat
       end if
       
       if sometracks then
           play playlist "WABAC Machine"
           reveal track 1 of user playlist "WABAC Machine"
       end if
   end tell
end if

on createList(newlist, folderlist)
   -- check for my playlist and create if necessary
   tell application "iTunes"
       if exists playlist newlist then
           delete every file track of playlist newlist
       else
           if length of folderlist > 0 then
               make new user playlist at (folder playlist folderlist) with properties {name:newlist}
           else
               make new user playlist with properties {name:newlist}
           end if
       end if
   end tell
end createList

To avoid confusion, I have named the second script "WABAC Machine" ("way back") after the time machine that Mr. Peabody and Sherman used on "The Bullwinkle Show."  If you don't know who they are, ask your parents, they'll know.

You can script something similar using other criteria to filter your results (or for choosing at random).  For example you can write a script to pull tunes with short durations, or play some tracks by artists whose name starts with a random letter.  You get the idea.

Now you can sit back and listen to songs from a particular year as if you were listening to an old radio station (one with no commercials).  If you use Apple's speech recognition, you can put these scripts in your "Speakable Items" folder and impress your friends by showing off something that even Windows 7 can't do.

That's all.  Go crunch some code!


Nitewing '98
--
I distrust morning people, largely because I suspect them of getting together early one day while the rest of us were asleep and setting up the rules of civilization.


Filed under: Script, iTunes, music, playlist

Offline

 

#2 2009-12-10 10:58:54 am

Adam Bell
Administrator
From:: Nova Scotia, Canada
Registered: 2005-10-04
Posts: 4660

Re: Do-It-Yourself Time Machine for iTunes (Building year-based playlists)

Very nice, indeed, Kevin. I've moved it to unScripted as you can see. big_smile


iMac running OS X 10.13.1

Offline

 
  • Index
  •  » unScripted
  •  » Do-It-Yourself Time Machine for iTunes (Building year-based playlists)

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)