Playlist Sorting at Air America Radio

Share this

Advomatic just added user play list functionality for Air America's player. Users are able to create their own play lists of favorite audio and video clips, and sort them in their preferred order.

To see this functionality in action, you'll need to go to the Air America site, and create a user account. After doing so, launch their player, by pressing on the big Listen Live button on the top left of every page.

Add two or three audio clips by pressing the "+" next to a clip, then go to the video tab and do the same thing.

Finally, go to the Playlist tab. Here, you can click and drag clips to sort them as desired. Go ahead. It's all saved, which you can confirm by going to another tab, logging out, logging back in, etc.

Site Recipe

For this functionality, we first used the Views Bookmark as a base. This allows the creation of custom node bookmarks, favorites, etc.

We already embed clips. Clips are a content type that will either reference a local audio file, served by a CDN (using a customized version of the File Field module), or a video clip, using the Embedded Media Field module.

We just created a new bookmark type for the clips as usual.

The player tab is just a view of a user's custom play list. The tab uses an ajax call to load up a javascript version of the page, which required a custom callback. (This method may become obsolete with the upcoming release of the Embed Widgets module.)

Adding the +/- buttons to the view items was achieved by simply overriding the theme function to add them, with a manual invoke of the nodeapi call in views_bookmark. Having the - button remove an item from the playlist was achieved with custom jQuery that simply removes the element from the DOM after the link's been clicked.

User Custom Sort

Shuffling the items was two steps. First, after installing jQuery UI, we invoke the following:

  $('.view-aar-player-favorite-clips ul').sortable({cancel:'a', update: function(e, ui){
    var items = $(this).sortable('toArray');
    var arLen = items.length;
    var output = new Array;
    for ( var i=0, len=arLen; i<len; ++i ) {
      output[i] = $('#'+items[i]).children('.play').children('a').attr('id').slice(13);
    $.get('/playlist/sort/' + eval(output));

The cancel:'a' ensures we can still click the links of the clip area. The update function is called after a drag & drop sort. It will grab the nid's of the items and send them back to the server. (FYI, we had to override theme_item_list to add unique id's to the list elements to make the sortable function work. NID's are stored in the play links of the individual view items, again by overriding the view output.)

Database Updates

The second part was writing a custom page callback, with the following:

*  This takes a newly sorted array of items from a jquery ajax'd JSON array, and changes the timestamp accordingly.
function aar_player_playlist_sort($items = '', $vbid = 1) {
  if (!
$user->uid) {
$items = explode(',', $items);
$time = time() - sizeof($items);
$items = array_reverse($items);
  foreach (
$items as $nid) {
db_query("UPDATE {views_bookmark_nodes} set timestamp=%d WHERE vbid=%d AND uid=%d AND nid=%d", $time++, $vbid, $user->uid, $nid);
t('Completed new sort.');

We used a custom query, because the Views Bookmark module doesn't currently offer an API function to do this. But the magic works fine, changing the sort order of our playlist.

The clips of the site may also be viewed at the On Demand page, which deserves a write-up of its own.

Much of the remaining functionality, such as clips automatically progressing and looping after playback, is actually featured in the upcoming Drupal Multimedia book that I've nearly completed writing, to be published soon by Packt Publishing. However, I'll continue writing more site recipes over the next week or three.

I need to thank Marco Carbone (mcarbone at and Jack Haas (jerseycheese at, both developers with Advomatic, for their help with the functionality. Marco built out the On Demand section, and I borrowed some of his javascript for the dynamic ajax of tabs. Jack themed the sucker.

(Cross-posted at

aar-player-tn.png37.87 KB
aar-player.png213.69 KB
sort-playlist.png19.58 KB
ondemand-clips.png61.24 KB


Michael's picture

Can it do private YT embedding? (Maybe a silly question :) )


Quick question - can i embed a private YT video using the above method?

I would really appreciate some help here, thank you :)

Kind regards,


Jules Carney's picture

I have to say, you did a

I have to say, you did a really nice job on explaining something that can be really tricky at times. There are times that I struggle with wrapping my head around topics like the this, thank you for summing it up well.


bobdunn893's picture

Drupal Rocks!

Now I can see why so many people are saying that Drupal is the way to go. If you are able to do this sort of thing I really need to get into using Drupal. I only have knowledge of wordpress and blogger but am a little worried that my technical knowledge will let me down.

aaron's picture

Doing this sort of thing does

Doing this sort of thing does (currently) require a little technical knowledge. But with such a strong and committed community, things are converging from many directions to make configuring even complex sites much easier.

This particular functionality does not yet exist in a generic format, but you can get fairly close without any coding. There are several modules, such as Views Bookmark, File Field, jQuery Media, and XSPF Player, that can be tweaked and massaged to do the job. And developers are quickly learning how to collaborate better to make them work together in more intuitive ways.

I'm not familiar with the set up of wordpress or blogger. But I can set up a site that replicates the look and functionality of such a blog in a matter of minutes. Granted, someone learning Drupal would have to get past the initial learning curve. But there are some excellent tutorials and site recipes out there, and literally hundreds of people willing to lend a hand.

And once you realize how simple it is to add the other stuff, you'll never turn back...

Jacob Angel's picture

Neat workaround

That custom query was an elegant way to get around the lack of an API for the Views Bookmark module. Neatly done.

aaron's picture

I had to backtrack my way

I had to backtrack my way through the Views Bookmark module to figure that one out. Other than the weakness of not inherently allowing a resort of its items, it's actually quite a powerful and flexible module. Pretty good for what was initially meant as a proof of concept...

Ezra's picture

This is huge!

Quite an accomplishment. Thanks for sharing this. Looks similar to the (great) feature provides.

aaron's picture


This has been a fun project to implement. Doing a chat feature for the site right now, and plan to make more write-ups about the site over the next few weeks; it was a lot of work, some of it cutting edge.

The Society for Venturism has chosen me as the recipient of its charity for this year, to hopefully offer me cryonic preservation when the time comes. And this month, Longecity, an excellent forum for the discussion of issues related to extending the lifespan of humans, has offered up a matching grant of up to a thousand dollars to help out! So help out! Please.