Everything You Need To Know About JF MP3
Class Properties
thePlaylist: new Array(), shuffleFlag: false, volMuteFlag: false, volBarInit: false, trackBarInit: false, repeatFlag: true, activeSound: null, trackBarCall: null, currentItem: null, currentItemRef: null, volHideDelayCall: null, pLt: null, shuffleArray: null, volHideDelay: 500, lastVol: 50, playState: 2, songDuration: 0, songTime: 0, conMilToSecCur: 0, conMilToMinCur: 0, actTCur: 0, actT: 0, conMilToSec: 0, conMilToMin: 0, currKStep: 0, relCount: 0,
thePlaylist: Playlist array that holds all items inside.
Dependencies: createPlaylist, addToPlaylist, playlistItemC, removeFromPlaylist
shuffleFlag: Flag stating if shuffle is on (true) or off (false)
Dependencies: next, shuffleOn, shuffleOff, shuffleToggle
volMuteFlag: Flag stating if mute is on (true) or off (false)
Dependencies: unMute, mute, muteToggle, createSound
volBarInit: If the volume bar has been initialized(true) or not(false)
Dependencies: volumeBar, createSound
trackBarInit: If the track bar has been initialized(true) or not(false)
Dependencies: createSound
repeatFlag: Flag stating if repeat is on (true) or off (false)
Dependencies: next, repeatOn, repeatOff, repeatToggle
activeSound: The sound object which SM2 attaches the loaded sound file to. All sound file actions are attached to this object
Dependencies: stop, play, pause, unMute, mute, volumeBar, trackBar, createSound
trackBarCall: The trackbar object, set as a property for easy access
Dependencies: trackBar, createSound
currentItem: Current playing playlist items REL property value used to stop reloading the same song accidentaly
Dependencies: next, previous, createPlaylist, addToPlaylist, playlistItemC, createSound
currentItemRef: DOM reference to the active playlist items anchor element
Dependencies: next, previous, playlistItemC
volHideDelayCall: The volume bar hide timer
Dependencies: volumeToggle
pLt: The volume bar hide timer
Dependencies: creatPlaylist, assignEvents
shuffleArray: The shuffle array is created when shuffle is activated and destroyed when it is disabled. It holds all the playlist items but in random order. Everytime a song from it is played, it is removed and the array is reordered
Dependencies: next, shuffleOn, shuffleOn
volHideDelay: The delay in milliseconds that the volume bar will hide itself once the user moves the mouse out of the volume bars container
Dependencies: volumeToggle
lastVol: The current volume level is copied here as to apply it to all new sound objects
Dependencies: volumeBar, createSound
playState: The current play state. So 2 = stopped, 1 = paused, 0 = playing
Dependencies: stop, play, pause, createPlaylist, addToPlaylist, assignEvents
songDuration, songTime: Song duration (as an estimate during streaming) and song time (its current position)
Dependencies: createSound
conMilToSecCur, conMilToMinCur, conMilToSec, conMilToMin: These handle converting milliseconds to seconds and minutes. Cur added at the end means its calculating the current time, without Cur it means is figuring out the total time
Dependencies: createSound
actTCur, actT: These are the converted time strings
Dependencies: createSound
currKStep: This calculates the position of the trackbar knob, every few milliseconds (whenever javascript polls the flash object) and will update the knobs position as need be
Dependencies: createSound
relCount: Rel count simply keeps track of rel property value assignments for each new playlist item. The rel value makes sure active songs are not repeated (in shuffle scenarios for example)
Dependencies: createPlaylist, addtoPlaylist
Function: Control Functions
_stop: function(){
/*
Function: _stop
What it Does: Stops the currently playing song, brining its start position
back to 0.
*/
this.activeSound.stop(); //SM2 function to stop the current sound object from playing
//remove and add classes to change the control buttons (from stopped to pause etc...)
this.jfmp3StopButt.removeClass('play');
this.jfmp3StopButt.removeClass('pause');
this.jfmp3StopButt.addClass('stop');
this.jfmp3StopButt.setProperty('title', 'stopped'); //set the title property of the stop/play/pause button
this.playState=2; //change play state 2 (stopped/default)
}
_play: function(){
/*
Function: _play
What it Does: Plays the song which was just called and created or which was paused.
*/
this.activeSound.play(); //SM2 function to play the current sound object
//remove and add classes to change the control buttons (from stopped to pause etc...)
this.jfmp3StopButt.removeClass('stop');
this.jfmp3StopButt.addClass('pause');
this.jfmp3StopButt.setProperty('title', 'pause playing'); //set the title property of the stop/play/pause button
this.playState=0; //change play state 0 (playing)
}
_pause: function(){
/*
Function: _pause
What it Does: Pauses the currently playing song.
*/
this.activeSound.pause(); //SM2 function to pause the current sound object
//remove and add classes to change the control buttons (from stopped to pause etc...)
this.jfmp3StopButt.removeClass('pause');
this.jfmp3StopButt.addClass('play');
this.jfmp3StopButt.setProperty('title','resume playing'); //set the title property of the stop/play/pause button
this.playState=1; //change play state 1 (paused)
}
_playToggle: function(a){
/*
Function: _playToggle
What it Does: Handles incoming play, stop, pause requests and executes which ever function
was requested. This gateway allows for extra flexibility in future revisions
and additions.
Paramters: a = switch flag for what function should be executed
*/
switch(a)
{
case 0:
this._play();
break;
case 1:
this._pause();
break;
case 2:
this._stop();
break;
}
}
Control functions handle playing, pausing, or stopping the currently loaded sound object.
Class Properties Used: playState, activeSound
Function: Next and Previous
_next: function(e){
/*
Function: _next
What it Does: Handles getting the next playlist item relative to the currently selected one.
Will play that item if it exists or or go the top of the list and start playback there.
Will check for repeat option as well.
Parameters: e = the click event reference
*/
if(this.shuffleFlag === true) //if shuffle is on (true)
{
if(this.shuffleArray.length > 0) //if the shuffle array length (all playlist items reorganized randomly into this array) is greater than 0 (still has songs unplayed)
{
if(this.currentItem == this.shuffleArray[0].getProperty('rel').toInt()) //if the current song being played is also the next song to be played in the shuffle array
//remove it from the array and go to the next item
{
this.shuffleArray.splice(0,1); //remove from the shuffle array
var tmp_arr = this.shuffleArray; //create a temporary array
this.shuffleArray = new Array(); //the rest of this block reorganizes the array so the index goes from 0, 1, 2, 3 etc...
for(x=0;x<tmp_arr.length;x++)
{
this.shuffleArray[x] = tmp_arr[x];
}
this._next(e); //recall the function and play next item (if there is one)
}
else //if the next item to be played int he shuffle array is not the current one being played
{
this.shuffleArray[0].fireEvent('click', e); //start playing the next song in shuffle playlist
this.shuffleArray.splice(0,1); //remove it fromt he shuffle playlist
var tmp_arr = this.shuffleArray; //create a temporary array
this.shuffleArray = new Array(); //the rest of this block reorganizes the array so the index goes from 0, 1, 2, 3 etc...
for(x=0;x<tmp_arr.length;x++)
{
this.shuffleArray[x] = tmp_arr[x];
}
}
}
else if(this.repeatFlag === true) //if there is no more items int he shuffle playlist, and repeat is on (true) recreate a new shuffled playlist array
{
this._shuffleOn();
this._next(e);
}
}
else //if shuffle is not on, do as you normally would (play the next item in the playlist)
{
if(this.currentItem === null && e != undefined) //if no song has been played yet and _next() was called via user click
{
$$('ul#jfmp3_playlistUlEl li a')[0].fireEvent('click', e); //play the first item on the playlist
}
else if(this.currentItem != null && e != undefined) //if there is a song already being played (or was played) and _next() was called via user click
{
var getNextLI = this.currentItemRef.getParent('li').getNext('li'); //get the next playlist items li element (parent)
if(getNextLI != null) //if there is a next LI element (meaning we arent already at the end of the playlist)
{
getNextLI.getChildren('a')[0].fireEvent('click', e); //play that next song
}
else if(this.repeatFlag != false) //if we are at the last element and repeating is allowed (true)
{
$$('ul#jfmp3_playlistUlEl li a')[0].fireEvent('click', e); //go back to the top and play the first song
}
}
else //if _next() was called from another function and e paramter was not defined (usually executed at the end of a song or by shuffle)
{
var getNextLI = this.currentItemRef.getParent('li').getNext('li'); //get the next playlist items li element (parent)
if(getNextLI != null) //if there is a next LI element (meaning we arent already at the end of the playlist)
{
var getCArr = getNextLI.getChildren('a')[0];
if(this.currentItem != (getCArr.getProperty('rel')).toInt())
{
this._playlistItemC(getCArr); //play next item
}
}
else if(this.repeatFlag != false) //if we are at the last element and repeating is allowed (true)
{
getNextLI = $$('ul#jfmp3_playlistUlEl li')[0];
var getCArr = getNextLI.getChildren('a')[0];
this._playlistItemC(getCArr); //go back to the top and play the first song
}
}
}
}
_previous: function(e){
/*
Function: _previous
What it Does: Handles getting the previous playlist item relative to the currently selected one.
Will play that item if it exists or or go the bottom of the list and start playback there.
Will check for repeat option as well.
*/
if(this.currentItem === null) //if no song has been played yet
{
$$('ul#jfmp3_playlistUlEl li a').getLast().fireEvent('click', e); //play the last item in the playlist
}
else //if atleast one song has already been played
{
var getPreviousLI = this.currentItemRef.getParent('li').getPrevious('li'); //get the previous li
if(getPreviousLI != null) //if it exists (meaning we are not at the very top of the playlist)
{
getPreviousLI.getChildren('a')[0].fireEvent('click', e); //play that item
}
else //else, play the last item in the playlist
{
$$('ul#jfmp3_playlistUlEl li a').getLast().fireEvent('click', e);
}
}
}
Previous and Next allow you to go to the next or previous item in the playlist. They are called either by the user or at the end of a song.
Class Properties Used: shuffleFlag, currentItem, repeatFlag, currentItemRef, shuffleArray
Function: Shuffle
_shuffleOff: function(){
/*
Function: _shuffleOff
What it Does: Turns off playlist shuffle. Which means at the end of every songs playback
the next will be played inline, as opposed to a random one.
*/
if(this.jfmp3ToggleSfle.hasClass('off') === false) //check if the shuffle button does not have the 'off' css class already
{
this.jfmp3ToggleSfle.addClass('off'); //add the 'off' class
}
this.shuffleArray = null; //clear the shuffle array
this.shuffleFlag = false; //disable shuffle
}
_shuffleOn: function(){
/*
Function: _shuffleOn
What it Does: Turns on playlist shuffle. Which means at the end of every songs playback
a random song will be chosen to play next as opposed to playing the song inline.
This function also creates an array of all the playlist items but in a random order.
*/
if(this.jfmp3ToggleSfle.hasClass('off') === true) //check if the shuffle button does have the 'off' css class already
{
this.jfmp3ToggleSfle.removeClass('off'); //remove the 'off' class
}
this.shuffleArray = $$('ul#jfmp3_playlistUlEl li a'); //create a shuffle array with all current playlist items
//some temporary variables
var valArr = [];
var k = 0;
var i = 0;
//create a temporary array
for (k = 0; k < this.shuffleArray.length; k++) { // Get key and value arrays
valArr.push(this.shuffleArray[k]);
}
this.shuffleArray=new Array();
valArr.sort(function() {return 0.5 - Math.random();});//resort the array randomly
for (i = 0; i < valArr.length; i++) { // Repopulate the old array
this.shuffleArray[i] = valArr[i];
}
this.shuffleFlag = true; //enable shuffle
}
_shuffleToggle: function(){
/*
Function: _shuffleToggle
What it Does: Handles incoming shuffle on/off requests and executes which ever function
was requested. This gateway allows for extra flexibility in future revisions
and additions.
*/
switch(this.shuffleFlag)
{
case true:
this._shuffleOff();
break;
case false:
this._shuffleOn();
break;
}
}
These functions control the shuffle feature. They enable or disable playlist shuffling as well as handle how the shuffled playlists are created, re-ordered and destroyed.
Class Properties Used: shuffleFlag, shuffleArray
Function: Repeat
_repeatOff: function(){
/*
Function: _repeatOff
What it Does: Turns off playlist repeating. Which means once the final song
has played the playlist will stop playing.
*/
if(this.jfmp3ToggleRp.hasClass('off') === false) //if repeat button does not have the 'off' class
{
this.jfmp3ToggleRp.addClass('off'); //add the 'off' class
}
this.repeatFlag=false; //disable repeat
}
_repeatOn: function(){
/*
Function: _repeatOn
What it Does: Turns on playlist repeating. Which means once the final song
has played the playlist will restart at the top.
*/
if(this.jfmp3ToggleRp.hasClass('off') === true) //if the repeat button does have the 'off' class
{
this.jfmp3ToggleRp.removeClass('off'); //remove the 'off' class
}
this.repeatFlag=true; //enable repeat
}
_repeatToggle: function(){
/*
Function: _repeatToggle
What it Does: Handles incoming repeat on/off requests and executes which ever function
was requested. This gateway allows for extra flexibility in future revisions
and additions.
*/
switch(this.repeatFlag)
{
case true:
this._repeatOff();
break;
case false:
this._repeatOn();
break;
}
}
These functions control the repeat feature. They enable or disable playlist repeating.
Class Properties Used: repeatFlag
Function: Unmute and Mute
_unMute: function(){
/*
Function: _unMute
What it Does: Unmutes the current song being played.
*/
if(this.activeSound != null) //if atleast one sound object has been created (if there are none, then we cant mute or unmute anything)
{
this.activeSound.unmute(); //SM2 function to unmute the player
}
if(this.jfmp3MuteUn.hasClass('muted') === true) //if the 'muted' css class is present
{
this.jfmp3MuteUn.removeClass('muted'); //remove the 'muted' css class
}
this.volMuteFlag=false;
}
_mute: function(){
/*
Function: _mute
What it Does: Mutes the current song being played.
*/
if(this.activeSound != null) //if atleast one sound object has been created (if there are none, then we cant mute or unmute anything)
{
this.activeSound.mute(); //SM2 function to mute the player
}
if(this.jfmp3MuteUn.hasClass('muted') === false) //if the 'muted' css class is not already present
{
this.jfmp3MuteUn.addClass('muted'); //add the 'muted' css class
}
this.volMuteFlag=true;
}
_muteToggle: function(){
/*
Function: _muteToggle
What it Does: Handles incoming mute/unmute requests and executes which ever function
was requested. This gateway allows for extra flexibility in future revisions
and additions.
*/
switch(this.volMuteFlag)
{
case true:
this._unMute();
break;
case false:
this._mute();
break;
}
}
These functions handle muting and unmuting the player. They apply to all songs, and not just the song being played.
Class Properties Used: volMuteFlag, activeSound
Function: Volume Control
_volumeBar: function(){
/*
Function: _volumeBar
What it Does: Handles volume bar functions.
*/
this.volumeBarVar = new Slider(this.jfmp3VolumeBarSldr, this.jfmp3VolumeBarKnob, {
steps: 100, //should never ever be changed
range: [100,0], //should never ever be changed
wheel: false, //dont allow mouse scroll to set volume
snap: true, //dont allow decimal numbers as steps (ex. 10 instead of 10.23)
mode: this.options.volumeDirection, //set by user options
onComplete: function(step){ //once dragging the slider is done, update the volume
this.activeSound.setVolume(step);
this.lastVol=step;
}.bind(this)
}).set(this.lastVol);
this.volBarInit=true; //the volume bar should only ever be initiated once
}
_volumeToggle: function(a){
/*
Function: _volumeToggle
What it Does: Toggle the display of the volume bar.
Paramters: a = Number to dictate if the volume bar element will be shown or hidden
*/
if(a===0) //if we want to show the volume bar
{
this.jfmp3VolumeBar.setStyle('visibility', 'visible');
$clear(this.volHideDelayCall); //clear any previous instance of the hide timer to avoid flicker
}
else if(a===1) //hide the volume bar
{
this.jfmp3VolumeBar.setStyle('visibility', 'hidden');
}
else //set the hide delay timer
{
this.volHideDelayCall = this._volumeToggle.delay(this.volHideDelay, this, 3);
}
}
These functions control how the volume bar works and when it should be shown/hidden.
Class Properties Used: volHideDelayCall, volHideDelay, volBarInit
Function: Colorize
_colorize: function(el){
/*
Function: _colorize
What it Does: Colorize or decolorize playlist items depending if they are being played or not.
Paramters: el = The element reference (in DOM) to the selected playlist item
*/
((this.jfmp3PlaylistSsdUl.getChildren('li')).
getChildren('a')).each(function(els){ //get all anchor tags of playlist
if(els.hasClass('jfmp3_colored')) //if already colored
{
els.removeClass('jfmp3_colored'); //remove the color
}
el.addClass('jfmp3_colored'); //add color to the current active playlist item
});
}
Colorize handles highlighting or unhighlighting playlist items. When a playlist item is clicked, it will be highlighted to show it is active and all other items will be unhighlighted (reverting back to the default style).
Class Properties Used: NONE
Function: TrackBar
_trackBar: function(){
/*
Function: _trackBar
What it Does: Handles the main trackbar of the player (the only one actually).
*/
this.trackBarCall = new Slider(this.jfmp3TrackBar, this.jfmp3TrackBarKnob, {
steps: this.songDuration, //set the SM2 and base don how the server sends the mp3 file
wheel: false, //dont let the scroll button on a mouse control the trackbar position
snap: true, //dont allow decimal numbers (ex. 10 instead of 10.23)
onChange: function(step){ //everytime you drag the knob (without letting go), chang esong duration relative to what you drag to
this.activeSound.setPosition(step);
}.bind(this),
onComplete: function(step){ //when you drag and let go, move the song to the location relative to where you dragged the knob
this.activeSound.setPosition(step);
}.bind(this)
});
this.jfmp3TrackBarKnob.setStyle('position', 'absolute'); //make sure the knob is set to absolute (various browsers switch to relative =_=)
}
This function controls the trackbar, its position during sound play and what it should do when its knob is dragged. It also handles skipping to a point in a song relative to where the user drags the knob.
Class Properties Used: activeSound, songDuration
Function: Playlist
_createPlaylist: function(){
/*
Function: _createPlaylist
What it Does: Creates the playlist at initialization, taking elements from the specified unordered-list,
seperating the required values, and placing them into the playlist array one at a time.
Also performs adding each item to the playlist or displaying an empty playlist message.
*/
$$('ul#'+this.options.playlistEl+' li').each(function(el){ //get all elements from the predefined playlist you made
var getChildA = el.getChildren('a')[0]; //get the anchor of this element
var getSongHref = getChildA.getProperty('href'); //get the href value of that anchor
if(getSongHref != "" && getSongHref != null && getSongHref != undefined) //if there is a href value
{
//get all required info for this song
var getTitle = getChildA.getChildren('span.title')[0].get('html');
var getArtist = getChildA.getChildren('span.artist')[0].get('html');
var getAlbum = getChildA.getChildren('span.album')[0].get('html');
var getCoverArt = getChildA.getChildren('span.coverart')[0].get('html');
var textInDisplay = ""; //start the empty display string for the playlist
if(getTitle == "")
{
getTitle = "Untitled"; //give the title a title if you didnt
}
textInDisplay = getTitle;
if(getArtist != "" && getArtist != null)
{
textInDisplay = textInDisplay+' by '+getArtist; //if you provided an artist for this song
}
this.thePlaylist.push(getSongHref+' ":" '+getTitle+' ":" '+getArtist+' ":" '+getAlbum+' ":" '+getCoverArt); //add to the playlist array
var newLI = new Element('li').inject(this.jfmp3PlaylistSsdUl); //create a new LI element and add it to the playlist (at the bottom)
var newA = new Element('a', {'rel':this.relCount, 'href':
getSongHref+'_&_'+getTitle+'_&_'+getArtist+'_&_'+getAlbum+
'_&_'+getCoverArt, 'html':textInDisplay}).inject(newLI);
//create a new anchor, give it the correct property values and insert it into the LI we created just before
var newAEvt = newA.addEvent('click', function(e){ //add the click event to this new playlist item right away
e.stop(); //stop the anchor tag from going anywhere (degrades nicely)
if(this.currentItem != (newA.getProperty('rel')).toInt() || this.playState === 2) //if we are not already playing this song
{
this._playlistItemC(newA);
}
}.bind(this));
this.relCount++;
}
}.bind(this));
if(this.thePlaylist.length===0) //if you dont have any songs, display one item int he playlist saying so.
{
var newLI = new Element('li').inject(this.jfmp3PlaylistSsdUl);
var newA = new Element('span', {'html': 'No items in playlist yet.'}).inject(newLI);
}
this.pLt = new Fx.Slide('jfmp3_playList'); //create the slider effect instance for the playlist
if(this.options.toggledByDefault === false) //if you want the playlist hidden by default
{
this.pLt.hide();
}
this._makeScrollbar(this.jfmp3PlaylistSsd, this.jfmp3ScrollB, this.jfmp3ScrollBHdle); //call the scrollbar function once the playlist is populated
}
_addToPlaylist: function(a,b,c,d,e){
/*
Function: _addToPlaylist
What it Does: Adds an item to the playlist using passed-in parameters,
as well as adds the item to the playlist array.
Paramters: a = mp3 location
b = mp3 title
c = mp3 artist
d = mp3 album
e = mp3 cover art
*/
if(a != "" && a != null && a != undefined) //same procedures as the create playlist function
{
var textInDisplay = ""; //start the empty display string for the playlist
if(b == "")
{
b = "Untitled"; //give the title a title if you didnt
}
textInDisplay = b;
if(c != "" && c != null)
{
textInDisplay = textInDisplay+' by '+c; //if you provided an artist for this song
}
this.thePlaylist.push(a+' ":" '+b+' ":" '+c+' ":" '+d+' ":" '+e);
var newLI = new Element('li').inject(this.jfmp3PlaylistSsdUl); //create a new LI element and add it to the playlist (at the bottom)
var newA = new Element('a', {'rel':this.relCount, 'href': a+'_&_'+b+'_&_'+c+'_&_'+d+'_&_'+e, 'html':textInDisplay}).inject(newLI); //create a new anchor, give it the correct property values and insert it into the LI we created just before
var newAEvt = newA.addEvent('click', function(e){ //add the click event to this new playlist item right away
e.stop(); //stop the anchor tag from going anywhere (degrades nicely)
if(this.currentItem != (newA.getProperty('rel')).toInt() || this.playState === 2) //if we are not already playing this song
{
this._playlistItemC(newA);
}
}.bind(this));
this.relCount++;
}
}
_playlistItemC: function(newA){
/*
Function: _playlistItemC
What it Does: Get the information from the playlist item and play it all.
Paramters: newA = Element reference to the anchor tag of the playlist item
*/
var getHref = newA.getProperty('href'); //get the href string
var breakToArr = getHref.split('_&_'); //split the string at every delimeter
this._createSound(breakToArr[0], breakToArr[1], breakToArr[2], breakToArr[3], breakToArr[4]); //create the sound object
this.allEl = $$('ul#jfmp3_playlistUlEl li a'); //get all the anchor tags in the playlist (one per item)
for(x=0;x<this.thePlaylist.length;x++) //go through each item and find the item that is currently being played then scroll to it by percentage
{
if(this.allEl[x] == newA)
{
this.moveToStep = (((x / (this.thePlaylist.length))+0.05)*100).round(0);
this.jfmp3_slider.set(this.moveToStep);
}
}
this._playToggle(0);
this.currentItem = (newA.getProperty('rel')).toInt(); //to check after what song is playing
this.currentItemRef = newA; //same as above but by reference to the element in the dom
this._colorize(newA); //run the coloring function for the playlist items
}
_removeFromPlaylist: function(a){
/*
Function: _removeFromPlaylist
What it Does: Removes a playlist item based on number passed in paramter a.
Parameters: a = Number of playlist item that should be removed (starting at 1 not 0)
*/
if(a > 0 && a <= this.thePlaylist.length && !isNaN(a*1)) //if 'a' is a number and makes sense
//(within the boundaries of the current playlist length etc)
{
if($$('ul#jfmp3_playlistUlEl li')[(a-1)]!=undefined) //does the item exist
{
this.thePlaylist.splice((a-1),1); //delete the item from the playlist array
$$('ul#jfmp3_playlistUlEl li')[(a-1)].destroy(); //delete the element
//reorder the playlist array's indexes
var tmp_arr = [];
var cnt = 0;
var key = '';
for(key in this.thePlaylist)
{
tmp_arr[cnt] = this.thePlaylist[key];
cnt++;
}
this.thePlaylist=tmp_arr;
}
}
}
_makeScrollbar: function(content,scrollbar,handle,horizontal,ignoreMouse){
/*
Function: _makeScrollbar
What it Does: Makes the scrollbar of the playlist work
Parameters: content = The playlist container
scrollbar = The scrollbar container
handle = The scrollbar handle
horizontal = Whether the scrolling should be done horizontally or vertically (default)
ignoreMouse = ignore scrolling with mouse wheel (off by default)
*/
if(content.getScrollSize().y - content.getSize().y > 0)
{
this.jfmp3_slider = new Slider(scrollbar, handle, {
steps: 100,
mode: (horizontal?'horizontal':'vertical'),
onChange: function(step)
{
var x = (horizontal?(((content.getScrollSize().x-content.getSize().x)/100)*step):0);
var y = (horizontal?0:(((content.getScrollSize().y-content.getSize().y)/100)*step));
content.scrollTo(x,y);
}.bind(this)
}).set(0);
if(!(ignoreMouse))
{
$$(content, scrollbar).addEvent('mousewheel', function(e)
{
e = new Event(e).stop();
var step = this.jfmp3_slider.step - e.wheel * 20;
this.jfmp3_slider.set(step);
}.bind(this)
);
}
$(document.body).addEvent('mouseleave',function()
{
this.jfmp3_slider.drag.stop()
}.bind(this)
);
}
else
{
scrollbar.fade(0);
}
}
These functions control various aspects of the playlist and playlist items. They control constructing the playlist, assining events to each playlist item, adding items to the playlist and removing items from the playlist. They also include scrollbar functions to control how the scrollbar works.
Class Properties Used: thePlaylist, relCount, currentItem, playState, pLt, currentItemRef
Function: CreateSound
_createSound: function(a,b,c,d,e){
/*
Function: _createSound
What it Does: Creates a sound object, using passed in parameters,
as well as handles time calculations, trackbar positioning
and streaming bar functions.
Paramters: a = mp3 location
b = mp3 title
c = mp3 artist
d = mp3 album
e = mp3 cover art
*/
if(this.currentItem != null) //if a sound object has already been created
{
soundManager.destroySound('mySound'); //destroy it first before redefining it
}
this.fadeFlag = false; //reset the stream bar fade flag
this.jfmp3Streamed.fade('show'); //show the stream bar
this.activeSound = soundManager.createSound({
id: 'mySound',
url: a,
onfinish: function(){
this._next(); //once the song finishes playing, get the next item in the playlist
}.bind(this),
whileloading: function(){
//while loading, update the stream bar according to how much of the song has been loaded
this.jfmp3Streamed.setStyle('width',
((this.activeSound.bytesLoaded/
this.activeSound.bytesTotal)*100).round(2)+'%');
//also update the length of the song to our current knowledge on the trackbar (steps is in milliseconds)
this.trackBarCall.steps = this.songDuration;
}.bind(this),
whileplaying: function(){
this.songDuration = this.activeSound.durationEstimate; //get the song duration estimate (best choice)
this.songTime = this.activeSound.position; //get the current songs position
if(this.trackBarInit === false) //init the trackbar if it hasnt already
{
this._trackBar();
this.trackBarInit = true;
}
if(this.activeSound.readyState === 3 && this.fadeFlag === false) //if streaming is done, hide the stream bar
{
this.fadeFlag = true;
this.jfmp3Streamed.fade('out');
this.trackBarCall.steps = this.songDuration;
}
//the following lines get the songs current position and convert it to the 00:00 format for displaying to the user
this.conMilToSecCur = ((this.songTime / 1000)%60).floor();
this.conMilToMinCur = ((this.songTime /(1000*60))%60).floor();
if(this.conMilToSecCur < 10)
{
this.actTCur = this.conMilToMinCur+":0"+this.conMilToSecCur;
}
else if(this.conMilToSecCur >= 10)
{
this.actTCur = this.conMilToMinCur+":"+this.conMilToSecCur;
}
//the following lines get the songs duration and convert it to the 00:00 format for displaying to the user
this.conMilToSec = ((this.songDuration / 1000)%60).floor();
this.conMilToMin = ((this.songDuration /(1000*60))%60).floor();
if(this.conMilToSec < 10)
{
this.actT = this.conMilToMin+":0"+this.conMilToSec;
}
else if(this.conMilToSec >= 10)
{
this.actT = this.conMilToMin+":"+this.conMilToSec;
}
//this sis for updating the trackbars knob position
this.currKStep = (((this.songTime/this.songDuration).round(2))*
(this.options.trackBarWidth-
(this.options.trackBarKnobWidth-5)));
var textInDisplay = ""; //start the variable for displaying text on the player witht he ongs info
textInDisplay = b;
if(c != "" && c != null)
{
textInDisplay = textInDisplay+' by '+c; //if artist provided
}
if(d != "" && d != null)
{
textInDisplay = textInDisplay+' from '+d; //if album provided
}
this.jfmp3InNP.empty(); //safari fix, clear the display element first
this.jfmp3InNP.set('html', 'Now Playing: '+textInDisplay+' ('+this.actTCur+'/'+this.actT+')'); //update the now playing text
this.jfmp3TrackBarKnob.setStyle('left', this.currKStep+'px'); //set the trackbars knob position relative tot he current songs position
}.bind(this)
});
if(this.volBarInit === false) //init the volume bar if it hasnt been already
{
this._volumeBar();
}
this.activeSound.setVolume(this.lastVol); //set the volume for this new sound object
if(this.volMuteFlag === true) //if the player is muted, keep it that way
{
this._mute();
}
if(e != "" && e != undefined)
{
this.jfmp3CoverArtImg.setProperties({'src': e, 'alt': b + ' - ' + c, 'title': b + ' - ' + c});
}
else
{
this.jfmp3CoverArtImg.setProperties({'src': this.options.defaultCoverArt, 'alt': b + ' - ' + c, 'title': b + ' - ' + c});
}
}
This function creates a sound object with SM2, and runs several functions and calculations every few milliseconds (like time calculation and duration).
Class Properties Used: activeSound, songDuration, currentItem, songTime, trackBarInit, conMilToSecCur, conMilToMinCur, actTCur, conMilToSec, conMilToMin, actT, currKStep, volBarInit, volMuteFlag
Function: Structure and Events
_structure: function(){
/*
Function: _structure
What it Does: Creates the structure of the entire player by declaring new elements and
injecting them into their specific areas of the page (within the container of targetEl).
Also alerts user if no targetEl is specified or found (should never happen
outside a development scenario).
*/
//check to see if the target element to load the player in exists first
if(this.options.targetEl == "" || this.options.targetEl === null || this.options.targetEl.length === 0 || $(this.options.targetEl) === null)
{
alert('Target element not valid, not found or not configured properly!\nYou need to set which element JFMP3 is supposed to load-in using the \'targetEl\' option.');
}
else //if it exists, build all the HTML elements, assing their properties and inject them into place
{
$(this.options.targetEl).set('html', '');
this.jfmp3Cont = new Element('div', {'id':'jfmp3_containerDiv'}).inject(this.options.targetEl);
this.jfmp3NowPlaying = new Element('div', {'id':'jfmp3_nowPlaying'}).inject(this.jfmp3Cont);
this.jfmp3InNP = new Element('div', {'html':this.options.defaultMessage}).inject(this.jfmp3NowPlaying);
this.jfmp3MainCtrl = new Element('div', {'id':'jfmp3_mainControl'}).inject(this.jfmp3NowPlaying, 'after');
this.jfmp3MainCtrlIn = new Element('div', {'id':'jfmp3_innerControl'}).inject(this.jfmp3MainCtrl);
this.jfmp3PrevButt = new Element('div', {'id':'jfmp3_previous', 'title':'previous track', 'html':''}).inject(this.jfmp3MainCtrlIn);
this.jfmp3StopButt = new Element('div', {'id':'jfmp3_spp', 'class':'stop', 'title':'stopped', 'html':''}).inject(this.jfmp3PrevButt, 'after');
this.jfmp3NextButt = new Element('div', {'id':'jfmp3_next', 'title':'next track', 'html':''}).inject(this.jfmp3StopButt, 'after');
this.jfmp3TrackBar = new Element('div', {'id':'jfmp3_trackBar', 'html':''}).inject(this.jfmp3NextButt, 'after');
this.jfmp3Streamed = new Element('div', {'id':'jfmp3_streamed', 'html':''}).inject(this.jfmp3TrackBar);
this.jfmp3TrackBarKnob = new Element('div', {'id':'jfmp3_trackBarKnob', 'html':''}).inject(this.jfmp3Streamed, 'after');
this.jfmp3TogglePl = new Element('div', {'id':'jfmp3_tP', 'title':'toggle playlist view', 'html':''}).inject(this.jfmp3TrackBar, 'after');
this.jfmp3ToggleRp = new Element('div', {'id':'jfmp3_repeat', 'title':'turn repeat on/off', 'html':''}).inject(this.jfmp3TogglePl, 'after');
this.jfmp3ToggleSfle = new Element('div', {'id':'jfmp3_shuffle', 'title':'turn shuffle on/off', 'html':''}).inject(this.jfmp3ToggleRp, 'after');
this.jfmp3Playlist = new Element('div', {'id':'jfmp3_playList'}).inject(this.jfmp3MainCtrl, 'after');
this.jfmp3PlaylistSd = new Element('div', {'id':'jfmp3_subDiv'}).inject(this.jfmp3Playlist);
this.jfmp3PlaylistSsd = new Element('div', {'id':'jfmp3_subDivDiv'}).inject(this.jfmp3PlaylistSd);
this.jfmp3PlaylistSsdUl = new Element('ul', {'id':'jfmp3_playlistUlEl'}).inject(this.jfmp3PlaylistSsd);
this.jfmp3ScrollB = new Element('div', {'id':'jfmp3_scrollBar', 'class':'jfmp3_scrollBar'}).inject(this.jfmp3PlaylistSsd, 'after');
this.jfmp3ScrollBHdle = new Element('div', {'id':'jfmp3_scrollBarHandle', 'class':'jfmp3_scrollBarHandle', 'html':''}).inject(this.jfmp3ScrollB);
this.jfmp3CoverArt = new Element('div', {'id':'jfmp3_coverart'}).inject(this.jfmp3ScrollB, 'after');
this.jfmp3CoverArtImg = new Element('img', {'src':'jfmp3/defaultCoverArt.jpg', 'alt':'JFMP3', 'title':'JFMP3'}).inject(this.jfmp3CoverArt);
this.jfmp3MuteUn = new Element('div', {'id':'jfmp3_muteUn', 'html':''}).inject(this.jfmp3Playlist, 'after');
this.jfmp3VolumeBar = new Element('div', {'id':'jfmp3_volumeBar', 'html':''}).inject(this.jfmp3MuteUn, 'after');
this.jfmp3VolumeBarSldr = new Element('div', {'id':'jfmp3_volumeSlider', 'html':''}).inject(this.jfmp3VolumeBar);
this.jfmp3VolumeBarKnob = new Element('div', {'id':'jfmp3_volumeKnob', 'html':''}).inject(this.jfmp3VolumeBarSldr);
this._assignEvents(); //now that all that is done, assign events to some of these new elements
}
}
_assignEvents: function(){
/*
Function: _assignEvents
What it Does: Handles assignment of base events to player controls like:
play, pause, stop etc...
*/
this.plFx = new Fx.Scroll(this.jfmp3PlaylistSsd); //toggle effect instance for the playlist
this.clickEvtSPP = this.jfmp3StopButt.addEvent('click', function(e){ //run when the stop/pasue/play button is pressed
switch(this.playState)
{
case 0:
this._pause();
break;
case 1:
this._play();
break;
}
}.bind(this));
this.clickEvtNext = this.jfmp3NextButt.addEvent('click', function(e){this._next(e)}.bind(this)); //run when next is pressed
this.clickEvtPrevious = this.jfmp3PrevButt.addEvent('click', function(e){this._previous(e)}.bind(this)); //run when previous is pressed
this.mouseEvtUnMutButt = this.jfmp3MuteUn.addEvents({'click': function(){ //run when mute/unmute is pressed
this._muteToggle()
}.bind(this),
'mouseenter': function(){
this._volumeToggle(0)
}.bind(this),
'mouseleave': function(){
this._volumeToggle(1)
}.bind(this)
});
this.mouseEvtVolBar = this.jfmp3VolumeBar.addEvents({'mouseenter': function(){ //run when the volume bar is hovered over or out
this._volumeToggle(0)
}.bind(this),
'mouseleave': function(){
this._volumeToggle(1)
}.bind(this)
});
if(this.options.toggleablePlaylist === true) //if the playlist is toggleable, enable the button
{
this.clickEvtTP = this.jfmp3TogglePl.addEvent('click', function(){this.pLt.toggle()}.bind(this));
}
else //or fade it out and disable it
{
this.jfmp3TogglePl.setStyles({'cursor':'default', 'opacity':0.2});
}
if(this.options.repeatablePlaylist === true) //if the playlist is repeatable, enable the button
{
this.clickEvtRP = this.jfmp3ToggleRp.addEvent('click', function(){this._repeatToggle()}.bind(this));
}
else //or fade it out and disable it
{
this.jfmp3ToggleRp.setStyles({'cursor':'default', 'opacity':0.2});
}
if(this.options.shuffleablePlaylist === true) //if the playlist is shuffleable, enable the button
{
this.clickEvtSFLE = this.jfmp3ToggleSfle.addEvent('click', function(){this._shuffleToggle()}.bind(this));
}
else //or fade it out and disable it
{
this.jfmp3ToggleSfle.setStyles({'cursor':'default', 'opacity':0.2});
}
}
These 2 functions handle creating the structure of the player (HTML) and assinging events to different parts of the player.
Class Properties Used: playState, pLt

Docs Navigation
