Example of extending plugin to accept new parameters (playlist start on given index)
Posted: Jul 26, 2009
I need to change the playlist plugin to be able to start on an index other than zero. I'm having difficulty figuring out how to change the playlist script to accept this new parameter. Below is my latest failed attempt. I'd appreciate any help. Thanks!
/**
* flowplayer.playlist 3.0.6. Flowplayer JavaScript plugin.
*
* This file is part of Flowplayer,http://flowplayer.org
*
* Author: Tero Piirainen, <info@flowplayer.org>
* Copyright (c) 2008 Flowplayer Ltd
*
* Dual licensed under MIT and GPL 2+ licenses
* SEE:http://www.opensource.org/licenses
*
* Date: 2009-02-16 06:51:28 -0500 (Mon, 16 Feb 2009)
* Revision: 1454
* Modified by: Mike Letulle <mike.letulle@full-leverage.com>
* Date of modification: 2009-07-26 15:00:43
*/
(function($) {
$f.addPlugin("playlist", function(wrap, options) {
// self points to current Player instance
var self = this;
var opts = {
playingClass: 'playing',
pausedClass: 'paused',
progressClass:'progress',
template: '${title}',
loop: false,
playOnClick: true,
manual: false,
startIndex:0
};
$.extend(opts, options);
wrap = $(wrap);
var manual = self.getPlaylist().length <= 1 || opts.manual;
var els = null;
var startIndex = opts.startIndex;
//{{{ "private" functions
function toString(clip) {
var el = template;
$.each(clip, function(key, val) {
if (!$.isFunction(val)) {
el = el.replace("${" +key+ "}", val).replace("$%7B" +key+ "%7D", val);
}
});
return el;
}
// assign onClick event for each clip
function bindClicks() {
els = wrap.children().unbind("click.playlist").bind("click.playlist", function() {
return play($(this), els.index(this));
});
}
function buildPlaylist() {
wrap.empty();
$.each(self.getPlaylist(), function() {
wrap.append(toString(this));
});
bindClicks();
}
function play(el, clip) {
if (el.hasClass(opts.playingClass) || el.hasClass(opts.pausedClass)) {
self.toggle();
} else {
el.addClass(opts.progressClass);
self.play(clip);
}
return false;
}
function clearCSS() {
if (manual) { els = wrap.children(); }
els.removeClass(opts.playingClass);
els.removeClass(opts.pausedClass);
els.removeClass(opts.progressClass);
}
function getEl(clip) {
return (manual) ? els.filter("[href=" + clip.url + "]") : els.eq(clip.index);
}
//}}}
/* setup playlists with onClick handlers */
// internal playlist
if (!manual) {
var template = wrap.is(":empty") ? opts.template : wrap.html();
buildPlaylist();
// manual playlist
} else {
els = wrap.children();
// allows dynamic addition of elements
if ($.isFunction(els.live)) {
$(wrap.selector + "> *").live("click", function() {
var el = $(this);
return play(el, el.attr("href"));
});
} else {
els.click(function() {
var el = $(this);
return play(el, el.attr("href"));
});
}
// setup player to play first clip
var clip = self.getClip(startIndex);
if (!clip.url && opts.playOnClick) {
clip.update({url: els.eq(0).attr("href")});
}
}
// onBegin
self.onBegin(function(clip) {
clearCSS();
getEl(clip).addClass(opts.playingClass);
});
// onPause
self.onPause(function(clip) {
getEl(clip).removeClass(opts.playingClass).addClass(opts.pausedClass);
});
// onResume
self.onResume(function(clip) {
getEl(clip).removeClass(opts.pausedClass).addClass(opts.playingClass);
});
// what happens when clip ends ?
if (!opts.loop && !manual) {
// stop the playback exept on the last clip, which is stopped by default
self.onBeforeFinish(function(clip) {
if (!clip.isInStream && clip.index < els.length -1) {
return false;
}
});
}
// on manual setups perform looping here
if (manual && opts.loop) {
self.onBeforeFinish(function(clip) {
var el = getEl(clip);
if (el.next().length) {
el.next().click();
} else {
els.eq(0).click();
}
return false;
});
}
// onUnload
self.onUnload(function() {
clearCSS();
});
// onPlaylistReplace
if (!manual) {
self.onPlaylistReplace(function() {
buildPlaylist();
});
}
// onClipAdd
self.onClipAdd(function(clip, index) {
els.eq(index).before(toString(clip));
bindClicks();
});
return self;
});
})(jQuery);
/**
* flowplayer.playlist 3.0.6. Flowplayer JavaScript plugin.
*
* This file is part of Flowplayer,http://flowplayer.org
*
* Author: Tero Piirainen, <info@flowplayer.org>
* Copyright (c) 2008 Flowplayer Ltd
*
* Dual licensed under MIT and GPL 2+ licenses
* SEE:http://www.opensource.org/licenses
*
* Date: 2009-02-16 06:51:28 -0500 (Mon, 16 Feb 2009)
* Revision: 1454
* Modified by: Mike Letulle <mike.letulle@full-leverage.com>
* Date of modification: 2009-07-26 15:00:43
*/
(function($) {
$f.addPlugin("playlist", function(wrap, options) {
// self points to current Player instance
var self = this;
var opts = {
playingClass: 'playing',
pausedClass: 'paused',
progressClass:'progress',
template: '${title}',
loop: false,
playOnClick: true,
manual: false,
startIndex:0
};
$.extend(opts, options);
wrap = $(wrap);
var manual = self.getPlaylist().length <= 1 || opts.manual;
var els = null;
var startIndex = opts.startIndex;
//{{{ "private" functions
function toString(clip) {
var el = template;
$.each(clip, function(key, val) {
if (!$.isFunction(val)) {
el = el.replace("${" +key+ "}", val).replace("$%7B" +key+ "%7D", val);
}
});
return el;
}
// assign onClick event for each clip
function bindClicks() {
els = wrap.children().unbind("click.playlist").bind("click.playlist", function() {
return play($(this), els.index(this));
});
}
function buildPlaylist() {
wrap.empty();
$.each(self.getPlaylist(), function() {
wrap.append(toString(this));
});
bindClicks();
}
function play(el, clip) {
if (el.hasClass(opts.playingClass) || el.hasClass(opts.pausedClass)) {
self.toggle();
} else {
el.addClass(opts.progressClass);
self.play(clip);
}
return false;
}
function clearCSS() {
if (manual) { els = wrap.children(); }
els.removeClass(opts.playingClass);
els.removeClass(opts.pausedClass);
els.removeClass(opts.progressClass);
}
function getEl(clip) {
return (manual) ? els.filter("[href=" + clip.url + "]") : els.eq(clip.index);
}
//}}}
/* setup playlists with onClick handlers */
// internal playlist
if (!manual) {
var template = wrap.is(":empty") ? opts.template : wrap.html();
buildPlaylist();
// manual playlist
} else {
els = wrap.children();
// allows dynamic addition of elements
if ($.isFunction(els.live)) {
$(wrap.selector + "> *").live("click", function() {
var el = $(this);
return play(el, el.attr("href"));
});
} else {
els.click(function() {
var el = $(this);
return play(el, el.attr("href"));
});
}
// setup player to play first clip
var clip = self.getClip(startIndex);
if (!clip.url && opts.playOnClick) {
clip.update({url: els.eq(0).attr("href")});
}
}
// onBegin
self.onBegin(function(clip) {
clearCSS();
getEl(clip).addClass(opts.playingClass);
});
// onPause
self.onPause(function(clip) {
getEl(clip).removeClass(opts.playingClass).addClass(opts.pausedClass);
});
// onResume
self.onResume(function(clip) {
getEl(clip).removeClass(opts.pausedClass).addClass(opts.playingClass);
});
// what happens when clip ends ?
if (!opts.loop && !manual) {
// stop the playback exept on the last clip, which is stopped by default
self.onBeforeFinish(function(clip) {
if (!clip.isInStream && clip.index < els.length -1) {
return false;
}
});
}
// on manual setups perform looping here
if (manual && opts.loop) {
self.onBeforeFinish(function(clip) {
var el = getEl(clip);
if (el.next().length) {
el.next().click();
} else {
els.eq(0).click();
}
return false;
});
}
// onUnload
self.onUnload(function() {
clearCSS();
});
// onPlaylistReplace
if (!manual) {
self.onPlaylistReplace(function() {
buildPlaylist();
});
}
// onClipAdd
self.onClipAdd(function(clip, index) {
els.eq(index).before(toString(clip));
bindClicks();
});
return self;
});
})(jQuery);