Sie sind auf Seite 1von 20

In this tutorial I will show you how to create a J avaScript MP3 Player with jQuery and the SoundManager 2

J avaScript library that uses a hidden SWF file to play the sounds.
Step 1: Getting the Libraries
In this step we will download all the files we will need throughout this tutorial. We will be using the
following libraries:
jQuery: A general purpose J avaScript library
jQuery UI: A user interface library built on top of jQuery
jScroller: A jQuery plugin that provides scrolling capabilities to text
SoundManager 2: A library that wraps Flashs Audio API in J avaScript
Now we will download these and save them to a convienient directory for future use.
Head over to the jQuery.com site and download the production version of jQuery.
We need to download a version of the jQuery UI library. This library comes with many different themes; the
one we will be using is called smoothness. Point your browser to jQueryUI.com, and on the right side of
the page choose smoothness from the pulldown menu then click the Download button. You can pick and
choose what you want to include in the download, but for the purposes of this tutorial we will just leave
everything checked. (If you decide to put this live on a server youll probably want to choose just what is
necessary, to save a little bit of bandwidth.)
Go to code.google.com and download the jScroller plugin.
Lastly, to get the SoundManager2 library head over to schillmania.com.
Step 2: Project Structure
Instead of explaining step by step how to set up the project folder structure, I have provided a start.zip in
the download files.
Basically, I moved all the J avaScript files into the js folder and the CSS files into the css folder. Also,
inside the css and js folders I have included the files mp3player.css and mp3player.js, respectively. The
mp3player.css already has the CSS written for positioning the MP3 player images. I will not be going into
much depth on the CSS, as the focus of this tutorial is on the J avaScript. The mp3player.js is blank right
now.
The start.zip also contains the following files/folders:
images: holds the images for the mp3player
swf: holds the .SWF files used by SoundManager
sounds: holds the MP3s
index.html: the main HTML page
You will need to extract this file on a server, as SoundManager 2 will not work otherwise, and will throw an
error. I am using local setup with WAMP.
The downloadable ZIP also contains a copy of the source from every Step of this tutorial, to make it easy to
follow along.
Step 3: Examining index.html
Open index.html in a text editor and have a look at its structure. The index.html includes the J avaScript/CSS
files, and the image and div tags for the MP3 Player. It is important that you follow the structure of this
HTML file when including the .js files, as we need the jQuery.js files to load before the soundmanager.js
file. (Throughout this tutorial I will refer to the images as buttons, because that is what they are acting
like.)
Below is an image showing the IDs of the images and divs that make up the MP3 Player:
Step 4: Document ready()
Open mp3player.js, located in the js folder and enter the following code.
1
2
3
4
pr i vat e f unct i on demonst r at e( ) : voi d
$( document ) . r eady( f unct i on( ) {
al er t ( " Document Ready" ) ;
}) ;
If you now open index.html, youll see an alert with the words Document Ready. jQuerys . r eady( )
method gets called when the DOM has fully loaded and is available for manipulation.
It is important to call this method when writing your applications, because if you try to start manipulating
DOM elements before they are loaded it will have no effect. For instance, if you tried to add a click handler
to a button before it has loaded it would have no effect.
Here is a link to the .ready() method in the jQuery documentation.
Step 5: SoundManager onready()
Add the following code within the $( document ) . r eady you added in the step above.
1
2
3
4
5
6
7
8
$( document ) . r eady( f unct i on( ) {
al er t ( " Document Ready" ) ;
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
soundManager . onr eady( f unct i on( ) {
al er t ( " SoundManager Ready" ) ;
}) ;
}) ;
Here we set up the soundManger . ur l which points to the directory we have the SWF files in, set the
soundManager . f l ashVer si on to 8, and call soundManager . onr eady( ) .
The onr eady( ) method of SoundManager works very much the same way as jQuerys . r eady( ) method.
When soundManager has fully loaded it fires off the . onr eady( ) method, and signals that we can start
adding properties to and calling methods on the SoundManager object. When we load soundManager.js it
automatically creates a global SoundManager object, aptly named soundManager , so there no need to say:
1var soundManager = new SoundManager ( ) ;
The documentation for SoundManager is available on schillmania.com.
Step 6: playSound()
Enter the following code within mp3player.js:
01
02
03
04
05
06
07
08
09
10
11
$( document ) . r eady( f unct i on( ) {
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
var t heMP3;
var cur r ent Song =0;
soundManager . onr eady( f unct i on( ) {
f unct i on pl aySound( ) {
t heMP3= soundManager . cr eat eSound( {
i d: ' sound' +cur r ent Song,
ur l : " . . / sounds/ 1. mp3"
}) ;
12
13
14
15
16
t heMP3. pl ay( ) ;
};
pl aySound( ) ;
}) ;
}) ;
Here we set up two global variables: t heMP3 and cur r ent Song. The t heMP3 variable is used with the
cr eat eSound( ) method of SoundManager, and the cur r ent Song variable will be used to keep track of which
track is playing (it will always be a number).
Within the . onr eady( ) method, we create a function pl aySound( ) , and inside this function we call the
cr eat eSound( ) method of SoundManager using our t heMP3 variable. We set a i d and a ur l to the MP3 file,
and tell the MP3 to play by calling t heMP3. pl ay( ) . Lastly we call the pl aySound( ) function which plays the
MP3.
If you open index.html now you should hear the MP3 playing. At this point there are 5 MP3 files in the
sound folder. (I have stored this folder a level above the i ndex. ht ml , so the zip file would not contain
multiple copies of the MP3s, and each step in the tutorial can use the same folder. You dont have to do
this, of course.)
The MP3s used in this tutorial are all public domain, and are from
http://funfunfunmedia.com/author/publicdomain2ten.
Step 7: Play Button
Being able to play the MP3s is all well and good, but we want some control over the MP3. In this step we
will wire up the play button. Add the following code to mp3player.js:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
soundManager . onr eady( f unct i on( ) {
f unct i on pl aySound( ) {
t heMP3= soundManager . cr eat eSound( {
i d: ' sound' +cur r ent Song,
ur l : " . . / sounds/ 1. mp3"
}) ;
t heMP3. pl ay( ) ;
};
$( " #pl ay_bt n" ) . cl i ck( f unct i on( ) {
var t hebut t on = $( t hi s) ;
i f ( t hebut t on. at t r ( " sr c" ) ==" i mages/ pl ay_but t on. png" ) {
t hebut t on. at t r ( " sr c" , " i mages/ pl ay_sel ect ed. png" ) ;
pl aySound( ) ;
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
}) ;
Here we select the play button by using the jQuery selector $( " #pl ay_bt n" ) , which selects the element on
the page with the id of play_btn.
Next we add a . cl i ck( ) method to the button, which will be called when the user clicks on the button. We
set up a variable t hebut t on equal to $( t hi s) which is the button itself. (This should be familiar if you are
coming from ActionScript.) We then check whether the images sr c attribute is equal to play_button.png,
and if it is we set it to play_selected.png.
Next we call pl aySound( ) which tells the MP3 to play. We then add a mouseover ( ) handler to the button,
which changes the mouse cursor to a pointer whenever the user moves their mouse over the button. We
have used a jQuery technique called chaining where we have chained the mouseover ( ) function onto the
. cl i ck( ) function.
Here are some helpful links to the jQuery documentation to help you understand the .click, .attr,
.mouseover and .css methods:
.click()
.attr()
.mouseover()
.css()
If you test the page now, you should be able to press the play button and have the MP3 start playing.
Step 8: Stop Button
In this step we will code the stop button. Add the following code beneath the $( " #pl ay_bt n" ) . cl i ck( )
function you added above make sure you add it after the . mouseover ( ) method.
1
2
3
4
5
6
7
$( " #st op_bt n" ) . cl i ck( f unct i on( ) {
$( " #pl ay_bt n" ) . at t r ( " sr c" , " i mages/ pl ay_but t on. png" ) ;
$( t hi s) . at t r ( " sr c" , " i mages/ st op_sel ect ed. png" ) ;
t heMP3. st op( ) ;
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Here we use the same chaining technique as with the play button, adding the . cl i ck( ) and . mouseover
methods to the stop button image. We reset the play button images src to play_button.png, set the stop
button images sr c attribute to stop_selected.png, and tell the MP3 to stop playing.
You can test this now and should be able to both play and stop the MP3.
Step 9: Pause Button
In this step we will code the pause button. Enter the following code beneath the $( " #st op_bt n" ) . cl i ck( )
method you added in the step above; again, make sure you add it after the . mouseover ( ) .
1
2
3
4
5
6
7
$( " #pause_bt n" ) . cl i ck( f unct i on( ) {
$( " #pl ay_bt n" ) . at t r ( " sr c" , " i mages/ pl ay_but t on. png" ) ;
$( t hi s) . at t r ( " sr c" , " i mages/ pause_sel ect ed. png" ) ;
t heMP3. pause( ) ;
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Same methods again: we change the play button images sr c attribute to play_button.png and change
the pause button images src to pause_selected. We then tell the MP3 to pause.
Step 10: Adding More MP3s
Before we can wire up the forward and back buttons we need more MP3s to play. There are five MP3 files
in the sound folder, and we need a way to access them. We will store the MP3 filenames in an array and
access them from there. Add the following code along with your other global variables:
1
2
3
4
pr i vat e f unct i on demonst r at e( ) : voi d
var t heMP3;
var cur r ent Song = 0;
var t r acks = [ " 1" , " 2" , " 3" , " 4" , " 5" ] ;
The t r acks array holds the filenames of the MP3s. I named the MP3s 1 through 5, just to keep it short.
Step 11: createSound() Revised
We will need to change the cr eat eSound( ) method now that we are dealing with multiple MP3s. Edit the
cr eat eSound( ) as below:
1
2
3
t heMP3= soundManager . cr eat eSound( {
i d: ' sound' +cur r ent Song,
ur l : " . . / sounds" +t r acks[ cur r ent Song] +" . mp3"
Here we changed the ur l property to point to the MP3s from the array. Currently cur r ent Song is equal to 0,
so it will play the first element in the array which happens to be called 1.mp3. When we click on the
next button we will increment cur r ent Song by one, and when we click on the previous button we will
decrement cur r ent Song by one. The pl aySong( ) method will be called when we click on either button. The
upcoming code will make this clear.
Step 12: FWD (Forward) Button
Add the following code below the $( " #pause_bt n" ) method, as always make sure you put it after the
mouseover ( ) .
1
2
3
$( " #f wd_bt n" ) . cl i ck( f unct i on( ) {
i f ( t heMP3 ! =undef i ned) {
t heMP3. st op( ) ;
4
5
6
7
8
9
cur r ent Song++;
pl aySound( ) ;
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Here we stop the MP3, increment cur r ent Song, and call pl aySound( ) . We first check to make sure that
t heMP3 is not undefined before executing any other code. If the user pressed the fwd button without first
pressing play, then t heMP3 would have not been instantiated yet. It would throw a J avaScript error, and
although it would not affect the usage of the app, it as always good to put in preventative measures like
this to make sure your page does not throw any errors.
You should now be able to press the fwd button to make the next song play (you can test it here). You
might notice that once you go through all five songs it comes to a screeching halt. We will fix this after we
get the back button hooked up!
Step 13: Back Button
Add the following code below the $( " #f wd_but t on" ) . cl i ck( ) . As always, make sure you put it underneath
the . mouseover ( ) .
1
2
3
4
5
6
7
8
9
$( " #back_bt n" ) . cl i ck( f unct i on( ) {
i f ( t heMP3 ! = undef i ned) {
t heMP3. st op( ) ;
cur r ent Song- - ;
pl aySound( ) ;
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
This is nearly identical to the code we added in the step above. All we are doing differently is decreasing
the cur r ent Song variable by 1. Again, if you try it out, youll notice that if you go below the number of
songs available nothing happens. Lets fix this in the next step.
Step 14: Fixing the FWD and BACK Buttons
Add the following code directly beneath the pl aySound( ) function.
1
2
3
4
5
6
7
f unct i on pl aySound( ) {
i f ( cur r ent Song>=t r acks. l engt h) {
cur r ent Song=0;
}
i f ( cur r ent Song<0) {
cur r ent Song = t r acks. l engt h- 1;
}
What we are doing here is making sure we keep the cur r ent Song variable within the bounds of our array. If
cur r ent Song is greater than the length of our array, we need to set it to 0. If cur r ent Song is less than 0 we
set it to one less than the arrays length that is, to the last element in the array.
Using this method, when we reach either end of the array we wrap back around, making a nice forward
and back system for our MP3 player.
Step 15: Volume Control
In this step we will wire up the volume control for our MP3 player. Add the following code beneath the
$( " #back_bt n" ) . cl i ck( ) . Make sure you put it beneath the mouseover ( ) .
01
02
03
04
05
06
07
08
09
10
11
12
13
$( " #vol umebar " ) . mousemove( f unct i on( e) {
var par ent Of f set = $( t hi s) . par ent ( ) . of f set ( ) ;
var r el X = Mat h. f l oor ( e. pageX - par ent Of f set . l ef t ) ;
var vol = Mat h. cei l ( ( r el X- 7) / 10) - 4;
i f ( vol >=1 && vol <=10) {
$( t hi s) . at t r ( " sr c" , " i mages/ vb" +vol +" . png" ) ;
i f ( t heMP3 ! = undef i ned) {
t heMP3. set Vol ume( vol *10)
}
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
This code might look a bit confusing, but we will break it down bit by bit.
Notice we have used mousemove( ) , so the code inside will be called as the user moves their mouse over the
volume bar, without them needing to click. The first thing we do is get the offset of the $( " #vol umebar " ) s
parent, which in this case is the #pl ayer div. You can verify this by adding the following code:
1al er t ( $( t hi s) . par ent ( ) . at t r ( " i d" ) ) ;
or by referring to this image again:
The . of f set ( ) method allows us to retrieve the current position of an element relative to the document.
Here we get the offset of the #pl ayer div, and in the next line of code we set a variable r el X equal to
( e. pageX - par ent Of f set . l ef t ) . What we are doing here is making sure when we mouseover #vol umebar
that we are getting the coordinates of the #vol ume bar itself (within the MP3 player). If we had not done
the above math, then the coordinates would have included the parent offset, and would throw off any
calculation if you decided to move the MP3 player to a new location in the page.
(I am assuming you are using a modern browser that allows you to log values. The FireBug plugin in
FireFox works quite nice for this. If you are on Chrome then select Tools > Developer Tools and click on
the Console tab.)
If you want to see what the par ent Of f set is, add the following below the var par ent Of f set =
$( t hi s) . par ent ( ) . of f set ( ) :
1consol e. l og( par ent Of f set ) ;
When I ran this in my browser it was around 326px with a few decimal places. Yours may read out
differently depending on what your screen resolution is. Below is an image that shows the parentOffset in
FireFox.
In the next section we are calculating a number between 1 and 10. This may look really confusing but we
will break it down bit by bit again.
Comment out the line var vol = Mat h. cei l ( ( r el X- 7/ 10) - 4) , add the following code and test:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$( " #vol umebar " ) . mousemove( f unct i on( e) {
var par ent Of f set = $( t hi s) . par ent ( ) . of f set ( ) ;
var r el X = Mat h. f l oor ( e. pageX - par ent Of f set . l ef t ) ;
/ / var vol = Mat h. cei l ( ( r el X- 7) / 10) - 4;
var vol = Mat h. cei l ( ( r el X) ) ;
consol e. l og( vol ) ;
i f ( vol >=1 && vol <=10) {
$( t hi s) . at t r ( " sr c" , " i mages/ vb" +vol +" . png" ) ;
i f ( t heMP3 ! = undef i ned) {
t heMP3. set Vol ume( vol *10)
}
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Now try to position your mouse cursor just between some of the dots. You should get a number like 57,
87,or 117 depending on where you place the cursor. Below is an image showing this.
Next add the following code.
01
02
03
04
05
06
07
$( " #vol umebar " ) . mousemove( f unct i on( e) {
var par ent Of f set = $( t hi s) . par ent ( ) . of f set ( ) ;
var r el X = Mat h. f l oor ( e. pageX - par ent Of f set . l ef t ) ;
/ / var vol = Mat h. cei l ( ( r el X- 7) / 10) - 4;
var vol = Mat h. cei l ( r el X- 7) ;
consol e. l og( vol ) ;
i f ( vol >=1 && vol <=10) {
08
09
10
11
12
13
14
15
$( t hi s) . at t r ( " sr c" , " i mages/ vb" +vol +" . png" ) ;
i f ( t heMP3 ! = undef i ned) {
t heMP3. set Vol ume( vol *10)
}
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Now you should be getting a whole number like 50, 80, 110. Again here is an image showing the changes.
Add the following code.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$( " #vol umebar " ) . mousemove( f unct i on( e) {
var par ent Of f set = $( t hi s) . par ent ( ) . of f set ( ) ;
var r el X = Mat h. f l oor ( e. pageX - par ent Of f set . l ef t ) ;
/ / var vol = Mat h. cei l ( ( r el X- 7) / 10) - 4;
var vol = Mat h. cei l ( ( r el X- 7) / 10) ;
consol e. l og( vol ) ;
i f ( vol >=1 && vol <=10) {
$( t hi s) . at t r ( " sr c" , " i mages/ vb" +vol +" . png" ) ;
i f ( t heMP3 ! = undef i ned) {
t heMP3. set Vol ume( vol *10)
}
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Getting closer we are now logging small whole numbers. Below is an image.
Youll notice the second circle logs 6 when between the circles it should equate to 2 for the volume. Seems
we are still off by 4, so we subtract 4 and viola we arive at the correct number! Hence the following code:
01
02
03
04
$( " #vol umebar " ) . mousemove( f unct i on( e) {
var par ent Of f set = $( t hi s) . par ent ( ) . of f set ( ) ;
var r el X = Mat h. f l oor ( e. pageX - par ent Of f set . l ef t ) ;
var vol = Mat h. cei l ( ( r el X- 7) / 10) - 4;
05
06
07
08
09
10
11
12
13
14
consol e. l og( vol ) ;
i f ( vol >=1 && vol <=10) {
$( t hi s) . at t r ( " sr c" , " i mages/ vb" +vol +" . png" ) ;
i f ( t heMP3 ! = undef i ned) {
t heMP3. set Vol ume( vol *10)
}
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Below is an image that show the result of the final calculation:
Now that we have the correct numbers, we check whether the vol is between 1 and 10. If it is, we set the
#vol umebar s src attribute to one of the 10 images of the volume bar that is in the images folder. For
example, if vol was equal to 5 then " i mages/ vb" +vol +" . png" would translate into images/vb5.png. Below
is an image of vb5.png to help make this clear.
Finally, we make sure that t heMP3 is not undefined, and if it isnt we set the volume on it using ( vol *10)
which would equal somewhere between 10 100, depending on what value vol happens to be.
Step 16: Progress Bar
In this step we will tie in the Progress Bar. In the HTML source, there is a di v with an id of #pr ogr essbar .
To turn this div into a Progress Bar we call jQuery UIs . pr ogr essbar ( ) method on it like so:
1$( " #pr ogr essbar " ) . pr ogr essbar ( ) ;
Add the following code within $( document ) . r eady( ) .
1
2
3
4
5
6
7
8
9
$( document ) . r eady( f unct i on( ) {
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
var t heMP3;
var cur r ent Song =0;
var t r acks = [ " 1" , " 2" , " 3" , " 4" , " 5" ] ;
$( " #pr ogr essbar " ) . pr ogr essbar ( {
val ue: 50
}) ;
Now refresh the page and you should see the Progress Bar at 50%. Okay, now set the value to zero.
1
2
3
$( " #pr ogr essbar " ) . pr ogr essbar ( {
val ue: 0
}) ;
SoundManager has a whi l ePl ayi ng( ) method that is called repeatedly while the sound is playing, and this
is where we will update our Progress Bar. Add the following code within cr eat eSound( ) .
01
02
03
04
05
06
07
08
09
10
11
12
t heMP3= soundManager . cr eat eSound( {
i d: ' sound' +cur r ent Song,
ur l : " . . / sounds/ " +t r acks[ cur r ent Song] +" . mp3" ,
whi l epl ayi ng: f unct i on( ) {
dur at i on = t hi s. dur at i on;
pos = t hi s. posi t i on;
songPosi t i on = ( pos/ dur at i on) *100;
consol e. l og( " Pos/ Dur at i on " + pos/ dur at i on) ;
consol e. l og( " Song Posi t i on " + songPosi t i on) ;
}

}) ;
Make sure you add the comma after ur l : " . . / sounds/ " +t r acks[ cur r ent Song] +" . mp3" . Here we set dur at i on
equal to the songs duration, and pos equal to the current position within the songs. We then figure out the
songPosi t i on percentage by dividing pos by dur at i on and multiplying by 100. Finally, we log the values so
we can see what they equate to.
We now have a number in the variable songPosi t i on that we can use with our Progress Bar. Add the
following code:
1
2
3
4
5
6
whi l epl ayi ng: f unct i on( ) {
dur at i on = t hi s. dur at i on;
pos = t hi s. posi t i on;
songPosi t i on = ( pos/ dur at i on) *100;
$( " #pr ogr essbar " ) . pr ogr essbar ( " opt i on" , " val ue" , songPosi t i on) ;
}
Here we are setting the Progress Bars value to songPosi t i on which will always be a number between 1 and
100. You will notice if you switch to a new song that the Progress Bar resets itself.
Step 17: Song Position
In this step we will tie in the time display. In the HTML there is a di v with the id #t i me, and this is where
we will insert the time display of the current MP3. Like the Progress Bar we will calculate this within the
whi l epl ayi ng( ) method.
Add the following code within whi l epl ayi ng( ) :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
whi l epl ayi ng: f unct i on( ) {
dur at i on = t hi s. dur at i on;
pos = t hi s. posi t i on;
songPosi t i on = ( pos/ dur at i on) *100;
$( " #pr ogr essbar " ) . pr ogr essbar ( " opt i on" , " val ue" , songPosi t i on) ;

var t i me = pos/ 1000;
consol e. l og( " Ti me " + t i me) ;
var mi n = Mat h. f l oor ( t i me/ 60) ;
consol e. l og( " Mi n" + mi n) ;
var mi nDi spl ay = ( mi n<10) ? " 0" +mi n : mi n;
var sec = Mat h. f l oor ( t i me%60) ;
consol e. l og( " Sec " + sec) ;
var secDi spl ay = ( sec<10) ? " 0" +sec : sec;
var amount Pl ayed = mi nDi spl ay+" : " +secDi spl ay;
}
Here we set up our t i me variable. Since pos is in milliseconds we divide by 1000 to get a number in
seconds, such as 2.038, 10.998 etc. We then set a variable mi n equal to Mat h. f l oor ( t i me/ 60) to give us
our minutes. Next, we set up a variable mi nDi spl ay to format the number; if mi n is less than 10 we add a 0
in front of it (as a string), otherwise we just leave it alone.
Next we set up a variable sec which is equal to Mat h. f l oor ( t i me%60) ; here we are using the modulo
operator which returns the remainder of a division, so in this case it is returning the remainder of t i me/ 60,
which is the number of seconds through the current minute. We set our secDi spl ay variable up the same
way we did the mi nDi spl ay variable: if sec is less than 10 we add a zero to it, otherwise we leave it as is.
Finally we set up a variable amount Pl ayed which shows the mi nDi spl ay and secDi spl ay with a colon in
between them, like 1: 30. (In case any of this is unclear, we are logging the values to help you understand.)
Now change the above code to the following:
1
2
3
4
5
6
7
8
var t i me = pos/ 1000;
var mi n = Mat h. f l oor ( t i me/ 60) ;
var mi nDi spl ay = ( mi n<10) ? " 0" +mi n : mi n;
var sec = Mat h. f l oor ( t i me%60) ;
var secDi spl ay = ( sec<10) ? " 0" +sec : sec;
var amount Pl ayed = mi nDi spl ay+" : " +secDi spl ay;

$( " #t i me" ) . t ext ( amount Pl ayed) ;
Notice that I removed all the consol e. l og calls, because it affected the performance of the time updating
it would only update every 2-3 seconds. Logging so much information at once seriously affects
performance. Remember this when you put your apps live!
Step 18: Song Duration
In this step we will set up the duration part of the time display. Add the following code, below the code you
added above:
1
2
3
4
5
6
var t i medur at i on = dur at i on/ 1000;
var mi ndur at i on = Mat h. f l oor ( t i medur at i on/ 60) ;
var mi nDi spl ay = ( mi ndur at i on<10) ? " 0" +mi ndur at i on : mi ndur at i on;
var secdur at i on = Mat h. f l oor ( t i medur at i on%60) ;
var secDi spl ay = ( secdur at i on<10) ? " 0" +secdur at i on : secdur at i on;
var t ot al Dur at i on = mi nDi spl ay+" : " +secDi spl ay;
Here we are using the same method to calculate the duration as we did with the time in the step above.
The only thing that is different is we are dividing dur at i on/ 1000, instead of pos/ 1000.
Now move the $( " #t i me" ) . t ext ( amount Pl ayed) below the line var t ot al Dur at i on =
mi ndur at i on+" : " +secdur at i on and change it to the following:
1$( " #t i me" ) . t ext ( amount Pl ayed + " / " + t ot al Dur at i on) ;
Here we are displaying both the amount Pl ayed and t ot al Dur at i on, separated by a slash.
Here is the all the code from these last two steps:
01
02
03
04
05
06
07
08
09
10
11
12
13
var t i me = pos/ 1000;
var mi n = Mat h. f l oor ( t i me/ 60) ;
var mi nDi spl ay = ( mi n<10) ? " 0" +mi n : mi n;
var sec = Mat h. f l oor ( t i me%60) ;
var secDi spl ay = ( sec<10) ? " 0" +sec : sec;
var amount Pl ayed = mi nDi spl ay+" : " +secDi spl ay;

var t i medur at i on = dur at i on/ 1000;
var mi ndur at i on = Mat h. f l oor ( t i medur at i on/ 60) ;
var mi nDi spl ay = ( mi ndur at i on<10) ? " 0" +mi ndur at i on : mi ndur at i on;
var secdur at i on = Mat h. f l oor ( t i medur at i on%60) ;
var secDi spl ay = ( secdur at i on<10) ? " 0" +secdur at i on : secdur at i on;
var t ot al Dur at i on = mi nDi spl ay+" : " +secDi spl ay;
14
15

$( " #t i me" ) . t ext ( amount Pl ayed +" / " +t ot al Dur at i on)
If you test now, you should see both the current time and total duration displayed.
Step 19: Getting the ID3 information
In this step we will get the ID3 information from the MP3s. SoundManager has an oni d3( ) method that is
fired off once the ID3 information from the MP3 is available. In testing I found that the the oni d3( ) method
only fires one time per song, so we need a way to cache the ID3s. We will use an array to accomplish this.
Add the following within $( document ) . r eady( ) .
1
2
3
4
5
6
7
$( document ) . r eady( f unct i on( ) {
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
var t heMP3;
var cur r ent Song =0;
var t r acks = [ " 1" , " 2" , " 3" , " 4" , " 5" ] ;
var i d3s=[ ] ;
Now below the whi l epl ayi ng( ) method you added in the steps above, add the following code.
01
02
03
04
05
06
07
08
09
10
11
12
13
whi l epl ayi ng: f unct i on( ) {
dur at i on = t hi s. dur at i on;
pos = t hi s. posi t i on;
songPosi t i on = ( pos/ dur at i on) *100;
/ / . . . . . .
/ / . . . . . .
},
oni d3: f unct i on( ) {
ar t i st = t hi s. i d3[ " TPE1" ] ;
t i t l e = t hi s. i d3[ " TI T2" ] ;
i d3s. push( {t heAr t i st : ar t i st , t heTi t l e: t i t l e}) ;
consol e. l og( " Ar t i st " + ar t i st + " Ti t l e " + t i t l e) ;
}
Make sure you add a comma after the closing brace of the whi l epl ayi ng( ) method as shown above.
Here we are getting the ID3 information for the artist and the title of the song, and pushing them into the
i d3s array. A good reference for the ID3 tags can be found on Wikipedia; we are using ID3v2. Finally we
are logging the values, as usual.
If you test now you whould see the artist and title of the song logged in the console.
Step 20: Displaying ID3 info
Now that we have the ID3 info, we will display it. In the HTML there is a di v named #scr ol l er _cont ai ner ,
and within this di v there is a di v named #scr ol l er with a p tag inside. This p tag is where we will insert
the ID3 information. Add the following code within the oni d3( ) method.
1
2
3
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " + i d3s[ cur r ent Song] [ " t heTi t l e" ]
) ;
}
Here we make sure that the i d3s[ cur r ent Song] ! =undef i ned for good housekeeping measures, and if it is
not then we set the $( " #scr ol l er p" ) text to the current songs ID3 information.
You can test now and should see the ID3 information being displayed. It is not moving yet, and the text
extends beyond the di v, but we will fix that in the following steps.
Step 21: Using the jScroller Plugin
The jScroller plugin allows us to make the text scroll along within a di v. We will be wiring up the jScroller
plugin in this step.
Before we can use the jScroller plugin we need to set it up. Add the following within $( document ) . r eady( ) :
01
02
03
04
05
06
07
08
09
10
$( document ) . r eady( f unct i on( ) {
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
var t heMP3;
var cur r ent Song =0;
var t r acks = [ " 1" , " 2" , " 3" , " 4" , " 5" ] ;
var i d3s=[ ] ;
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) ;
$j Scr ol l er . cache. i ni t = t r ue; / / Tur n of f def aul t Event
$j Scr ol l er . conf i g. r ef r esh = 100;
Here we are initializing the j Scr ol l er plugin, by passing the two di vs to it and setting the direction and
speed. We set the cache. i ni t property to true, which disables the default events, and set the
conf i g. r ef r esh to 100 milliseconds, which determines how frequently it refreshes the display.
By default the Autoscroller will stop when you leave the window or the document and start again when you
access the window or document again. In some cases it could be that you want to stop the Scroller with
these Default Events, so you can turn them off with $j Scr ol l er . cache. i ni t .
If you test now you will see the text does not extend beyond the di v any more. So with that fixed, lets get
it moving!
Add the following code changes within the oni d3 method:
01
02
03
04
05
06
07
08
09
10
11
oni d3: f unct i on( ) {
ar t i st = t hi s. i d3[ " TPE1" ] ;
t i t l e = t hi s. i d3[ " TI T2" ] ;
i d3s. push( {t heAr t i st : ar t i st , t heTi t l e: t i t l e}) ;
$j Scr ol l er . st op( ) ;
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " +
i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;
}
var t =set Ti meout ( st ar t Scr ol l er , 2000) ;

}
Here we are stopping the j Scr ol l er by calling j Scr ol l er . st op( ) . We then use
set Ti meout ( st ar t Scr ol l er , 2000) , which waits two seconds then calls the st ar t Scr ol l er ( ) function which
we will code next. This gives a short delay between the time the text shows and starts moving.
Add the following within $( document ) . r eady( )
01
02
03
04
05
06
07
08
09
10
11
$( document ) . r eady( f unct i on( ) {
soundManager . ur l = ' swf ' ;
soundManager . f l ashVer si on = 8;
/ / . . . . . .
/ / . . . . . .
$( " #pr ogr essbar " ) . pr ogr essbar ( {
val ue: 0
}) ;
f unct i on st ar t Scr ol l er ( ) {
$j Scr ol l er . st ar t ( ) ;
}
Here we are just telling the j Scr ol l er plugin to start.
Now if you test, the text starts scrolling after two seconds. You will notice when you change songs that the
text just changes no matter where it is at; if it is halfway across then the new text shows up halfway
across. This looks quite bad, but we will fix it in the next step.
Step 22: Modifying the jScroller plugin
The jScroller plugin does not have a method to reset itself, but we can get the source code and add our
own reset functionality. You can grab the source from Google Code. Once you have downloaded this
J avaScript file, put it in the js folder. You will also need to update the HTML file to point to this file from
now on.
1
2
3
4
5
<scr i pt t ype=" t ext / j avascr i pt " sr c=" j s/ j quer y- 1. 7. 1. mi n. j s" ></ scr i pt >
<scr i pt t ype=" t ext / j avascr i pt " sr c=" j s/ j quer y- ui - 1. 8. 17. cust om. mi n. j s" ></ scr i pt >
<scr i pt t ype=" t ext / j avascr i pt " sr c=" j s/ j scr ol l er - 0. 4- sr c. j s" ></ scr i pt >
<scr i pt sr c=" j s/ soundmanager 2- j smi n. j s" ></ scr i pt >
<scr i pt t ype=" t ext / j avascr i pt " sr c=" j s/ mp3pl ayer . j s" ></ scr i pt >
Now open the jScroller src file you just downloaded, and add the following after pause: f unct i on( ) :
01
02
03
04
05
06
07
08
09
10
11
12
13
pr i vat e f unct i on demonst r at e( ) : voi d
pause: f unct i on( obj , st at us) {
i f ( obj && t ypeof st at us ! == ' undef i ned' ) {
f or ( var i i n $j Scr ol l er . conf i g. obj ) {
i f ( $j Scr ol l er . conf i g. obj [ i ] . chi l d. at t r ( " i d" ) === obj . at t r ( " i d" ) ) {
$j Scr ol l er . conf i g. obj [ i ] . pause = st at us;
}
}
}
},
r eset : f unct i on( ) {
$j Scr ol l er . conf i g. obj =[ ] ;
},
What we are doing here is clearing out the conf i g. obj . Then all we have to do is instaintiate a new
$j Scr ol l er object. This will become clear in the code below.
Add the following within the oni d3( ) method.
01
02
03
04
05
06
07
08
09
10
11
12
oni d3: f unct i on( ) {
ar t i st = t hi s. i d3[ " TPE1" ] ;
t i t l e = t hi s. i d3[ " TI T2" ] ;
i d3s. push( {t heAr t i st : ar t i st , t heTi t l e: t i t l e}) ;
$j Scr ol l er . st op( ) ;
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " +
i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;
}
$j Scr ol l er . r eset ( ) ;
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) ;
var t =set Ti meout ( st ar t Scr ol l er , 2000) ;
}
As you can see we call our newly created $j Scr ol l er . r eset ( ) function, and since we cleared everything
out, we need to create a new $j Scr ol l er by calling
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) .
If you test now you will see the text resets itself no more changing halfway through. Pretty sweet, eh?
Step 23: Stopping the $jScroller
Whenever we press the stop button the text keeps scrolling. It would be nice to make the text stop as well.
Add the following code to the $( " #st op_bt n" ) . cl i ck( ) .
1
2
3
4
5
6
7
8
$( " #st op_bt n" ) . cl i ck( f unct i on( ) {
t heMP3. st op( ) ;
$j Scr ol l er . st op( ) ;
$( " #pl ay_bt n" ) . at t r ( " sr c" , " i mages/ pl ay_but t on. png" ) ;
$( t hi s) . at t r ( " sr c" , " i mages/ st op_sel ect ed. png" ) ;
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
While we are here, lets do the same thing for the pause button. Add the following code to
$( " #pause_bt n" ) . cl i ck( ) :
1
2
3
4
5
6
7
8
$( " #pause_bt n" ) . cl i ck( f unct i on( ) {
$( " #pl ay_bt n" ) . at t r ( " sr c" , " i mages/ pl ay_but t on. png" ) ;
$( t hi s) . at t r ( " sr c" , " i mages/ pause_sel ect ed. png" ) ;
t heMP3. pause( ) ;
$j Scr ol l er . st op( ) ;
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Thats all well and good, but now we need to start again when we press play. We do this in the next step.
Step 24: Starting the $jScroller
This is easy enough. Add the following code to the $( " #pl ay_bt n" ) . cl i ck( ) :
01
02
03
04
05
06
07
08
09
10
$( " #pl ay_bt n" ) . cl i ck( f unct i on( ) {
var t hebut t on = $( t hi s) ;
i f ( t hebut t on. at t r ( " sr c" ) ==" i mages/ pl ay_but t on. png" ) {
t hebut t on. at t r ( " sr c" , " i mages/ pl ay_sel ect ed. png" ) ;
pl aySound( ) ;
$j Scr ol l er . st ar t ( ) ;
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Test it out here.
Step 25: Continous Play
As of right now when a song ends we have to press the forward button to go to the next song. It would be
nice to have the MP3 player automatically advance. That is just what we will do in this step.
SoundManager has an onf i ni sh( ) function that gets called when the current song finishes playing. Add the
following code beneath the oni d3 function:
01
02
03
04
05
06
07
oni d3: f unct i on( ) {
ar t i st = t hi s. i d3[ " TPE1" ] ;
t i t l e = t hi s. i d3[ " TI T2" ] ;
i d3s. push( {t heAr t i st : ar t i st , t heTi t l e: t i t l e}) ;
$j Scr ol l er . st op( ) ;
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " +
i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
}
$j Scr ol l er . r eset ( ) ;
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) ;
var t =set Ti meout ( st ar t Scr ol l er , 2000) ;
},
onf i ni sh: f unct i on( ) {
cur r ent Song++;
pl aySound( ) ;
$j Scr ol l er . st op( ) ;
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " +
i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;
}

$j Scr ol l er . r eset ( ) ;
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) ;
var t =set Ti meout ( st ar t Scr ol l er , 2000) ;

al er t ( i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;

}
Make sure you add the comma after the closing brace of the oni d3 function.
Here all we are doing is incrementing the cur r ent Song variable and calling pl aySound( ) . You will notice that
it uses the same logic that the oni d3( ) function uses to r eset ( ) and add( ) a new $j Scr ol l er . The reason
we have to do it in the f i ni sh( ) function as well as the oni d3( ) function, is that oni d3( ) only gets called
once for each song. If we happen to go through all the songs without this code here, then text would not
change on the next round. This is why we made the i d3s array, so we could have a cache of the artist and
title.
Now if you test and let the songs play all the way through it should advance to the next song
automatically.
Step 26: Forward and Back Buttons
Now that we are playing through all the songs, pressing the forward and back buttons presents the same
problem the onf i ni sh( ) function had. Since we went through all the songs we need to pull in the ID3s from
the i d3s array. So once again we will use the same code.
This is starting to get a bit messy, so lets create a function that contains the relevant code. Add the
following above the st ar t Scr ol l er ( ) function:
01
02
03
04
05
06
07
08
09
10
11
12
13
f unct i on updat eAr t i st ( ) {
$j Scr ol l er . st op( ) ;
i f ( i d3s[ cur r ent Song] ! =undef i ned) {
$( " #scr ol l er p" ) . t ext ( i d3s[ cur r ent Song] [ " t heAr t i st " ] + " : " +
i d3s[ cur r ent Song] [ " t heTi t l e" ] ) ;
}

$j Scr ol l er . r eset ( ) ;
$j Scr ol l er . add( " #scr ol l er _cont ai ner " , " #scr ol l er " , " l ef t " , 2) ;
var t =set Ti meout ( st ar t Scr ol l er , 2000) ;
}
f unct i on st ar t Scr ol l er ( ) {
$j Scr ol l er . st ar t ( ) ;
}
We have seen this code a few times by now, so there is no need to explain it. All we need to do is add it to
the forward and back buttons. Add the following code in the $( " #f wd_bt n" ) . cl i ck( ) :
01
02
03
04
05
$( " #f wd_bt n" ) . cl i ck( f unct i on( ) {
i f ( t heMP3 ! =undef i ned) {
t heMP3. st op( ) ;
cur r ent Song++;
pl aySound( ) ;
06
07
08
09
10
updat eAr t i st ( )
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
And add the following within the $( " #back_bt n" ) . cl i ck( ) .
01
02
03
04
05
06
07
08
09
10
$( " #back_bt n" ) . cl i ck( f unct i on( ) {
i f ( t heMP3 ! = undef i ned) {
t heMP3. st op( ) ;
cur r ent Song- - ;
pl aySound( ) ;
updat eAr t i st ( ) ;
}
}) . mouseover ( f unct i on( ) {
$( t hi s) . css( " cur sor " , " poi nt er " ) ;
}) ;
Now if you test the forward and back buttons they should change the text as well.
Step 27:Clean up onid3() and onfinish
Now that we have made the updat eAr t i st ( ) function, lets go back and remove all that unnecessary code
from the oni d3( ) and onf i ni sh( ) functions. Change the oni d3( ) function to the following:
1
2
3
4
5
6
oni d3: f unct i on( ) {
ar t i st = t hi s. i d3[ " TPE1" ] ;
t i t l e = t hi s. i d3[ " TI T2" ] ;
i d3s. push( {t heAr t i st : ar t i st , t heTi t l e: t i t l e}) ;
updat eAr t i st ( ) ;
},
And change the onf i ni sh( ) function as follows.
1
2
3
4
5
onf i ni sh: f unct i on( ) {
cur r ent Song++;
pl aySound( ) ;
updat eAr t i st ( ) ;
}
That is much better.
Step 28: Your Homework
Right now, if you press the pause or stop button, their images change to the selected image. But when you
press play again they do not change back to the regular image. Make it so when you press play, the pause
and stop buttons change back to the unselected image.
Conclusion
Using SoundManager 2 we have coded a sweet little J avaScript MP3 Player. I could have used HTML5
Audio, but we would have lost the ID3 functionality, and so would have had to hard-code all of our artists
and titles. SoundManager automatically uses HTML5 Audio for the iDevices (iPhone, iPod, iPad), so if you
are looking for a J avaScript sound library to use for your HTML5 iPad apps, maybe you should consider
SoundManager.
I hope youve found this tutorial helpful, and thanks for reading!
J ames Tyner
J ames Tyner loves to program in all kinds of languages during the day.At night he spends his time playing
semi-professional guitar with his band.When hes not programming or playing guitar he can be found at the
local Starbucks sipping on a Venti Coffee and reading a good book.
See more content from this author

Das könnte Ihnen auch gefallen