Flowplayer is an excellent flash media player, capable of playing video and audio. It comes with it’s own playlist system, but it’s very limited.

This article details how to create a custom playlist system for Flowplayer using jQuery and Flowplayer’s javascript API. This system will allow you to manipulate playlist items without interrupting current playback and adds several functions not available in the Flowplayer JS API.
Most of the examples are coming from my experience in making an online mp3 player, so mp3, audio, and songs will be referenced a lot, but the same can be applied to video clips as well.

UPDATED: See it in action here: http://www.samutz.com/flowplayer/video-demo.html

First you need to call the jQuery and Flowplayer scripts on your player’s page.

<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type='text/javascript' src='/js/flowplayer/flowplayer-3.1.1.min.js'></script>

Next, create a div on this page where you want your player to appear, then create a div for your playlist too.

<div id="playerdiv"></div>
<div id="playlist"></div>

For appearances, I’m going to make the playlist div a scrollable box. You probably won’t want a huge playlist to stretch your whole page if you’re going to have more content on the page. Of course, how you want to style it is completely up to you.

#playlist {
	height: 400px;
	overflow: auto;
}

Now for the Javascript. Flowplayer’s API will set its commands to the $f() namespace by default. jQuery will set itself to the $() namespace.

First, setup/configure the player.
playerdiv is the div you created above to place the player.
If you want to play mp3s or another supported audio format, load the flowerplayer audio plugin.
Set baseUrl to the main location of the files you’re going to play. Files loaded will be referenced relative to this location.
This setup function will modified later in the tutorial as we add custom playlist functions.

$f("playerdiv", "/js/flowplayer/flowplayer.swf", {
	plugins: {
		audio: {
			url: '/js/flowplayer/flowplayer.audio.swf'
		}
	},
	clip: {
		autoPlay: true,
		autoBuffering: true,
		baseUrl: 'http://www.samutz.com/media/'
	}
});

Next, lets create some variables that we’re going to be using through most of our functions.
playlist will be our actual playlist, an array containing clip objects for the player to use.
playlist_clip will be used to track the current playing clip.
playlist_shuffle and playlist_repeat will be used to track what mode the playlist is in. Set either to true if you want one to be enabled by default.

var playlist = [];
var playlist_clip = 0;
var playlist_shuffle = false;
var playlist_repeat = false;

Now let’s create our first custom function, add_clip().
This function will add a clip object to the playlist array.
How you get the clip information is entirely up to you. In this example, I have a database containing clip information, so I use a php file to query the database and return the information as xml. The XML is called and then parsed by jQuery into an object, then the object is pushed to the end of the playlist array.

Example of the returned XML:
url is relative the baseUrl set in the player’s setup function.
title can be whatever you want.
You can also add other properties if you want for display in the playlist, such as filesize, length, artist, album, etc.

<response>
	<url>something.mp3</url>
	<title>Some Song Name</title>
</response>

And now for the function.
old_len will be used to determine if the playlist was empty before the clip was added. If it was, then we’ll start playing the newly added clip immediately.
playlist.push is what actually adds the information as an object to the playlist array.

function add_clip(id)
{
	$.ajax({
	    type: 'GET',
	    url: '/clip.php?id=' + id,
	    dataType: "xml",
	    success: function(response) {
		old_len = playlist.length;
		playlist.push ({
			url: $("url", response).text(),
			title: $("title", response).text()
		});
		if (old_len == 0) {
			play_clip(0);
		}
		refresh_playlist();
	    }
	});
}

Notice the play_clip(0) and refresh_playlist() in the above function. These are more functions that we’ll create.

Let’s create play_clip() next. This function simply calls the flowplayer API’s $f().play() function to send a clip object to the player.
id is simply the array id of the clip. 0 is the first clip in the playlist array, 1 is the 2nd clip and so on.
playlist_clip is that var we defined earlier to track the current playing clip.
We will revisit this function after the playlist_refresh() function is created.

function play_clip(id)
{
	$f().play(playlist[id]);
	playlist_clip = id;
}

So let’s create refresh_playlist() next. We need this function to keep the #playlist div updated and highlighting the current playing clip.
The function reads the playlist array and then generates html based on the data then writes that html to the #playlist div.
This html will be links that, when clicked, will play that clip using the play_clip() function we just created.
Again, how you style or layout your playlist is entirely up to you. In this basic example I’ll use simple text.
We’ll revisit this when we add delete and move up/down controls.

