Wrox Home  
Search
del.icio.us Mashups
by Brett O'Connor
January 2007, Paperback


Excerpt from del.icio.us Mashups

Media Tag Remix: A del.icio.us MP3 Jukebox

by Brett O'Connor

del.icio.us seems so very simple at its core that it might be hard to realize the immense potential for mashups that exists within. Rest assured, there's a lot you can do with the massive database of the world's most trusted and favorite web links that del.icio.us provides, even without touching the del.icio.us API (Application Programming Interface). del.icio.us' RSS feeds alone provide a staggering amount of information about the web and what's interesting, hot, and new, and all in real-time.

del.icio.us doesn't just have a handful of RSS feeds, by the way. There are unique RSS feeds for almost every page and tag on del.icio.us, creating unlimited potential for the information you can discover. Taming all this data can be a challenge, but if you know how to aggregate and mix these feeds properly you can come up with some very fun tools and tricks. del.icio.us' RSS feeds are even a great way to go beyond the world of web mashups and start mixing del.icio.us up with desktop software itself.

One secret of making the most of del.icio.us RSS feeds as a developer is understanding the special filetype tags. You're probably familiar with the way that del.icio.us users utilize their own system of tags to organize their bookmarks, but you may not be aware that, depending on certain conditions, del.icio.us automatically adds special "system" tags as well.

Because I am a music and podcast fan, one of my personal favorite system tags is the system:filetype:mp3 tag. This is a media tag that tracks all MP3 files posted to del.icio.us. That's right, every mp3 ever linked to publicly by any del.icio.us user is automatically given this tag. Check it out for yourself by browsing here:

http://del.icio.us/tag/system:filetype:mp3

You can combine the system:filetype:mp3 tag with another tag to narrow the list down. For example, the following page will show you all mp3s that del.icio.us users have also tagged with "rock."

http://del.icio.us/tag/system:filetype:mp3+rock

The RSS feed for the system:filetype:mp3 tag is here:

http://del.icio.us/rss/tag/system:filetype:mp3

If you're in to podcasts you'll be happy to note that that this RSS feed is loaded with enclosures, so it will work great with your favorite podcast-enabled reader. That said, it might be nice to take a little more control of the system:filetype:mp3 feed and learn how you can use it in your own applications. Truly, if any tag deserves to break out of RSS and be molded into something new, this is the one.

With this brief project you will learn how to remix the system:filetype:mp3 tag into a music playlist that can be played in most software media players, including Apple's iTunes, WinAmp, and the multi-platform VLC (available at http://www.videolan.org/vlc/). The content and generation of this playlist will be produced by PHP and controlled via a web interface.

To get started, you will need a PHP-enabled local or public web. You'll also need to download the MagpieRSS parser for PHP, which you can get for free here:

http://magpierss.sourceforge.net/

MagpieRSS will be used to fetch and parse the RSS feed and then output it as a different type of file. The file you will generate is called a PLS file. PLS is a rough, mostly undocumented file format that essentially lists multimedia files and their locations in a certain way. Fortunately, most media players can interpret the list properly. The media player then does the work of streaming and playback of the audio file. So, all your script has to do is reinterpret the MP3 filetype tag into the proper file format. You will wrap this file generation code in an interface that will let you input a particular tag (if desired) before downloading the PLS file which will limit its content.

To begin, create a new directory wherever you would like this project to exist called "jukebox." Create inside this directory another directory called "cache," as well as a directory called "lib." The cache directory is where MagpieRSS will store its information, so you'll want to make sure it's writable by your web server. Then, download MagpieRSS and take its four files (rss_fetch.inc, rss_parser.inc, rss_cache.inc, and rss_utils.inc) as well as the "extlib" directory from the archive and place them in the "lib" directory.

Then create inside the "jukebox" directory an index.php script in your editor and insert the following code:

<?php
//base filetype tag feed url
define('BASE_MP3_FEED_URL','http://del.icio.us/rss/tag/system:filetype:mp3');
//bring in magpie goodness
require_once('lib/rss_fetch.inc');
//set cache directory
define('MAGPIE_CACHE_DIR', 'cache');
//get rid of error Notices because magpie produces some
error_reporting(E_ERROR | E_WARNING | E_PARSE);

Next write a control statement that checks for the presence of a POST variable called fetchpls. This statement will trigger the download of the PLS file. Otherwise, the HTML markup including the tag-entry form will be displayed. You'll notice that there's not much to generating the PLS file — it's really quite an easy task for PHP to perform.

if (isset($_POST['fetchpls'])) {
    //add any tags
    if (isset($_POST['tag']))
        $feed_url = BASE_MP3_FEED_URL."+".$_POST['tag'];
    else
        $feed_url = BASE_MP3_FEED_URL;
    //grab the feed
    $rss = fetch_rss($feed_url);
    //setup headers
    header("Content-type: audio/mpegurl");
    header('Content-Disposition: attachment; filename="jukebox.pls"');
    //output pls
    echo "[playlist]\n";
    $i = 1;
    foreach ($rss->items as $item) {
        echo "File".$i."=".$item['link']."\n";
        echo "Title".$i."=".$item['title']."\n";
        $i++;
    }
    echo "NumberOfEntries=".sizeof($rss->items)."\n";
    echo "Version=2\n";
    //die to stop further execution
    die();
}
?>

