macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Using Java to Expand iTunes Functionality
Pages: 1, 2

Extending Chord

The com.fivevoltlogic.mytunes.Chord class is to MyTunes what the ContentHandler interface is to SAX; Chord's methods can be overridden to suit your needs. As mentioned earlier, we'll create a Chord to populate a MySQL database with the information from your iTunes library. While the design could be improved in many ways, it serves as an excellent introduction, and after reading and walking through this tutorial, you'll be confident and knowledgeable enough to use MyTunes in any way that you could wish.

Prerequisites

The walkthrough assumes the reader already has MySQL up and running on his or her Mac, and has a basic level of competency in using and administrating the server. If this is not the case, Marc Liyonage has an excellent walkthrough for installing the MySQL server on OS X, and the online documentation is available here. In addition to xerces.jar and mytunes.jar, we'll need a JDBC driver to connect to the MySQL database that we're populating. MySQL Connector/J will do exactly that. Again, extract and place the JAR file in /Library/Java/Extensions/ and we'll be ready to go.

The first step is to create the database tables that will hold the desired information; here is a MySQL script that will accomplish that task. Three tables will be created (see the script for details on which columns will be created in each table to correspond to the fields of the Track and Playlist beans), two of which are self-explanatory:

  • Tracks: holds information about an iTunes track.
  • Playlists: holds information about an iTunes playlist.
  • PlaylistTracks: maps Tracks to a Playlist; this table is necessary to describe the many-to-one relationship between Tracks and Playlists.

To create the tables in the FVL database (as an example), open up the Terminal and type the following command:


mysql FVL < mytunes.mysql

With the database ready to go, the next step is to extend the Chord class to populate the database with the information that it receives. The resulting class is available here, and upon running it, you should receive no output. However, upon checking our database, we see that the information has been properly stored in the database:

Viewing the number of tracks in our iTunes music library
Viewing the number of tracks in our iTunes music library

And now that our information is stored in an SQL database, we can run a variety of queries on our music data:

  • select * from Tracks where trackArtist="Bran Van 3000" or trackArtist="The Weakerthans" will return all information from all tracks by either Bran Van 3000 or The Weakerthans.
  • select trackId from Tracks where trackDuration < 180 and trackRating > 80 returns the database ID for all tracks that are shorter than three minutes and have a rating of four or five stars.

Wrapping Up

With MySQLImport, we saw how to populate an SQL database with the information from our iTunes library. However, this task is just one example of using MyTunes; if you come up with any clever ideas for other Chords, post your thoughts in the comments section at the bottom of this article.

Remote Control

We just saw how to create a Chord to populate a MySQL database with information from the iTunes library. However, the com.fivevoltlogic.mytunes package contains several utility classes that are not related to the library. As you can probably guess by the heading, MyTunes also allows you to control iTunes via Java.

How Does it Work?

If you open up iTunes' dictionary in Script Editor and compare it to com.fivevoltlogic.mytunes.Remote's API, you'll see there is a similarity between the two. There's good reason for this: the majority of Remote's methods are actually just wrappers around iTunes' available AppleScript commands:

  • playTrack(int) plays a track with the corresponding database id from the library.
  • playArtist(String) plays the first track in the library with the corresponding artist.
  • pause(), backTrack(), nextTrack(), playPause(), previousTrack(), stop(), etc. are self-explanatory.

When one of the above methods is invoked, a file is created in the directory indicated by the System property java.io.tmpdir (which, by default, evaluates to /tmp). The contents of this file are merely an AppleScript that will be passed as an argument to the /usr/bin/osascript command. For example, create an instance of Remote and invoke the playPlaylistTrack(playlist, track), as in this example, a file named mytunes.remote will be created containing the following text:


tell application "iTunes"
  play (track 4 of playlist 1)
end tell
	

Related Reading

Java and XML
Solutions to Real-World Problems
By Brett McLaughlin

This file is then passed as an argument to the /usr/bin/osascript command.

Following the completion (successful or not) of the method's execution, the temporary file will be deleted to allow the next command to be executed. Because control of iTunes is done in this manner, the method is required to be synchronized.

The Final Piece of the Puzzle

You have now been introduced to all classes in the com.fivevoltlogic.mytunes package but one. We just saw how to control iTunes from a Java class that is running on the local machine (localhost); the next step is to control iTunes from a different machine. And since we're using Java and XML as our foundation, there are three choices to implement this feature:

All three frameworks are under the same general umbrella: distributed computing. And with three different choices, there are a variety of reasons to choose one over the others in certain situations. RMI's main drawback is that both sides of the communication line must be written in Java. While this isn't necessarily bad, the client, ideally, shouldn't be tied down to just one language. And because XML-RPC is easier than SOAP to get up and running, we'll use it as our transport from to client to server and back again. For a more detailed description and comparison of the protocols, see Java & XML 2nd Edition by Brett McLaughlin, O'Reilly & Associates, 2001.

The first step is to get the server up and running. If you wish, you can specify a port that the server should listen to; by default, it uses the property given in ~/.mytunes.xml:

Sample output when starting the XML-RPC server
Sample output when starting the XML-RPC server

Once BaseStation is listening, we'll need to create a client to talk to the server. Because of XML-RPC's simplicity, this can be done in a matter of minutes (for an introduction to XML-RPC, see Eric Kidd's how-to). The source for RPCTest.java is available here. Because both the server and client are running on the same machine, this example isn't very practical, but if you have two or more Macs on a network, it is trivial to control another Mac to behave as a jukebox. Throw this into a servlet (see this article on Apple's Developer Connection to get Apache Tomcat up and running on OS X) and you've got remote control of iTunes from a web interface.

Roadmap

You've now seen how to use most of the desired features of MyTunes are in place. However, there are several things that remain to be completed:

  • The isSmart() method of the Playlist class always returns false.
  • Playlists are dealt with in the order in which they are located in the XML file; hence, their getId() method returns a value based on that, which has nothing to do with the index of the playlist in iTunes' sorting order.
  • Anything else that comes to mind.

These changes and additions will be incorporated into the package as time permits. If you're interested in the package, stay tuned to the project's home page to keep abreast of any updates and changes that will be released. If there's anything else that you think should be incorporated, send your suggestions to me via email( ), or post them in the comments section below.

David Miller is combining his passions of photography and working on the web at iStockphoto; when not hacking away with a text editor and a few web browsers in hand, he can be seen huddled over his laptop tweaking levels and curves for his freelance photography. Keep track of David's latest projects over at his home on the web.


Return to the Mac DevCenter