function refresh_playlist()
{
	html = '';
	for(var i=0;i<playlist.length;i++){
		html = html + '<a id="playlist_clip_' + i + '" href="javascript:play_clip(' + i + ')">' + playlist[i].title + '</a><br/>';
	}
	$("#playlist").html(html);
}

Now let’s go ahead and revise both of the above functions so that the current playing clip is styled differently from the rest of the clips in the playlist.
In this example I’ll use a css class called playlist_active.

function play_clip(id)
{
	$("#playlist_clip_" + playlist_clip).removeClass('playlist_active');
	$f().play(playlist[id]);
	playlist_clip = id;
	$("#playlist_clip_" + playlist_clip).addClass('playlist_active');
}

function refresh_playlist()
{
	html = '';
	for(var i=0;i<playlist.length;i++){
		html = html
		 + '<a id="playlist_clip_' + i + '" href="javascript:play_clip(' + i + ')">' + playlist[i].title + '</a>'
		 + '<br/>';
	}
	$("#playlist").html(html);
	$("#playlist_clip_" + playlist_clip).addClass('playlist_active');
}

Now that refresh_playlist() is done, we want the player to call it once when the player loads, so we’ll edit the setup function and add an onLoad event listener.

$f("playerdiv", "/js/flowplayer/flowplayer.swf", {
	plugins: {
		audio: {
			url: '/js/flowplayer/flowplayer.audio.swf'
		}
	},
	clip: {
		autoPlay: true,
		autoBuffering: true,
		baseUrl: 'http://www.samutz.com/media/'
	},
	onLoad: function() {
		refresh_playlist();
	}
});

Next let’s create a delete_clip() function to remove clips from the playlist.
This is fairly simple. The function will remove the clip object. If the clip being removed is the current playing clip, the active clip will be set to the one before it. Then the playlist will be refreshed.

function delete_clip(id)
{
	playlist.splice(id,1);
	if (playlist_clip == id) {
		playlist_clip = playlist_clip - 1;
	}
	refresh_playlist();
}

Now we just need a link to allow the user to call the command. For this example, I’ll add a simple [X] link to the playlist items to do this.

function refresh_playlist()
{
	html = '';
	for(var i=0;i<playlist.length;i++){
		html = html
		 + '<a href="javascript:delete_clip(' + i + ')">[X]</a> - '
		 + '<a id="playlist_clip_' + i + '" href="javascript:play_clip(' + i + ')">' + playlist[i].title + '</a>'
		 + '<br/>';
	}
	$("#playlist").html(html);
	$("#playlist_clip_" + playlist_clip).addClass('playlist_active');
}

To further manipulate the playlist, let’s create a function to move clips up and down the list.
However, I also use a custom array move function to move objects in any array, not specifically the playlist.

Array.prototype.move = function(index, delta)
{
	var index2, temp_item;
	if (index < 0 || index >= this.length) {
		return false;
	}
	index2 = index + delta;
	if (index2 < 0 || index2 >= this.length || index2 == index) {
		return false;
	}
	temp_item = this[index2];
	this[index2] = this[index];
	this[index] = temp_item;
	return true;
}

And now for our playlist_move() function:

function playlist_move(id, delta)
{
	if (delta == 'up' && id != 0) {
		playlist.move(id, -1);
		if (id == playlist_clip) {
			playlist_clip = id - 1;
		} else if (playlist_clip == id - 1) {
			playlist_clip = id;
		}
		refresh_playlist();
	} else if (delta == 'down' && id != (playlist.length - 1)) {
		playlist.move(id, 1);
		if (playlist_clip == id) {
			playlist_clip = id + 1;
		} else if (playlist_clip == id + 1) {
			playlist_clip = id;
		}
		refresh_playlist();
	}
}

Now let’s add controls to the refresh_playlist() html for the user to use. For this example, I’ll add [U] for up and [D] for down.

