After creating a Simple FLV Player using ActionScript 3.0, I decided to extend my learning by going through the process of creating a simple MP3 player using ActionScript 3.0 and Flex 2. For requirements, all I wanted my MP3 player to do was play from a static list of MP3 files and have controls allowing me to play, pause, stop, go to the next song in playlist, and go to a previous song in the playlist. I have seen quite a few of these floating around the internet, so I figured it should be pretty easy and, as expected, it was.
If you like MP3s, you might be interested in music lessons too. Find out if piano lessons or guitar lessonsright for you today.might be
Prerequisites:
Flex 2 SDK: http://www.adobe.com/products/flex/sdk/
Public Domain MP3 Files: http://www.publicdomain4u.com/
1) Install Flex 2 SDK
After downloading the flex_sdk_2.zip, I just unzipped the contents in to a work folder, c:\flex_sdk_2. The key resources I used from this package with were the compiler, bin\mxmlc.exe, and the debug Flash player (player\debug\SAFlashPlayer.exe).
2) I generated the following source in my favorite text editor, please note that I decided to go with the “source is the documentation” style of documentation for what and why I did:
The ActionScript source for the mp3 player class, SimpleSimpleMP3Player.as:
package {
import mx.containers.Panel;
import mx.controls.Button;
import flash.events.*;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.utils.Timer;
public class SuperSimpleMP3Player extends Panel {
// Song List
private var songURLs:Array =["SongFromCottonField.MP3, "Bill_Cox--My_Rough_and_Rowdy_Ways.mp3", "Robert_Johnson-Love_In_Vain.mp3", "Andy_Iona-Naughty_Hula_Eyes.mp3", "AtlantaBound.MP3", "MamieSmithHerJazzHounds-CrazyBlues.mp3"];
// Current Song to Play
private var currentIndex:Number = 0;
// Sound Channel to monitor
private var song:SoundChannel;
// Request object for obtaining mp3
private var request:URLRequest
// Pause state management
private var paused:Boolean = true;
// Stopped state management
private var stopped:Boolean = false;
// Retains what position the song was in
// when it was paused, so we can go back to
// the same position when we hit play again.
private var position:Number;
// Sound... Factory for initializing our song.
private var soundFactory:Sound;
// The magic var that allows us to set the actual
// implementation of the play button from the Flex
// MXML. This allows a custom component, see
// SimpleMP3.mxml, to set the actual button that
// playButton referres to, letting us change the
// label, or any other property of the button in
// our ActionScript.
public var playButton:Button;
public function SuperSimpleMP3Player() {
super();
playMP3(currentIndex);
}
// Play MP3 at specified index in songURLs array.
public function playMP3(mp3Index:Number):void {
stopped = false;
paused = false;
position = 0;
var request:URLRequest = new URLRequest(songURLs[mp3Index]);
soundFactory = new Sound();
soundFactory.addEventListener(Event.ID3, id3Handler);
soundFactory.load(request);
song = soundFactory.play();
song.addEventListener(Event.SOUND_COMPLETE,
soundCompleteHandler);
}
// Since the id3 information is not available until it
// is read off the string we need to make sure we have
// a way of updating the UI once it has been loaded.
// Having songName as a bindable allows us to do that,
// and the id3Handler will notify us when the information
// is ready to be displayed.
[Bindable("songNameChanged")]
public function get songName():String {
return soundFactory.id3.artist + " - " + soundFactory.id3.songName;
}
// Alert songNameChanged bind when id3 information
// has been loaded.
private function id3Handler(event:Event):void {
dispatchEvent(new Event("songNameChanged"));
}
// Start the next song, once the current one has
// finished playing.
private function soundCompleteHandler(event:Event):void {
position = 0;
currentIndex++;
if (currentIndex >= songURLs.length) {
currentIndex = 0;
}
playMP3(currentIndex);
}
// Pause current song, or play song if already paused.
// Setting playButton label such that any GUI button
// that is attached will change with play or pause.
public function pause():void {
if (!stopped) {
if (!paused) {
paused = true;
position = song.position;
song.stop();
playButton.label = ">";
} else {
paused = false;
song = soundFactory.play(position);
song.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
playButton.label = "||";
}
} else {
playMP3(currentIndex);
playButton.label = "||";
}
}
// Stop current song
public function stop():void {
stopped = true;
song.stop();
position = 0;
playButton.label = ">";
}
// Switch to Next Song
public function next():void {
currentIndex++;
if (currentIndex >= songURLs.length) {
currentIndex = 0;
}
song.stop();
position = 0;
// Track if player was already playing,
// paused, or stopped. If stopped or
// paused, still "play" so we can start
// streaming and obtain the id3 info.
var wasStopped:Boolean = stopped;
var wasPaused:Boolean = paused;
playMP3(currentIndex);
if (wasStopped) {
stop();
return;
}
if (wasPaused) {
paused = true;
position = song.position;
song.stop();
}
}
// Switch to Previous Song
public function prev():void {
currentIndex--;
if (currentIndex < 0) {
currentIndex = songURLs.length - 1;
}
song.stop();
position = 0;
// Track if player was already playing,
// paused, or stopped. If stopped or
// paused, still "play" so we can start
// streaming and obtain the id3 info.
var wasStopped:Boolean = stopped;
var wasPaused:Boolean = paused;
playMP3(currentIndex);
if (wasStopped) {
stop();
return;
}
if (wasPaused) {
paused = true;
position = song.position;
song.stop();
}
}
}
}
The MXML for the custom mp3 player component, SimpleMP3.mxml:
<?xml version="1.0"?> <!-- SimpleMP3.mxml --> <custom:SuperSimpleMP3Player xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:custom="*">
<mx:Label text="{String(songName)}"/>
<mx:ControlBar horizontalAlign="center">
<mx:Spacer width="100%"/>
<mx:Button id="prevButton" label="<<"
click="prev()"/>
<mx:Button id="pauseButton" label="||" click="pause()"/>
<mx:Button id="stopButton" label="X" click="stop()"/>
<mx:Button id="nextButton" label=">>" click="next()"/>
<mx:Spacer width="100%"/>
</mx:ControlBar>
</custom:SuperSimpleMP3Player>
The MXML for container application, SimpleMP3Player.mxml:
<xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:custom="*" layout="vertical" <custom:SimpleMP3 id="myMP3" headerHeight="0" width="400"/> </mx:Application>
4) From the command line I compiled the file:
c:/flex_sdk_2/learning>../bin/mxmlc.exe -use-network=false SimpleMP3Player.as
Note that I had to use the ‘-use-network=false’ directive. This told the compiler that I will not be using the network in my testing so don’t worry about sandbox issues when trying to load the flv from my local drives. Once I decide, if I decided, to deploy this to a website, I will need to recompile my code without this directive.
6) After compilation succeeded, I loaded the swf in the debug Flash Player:
c:/flex_sdk_2/learning>../player/debug/SAFlashPlayer.exe
SimpleMP3Player.swf
Success. However, please don’t think of this as the only way of doing or even close to the best way of doing. No best practices used here, like supplying some sort of packaging/namespacing for my custom code and components, just me documenting my learning experience.
I do hope this helps a few other with their own learning experiements and if you know of cleaner solutions, please feel free to leave some feedback in my comments section.
For reference, the source can also be downloaded from http://www.kriggio.com/mp3player/SuperSimpleMP3Player.zip
The following link, which may or may not be available depending if I have to take it down due to bandwidth issues, demonstrates the above code: http://www.kriggio.com/mp3player/mp3.html. Streaming mp3s = lots of bandwidth.
Tags: actionscrip 3, Adobe, AS3, code, download, Files, Flash, Flex, mp3, player, Resources, Source, Tips, Tutorial
July 25th, 2007 at 7:02 pm
This is very helpful. I created a frame-based jukebox last christmas (http://jukebox.marymcgivern.com/)and now want to update it in 3.0 scripting. Your documentation helps with that process.
August 11th, 2007 at 10:22 pm
I have tried to build an mp3 player almost according to the same principle, using ac3.0 in flash CS3.
Application works fine on desktop. But in browser firefox, I get this error Error #2044: Unhandled IOErrorEvent:. text=Error #2032: Stream Error.
So i added s.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); where s is sound. Now i am getting this error but music won’t play.
Please help
Thanks
Irfan
October 5th, 2007 at 10:57 am
I just downloaded and working on it.
November 8th, 2007 at 9:52 pm
Man, you should really use the `code` and `pre` tags in HTML so your example doesn’t look so terrible.
December 10th, 2007 at 3:46 pm
Very useful for learning basic mxml component structure, and adding ear-candy to my first flex-app. Thanks man. You really helped me out! *two thumbs up*
December 30th, 2007 at 5:49 am
Thank you very much! This article is very helpful!
February 21st, 2008 at 5:16 pm
I’ve created something similar using Flash. Take a look here, fla file included.
http://jared.simplistika.com/actionscript-3-xml-mp3-player/
March 26th, 2008 at 4:29 am
Thank you , nice read . Actually i am completely new to flex and since i know c++ and c# this article seems to be easy . Just the mxml i need to concentrate .
May 19th, 2008 at 8:57 am
wow thanks! how about with volume control and xml playlist. thanks
July 18th, 2008 at 11:12 am
Thanks a lot
August 25th, 2008 at 1:45 pm
Thanks for the code!
I just walked through the process you outlined and it works great.
Thanks
-Dave
November 14th, 2008 at 7:46 pm
private var songURLs:Array =[“SongFromCottonField.MP3,
missing a “
November 20th, 2008 at 10:41 am
In case I have an array of binary which is generated from a mp3 file, how can we play it?
Please help
Thanks
December 9th, 2008 at 7:33 am
This was made a while back with AS2. Have a look and let me know what you think. Try loading up a playlist by typing Queen.m3p and loading playlist. (No songs online these days sadly), but you can add your own songs.
This is about 5 years old now, but can dig up the FLA file if anyone is interested.
December 10th, 2008 at 10:05 pm
I am getting this error when i hit the pause button, anyone know why?
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at SuperSimpleMP3Player/pause()[C:\Perforce\Pauline\JeferyLevy\flex\JeferyLevy\src\SuperSimpleMP3Player.as:69]
at simpleMP3/__pauseButton_click()[C:\Perforce\Pauline\JeferyLevy\flex\JeferyLevy\src\simpleMP3.mxml:9]
January 10th, 2009 at 7:26 pm
nice tutorial, any other simple script??
September 7th, 2009 at 5:53 am
I was also getting an error #1009 until I changed the code in “SimpleMP3.mxml” for the pause button as follows:
<mx:Button id="pauseButton" … to <mx:Button id="playButton" …