iTunes scripts I can’t live without
posted at around evening time by Constantinos. Filed under Code, OS XThis post was originally published in 2007
The tips and techniques explained may be outdated.
I have few obsessions in my life, and one of those happens to be keeping my iTunes library in some form (and definition) of ‘order’, without having me go completely insane. This involves keeping the ID3 data as accurate as I can make it (very tedious process as I had about 100 songs named Track 3 – Unknown Artist), but that is more or less under control. What I’m working on now is rating all of my music (I’m sure every one has their own rating scheme, and there’s no need to share mine here… Just suffice to say that a 0-star rating means the song hasn’t been reviewed), and also getting as much album artwork to go with iTune’s cover flow so I can use it without looking at the same default image every time…
Doing all this manually would pretty much take up all my time, so over a period of few months (back when I first started dealing with my iTunes library), I built a few applescripts which help me manage all these tasks, and which are bound to keyboard shortcuts in Quicksilver.
Rating
I have all the standard 0-5 star rating scripts, which are bound to cmd-opt-0 through cmd-opt-5 respectively. Since I use Growl, I wanted a notification to come up for this fact, and use the album artwork (if any) as the notification icon. This is the script for the 5 star rating, where for every other (0-4 stars) script the only modification is the actual rating (commented in the script)
property emdash : «data utxt2014» as Unicode text property black_star : «data utxt272F» as Unicode text property white_star : «data utxt2606» as Unicode text property dot : «data utxt00B7» as Unicode text set appName to "GrowlHelperApp" set app2Name to "iTunes" tell application "System Events" set appIsRunning to (name of processes contains appName) and (name of processes contains app2Name) end tell if appIsRunning then tell application "iTunes" if class of current track is in {track, file track, URL track, device track, shared track, audio CD} then (* Increments of 20, from 0 to 100 for 0 - 5 stars *) set rating of current track to 100 end if my notifyTrack(current track, player position, "5 Stars") (* or whatever else you want *) end tell end if on notifyTrack(myTrack, pos, txt) tell application "iTunes" set trkName to name of myTrack set trkArtist to artist of myTrack set trkAlbum to album of myTrack set trkTime to time of myTrack set trkRating to (rating of myTrack) / 20 set trkPos to my getTimeString(pos) set artworkCount to count of artwork of myTrack if artworkCount > 0 then tell myTrack set trkArt to (data of artwork 1) end tell else set iTunesIcon to "Macintosh HD:Applications:iTunes.app:Contents:Resources:iTunes.icns" set trkArt to read (file iTunesIcon) as picture end if if (txt is equal to false) then set txt to trkName set trkInfo to trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist & return & trkAlbum else set trkInfo to trkName & return & trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist if (trkAlbum is not equal to "") then set trkInfo to trkInfo & " (" & trkAlbum & ")" end if end if end tell my showQSNotify(txt, trkArt, trkInfo) end notifyTrack on showStars(trkRating) set stars to "" repeat trkRating times set stars to stars & black_star end repeat repeat (5 - trkRating) times set stars to stars & " " & dot end repeat return stars end showStars on showQSNotify(txt, trkArt, trkInfo) tell application "GrowlHelperApp" set the allNotificationsList to {"Rating Change", "Song Skipping", "Song Info"} register as application ¬ "Hotkey iTunes Notification" all notifications allNotificationsList default notifications allNotificationsList ¬ icon of application "iTunes" if (trkArt is equal to missing value) then notify with name "Rating Change" title txt description trkInfo application name "Hotkey iTunes Notification" else notify with name "Rating Change" title txt description trkInfo application name "Hotkey iTunes Notification" pictImage the trkArt end if end tell end showQSNotify on showTrackInfo() try tell application "GrowlTunes" show current track end tell end try end showTrackInfo on getTimeString(secs) set no_seconds to the secs as number set no_minutes to no_seconds div 60 set no_seconds to no_seconds mod 60 if no_seconds < 10 then set seconds_text to "0" & (no_seconds as string) else set seconds_text to no_seconds as string end if if no_minutes ≥ 60 then set no_hours to no_minutes div 60 set no_minutes to no_minutes mod 60 if no_minutes < 10 then set no_minutes to "0" & (no_minutes as string) end if set minutes_text to (no_hours as string) & ":" & (no_minutes as string) else set minutes_text to no_minutes as string end if return minutes_text & ":" & seconds_text end getTimeString |
Skipping
Sometimes, I find myself having a few hours of free time, where I want to just sit down and rate all my unrated songs. Instead of using the mouse to skip through every song (since I’ve already heard all of them, I just haven’t considered a rating for them), I have a script that skips a quarter of the song on each press, and places the playhead at 3 seconds from the end on the 4th activation. Useful for quickly skipping through a song.
property emdash : «data utxt2014» as Unicode text property black_star : «data utxt272F» as Unicode text property white_star : «data utxt2606» as Unicode text property dot : «data utxt00B7» as Unicode text set appName to "GrowlHelperApp" set app2Name to "iTunes" tell application "System Events" set appIsRunning to (name of processes contains appName) and (name of processes contains app2Name) end tell if appIsRunning then try tell application "iTunes" set myTrack to current track set dur to duration of myTrack set q1 to dur / 4 set q2 to q1 * 2 set q3 to q1 * 3 set q4 to dur - 3 set curPos to player position set counter to 0 set theList to {q1, q2, q3, q4, dur} set pos to 0 repeat while pos is less than or equal to curPos set counter to counter + 1 set pos to item counter of theList end repeat if pos is less than 1 then set pos to 1 set player position to pos if counter is greater than 3 then my notifyTrack(myTrack, player position, "Ending Song") else my notifyTrack(myTrack, player position, "Song Skip") end if (* my showTrackInfo() *) end tell end try end if on notifyTrack(myTrack, pos, txt) tell application "iTunes" set trkName to name of myTrack set trkArtist to artist of myTrack set trkAlbum to album of myTrack set trkTime to time of myTrack set trkRating to (rating of myTrack) / 20 set trkPos to my getTimeString(pos) set artworkCount to count of artwork of myTrack if artworkCount > 0 then tell myTrack set trkArt to (data of artwork 1) end tell else set iTunesIcon to "Macintosh HD:Applications:iTunes.app:Contents:Resources:iTunes.icns" set trkArt to read (file iTunesIcon) as picture end if if (txt is equal to false) then set txt to trkName set trkInfo to trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist & return & trkAlbum else set trkInfo to trkName & return & trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist if (trkAlbum is not equal to "") then set trkInfo to trkInfo & " (" & trkAlbum & ")" end if end if end tell my showQSNotify(txt, trkArt, trkInfo) end notifyTrack on showStars(trkRating) set stars to "" repeat trkRating times set stars to stars & black_star end repeat repeat (5 - trkRating) times set stars to stars & " " & dot end repeat return stars end showStars on showQSNotify(txt, trkArt, trkInfo) tell application "GrowlHelperApp" set the allNotificationsList to {"Rating Change", "Song Skipping", "Song Info"} register as application ¬ "Hotkey iTunes Notification" all notifications allNotificationsList default notifications allNotificationsList ¬ icon of application "iTunes" if (trkArt is equal to missing value) then notify with name "Song Skipping" title txt description trkInfo application name "Hotkey iTunes Notification" else notify with name "Song Skipping" title txt description trkInfo application name "Hotkey iTunes Notification" pictImage the trkArt end if end tell end showQSNotify on showTrackInfo() try tell application "GrowlTunes" show current track end tell end try end showTrackInfo on getTimeString(secs) set no_seconds to the secs as number set no_minutes to no_seconds div 60 set no_seconds to no_seconds mod 60 if no_seconds < 10 then set seconds_text to "0" & (no_seconds as string) else set seconds_text to no_seconds as string end if if no_minutes ≥ 60 then set no_hours to no_minutes div 60 set no_minutes to no_minutes mod 60 if no_minutes < 10 then set no_minutes to "0" & (no_minutes as string) end if set minutes_text to (no_hours as string) & ":" & (no_minutes as string) else set minutes_text to no_minutes as string end if return minutes_text & ":" & seconds_text end getTimeString |
Download this script
This method works well with a couple of smart playlists and clever manipulation of the Party Shuffle feature. I have two smart playlists (one of them is used to filter out tv shows and movies, but not video clips). One is named “Other Video”, and has the following rules:
- Match any of the following:
- Video kind is Movie
- Video kind is TV Show
The other is named “All Unrated”, and has the following rules:
- Match all of the following:
- My rating is less than 1 star
- Podcast is false
- Playlist is not Other Video
Finally, in Party Shuffle, at the bottom, I have Source: “All Unrated”, Display 5 recently played songs, and 15 upcoming songs. This way, even though the song I just rate will be removed from the “All Unrated” smart playlist, it won’t stop playing as it’s in the Party Shuffle playlist.
Artwork
I first ran “Get Album Artwork” in iTunes, but obviously that had a fairly limited success as a lot of my music has vital information like Album missing, and also a lot of the music I listen to isn’t even in the iTunes store. To cover the gap, I’m a fanatic GrowlTunes user, which does all the heavy work of fetching album covers (sometimes more successfully than others). GrowlTunes first looks for album artwork in the song itself, and if it doesn’t find any it then fetches it from the internet to display the Growl alert. What it does NOT do is save it with the song, but it DOES save it locally so it doesn’t have to fetch it again (in my opinion this is a very good thing as anything under a 95% success ratio you’ll want to review, and GrowlTunes is more like 70%). So what I’ve done is prepared a script that, for the current track, looks at the default GrowlTunes location, and if it finds an album cover it adds it to the song (to run it, you will need to replace your own short user name at the first line of the script):
property myUserName : "Constantinos" property appName : "iTunes" tell application "System Events" to set appIsRunning to name of processes contains appName if appIsRunning then tell application "iTunes" try set myTrack to current track set trackName to name of myTrack if (trackName is equal to "") then set trackName to "Unknown Track" end if set trackArtist to artist of myTrack if (trackArtist is equal to "") then set trackArtist to "Unknown Artist" end if set trackAlbum to album of myTrack if (trackAlbum is equal to "") then set trackAlbum to "Unknown Album" end if end try end tell set artworkFilename to "/Users/" & myUserName & "/Library/Images/Music/" & trackArtist & "/" & trackAlbum & "/Tracks/" & trackName & "/Track.png" set deleteFilename to "Macintosh HD:Users:" & myUserName & ":Library:Images:Music:" & trackArtist & ":" & trackAlbum & ":Tracks:" & trackName & ":Track.png" set deleteCoverFilename to "Macintosh HD:Users:" & myUserName & ":Library:Images:Music:" & trackArtist & ":" & trackAlbum & ":Cover.png" set albumCoverFilename to "/Users/" & myUserName & "/Library/Images/Music/" & trackArtist & "/" & trackAlbum & "/Cover.png" set tempfile to "Macintosh HD:tmp:temporary.pict" tell application "Image Events" (* set artworkFile to (POSIX file artworkFilename) set myImage to open (artworkFile as alias) *) set myImage to open artworkFilename try save myImage as PICT in (file tempfile) on error try set deleteFilename to deleteCoverFilename set myImage to open albumCoverFilename save myImage as PICT in (file tempfile) on error return end try end try close myImage end tell tell application "iTunes" set myTrack to current track set artworkCount to count of artwork of myTrack set myArt to read (file tempfile) from 513 as picture if artworkCount > 0 then set data of artwork (artworkCount + 1) of current track to myArt else set data of artwork 1 of current track to myArt end if end tell tell application "Image Events" delete (file tempfile) delete (file deleteFilename) end tell end if |
Notifications
The first two scripts use the same “Hotkey iTunes Notification” application name to register with Growl, with three types of notification: “Rating Change”, “Song Skipping” and “Song Info”. The last one simply brings up a detailed notification dialog with the current song’s playhead position, title, artist, rating, album and album art, which can all fit in the small “Smoke” style notification window. If you’re interested in that, the script follows:
property emdash : «data utxt2014» as Unicode text property black_star : «data utxt272F» as Unicode text property white_star : «data utxt2606» as Unicode text property dot : «data utxt00B7» as Unicode text set appName to "GrowlHelperApp" set app2Name to "iTunes" tell application "System Events" set appIsRunning to (name of processes contains appName) and (name of processes contains app2Name) end tell if appIsRunning then tell application "iTunes" my notifyTrack(current track, player position, false) end tell end if on notifyTrack(myTrack, pos, txt) tell application "iTunes" set trkName to name of myTrack set trkArtist to artist of myTrack set trkAlbum to album of myTrack set trkTime to time of myTrack set trkRating to (rating of myTrack) / 20 set trkPos to my getTimeString(pos) set artworkCount to count of artwork of myTrack if artworkCount > 0 then tell myTrack set trkArt to (data of artwork 1) end tell else set iTunesIcon to "Macintosh HD:Applications:iTunes.app:Contents:Resources:iTunes.icns" set trkArt to read (file iTunesIcon) as picture end if if (txt is equal to false) then set txt to trkName set trkInfo to trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist & return & trkAlbum else set trkInfo to trkName & return & trkPos & "/" & trkTime & " " & emdash & " " & my showStars(trkRating) & return & trkArtist if (trkAlbum is not equal to "") then set trkInfo to trkInfo & " (" & trkAlbum & ")" end if end if end tell my showQSNotify(txt, trkArt, trkInfo) end notifyTrack on showStars(trkRating) set stars to "" repeat trkRating times set stars to stars & black_star end repeat repeat (5 - trkRating) times set stars to stars & " " & dot end repeat return stars end showStars on showQSNotify(txt, trkArt, trkInfo) tell application "GrowlHelperApp" set the allNotificationsList to {"Rating Change", "Song Skipping", "Song Info"} register as application ¬ "Hotkey iTunes Notification" all notifications allNotificationsList default notifications allNotificationsList ¬ icon of application "iTunes" if (trkArt is equal to missing value) then notify with name "Song Info" title txt description trkInfo application name "Hotkey iTunes Notification" else notify with name "Song Info" title txt description trkInfo application name "Hotkey iTunes Notification" pictImage the trkArt end if end tell end showQSNotify on showTrackInfo() try tell application "GrowlTunes" show current track end tell end try end showTrackInfo on getTimeString(secs) set no_seconds to the secs as number set no_minutes to no_seconds div 60 set no_seconds to no_seconds mod 60 if no_seconds < 10 then set seconds_text to "0" & (no_seconds as string) else set seconds_text to no_seconds as string end if if no_minutes ≥ 60 then set no_hours to no_minutes div 60 set no_minutes to no_minutes mod 60 if no_minutes < 10 then set no_minutes to "0" & (no_minutes as string) end if set minutes_text to (no_hours as string) & ":" & (no_minutes as string) else set minutes_text to no_minutes as string end if return minutes_text & ":" & seconds_text end getTimeString |
Download this script
That’s pretty much it… Enjoy!
1. Comment by Daryl
on 17 Aug 2007 @ 10:21 pm
I wanted a simple apple script that will simply play the first anyNumber of seconds of a song so I can play my music in an ‘intro mode’ feel at night with dashboard open so my lyrics fetch widget can get all the lyrics for my iTunes lib. If you could help me with some applescripting (I am pretty good at programming, but I don’t yet understand applescript. The language is too close to human language, I think I need a language to be obscure to understand it 😉 ) It would be in your debt.
Thanks in advance
2. Comment by Constantinos
on 22 Aug 2007 @ 3:20 am
I’d love to help, but I can’t see how such an applescript would work without having the script be resident and running… Which actually might be a solution.
How about trying something like this:
where 1 to 1000 is just a “large loop”, I’m sure there’s an easy way to have an infinite loop in applescript but it doesn’t pop in my head right now. Also the “delay 15” part will let the current song play for 15 seconds before moving on to the next track. Modify to your enjoyment.
This is obviously really crude and can probably handle a lot of improvement, but I don’t see a way of getting rid of the loop/delay part of the program which is what bugs me. To stop this you’ll have to terminate the applescript.
3. Comment by Constantinos
on 17 Sep 2007 @ 1:55 am
Note on the skipping script: There was a bug where if you tried to skip as soon as the song started, or twice in less than a second, it would skip to the same quarter of the song. If you’re experiencing this problem, copy the updated script above.
4. Comment by Daniel
on 11 Jun 2008 @ 6:13 pm
I’m new to apple scripts and have tried reading up on where to put these to get them running.
But the more i search the more questions i came up with. But, here are my top 2.
1. where do i place the scripts
2. they are auto running correct? in other words i dont have to run the script every time i start itunes correct?
5. Comment by L8on
on 18 Jul 2008 @ 1:09 am
You have great scrips! However, I can’t seem to find the one I want anywhere on the internet. I am looking for a script I can run to enable single repeat of a song until I run it again [or run another script to go back to repeat all].
I am often on a random playlist and hear a song I want to hear again and don’t want to have to switch to iTunes to turn repeat on and then off again. I also don’t want to just rewind to beginning as the song doesn’t get the “play count”.
Then I would be able to trigger this script with a keystroke.
ANY SUGGESTIONS!
thanks!
6. Comment by Constantinos
on 18 Jul 2008 @ 3:24 pm
This is ENTIRELY untested, I just typed it up in this textbox. But it should be something along these lines:
Let me know if it works for you, or what errors it produces.
7. Comment by L8on
on 21 Jul 2008 @ 4:40 am
THANK YOU VERY MUCH! I ran it over and over again with iTunes in the background and it does EXACTLY what I want it to do. I just wish Apple would’ve build a toggle into the mini controller. Thank you so very much! Is there any way there can be a way of knowing whether it’s on “one” or “all”? To check I’d have to switch to iTunes which kind defeats the purpose. Either way, I’m very happy with it.
How did you get so good at script writing?
I’ll definitely be reading the blog more often…
8. Comment by L8on
on 21 Jul 2008 @ 5:01 am
just a thought. I saved it as an application on my desktop. Can you make the label on the turn green when it is on “one” and turn red when it is on “all”? That would be great and would instantly let me know mid-song whats the status.
In the middle of a song, I might think, okay this is the last time I wanna hear it but dont want to have to pull up iTunes to change it if in fact it was on repeat.
Thanks again!
9. Comment by Ian Jones
on 22 Sep 2008 @ 11:25 am
Is it possible to have a script that finds all “orphaned” songs (listing not linked to file) and move them to a playlist so that I can work through them to re-link them? I’ve seen scripts that find the orphans, but then just writes the list to a text file.
10. Comment by Alex Drost
on 23 Oct 2010 @ 11:05 am
Hi there, I absolutely love your script techniques. I’m having the same problems as you – a large library which I want to fix with tags and ratings. Now I’m looking desperately for a script which reminds me to rate the item, e.g. 15 seconds before the end of the song.
e.g. the song’s playing and 15 seconds before it, a little bell (or something like that) rings and I just hit my shortcuts to rate the song. That way, I don’t have to jump back and forth (esp. with soundtracks) whether I have skipped a song or not. 🙂
Do you have an idea?
Best!
Alex. 🙂
11. Comment by TomTom
on 21 Jun 2011 @ 10:43 pm
Hey dude..
Cool scripts..
I was wondering if I could ask you about making a fairly easy script, or at least I think it will be easy, that simply links GrowlTunes to launch/quit when launching/quitting iTunes..?
If its even possible..?
PS. I know this post is quite old, but I’m hoping your still checking up once every now and then…