function refresh_playlist()
{
	html = '';
	for(var i=0;i<playlist.length;i++){
		html = html
		 + '<a href="javascript:delete_clip(' + i + ')">[X]</a> - '
		 + '<a href="javascript:playlist_move(' + i + ', \'up\')">[U]</a> - '
		 + '<a href="javascript:playlist_move(' + i + ', \'down\')">[D]</a> - '
		 + '<a id="playlist_clip_' + i + '" href="javascript:play_clip(' + i + ')">' + playlist[i].title + '</a>'
		 + '<br/>';
	}
	$("#playlist").html(html);
	$("#playlist_clip_" + playlist_clip).addClass('playlist_active');
}

For fun, here’s a function to randomize the order of the playlist.

function playlist_randomize()
{
	oldpl = playlist;
	newpl = [];
	while (oldpl.length > 0) {
		rand = Math.floor(Math.random() * oldpl.length);
		newpl.push(oldpl[rand]);
		oldpl.splice(rand,1);
	}
	playlist = newpl;
	play_clip(playlist_clip);
	refresh_playlist();
}

And one last function to manipulate the playlist: playlist_clear()

function playlist_clear()
{
	playlist = [];
	refresh_playlist();
}

Now that playlist manipulation is finished, let’s get some functions made to navigate the playlist, starting with Next and Previous controls.

function player_next()
{
	if (playlist_shuffle == true) {
		rand = Math.floor(Math.random() * playlist.length);
		play_clip(rand);
	} else {
		if (playlist_clip != (playlist.length - 1)) {
			play_clip(playlist_clip + 1);
		} else if (playlist_clip==(playlist.length-1) && playlist_repeat==true) {
			play_clip(0);
		}
	}
}

function player_previous()
{
	if (playlist_shuffle == true) {
		rand = Math.floor(Math.random() * playlist.length);
		play_clip(rand);
	} else {
		if (playlist_clip != 0) {
			play_clip(playlist_clip - 1);
		} else if (playlist_clip == 0 && playlist_repeat == true) {
			play_clip(playlist.length - 1);
		}
	}
}

Now you can allow the user to call these functions with your own custom buttons/links.

<div id="playerdiv"></div>
<div id="controls">
	<a href="javascript:player_previous()">Previous</a> - <a href="javascript:player_next()">Next</a>
</div>
<div id="playlist"></div>

Also, we want the player to advance to the next clip in the playlist when the current clip is done playing, so we’ll add an event listener to the clip section of the player setup function.
I can’t recall why I had to use a timeout, other than it simply didn’t work unless I did. I’m guessing the player couldn’t load a new clip at the exact same time it was finishing the playing clip.

$f("playerdiv", "/js/flowplayer/flowplayer.swf", {
	plugins: {
		audio: {
			url: '/js/flowplayer/flowplayer.audio.swf'
		}
	},
	clip: {
		autoPlay: true,
		autoBuffering: true,
		baseUrl: 'http://www.samutz.com/media/',
		onFinish: function() {
			setTimeout('player_next()',1000);
		}
	},
	onLoad: function() {
		refresh_playlist();
	}
});

Now lets add toggles for the repeat and shuffle modes.

<div id="playerdiv"></div>
<div id="controls">
	<a href="javascript:player_previous()">Previous</a> - <a href="javascript:player_next()">Next</a><br/>
	<a id="repeat" href="javascript:player_repeat()">Repeat Disabled</a> - <a id="shuffle" href="javascript:player_shuffle()">Shuffle Disabled</a>
</div>
<div id="playlist"></div>

In repeat mode, the player will play the first clip in the playlist after it plays the last clip.

function player_repeat()
{
	if (playlist_repeat == false) {
		playlist_repeat = true;
		$("#repeat").html('Repeat Enabled');
		if (playlist_shuffle == true) {
			playlist_shuffle = false;
			$("#shuffle").html('Shuffle Disabled');
		}
	} else {
		playlist_repeat = false;
		$("#repeat").html('Repeat Disabled');
	}
}

In shuffle mode, the player will play a random clip from the playlist.

function player_shuffle()
{
	if (playlist_shuffle == false) {
		playlist_shuffle = true;
		$("#shuffle").html('Shuffle Enabled');
		if (playlist_repeat == true) {
			playlist_repeat = false;
			$("#repeat").html('Repeat Disabled');
		}
	} else {
		playlist_shuffle = false;
		$("#shuffle").html('Shuffle Disabled');
	}
}

And that’s all I have. Hopefully, these functions will help you get your own playlist system working for Flowplayer.

Check out the working demo here to see it in action:
http://www.samutz.com/flowplayer/video-demo.html