Here is the link to the tutorial:
http://forums.ultrashock.com/ff.htm?http://forums.ultrashock.com/forums/showthread.php?s=&postid=708395
This application had no playlist functionality, so i added one.
Here is the code with the mp3player and playlist (i won't go thru explaining how it works, you can find that on the utltrashock tutorial):
import Library;
import mx.transitions.Tween;
import mx.transitions.easing.*;
class MusicPlayer
{
//---------------------------------------------------------------------------
// Class Properties
//---------------------------------------------------------------------------
//Target/Path to the player movieclip.
private var __path:MovieClip;
//As a shortcut to XML I've decided to define track(s) information in an object.
private var __tracks:Object;
//Allows for use of Sound class methods, such as attachSound and start.
//You can't listen to audio without a Sound object.
private var __music:Sound;
//Current track position (in milliseconds)
private var __position:Number;
//Current track volume (on a ratio of 0 to 100). Without this property each
//track would automatically start with a volume of 100.
private var __volume:Number = 100;
//Used to determine if pause has been executed or not. If so play will
//perform different actions to start from the paused position.
private var __paused:Boolean = false;
//ID of current track
private var __trackid:Number;
private var listTrackId:Number
//---------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------
//Every classes constructor is automatically run when an instance
//of the class is created.
function MusicPlayer(path:MovieClip, tracks:Object, init:Number)
{
//Sets constructor variables to the corresponding class properties.
__path = path;
__tracks = tracks;
__trackid = (init-1);
//Attaches actions to all UI controls.
setupUI();
//Begins playing the initial track.
loadNextTrack();
//Constantly updates scale of position and load bar.
positionBar();
loadBar();
loadPlaylist()
}
//---------------------------------------------------------------------------
// Class methods
//---------------------------------------------------------------------------
private function changeVolume():Void
{
var target = __path.volume;
//Sets volume property to the ratio between where the bar was pressed and it's total width.
__volume = (target._xmouse/target._width)*100;
//Slides bar to corresponding scale based on above ratio.
var tween = new Tween(target.mask, "_xscale", Back.easeOut, target.mask._xscale, __volume, 10);
var slider = new Tween(__path.slider_btn, "_x", Back.easeOut, __path.slider_btn._x, (__path.volume._x+target._xmouse)-(__path.slider_btn._width/2), 10);
//Updates volume of the track.
__music.setVolume(__volume);
}
private function setupUI():Void
{
//Attaches onRollOver events for all UI controls.
//A loop is used because all UI events excluding onRelease are the same.
for(var i in __path.controls)
{
__path.controls[i].onRollOver = function()
{
this.gotoAndStop("hover");
}
__path.controls[i].onRollOut = function()
{
this.gotoAndStop("up");
}
}
__path.controls.play_btn.onRelease = __path.controls.play_btn.onReleaseOutside = Library.delegate(this, "playTrack");
__path.controls.pause_btn.onRelease = __path.controls.pause_btn.onReleaseOutside = Library.delegate(this, "pauseTrack");
//Plays the previous or next track. The next track is determined using the getTrackID method.
__path.controls.prev_btn.onRelease = __path.controls.prev_btn.onReleaseOutside = Library.delegate(this, "loadPrevTrack");
__path.controls.next_btn.onRelease = __path.controls.next_btn.onReleaseOutside = Library.delegate(this, "loadNextTrack");
__path.volume.onPress = Library.delegate(this, "changeVolume");
}
private function pauseTrack():Void
{
__paused = true;
updateUIStatus();
//Remembers position when paused. This is needed for when the track is re-started
//so that it knows what position to start from.
__position = __music.position;
__music.stop();
}
private function getTrackID(direction:Number):Number
{
var id = __trackid;
//Adds direction (-1 is previous and 1 is next) to the current track ID.
id += direction;
//Instead of stopping at the first or last track, loop.
if(id < 0)
{
//Sets ID to the last track ID if less than zero.
id += __tracks["titles"].length;
}
else
{
//Sets ID to the first track ID if greater than total tracks.
id %= __tracks["titles"].length;
}
return id;
}
//Updates status of the play and pause buttons according to if paused or not
private function updateUIStatus():Void
{
if(__paused)
{
__path.controls.play_btn.enabled = true;
__path.controls.play_btn.gotoAndStop("up");
__path.controls.pause_btn.gotoAndStop("hover");
__path.controls.pause_btn.enabled = false;
}
else
{
__path.controls.pause_btn.enabled = true;
__path.controls.pause_btn.gotoAndStop("up");
__path.controls.play_btn.gotoAndStop("hover");
__path.controls.play_btn.enabled = false;
}
}
private function playTrack():Void
{
//Checks if track is paused. If so start from pause position, otherwise start from the beginning.
if(__paused)
{
__music.start(__position/1000);
__paused = false;
updateUIStatus();
}
else
{
__music.start();
}
}
private function beginLoad(id:Number):Void
{
__trackid = id;
//Resets sound. Without this position and duration will output the values
//from the first track loaded.
__music = new Sound();
//When track is finished playing, play the next one.
__music.onSoundComplete = Library.delegate(this, "loadNextTrack");
//Starts streaming track
__music.loadSound(__tracks["urls"][id], true);
__music.setVolume(__volume);
__paused = false;
updateUIStatus();
//Populates title and artist textfields with new track data.
__path.title_txt.text = __tracks["titles"][id].toUpperCase();
__path.artist_txt.text = __tracks["artists"][id].toUpperCase();
//Resets position and load bar scale.
__path.track.mask._xscale = __path.track.load_mask._xscale = 0;
__path.playlist.selectedIndex = id
}
private function loadNextTrack():Void
{
//Starts loging the next track. The next tracks ID is processed by the getTrackID
//method to enable looping.
beginLoad(getTrackID(1));
}
private function loadPrevTrack():Void
{
beginLoad(getTrackID(-1));
}
private function positionBar():Void
{
//Constantly updates bar scale.
__path.track.mask.onEnterFrame = Library.delegate(this, "updatePositionBar");
}
private function updatePositionBar():Void
{
//Finds percentage loaded of the track loading
var percent = (__music.getBytesLoaded()/__music.getBytesTotal())*100;
if(percent > 0)
{
__path.track.mask._xscale = __music.position/(__music.duration/percent);
}
}
private function loadBar():Void
{
__path.track.load_mask.onEnterFrame = Library.delegate(this, "updateLoadBar");
}
private function updateLoadBar():Void
{
var percent = (__music.getBytesLoaded()/__music.getBytesTotal())*100;
if(percent > 0)
{
__path.track.load_mask._xscale = percent;
}
}
//Returns ID of the current track playing.
public function get trackid()
{
return __trackid;
}
private function loadPlaylist()
{
playlistStyle()
// adds a default icon to the list's items (you need to have an mc in the library with an instance nam of "playlistIcon")
//playlist.defaultIcon = "playlistIcon"
// populate the playlist
for(var i:Number=0; i<__tracks["titles"].length; i++)
{
var trackInfo:String = __tracks["artists"][i] + " - " + __tracks["titles"][i];
__path.playlist.addItem(trackInfo, i)
}
// create listener to detect change in the list
var owner:MusicPlayer = this
var listListener:Object = new Object();
listListener.change = function(evt_obj:Object)
{
owner.listTrackId = evt_obj.target.selectedIndex
owner.playlistSelectedTrack()
}
__path.playlist.addEventListener("change", listListener)
// select initial track
__path.playlist.selectedIndex = 0
}
private function playlistSelectedTrack()
{
beginLoad(listTrackId)
}
private function playlistStyle()
{
// adds style to the playlist
var arrListColors:Array = new Array(0xA3E3FE, 0xD5F2FF)
__path.playlist.alternatingRowColors = arrListColors
__path.playlist.rollOverColor = 0xFFFF2B
__path.playlist.selectionColor = 0x008ECC
}
}