Getting started
First I'll just go through what we need to complete this tutorial:
I've used the 3rd party class Caurina Tweener to tween elements on the screen. This is not required because you can use Flash's own tween class to do the same job. Mind you, if you're not familiar with Caurina I suggest you to take a look. Tween Lite is another 3rd party tweener you might have heard of. It's a very powerful tween class which you could also use for this project if you wanted. You can find Caurina Tweener in the source code.
- The source code includes one mp3 file that we'll need: Tarzan's mighty yell :). You can also use your own mp3 if you like.
- Also in the source code you'll find the directory "ai" which contains the simplemp3player.ai file. This file includes all the graphics for the player.
- Lastly I've included font that we need. It's called 04b03 and it's a bitmap font. Install it and you're ready to go.
Step 1: Create New File
First you need to create a new Flash Actionscript 3.0 document. You don't need to adjust any document properties.
Go to Flash > Preferences > AI file importer on Mac or Edit > Preferences > AI file importer on Windows. Make sure you have the following settings:
Save it and give it the name "SimpleMP3Player.fla". Also copy the directory "caurina" and "tarzan.mp3" to same place as your .fla file.
Step 2: Import Illustrator File
Now we're ready to import the Illustrator file. Go to File > Import > Import to Stage. Locate "simplemp3player.ai" from the source package "ai" directory, press OK and you'll get the screen as shown below. Set the Convert to layers "Flash layers" so you get all the layers contained within the ai file directly to Flash. The next two options, as shown in the image, place all the artwork to same coordinates as in ai file and resize your Flash document exactly to size that we need.
When you click OK in the import dialog your document should look like the image shown above.
Step 3: Create the Button Sprite
You probably noticed play and pause buttons in the last image. Those are going to be our button sprite that controls the sound. All the buttons are grouped into one group.
Select only buttons group and press F8 to get the "Convert to symbol" screen. Give it the name "buttons" and make sure you've selected MovieClip as the type. Set the registration to the top left corner and click OK. Switch to the Properties panel and give the object a instance name "buttons". The image below illustrates these steps visually:
We have our buttons in one movieclip, but the mask is not included. We need one more movieclip to bind them all together.
Select the buttons movieclip and the mask object. Again press F8 and now give it a name of "buttonSprite". Also remember to give it a instance name. This time "bs" (I know what you're thinking, but this is an abbreviation of ButtonSprite).
Step 4: Manual Masking
Now our button sprite is almost ready to rock. All we need to do is mask it so that it shows just one button at a time.
Double-click your buttonSprite movieclip. Create a new layer above the active layer and name it "mask". Select the mask object and cut it using "Cmd + X" on Mac or "Ctrl + X" on Windows. Select the mask layer and paste using "Cmd + V" on Mac or "Ctrl + V" on Windows. It doesn't matter where your mask object is because next we align it to right place.
With your mask still selected open up the Align panel(Window > Align) and make sure the "To stage" button is pressed down. Now press the "Align top edge" and "Align left edge" buttons and your mask object should now be in the correct position, the top left corner of your movieclip.
The only thing remaining to do is mask the buttons. Right-click above the mask layer and choose Mask.
You can see the effect instantly; only one button is visible.
Step 5: Start Creating the Display
Let's forget the buttons for a while and focus on the MP3 player's display. I'll show you how to build this display element manually. It could be done with AS3, of course, but let's do it manually this time.
First select the mask element from mask layer. Convert it to a movieclip and give it the name "displayMask". Use this name as the instance name too. The mask for display is ready, so hide the layer. Next, create a layer between the buttons layer and the mask layer. Name it "text". Select the Text tool from the Tools palette and use the options shown in the image below:
Step 6: Add Textfields to Display
We need textfields to show our information (artist, song name, loading percentage and song length). We'll create textfields manually to the stage.
First draw textfieds on the text layer as shown in the image below. Convert all three textfields in to one single movieclip called "playerTexts". Create one more textfield and call it "preloader". You don't need to convert this to a movieclip.
Step 7: Complete the Display
All we need to do is include our new loader-textfield and playerTexts-movieclip in one movieclip so we can control texts as and when we like.
Select the loader-textfield and playerTexts-movieclip and press F8. Give it a name and an instance name of "display". Now we've completed our display hierarchy, it should look like this:
To write a data example to songInfo-textfield we have to write the following line of code:
- display.playerTexts.songInfo.text = 'This is where we put the artist and song name';
display.playerTexts.songInfo.text = 'This is where we put the artist and song name';
So now we have every graphical element ready that we need for the MP3 Player. Next we'll jump deep into the code, so dive with me!
Step 8: Create Document Class File
To get the code to work we need to create the document class. Document class code is executed first when .swf files play. You don't need to write your code to the timeline anymore and your class is easier to import to another .fla file in the future if it's needed.
Go to File > New. Select "Actionscript file" from the window which opens and click OK. Save the file to the same folder as your .fla file and name it "SimpleMP3Player.as".
Now assign your new .as file as document class. Click the stage and go to the Properties panel. There you'll find the "Class" field where you need to enter the class name you've created. Enter "SimpleMP3Player" and click the small pencil button. If you spelled the class name correctly the "SimpleMP3Player.as" file should become active. Otherwise Flash will throw an error.
Step 9: The Code
Code brings everything to life. Here's the completed ActionScript, I'll explain it block by block. Check also the source code from the source package, I've commented it from beginning to end.
- package
- {
- import flash.display.MovieClip;
- import flash.events.Event;
- import flash.events.EventDispatcher;
- import flash.events.IOErrorEvent;
- import flash.events.MouseEvent;
- import flash.events.ProgressEvent;
- import flash.events.TimerEvent;
- import flash.media.Sound;
- import flash.media.SoundChannel;
- import flash.media.ID3Info;
- import flash.net.URLRequest;
- import flash.utils.Timer;
- import flash.text.TextField;
- import flash.text.TextFieldAutoSize;
- import caurina.transitions.Tweener;
-
- public class SimpleMP3Player extends MovieClip
- {
-
- private var mp3File:Sound;
- private var mp3FilePosition:SoundChannel;
- private var id3Data:ID3Info;
- private var id3InfoAvailable = false;
-
- private var updateTime:Timer;
-
- private var playingSound:Boolean = false;
- private var soundPosition:Number;
- private var songReachedEnd:Boolean = false;
-
- private var buttonPos:Array = new Array('0', '-36', '-72', '-108', '-144', '-180', '-216', '-252');
-
- public function SimpleMP3Player()
- {
- display.playerTexts.x = -73;
- display.mask = displayMask;
-
- bs.buttons.buttonMode = bs.buttons.enabled = false;
- bs.buttons.y = buttonPos[3];
-
- loadMP3();
- }
-
- private function loadMP3():void
- {
- mp3File = new Sound();
- mp3File.addEventListener(ProgressEvent.PROGRESS, mp3FileLoading);
- mp3File.addEventListener(Event.COMPLETE, mp3FileLoaded);
- mp3File.addEventListener(IOErrorEvent.IO_ERROR, errorLoadingSound);
-
- mp3File.addEventListener(Event.ID3, getID3Data);
- mp3File.load(new URLRequest('tarzan.mp3'));
-
- Tweener.addTween(display.preloader, {x: 96, time:1});
- }
-
- private function mp3FileLoading(e:ProgressEvent):void
- {
- var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
- display.preloader.text = 'LOADING...' + currentPercent + '%';
-
- if (currentPercent > 50 && id3InfoAvailable)
- {
- Tweener.addTween(display.preloader, {x: 200, time:1, onComplete:playMP3, onCompleteParams:[false, 0]});
- mp3File.removeEventListener(ProgressEvent.PROGRESS, mp3FileLoading);
- }
- }
-
- private function mp3FileLoaded(e:Event):void
- {
- mp3File.removeEventListener(Event.COMPLETE, mp3FileLoaded);
- mp3File.removeEventListener(ProgressEvent.PROGRESS, updateBufferField);
- Tweener.addTween(display.playerTexts.buffer, {x: 200, time:1});
- }
-
- private function errorLoadingSound(e:IOErrorEvent):void
- {
- trace('Error loading sound: ' + e);
- }
-
- private function getID3Data(e:Event):void
- {
- id3InfoAvailable = true;
- id3Data = mp3File.id3;
- }
-
- private function playMP3(useSp:Boolean, sp:Number):void
- {
- if (useSp) mp3FilePosition = mp3File.play(sp);
- else mp3FilePosition = mp3File.play();
-
- playingSound = true;
- mp3FilePosition.addEventListener(Event.SOUND_COMPLETE, songFinished);
- mp3File.addEventListener(ProgressEvent.PROGRESS, updateBufferField);
-
- bs.buttons.buttonMode = bs.buttons.enabled = true;
- bs.buttons.y = buttonPos[0];
-
- bs.buttons.addEventListener(MouseEvent.MOUSE_OVER, mouseOverBs);
- bs.buttons.addEventListener(MouseEvent.MOUSE_OUT, mouseOutBs);
- bs.buttons.addEventListener(MouseEvent.CLICK, mouseClickBs);
-
- updateTime = new Timer(100);
- updateTime.addEventListener(TimerEvent.TIMER, getMP3Time);
- updateTime.start();
-
- var si:String = id3Data.artist + ' - ' + id3Data.songName;
- si = si.toUpperCase();
- display.playerTexts.songInfo.autoSize = TextFieldAutoSize.LEFT;
- display.playerTexts.songInfo.wordWrap = false;
- display.playerTexts.songInfo.text = si;
-
- Tweener.addTween(display.playerTexts, {x: 60, time:1});
- }
-
- private function updateBufferField(e:ProgressEvent):void
- {
- var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
- display.playerTexts.buffer.text = currentPercent + '%';
- }
-
- private function getMP3Time(e:TimerEvent):void
- {
- var totalMinutes = Math.floor(mp3File.length / 1000 / 60);
- var totalSeconds = Math.floor(mp3File.length / 1000) % 60;
- var currentMinutes = Math.floor(mp3FilePosition.position / 1000 / 60);
- var currentSeconds = Math.floor(mp3FilePosition.position / 1000) % 60;
-
- if (totalSeconds < totalseconds =" if (currentSeconds < currentseconds ="
- display.playerTexts.times.text = currentMinutes + ':' + currentSeconds + '/' + totalMinutes + ':' + totalSeconds;
- }
-
- private function songFinished(e:Event):void
- {
- mp3FilePosition.removeEventListener(Event.SOUND_COMPLETE, songFinished);
- updateTime.removeEventListener(TimerEvent.TIMER, getMP3Time);
-
- bs.buttons.y = buttonPos[3];
- mp3FilePosition.stop();
-
- playingSound = false;
- songReachedEnd = true;
-
- soundPosition = 0;
- display.playerTexts.times.text = 'PLAY AGAIN?';
- }
-
-
-
-
-
- private function mouseOverBs(e:MouseEvent):void
- {
- if (playingSound) bs.buttons.y = buttonPos[5];
- else bs.buttons.y = buttonPos[1];
-
- if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[1];
- }
-
- private function mouseOutBs(e:MouseEvent):void
- {
- if (playingSound) bs.buttons.y = buttonPos[0];
- else bs.buttons.y = buttonPos[4];
-
- if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[3];
- }
-
- private function mouseClickBs(e:MouseEvent):void
- {
- if (playingSound)
- {
- bs.buttons.y = buttonPos[4];
- soundPosition = mp3FilePosition.position;
- updateTime.stop();
- mp3FilePosition.stop();
- playingSound = false;
- display.playerTexts.times.text = 'PAUSE';
- }
- else if (!playingSound)
- {
- bs.buttons.y = buttonPos[2];
- playMP3(true, soundPosition);
- playingSound = true;
-
- }
- else if (songReachedEnd)
- {
- songReachedEnd = false;
- playMP3(false, 0);
- }
- }
- }
- }
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.ID3Info; import flash.net.URLRequest; import flash.utils.Timer; import flash.text.TextField; import flash.text.TextFieldAutoSize; import caurina.transitions.Tweener; public class SimpleMP3Player extends MovieClip { // Create some variables that we need private var mp3File:Sound; private var mp3FilePosition:SoundChannel; private var id3Data:ID3Info; private var id3InfoAvailable = false; private var updateTime:Timer; private var playingSound:Boolean = false; private var soundPosition:Number; private var songReachedEnd:Boolean = false; private var buttonPos:Array = new Array('0', '-36', '-72', '-108', '-144', '-180', '-216', '-252'); public function SimpleMP3Player() { display.playerTexts.x = -73; display.mask = displayMask; bs.buttons.buttonMode = bs.buttons.enabled = false; bs.buttons.y = buttonPos[3]; loadMP3(); } private function loadMP3():void { mp3File = new Sound(); mp3File.addEventListener(ProgressEvent.PROGRESS, mp3FileLoading); mp3File.addEventListener(Event.COMPLETE, mp3FileLoaded); mp3File.addEventListener(IOErrorEvent.IO_ERROR, errorLoadingSound); mp3File.addEventListener(Event.ID3, getID3Data); mp3File.load(new URLRequest('tarzan.mp3')); Tweener.addTween(display.preloader, {x: 96, time:1}); } private function mp3FileLoading(e:ProgressEvent):void { var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100); display.preloader.text = 'LOADING...' + currentPercent + '%'; if (currentPercent > 50 && id3InfoAvailable) { Tweener.addTween(display.preloader, {x: 200, time:1, onComplete:playMP3, onCompleteParams:[false, 0]}); mp3File.removeEventListener(ProgressEvent.PROGRESS, mp3FileLoading); } } private function mp3FileLoaded(e:Event):void { mp3File.removeEventListener(Event.COMPLETE, mp3FileLoaded); mp3File.removeEventListener(ProgressEvent.PROGRESS, updateBufferField); Tweener.addTween(display.playerTexts.buffer, {x: 200, time:1}); } private function errorLoadingSound(e:IOErrorEvent):void { trace('Error loading sound: ' + e); } private function getID3Data(e:Event):void { id3InfoAvailable = true; id3Data = mp3File.id3; } private function playMP3(useSp:Boolean, sp:Number):void { if (useSp) mp3FilePosition = mp3File.play(sp); else mp3FilePosition = mp3File.play(); playingSound = true; mp3FilePosition.addEventListener(Event.SOUND_COMPLETE, songFinished); mp3File.addEventListener(ProgressEvent.PROGRESS, updateBufferField); bs.buttons.buttonMode = bs.buttons.enabled = true; bs.buttons.y = buttonPos[0]; bs.buttons.addEventListener(MouseEvent.MOUSE_OVER, mouseOverBs); bs.buttons.addEventListener(MouseEvent.MOUSE_OUT, mouseOutBs); bs.buttons.addEventListener(MouseEvent.CLICK, mouseClickBs); updateTime = new Timer(100); updateTime.addEventListener(TimerEvent.TIMER, getMP3Time); updateTime.start(); var si:String = id3Data.artist + ' - ' + id3Data.songName; si = si.toUpperCase(); display.playerTexts.songInfo.autoSize = TextFieldAutoSize.LEFT; display.playerTexts.songInfo.wordWrap = false; display.playerTexts.songInfo.text = si; Tweener.addTween(display.playerTexts, {x: 60, time:1}); } private function updateBufferField(e:ProgressEvent):void { var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100); display.playerTexts.buffer.text = currentPercent + '%'; } private function getMP3Time(e:TimerEvent):void { var totalMinutes = Math.floor(mp3File.length / 1000 / 60); var totalSeconds = Math.floor(mp3File.length / 1000) % 60; var currentMinutes = Math.floor(mp3FilePosition.position / 1000 / 60); var currentSeconds = Math.floor(mp3FilePosition.position / 1000) % 60; if (totalSeconds < totalseconds =" '0'" currentseconds =" '0'" text =" currentMinutes" y =" buttonPos[3];" playingsound =" false;" songreachedend =" true;" soundposition =" 0;" text =" 'PLAY" y =" buttonPos[5];" y =" buttonPos[1];" y =" buttonPos[1];" y =" buttonPos[0];" y =" buttonPos[4];" y =" buttonPos[3];" y =" buttonPos[4];" soundposition =" mp3FilePosition.position;" playingsound =" false;" text =" 'PAUSE';" y =" buttonPos[2];" playingsound =" true;" songreachedend =" false;">Step 10: Basic Package Code
- package
- {
-
-
-
- public class SimpleMP3Player extends MovieClip
- {
- public function SimpleMP3Player()
- {
-
- }
- }
- }
package { // Place where all the class imports goes public class SimpleMP3Player extends MovieClip { public function SimpleMP3Player() { } } }
Our start point looks like the example above. Remember that the class name should be same as your document class file name. Everything inside the public function SimpleMP3Player executes right after Flash has loaded our class.
Step 11: Import Required Classes
Let's import all the classes that our MP3 player needs to work properly.
- package
- {
- import flash.display.MovieClip;
- import flash.events.Event;
- import flash.events.EventDispatcher;
- import flash.events.IOErrorEvent;
- import flash.events.MouseEvent;
- import flash.events.ProgressEvent;
- import flash.events.TimerEvent;
- import flash.media.Sound;
- import flash.media.SoundChannel;
- import flash.media.ID3Info;
- import flash.net.URLRequest;
- import flash.utils.Timer;
- import flash.text.TextField;
- import flash.text.TextFieldAutoSize;
- import caurina.transitions.Tweener;
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.ID3Info; import flash.net.URLRequest; import flash.utils.Timer; import flash.text.TextField; import flash.text.TextFieldAutoSize; import caurina.transitions.Tweener;
Everything should be quite straight forward. In the last line we import Caurina Tweener. Make sure you have the caurina directory in the same location as your .fla file.
Step 12: Declare Variables
All variables are private. Only the SimpleMP3Player class can use them.
- private var mp3File:Sound;
- private var mp3FilePosition:SoundChannel;
private var mp3File:Sound; private var mp3FilePosition:SoundChannel;
The mp3File sound object stores our Tarzan.mp3 sound. mp3FilePosition is a SoundChannel object. We need it to tell us current mp3File position in milliseconds. With this object we can also stop the mp3 file.
- private var id3Data:ID3Info;
- private var id3InfoAvailable = false;
private var id3Data:ID3Info; private var id3InfoAvailable = false;
The id3Data object stores mp3 sounds id3 information. For example, the song name and name of the artist. id3InfoAvailable tells our preloader that id3 info is available so code can start to play mp3File.
- private var updateTime:Timer;
private var updateTime:Timer;
updateTime is our timer object that updates the display times-textfield. You can find more info about the Timer class here. I'll go through this later.
- private var playingSound:Boolean = false;
- private var soundPosition:Number;
- private var songReachedEnd:Boolean = false;
private var playingSound:Boolean = false; private var soundPosition:Number; private var songReachedEnd:Boolean = false;
playingSound is simply a boolean variable that tell us if mp3File is currently playing. soundPosition stores a numeric value when users push the Pause button so we can continue playing music from the paused position when user clicks the Play button. songReachedEnd indicates that song has finished playing.
-
-
-
-
-
-
-
-
-
-
-
- private var buttonPos:Array = new Array('0', '-36', '-72', '-108', '-144', '-180', '-216', '-252');
/* * buttonPos[0] = playUp * buttonPos[1] = playOver * buttonPos[2] = playDown * buttonPos[3] = playDis * buttonPos[4] = pauseUp * buttonPos[5] = pauseOver * buttonPos[6] = pauseDown * buttonPos[7] = pauseDis */ private var buttonPos:Array = new Array('0', '-36', '-72', '-108', '-144', '-180', '-216', '-252');
Finalyl, last but not least, our array variable that holds the buttons movieclip y coordinates. For example:
- bs.buttons.y = buttonsPos[4];
bs.buttons.y = buttonsPos[4];
The pause button is then showed on the screen. If you use 0 inside the [brackets] you'll see the Play button.
Step 13: Masking with Code
It's time to see what our code does first when it's loaded. Let's handle the first function in our code; the SimpleMP3Player function.
- public function SimpleMP3Player()
- {
- display.mask = displayMask;
- display.playerTexts.x = -73;
public function SimpleMP3Player() { display.mask = displayMask; display.playerTexts.x = -73;
the SimpleMP3Player function is a constructor function so it has to be public. Renaming it to private causes an error. Functions' default state is public so you don't necessarily have to write "public" before the function.
Masking with code is very easy and straight forward. On line 3 you see code for the masking. We just assign the "displayMask" movieclip to the "display" movieclip's mask property. That's it.
Second property display.playerTexts.x relocates the "playerTexts" movieclip along the horizontal axis. We simply move it out of sight to coordinate -73. Mask hides "playerTexts" movieclip.
Step 14: Methods, Button Modes and BS
- bs.buttons.buttonMode = bs.buttons.enabled = false;
- bs.buttons.y = buttonPos[3];
bs.buttons.buttonMode = bs.buttons.enabled = false; bs.buttons.y = buttonPos[3];
"buttons" is a movieclip and by default when mouse hovers over it, the cursor stays as a basic arrow. Setting the "buttonMode" property to true turns the cursor into a hand when the mouse is hovering over. In the beginning we want that cursor as an arrow so buttonMode is set to false. On the same line we set the "enabled" property to false. That means that the "buttons" movieclip isn't clickable. In line 2 we set the "buttons" movieclip position to disabled play button.
The first line can be confusing, but if I write it like this...
- bs.buttons.buttonMode = false;
- bs.buttons.enabled = false;
bs.buttons.buttonMode = false; bs.buttons.enabled = false;
...you can probably see it more clearly. I save space by writing it in one line.
All we do now is call our "loadMP3" method.
loadMP3();
Step 15: loadMP3 Method
This method is our main method. What it does is load the mp3-file, declare necessary EventListeners and slide the preloader to display.
mp3File = new Sound();
This line creates a new Sound object. We can access all Sound class methods and properties through mp3File.
- mp3File.addEventListener(ProgressEvent.PROGRESS, mp3FileLoading);
- mp3File.addEventListener(Event.COMPLETE, mp3FileLoaded);
- mp3File.addEventListener(IOErrorEvent.IO_ERROR, errorLoadingSound);
-
- mp3File.addEventListener(Event.ID3, getID3Data);
mp3File.addEventListener(ProgressEvent.PROGRESS, mp3FileLoading); mp3File.addEventListener(Event.COMPLETE, mp3FileLoaded); mp3File.addEventListener(IOErrorEvent.IO_ERROR, errorLoadingSound); mp3File.addEventListener(Event.ID3, getID3Data);
The first line declares PROGRESS event and every time the event is invoked it calls the mp3FileLoading method. This listener has a few properties which we need. First is bytesTotal which holds the whole size of the mp3-file in bytes. Second is bytesLoaded which holds the currently loaded bytes. With these two properties we can count the percentage that file has loaded and display it for the user.
The second line invokes when the entire mp3-file has loaded. It calls mp3FileLoaded method.
The third line is for error handling. For example, if and mp3-file isn't found, this event invokes. It calls errorLoadingSound method.
In line 5 the event is invoked when id3-data is available. It calls getID3Data method.
- mp3File.load(new URLRequest('tarzan.mp3'));
mp3File.load(new URLRequest('tarzan.mp3'));
"load" method loads our Tarzan mp3-file. Inside brackets we declare a new URLReaquest and inside it is the path to our mp3-file. Our path is relative and tarzan.mp3 must be in same location as the .fla and .as files. This line is the same as below. Use whichever one you prefer.
- var req:URLRequest = new URLRequest('tarzan.mp3');
- mp3File.load(req);
var req:URLRequest = new URLRequest('tarzan.mp3'); mp3File.load(req);
This is first time we are using Caurina, so I'll quickly demonstrate how it works.
- Tweener.addTween(target, {properties});
Tweener.addTween(target, {properties});
This is the base code. Target is where you write the name of the target object which you want to tween. In properties you define what you want to do with the target. You can modify, for example, the x and y coordinates, transparency, scale or rotation.
- Tweener.addTween(display.preloader, {x: 96, time:1});
Tweener.addTween(display.preloader, {x: 96, time:1});
Our target is the "preloader" textfield inside the "display" movieclip. Property "x" moves it and the "time" property indicates the time that the tween takes. Time is measured in seconds. If you want milliseconds use ".5" notation.
Step 16: mp3FileLoading Event Method
- private function mp3FileLoading(e:ProgressEvent):void
- {
- var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
- display.preloader.text = 'LOADING...' + currentPercent + '%';
-
- if (currentPercent > 50 && id3InfoAvailable)
- {
- Tweener.addTween(display.preloader, {x: 200, time:1, onComplete:playMP3, onCompleteParams:[false, 0]});
- mp3File.removeEventListener(ProgressEvent.PROGRESS, mp3FileLoading);
- }
- }
private function mp3FileLoading(e:ProgressEvent):void { var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100); display.preloader.text = 'LOADING...' + currentPercent + '%'; if (currentPercent > 50 && id3InfoAvailable) { Tweener.addTween(display.preloader, {x: 200, time:1, onComplete:playMP3, onCompleteParams:[false, 0]}); mp3File.removeEventListener(ProgressEvent.PROGRESS, mp3FileLoading); } }
As I mentioned earlier, the "mp3FileLoading" method shows a percentage value of how much the mp3-file has been loaded. It also starts the song whenthe percentage climbs higher than 50%.
currentPercent is for counting the percentage value. We round it up with the "Math.round" method. Line 4 writes the percentage value to our textfield so the user can see what's happening with loading.
Inside the "if" statement we check if the percentage is above 50 and the "id3InfoAvailable" variable is true. If both return true, the "if" statement executes everything inside the brackets.
When the if statement is true, we tween the "preloader" textfield away. When the tween is complete, Caurina calls the "playMP3" method and passes two properties to it. We see the "playMP3" method in the next step.
The PROGRESS event is no longer needed, so we remove it on line 9.
Step 17: mp3FileLoaded Event Method
- private function mp3FileLoaded(e:Event):void
- {
- mp3File.removeEventListener(Event.COMPLETE, mp3FileLoaded);
- mp3ile.removeEventListener(ProgressEvent.PROGRESS, updateBufferField);
- Tweener.addTween(display.playerTexts.buffer, {x: 200, time:1});
- }
private function mp3FileLoaded(e:Event):void { mp3File.removeEventListener(Event.COMPLETE, mp3FileLoaded); mp3ile.removeEventListener(ProgressEvent.PROGRESS, updateBufferField); Tweener.addTween(display.playerTexts.buffer, {x: 200, time:1}); }
This method is invoked when the whole song is loaded. First we remove unnecessary EventListeners. In line 5 we tween the "buffer" textfield to the right.
Step 18: ErrorLoadingSound Event Method
- private function errorLoadingSound(e:IOErrorEvent):void
- {
- trace('Error loading sound: ' + e);
- }
private function errorLoadingSound(e:IOErrorEvent):void { trace('Error loading sound: ' + e); }
This error handling is really basic. It only traces errors if errors occur.
Step 19: getID3Data Event Method
- private function getID3Data(e:Event):void
- {
- id3InfoAvailable = true;
- id3Data = mp3File.id3;
- }
private function getID3Data(e:Event):void { id3InfoAvailable = true; id3Data = mp3File.id3; }
We set "id3InfoAvailable" to true in line 3. The "mp3FileLoading" method checks this variable every time and starts the sound only if it's true. This way we ensure that id3 info is available so the user sees real info on the display.
In line 4 we assign mp3File id3 metadata to ID3Info object named id3Data which we created in Step 12.
Step 20: playMP3 Method
This method is the more vital method in our player. Let's look at the first block.
- private function playMP3(useSp:Boolean, sp:Number):void
- {
- if (useSp) mp3FilePosition = mp3File.play(sp);
- else mp3FilePosition = mp3File.play();
private function playMP3(useSp:Boolean, sp:Number):void { if (useSp) mp3FilePosition = mp3File.play(sp); else mp3FilePosition = mp3File.play();
The "playMP3" method requires two properties. "useSp" indicates "use sound position" and "sp" is "sound position".
In line 3 we test if "useSp" is true. If so, the code plays our song starting from the desired point. This point is passed in the "sp" property. If false, we start playing the song from the beginning. All this is related to the play-pause button.
- playingSound = true;
- mp3FilePosition.addEventListener(Event.SOUND_COMPLETE, songFinished);
- mp3File.addEventListener(ProgressEvent.PROGRESS, updateBufferField);
playingSound = true; mp3FilePosition.addEventListener(Event.SOUND_COMPLETE, songFinished); mp3File.addEventListener(ProgressEvent.PROGRESS, updateBufferField);
Line 1 sets the playingSound to true. Now we can check if the sound is playing and do what ever is necessary.
New EventListener in line 2 fires up every time the song finishes playing. The "songFinished" method is executed. Notice that we add EventListener to mp3FilePosition object.
Second new EventListener in line 3 adds the same "PROGRESS" event to mp3File as in the start of code. This listener just fires up a different method. The "updateBuffer" method is for updating the "buffer" textfield.
- bs.buttons.buttonMode = bs.buttons.enabled = true;
- bs.buttons.y = buttonPos[0];
bs.buttons.buttonMode = bs.buttons.enabled = true; bs.buttons.y = buttonPos[0];
The first line you'll already find familiar. Our mp3-file is playing so we can update buttons to show the appropriate state, enable "buttonMode" and "enabled" properties.
We use "Timer" to show the current sound position in seconds. With "Timer" you can execute methods in time sequences.
- updateTime = new Timer(100);
- updateTime.addEventListener(TimerEvent.TIMER, getMP3Time);
- updateTime.start();
updateTime = new Timer(100); updateTime.addEventListener(TimerEvent.TIMER, getMP3Time); updateTime.start();
Here, the first line creates a new "Timer" object with 100 milliseconds interval. You may wonder why we want to update the current time every 100 millisecs.. 1 second is too slow for our player and even 0.5 seconds is too slow. I want it to update time really smoothly. More on Timer-class.
We also need an EventListener to actually do something every 100 milliseconds. "TIMER" event executes the "getMP3Time" method that I'll go through in the next step.
Line 4 starts our "Timer".
- var si:String = id3Data.artist + ' - ' + id3Data.songName;
- si = si.toUpperCase();
- display.playerTexts.songInfo.autoSize = TextFieldAutoSize.LEFT;
- display.playerTexts.songInfo.wordWrap = false;
- display.playerTexts.songInfo.text = si;
-
- Tweener.addTween(display.playerTexts, {x: 60, time:1});
var si:String = id3Data.artist + ' - ' + id3Data.songName; si = si.toUpperCase(); display.playerTexts.songInfo.autoSize = TextFieldAutoSize.LEFT; display.playerTexts.songInfo.wordWrap = false; display.playerTexts.songInfo.text = si; Tweener.addTween(display.playerTexts, {x: 60, time:1});
In the last block we show the id3 metadata to the user. Artist name and song name are pushed to a new variable in the first line. This is because I want to capitalize the entire string in the next line. We're using the bitmap font, so I think it just looks better in uppercase.
In line 3 we ensure that the "songInfo" textfield is long enough to show the "si" string. Line 4 is to avoid the word wrapping in the textfield and in line 5 we simply assign the "si" string to thee "songInfo" textfield.
The last line slides the "playerTexts" movieclip to "display".
Step 21: updateBufferField Method
It's polite to show the user how much the mp3-file data is loaded. We have our preloader, but I thought we'd need also a buffer field because our song starts to play after 50% is loaded. This method continues where "mp3FileLoading" method left off.
- private function updateBufferField(e:ProgressEvent):void
- {
- var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
- display.playerTexts.buffer.text = currentPercent + '%';
- }
private function updateBufferField(e:ProgressEvent):void { var currentPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100); display.playerTexts.buffer.text = currentPercent + '%'; }
There is nothing special here, just a private function with two lines of action. Basic percentage counting and assigning it to the "buffer" textfield.
Step 22: getMP3Time Event Method
I show this method all at once because this is just math and really basic coding.Let's go it through anyway.
- private function getMP3Time(e:TimerEvent):void
- {
- var totalMinutes = Math.floor(mp3File.length / 1000 / 60);
- var totalSeconds = Math.floor(mp3File.length / 1000) % 60;
- var currentMinutes = Math.floor(mp3FilePosition.position / 1000 / 60);
- var currentSeconds = Math.floor(mp3FilePosition.position / 1000) % 60;
-
- if (totalSeconds < totalseconds =" if (currentSeconds < currentseconds ="
- display.playerTexts.times.text = currentMinutes + ':' + currentSeconds + '/' + totalMinutes + ':' + totalSeconds;
- }
private function getMP3Time(e:TimerEvent):void { var totalMinutes = Math.floor(mp3File.length / 1000 / 60); var totalSeconds = Math.floor(mp3File.length / 1000) % 60; var currentMinutes = Math.floor(mp3FilePosition.position / 1000 / 60); var currentSeconds = Math.floor(mp3FilePosition.position / 1000) % 60; if (totalSeconds < totalseconds =" '0'" currentseconds =" '0'" text =" currentMinutes">In the first 4 lines we count times that we need. This is a bit tricky because all returning values are in milliseconds. We also round minutes and seconds down.
Line 8 and 9 are for adding an extra zero before seconds if those values are below 10 (this is only tweaking and not required). For me the "time" textfield then looks a bit cleaner.
The last line shows the whole time to user.
Step 23: songFinished Event Method
Let's continue with the very basic code.
- private function songFinished(e:Event):void
- {
- mp3FilePosition.removeEventListener(Event.SOUND_COMPLETE, songFinished);
- updateTime.removeEventListener(TimerEvent.TIMER, getMP3Time);
-
- bs.buttons.y = buttonPos[3];
- mp3FilePosition.stop();
-
- playingSound = false;
- songReachedEnd = true;
-
- soundPosition = 0;
- display.playerTexts.times.text = 'PLAY AGAIN?';
- }
private function songFinished(e:Event):void { mp3FilePosition.removeEventListener(Event.SOUND_COMPLETE, songFinished); updateTime.removeEventListener(TimerEvent.TIMER, getMP3Time); bs.buttons.y = buttonPos[3]; mp3FilePosition.stop(); playingSound = false; songReachedEnd = true; soundPosition = 0; display.playerTexts.times.text = 'PLAY AGAIN?'; }
The "songFinished" event method is launched every time the song finishes playing.
In the first two lines we remove unnecessary EventListeners. Next we show the disabled play-button to the user and stop the mp3-file. Stopping is not required, but we do it just in case.
"playingSound" is set to false and "songReachedEnd" to true. In nthe ext step you see why we need the "songReachedEnd" variable.
"soundPosition" is accessible from anywhere in our class so it has to be set to 0 at this point. Now we ensure that if the user wants to play thee song again it starts from the beginning.
The last line sets the "times" textfield to show "PLAY AGAIN?" text. Our users are the kings, that's why we need to give all possible information to them.
Step 24: mouseOverBs and mouseOutBs Event Methods
- private function mouseOverBs(e:MouseEvent):void
- {
- if (playingSound) bs.buttons.y = buttonPos[5];
- else bs.buttons.y = buttonPos[1];
-
- if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[1];
- }
private function mouseOverBs(e:MouseEvent):void { if (playingSound) bs.buttons.y = buttonPos[5]; else bs.buttons.y = buttonPos[1]; if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[1]; }
Here the "mouseOverBs" method is fired everytime the mouse goes over the "bs" movieclip.
First these event methods check if "playingSound" is true and if the "buttons" movieclip is in the "pause over" state. Otherwise it shows the "play over" state. Our last line checks if the sound has finished playing and it's waiting if the user wants to play the song again.
- private function mouseOutBs(e:MouseEvent):void
- {
- if (playingSound) bs.buttons.y = buttonPos[0];
- else bs.buttons.y = buttonPos[4];
-
- if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[3];
- }
-
private function mouseOutBs(e:MouseEvent):void { if (playingSound) bs.buttons.y = buttonPos[0]; else bs.buttons.y = buttonPos[4]; if (songReachedEnd && !playingSound) bs.buttons.y = buttonPos[3]; }
This other method is for when the mouse leaves above the "bs" movieclip.
This is similar to the method before.
Step 25: mouseClickBs Event Method
This event method is the heart of our "bs" movieclip's click function.
- if (playingSound)
- {
- bs.buttons.y = buttonPos[4];
- soundPosition = mp3FilePosition.position;
- updateTime.stop();
- mp3FilePosition.stop();
- playingSound = false;
- display.playerTexts.times.text = 'PAUSE';
if (playingSound) { bs.buttons.y = buttonPos[4]; soundPosition = mp3FilePosition.position; updateTime.stop(); mp3FilePosition.stop(); playingSound = false; display.playerTexts.times.text = 'PAUSE';
When you click the button it first checks if sound is playing. If so, it relocates the "buttons" movieclip, stores current sound position (where we can continue to play from if we want), stops our "Timer", stops our song, sets "playingSound" to false and updates "times" textfield text to "PAUSE". This block of code is our pause-button.
- else if (!playingSound)
- {
- bs.buttons.y = buttonPos[2];
- playMP3(true, soundPosition);
- playingSound = true;
-
- }
else if (!playingSound) { bs.buttons.y = buttonPos[2]; playMP3(true, soundPosition); playingSound = true; }
This code block starts our song from the pause-state. It checks that our song is not playing and starts the song from stored "soundPosition".
- else if (songReachedEnd)
- {
- songReachedEnd = false;
- playMP3(false, 0);
- }
else if (songReachedEnd) { songReachedEnd = false; playMP3(false, 0); }
The last block checks that if the song has finished playing and the user wants to play song again, it starts the song from the beginning.
Conclusion
SimpleMP3Player is now complete...(as far as I'm concerned). Now it's your turn to add some features to it. Maybe you want to add a stop-button or maybe give it playlist features with XML. Make "songInfo" textfield scrollable so longer data is showed completely. The possibilities are endless!
Don't forget to check the source code in the source package. I have commented the code from beginning to end so you can learn this tut in that way too. Thanks for reading!
source from : flash tuts+
0 nhận xét:
Post a Comment