Hacking iTunes
by Niel Bornstein
|
Pages: 1, 2
Playlists
You can use XSLT to get a list of all of the playlists in your library.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="plist/dict/key[text()='Playlists']/ \
following-sibling::array/dict">
<xsl:value-of select="key[text()='Name']/ \
following-sibling::string" /><xsl:value-of select="$newline" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
You can transform the playlists from the Music Library into other formats using XSLT. For example, the WinAmp playlist formats, documented at forums.winamp.com/showthread.php?threadid=65772, can be generated through an XSLT transform.
The M3U format is a simple text file listing directories and file names separated by a hyphen. The following stylesheet transforms a named iTunes playlist into a M3U playlist with the same name:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:param name="playlist" />
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="plist/dict/key[text()='Playlists']/ \
following-sibling::array/dict/key[text()='Name']/ \
following-sibling::string[text()=$playlist]/ \
following-sibling::key[text()='Playlist Items']/ \
following-sibling::array/dict">
<xsl:call-template name="track">
<xsl:with-param name="trackid" select=
"key[text()='Track ID']/following-sibling::integer" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="track">
<xsl:param name="trackid" />
<xsl:variable name="url"
select="//plist/dict/key[text()='Tracks']/ \
following-sibling::dict/dict/key[text()='Track ID']/ \
following-sibling::integer[text()=$trackid]/../ \
key[text()='Location']/following-sibling::string" />
<xsl:value-of select="$url" /><xsl:value-of select="$newline" />
</xsl:template>
</xsl:stylesheet>
Piping the output of this transform to a file with the .m3u extension will result in a double-clickable file that will play in WinAmp, iTunes, or even the Mac OS X Finder. This stylesheet can easily be extended to create an extended M3U or PLS file.
You can also create arbitrary playlists on the fly simply by creating the right XPath query.
The Web
Apple provides a browser-based service that allows you to look up a particular song or artist in the iTunes Music Store. Available online at phobos.apple.com/WebObjects/MZSearch.woa/wa/itmsLinkMaker, the ITMS Link Maker allows you to search for a song, album, or artist, and creates a link to direct the iTunes music player to the song in the music store. This could be useful if, for example, you publish a list of recently played songs on your weblog, and you want to let your readers buy the songs you've recently listened to.
Apple also provides a service to create an RSS feed of iTunes songs based on criteria you select, including genre, regional music store (France, Germany, U.K., or U.S.), feed type (new releases, just added, iTunes top songs, iTunes top albums, or featured albums and exclusives), feed size (from five to 100), and whether to show explicit content. Located on the Web at phobos.apple.com/WebObjects/MZSearch.woa/wa/MRSS/rssGenerator, this service returns a URL for your criteria. For example, an RSS feed of the top ten folk songs in the U.S. iTunes music store would be available at this URL.
Parsing RSS 2.0 is left as an exercise for the reader.
Amazon and Google
Amazon.com recently announced the beta trial of their web
services version 4.0. Using Mono's wsdl tool, we can
generate web-service client code with the following command
line:
wsdl http://aws-beta.amazon.com/AWSSchemas/AWSProductData/beta/US.wsdl
That command produces a file called AWSProductData.cs, which can be used to communicate with the Amazon.com web services.
Similarly, Google's web API is available as a WSDL, which can be downloaded with the Google Web API SDK. Once you've produced GoogleSearchService.cs, you can use it in much the same way.
For example, you can look up any artist in the Amazon.com catalog and return a list of that artist's recordings and any similar recordings. Then you can look up the artist in Google and find a number of related web sites. The following program does just that:
using System;
using System.Collections.Specialized;
using System.Text;
namespace LookupArtist
{
class LookupArtist
{
private StringCollection similars = new StringCollection();
private StringCollection discs = new StringCollection();
private const string amazonKey = "xxxx";
private const string googleKey = "yyyy";
static void Main(string[] args)
{
string artist = args[0];
LookupArtist search = new LookupArtist(artist);
}
LookupArtist(string artist)
{
AmazonSearch(artist);
GoogleSearch(artist);
}
private void AmazonSearch(string artist) {
ItemSearch search = new ItemSearch();
search.SubscriptionId = amazonKey;
search.Request = new ItemSearchRequest[1]
{ new ItemSearchRequest() };
search.Request[0].SearchIndex = "Music";
search.Request[0].Artist = artist;
search.Request[0].ResponseGroup = new string[]
{ "Similarities", "ItemAttributes" };
AWSProductData productData = new AWSProductData();
ItemSearchResponse response = productData.ItemSearch(search);
foreach (Items items in response.Items) {
foreach (Item item in items.Item) {
if (!discs.Contains(item.ItemAttributes.Title)) {
discs.Add(item.ItemAttributes.Title);
}
foreach (SimilarProductsSimilarProduct sim in
item.SimilarProducts)
{
string s = string.Format("{0} (ASIN {1})",
sim.Title, sim.ASIN);
if (!similars.Contains(s)) {
similars.Add(s);
}
}
}
}
Console.WriteLine("Discs by {0}:", artist);
foreach (string disc in discs) {
Console.WriteLine("\t{0}", disc);
}
Console.WriteLine("Similar discs:");
foreach (string similar in similars) {
Console.WriteLine("\t{0}", similar);
}
}
private void GoogleSearch(string artist) {
GoogleSearchService search = new GoogleSearchService();
GoogleSearchResult result =
search.doGoogleSearch(googleKey,
artist, 0, 10, false, string.Empty,
false, string.Empty, string.Empty,
string.Empty);
Console.WriteLine("Related web sites:");
foreach (ResultElement element in result.resultElements) {
Console.WriteLine("\t{0} <{1}>",
element.title, element.URL);
}
}
}
}
}
Be sure to replace the values of the variables amazonKey
and googleKey with the appropriate developer ID for each
service.
Searching for John Coltrane, for example, produces this output:
Discs by John Coltrane:
Kind of Blue
A Love Supreme
Thelonious Monk with John Coltrane
John Coltrane & Johnny Hartman
The Ultimate Blue Train
My Favorite Things
Giant Steps [Deluxe Edition]
Very Best of John Coltrane
Love Supreme (Dlx) (Dig)
Live at Birdland
Similar discs:
Time Out (ASIN B000002AGN)
Sketches of Spain [Bonus Tracks] (ASIN B000002AH7)
The Ultimate Blue Train (ASIN B000005H7D)
Birth of the Cool (ASIN B00005614M)
Thelonious Monk with John Coltrane (ASIN B000000Y2F)
Kind of Blue (ASIN B000002ADT)
My Favorite Things (ASIN B000002I53)
Giant Steps [Deluxe Edition] (ASIN B000003489)
Saxophone Colossus (ASIN B000000YG5)
Collection: 1947-1972 (ASIN B00000BKK5)
Sarah Vaughan W/ Clifford Brown (ASIN B00004NHCC)
Ballads (ASIN B000003N7I)
Getz/Gilberto (ASIN B0000047CX)
I Just Dropped by to Say Hello (ASIN B000003N83)
A Love Supreme (ASIN B0000A118M)
The Essential Charlie Parker (ASIN B000001E03)
Miles Davis - Greatest Hits [Columbia 1997] (ASIN B000002ALA)
A Love Supreme: The Story of John Coltrane's Signature Album (
ASIN 0670031364)
Live at Birdland (ASIN B000003N8O)
Crescent (ASIN B000003N8R)
The Complete 1961 Village Vanguard Recordings (ASIN B000003NA3)
Live At The Village Vanguard: The Master Takes (ASIN B0000065KK)
The Complete Africa/Brass Sessions (ASIN B000003N7U)
Related web sites:
::: JOHNCOLTRANE.COM ::: <http://www.johncoltrane.com/>
::: JOHNCOLTRANE.COM :::
<http://www.johncoltrane.com/automat/swf/main.htm>
<b>JOHN</b> <b>COLTRANE</b>
<http://home.att.net/~dawild/john_coltrane.htm>
The Recordings of <b>John</b> <b>Coltrane</b>: A Discography
<http://home.att.net/~dawild/john_coltrane_discography.htm>
Artists: <b>John</b> <b>Coltrane</b>
<http://www.northwestern.edu/WNUR/jazz/artists/coltrane.john/>
<b>John</b> <b>Coltrane</b> | My Favorite Things
<http://www.room34.com/coltrane/>
A Tribute to <b>John</b> <b>Coltrane</b>
<http://www.geocities.com/BourbonStreet/5066/trane.html>
Jazzone Online's <b>John</b> <b>Coltrane</b> Page
<http://www.geocities.com/BourbonStreet/Square/9063/index/coltrane.html>
<b>John</b> <b>Coltrane</b> discography
<http://webusers.siba.fi/~eonttone/trane.html>
PBS - JAZZ A Film By Ken Burns:
Selected Artist Biography - <b>John</b> <b>...</b>
<http://www.pbs.org/jazz/biography/artist_id_coltrane_john.htm>
Summary
I hope I've given you some ideas of ways to mess with an XML file that every iTunes user has on his or her hard disk, the iTunes Music Library. Of course, there is a lot more you can do. I haven't even fully explored the capabilities of Amazon and Google, much less investigated the full scope of web services out there.
2010-07-10 05:44:06 stellamcnorty- Decoding the iTunes Music Library Location field
2009-11-05 05:56:42 garberfc - ermmmm...
2008-05-30 04:24:52 lukxz - Smart Playlist Decoding
2008-04-06 13:15:41 the_ev - Where is the "checked" attribute kept?
2006-05-06 19:49:48 Itamar - Where is the "checked" attribute kept?
2008-01-21 15:18:51 BobSkinner - Great stuff, I'm making a phpversion of it!
2006-04-28 15:37:59 mskogly