After closing the PHP block add the following HTML markup:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>A del.icio.us Jukebox!</title>
    <style type="text/css">
    body
    {
        margin: 1em;
        font-family: Helvetica, Arial, Sans-Serif;
    }
    </style>
</head>
<body>
<form method="post">
Export a music playlist live from 
<a href="http://del.icio.us/tag/system:filetype:mp3">del.icio.us</a>.
<br />
<br />
Enter in a tag to narrow it down (optional), or just hit "Get Playlist"
<br />
<br /> 
Tag: <input type="text" name="tag" 
    value="<?php if (isset($_GET['tag'])) echo $_GET['tag']; ?>" />
<br />
<br />
<input type="hidden" name="fetchpls" value="true" />
<input type="submit" value="Get Playlist" />
</form>
</body>
</html>

That's all there is to it. Browse to the jukebox project and you should see a form prompting you to download the playlist, and optionally enter in a tag. Press the Get Playlist button, or if you like, enter a tag like "podcasts" before doing so to only fetch items also tagged with "podcast." You should be prompted to download a file, or a file will begin downloading (depending on the default file handling behavior of your web browser).

Then, just open the file in iTunes, WinAmp, or VLC. You'll see the complete list of MP3 tracks and their titles load and begin playing.

Keep in mind that files in this playlist may be protected against hotlinking or may have been moved or deleted after being saved to del.icio.us. However, if you find an MP3 file that doesn't play, just skip to the next track. You're bound to find some new music, podcast, or spoken word piece eventually. This is what del.icio.us sounds like!

How does it work? Take a look at the portion of code that checks for the existence of $_POST['fetchpls'], which is of course triggered by the user submitting the Get Playlist form. When this happens, the filetype tag RSS feed is first retrieved by Magpie here:

//add any tags
if (isset($_POST['tag']))
    $feed_url = BASE_MP3_FEED_URL."+".$_POST['tag'];
else
    $feed_url = BASE_MP3_FEED_URL;
//grab the feed
$rss = fetch_rss($feed_url);

Then, you use PHP's header() function to alter the document headers sent by the script. This time, you make the Content-Type equal audio/mpegurl, the suggested content type for a PLS file. In addition, the Content-Disposition line will trigger the user's web browser to download the file rather than attempt to display it in the browser or do something else with it. Note that you can give the file a name with this particular header as well.

//setup headers
header("Content-type: audio/mpegurl");
header('Content-Disposition: attachment; filename="jukebox.pls"');

The actual contents of the PLS file format are extremely simple. It looks something like this:

[playlist]
File1:http://www.website.com/song.mp3
Title1:Awesome Song!
NumberOfEntries=1
Version=2

You can probably divine what's necessary in the file. First, it must begin with [playlist], then lists each file line-by-line with File# pointing to the location of the MP3 and Title# the title of the MP3. Then, near the bottom the file is a line containing the NumberOfEntries in the playlist, and Version=2 just lets whatever is opening the PLS file know which PLS schema is being used. There are a couple of deviations on this format throughout the web (unlike RSS, PLS is hardly strictly determined by schema documents and so forth), but this at its core is what you'll need in a standard PLS file.

So, you simply process each RSS item accordingly:

//output pls
echo "[playlist]\n";
$i = 1;
foreach ($rss->items as $item) {
    echo "File".$i."=".$item['link']."\n";
    echo "Title".$i."=".$item['title']."\n";
    $i++;
}
echo "NumberOfEntries=".sizeof($rss->items)."\n";
echo "Version=2\n";
//die to stop further execution
die();

The die() at the end is always a good idea when producing a file from a PHP script because it will prevent the script from continuing on and producing any further unwanted data. Also note that each line ends in \n, which produces a new line feed in the file.

This simple project is a great way to demonstrate the power of del.icio.us' RSS feeds. Bringing the data into PHP gives you a lot more flexibility with where you can take it. Imagine modifying the form to accept input on which del.icio.us users, date ranges, or keywords you would like to limit links to before the playlist is created. Or, you could design it so that the mp3 bookmarks are saved to a database or automatically downloaded to your computer. Really, now that you've got the data out of del.icious and into a mashable form, the sky is the limit.

There's several other filetype tags as well that you can experiment with as well, including images and video. And of course there is the del.icio.us API, which will not only let you use del.icio.us data, but change and add to it as well. Still, del.icio.us' RSS feeds are a great entry point for the beginning del.icio.us Mashup developer.

This article is adapted from del.icio.us Mashups, by Brett O'Connor (Wrox, 2007, ISBN: 978-0-470-09776-2), Chapter 10, "Remixing RSS Feeds." Brett O'Connor lives in Denver, Colorado, where he heads Blimps go 90, a private web technology consultant firm. He is also one of the managing partners for the online tattoo artwork and lifestyle-related websites Flash2xs.com and TattooFinder.com.