Aug 22, 2007

Playlist functionality for Mp3Player

Yesterday i runned into a mp3 tutorial on ultrashock.com made by Julian Wilson - Neverrain.net. Which is a simple application that can load and play mp3's with simple buttons functionality (of play/pause/stop/next/previous) and a nice volume control.
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
}
}

May 10, 2007

OBJECT DOCK

Finaly you may install and use a a good free MAC fish-eye menu on your Windows System !!

"ObjectDock™ is a program that enables users to organize their shortcuts, programs and running tasks into an attractive and fun animated Dock. By allowing users to have more control over how they organize their desktop, users can take control of their desktop icons and shortcuts to have them be available when where and how they need them. This, all with the unique style and top-rate performance that ObjectDock is known to deliver!"

Download here, it's FREE (Plus version available for $19.95)
http://www.stardock.com/products/objectdock/

May 8, 2007

Hey! my first post

Olla every flash head !
This is the first Flashy blog post, so keep it close,
new fresh posts comming right up :)