Ruby script for iTunes on both Windows and Mac OS X

2007-03-02

I see people automating complex tasks on their computers by using scripts. Same here, I love it. When it comes to iTunes, we Mac OS X owners are using AppleScript – and the best place to start looking for all sorts of solutions is Doug’s page. For Windows users their iTunes looks the same, but the AppleScript won’t work. Instead, they can use VBscript or JavaScript to accomplish pretty much similar things. However, I think the Mac people are leading in terms of iTunes scripting solutions that are available for download. And I know that Doug gets lots of requests to provide the same functionality for Windows, too.

Now I had a dream. Wouldn’t it be great to use a scripting language that is available both on Windows and Mac OS X, and create cross-platform iTunes scripts? My pick would be Ruby, as I already know that from Rails development. Mac users need rubygems and rbosa, Windows users just need ruby. Then run this here:

if RUBY_PLATFORM.match('darwin')
  require 'rubygems'
  require 'rbosa'
  itunes = OSA.app('iTunes')
elsif RUBY_PLATFORM.match('mswin')
  require 'win32ole'
  itunes = WIN32OLE.new('iTunes.Application')
else
  #any other platform that has iTunes? add here...
end
itunes.play

Works so far! Do you like that???

Think of ruby scripts that can be used by both Windows and Mac users… Think of script developers on both platforms helping each others… Think of Ruby on Rails applications where you can query and tidy your music collection from any browser window in the world…

Nice. I need to reserve some time to digg more into this topic.

Advertisements

One Response to “Ruby script for iTunes on both Windows and Mac OS X”

  1. has Says:

    FWIW, there was a Python guy wrote a cross-platform library called pytunes a couple years back. Dunno what happened to the project, but you should be able to Google it easy enough.

    As far as abstracting away the differences between the COM and Apple event APIs, one issue you’ll need to consider is performance when working with playlist tracks. Windows and Mac take rather different approaches to IPC. COM uses a fine-grained approach with lots of object iterators and fast, simple calls. Apple events, however, were originally designed for System 7 which had rotten IPC performance, so much prefer a coarse-grained approach based on using complex queries with fewer calls.

    You can still use the iterate-and-get approach, of course, but since the internal implementation of iTunes and other Mac apps tend to optimise heavily for the coarse-grain approach, performance quickly drops through the floor as the number of objects involved goes up.

    For example, to get the name, artist and album of each track in a playlist, it’s far faster to send three queries asking for all the names, then all the artists, then all the albums, than it is to get a list of track references and get the name, artist and album for each in turn as you would in COM:


    require 'appscript'

    tracks_ref = Appscript.app('iTunes').playlists['my list'].tracks # 150-item playlist

    # using queries
    t = Time.new
    names = tracks_ref.name.get
    artists = tracks_ref.artist.get
    albums = tracks_ref.album.get
    track_info = names.zip(artists, albums)
    p Time.new - t # 0.05 sec

    # using iteration
    t = Time.new
    track_info = tracks_ref.get.collect { |i| [i.name.get, i.artist.get, i.album.get] }
    p Time.new - t # 0.9 sec (!)

    Also, things get worse as the number of tracks increase, e.g. with a 4000-track playlist the numbers were more like 1 sec vs. 30 sec.

    If this is going to be an issue, you may be able to come up with a uniform API design that abstracts all implementation details completely away under, say, an SQL-like table-oriented approach, e.g.:

    ITunes.do_query(‘SELECT name, artist, album FROM playlist “my list”‘)

    Otherwise it’s a toss-up between using the COM-style iterate-plus-get approach on both Mac and Windows, which is simplest to implement but will perform very poorly under load on Macs, or having users write platform-specific code at least some of the time.

    The appscript manual has a bit more advice on this sort of stuff, or you’re welcome to drop me an email if you’d like to discuss further.

    HTH

    has

    p.s. The following may also interest you – it’s a command-line controller for iTunes written in Ruby:

    http://rubyforge.org/forum/forum.php?forum_id=12587


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: