Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Custom Music Player in AS3?

Engaged ,
Oct 31, 2013 Oct 31, 2013

Hello, I am trying to make a Music Player in Flash.

So far I loaded the Xml data and the buttons all work. However, I cant seem to figure out a way to do a duration slider that moves based on the sounds length property. I also want to make it interactive, (click and drag seeking). In addition I want to make another slider for volume. I have look all over the internet I cant find anything thing programming a CUSTOM slider. Everything on slider control is using the Flash compenets default slider. How can I use my own slider for AS3?

I have a knob called sliderDragger (movieclip) and the bar is set to be masked on by dbMask (movieclip);

Here is a picture of it: 

http://i713.photobucket.com/albums/ww137/macjsus/jukeBox_zps7c7b339e.jpg

Here are my variables:

//XML Song List Vars

var my_songs:XMLList;

var my_total:Number;

//Sound Vars

var my_sound:Sound;

var my_channel:SoundChannel;

//Current Song Vars

var current_song:Number = 0;

//Position, and Pause Vars

var song_position:Number;

var song_paused:Boolean;

//XML Loader

var myXMLLoader:URLLoader = new URLLoader();

myXMLLoader.load(new URLRequest("playlist.xml"));

myXMLLoader.addEventListener(Event.COMPLETE, processXML);

Also does any know how to make an equalizer out of it? I was told that I would need a plug-in like Hype to do a realistic equalizer. I curently have sort of a rig for it but I want it to look more random. Is there a way to create a loop that generates a random number that can be output to different variables, and the randomness is a range of 6 to 30 (or 0 to 30 if is easier)?

Here is my code, I have a movieclip called EQBar, that has an animated bar(30 frames long), duplicated it and gave each one an instance name like:  eqBarLeft1,2,3 and eqBarRight1,2,3, and I basically just said gotoandStop, at random frames in the movieclip. The leftPeak and rightPeak of the SoundChannel (my_channel) is multipled by a random rounded number, that determines the frame that gotoAndStop will apply to, in the EQBar movieclip. I want to create a variable to replace the multiplied numbers, in the following code:

// Set up the onEnterFrame Event for EQ

addEventListener(Event.ENTER_FRAME, eqStart);

function eqStart(event:Event):void {

          // ANIMATED EQ BARS CODE

    eqBarLeft1.gotoAndStop (Math.round(my_channel.leftPeak * 12) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight1.gotoAndStop (Math.round(my_channel.rightPeak * 29) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft2.gotoAndStop (Math.round(my_channel.leftPeak * 17) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight2.gotoAndStop (Math.round(my_channel.rightPeak * 27) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft3.gotoAndStop (Math.round(my_channel.leftPeak * 18) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight3.gotoAndStop (Math.round(my_channel.rightPeak * 22) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft4.gotoAndStop (Math.round(my_channel.leftPeak * 10) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight4.gotoAndStop (Math.round(my_channel.rightPeak * 28) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft5.gotoAndStop (Math.round(my_channel.leftPeak * 19) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight5.gotoAndStop (Math.round(my_channel.rightPeak * 25) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft6.gotoAndStop (Math.round(my_channel.leftPeak * 28) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight6.gotoAndStop (Math.round(my_channel.rightPeak * 26) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft7.gotoAndStop (Math.round(my_channel.leftPeak * 10) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight7.gotoAndStop (Math.round(my_channel.rightPeak * 30) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft8.gotoAndStop (Math.round(my_channel.leftPeak * 25) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight8.gotoAndStop (Math.round(my_channel.rightPeak * 14) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft9.gotoAndStop (Math.round(my_channel.leftPeak * 27) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight9.gotoAndStop (Math.round(my_channel.rightPeak * 12) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft10.gotoAndStop (Math.round(my_channel.leftPeak * 28) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight10.gotoAndStop (Math.round(my_channel.rightPeak * 20) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft11.gotoAndStop (Math.round(my_channel.leftPeak * 11) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight11.gotoAndStop (Math.round(my_channel.rightPeak * 25) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft12.gotoAndStop (Math.round(my_channel.leftPeak * 16) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight12.gotoAndStop (Math.round(my_channel.rightPeak * 12) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft13.gotoAndStop (Math.round(my_channel.leftPeak * 30) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight13.gotoAndStop (Math.round(my_channel.rightPeak * 15) ); // 30 is the amount of frames in our EQbar clips

          eqBarLeft14.gotoAndStop (Math.round(my_channel.leftPeak * 10) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight14.gotoAndStop (Math.round(my_channel.rightPeak * 23) ); // 30 is the amount of frames in our EQbar clips*/

}


I tried one looping variable but it outputs the same number to all it is applied to:

var sum:Number = 0;

while (sum < my_channel.position) {

          trace(rand);

          var rand:Number = Math.random();

          // create a random number between 0 and 1

          sum += rand;

}

TOPICS
ActionScript
1.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 31, 2013 Oct 31, 2013

you can use linear interpolation to define parameters for any slider:

paramF(slider1,0,0,slider1.width-slider1.thumbbar.width,yoursound.length);

// in your loop that checks slider1's thumbbar:

yoursoundchannel.position=slider1.m*slider1.thumbbar.x+slider1.b

function paramF(mc:MovieClip,x1:Number,y1:Number,x2:Number,y2:Number):void{

mc.m=(y1-y2)/(x1-x2);

mc.b=y1-mc.m*x1;

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Oct 31, 2013 Oct 31, 2013

I am confused, what does paramF mean?

I replaced: yoursoundchannel with my_channel, and yoursound with my_sound. And changed the instance name of my sliderDragger movieclip to slider1, which is inside of a movieclip called duration_mc.

and it now looks like this:

paramF(duration_mc.slider1,0,0,duration_mc.slider1.width-duration_mc.slider1.thumbbar.width,my_sound.length);

my_channel.position=duration_mc.slider1.m*duration_mc.slider1.thumbbar.x+duration_mc.slider1.b

function paramF(mc:MovieClip,x1:Number,y1:Number,x2:Number,y2:Number):void{

          mc.m=(y1-y2)/(x1-x2);

          mc.b=y1-mc.m*x1;

}

Then I get this error:

Scene 1, Layer 'Actions', Frame 1, Line 951059: Property is read-only.

(refereing to "my_channel.position=duration_mc.slider1.m*duration_mc.slider1.thumbbar.x+duration_mc.slider1.b"

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 01, 2013 Nov 01, 2013

my error.  replace line 95 with:

my_channel=my_sound.play(duration_mc.slider1.m*duration_mc.slider1.thumbbar .x+duration_mc.slider1.b);

also, make sure there's a thumbbar movieclip in slider1 that's your actual slider thumb.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 01, 2013 Nov 01, 2013

Thanks for the fix.

I figured out a different method, one that I understand a little better, I dont know what paramF means (goolge actually brought me back to this forum page) and and not sure exactly of the slop/ y-intercept formula was gonna make this work.

I made and ENTER_FRAME listener and Event, then made a var for timeMax which rounds out the length of the song to whole numbers. Then a var called curPS which rounds out the current position to whole numbers. Then, a var sliderPos which divides the current position of the song by the songs' length, and multiplied it by 240(the length of my symbol for the bar), then that is applied to the mask on the bar, and slider.

addEventListener(Event.ENTER_FRAME, durSlider);

function durSlider(event:Event):void {

          var timeMax:Number = Math.round(my_sound.length/1000);

          var curPs:Number = Math.round(my_channel.position/1000);

          var sliderPos:Number = Math.round((curPs/timeMax)*240);

          duration_mc.sliderDr_mc.x=sliderPos;

          duration_mc.dbMask.width=sliderPos;

I still have to make it interactive I got some drag functions set up, I just need test and fin tune. Also I still could use some help of the looping random  number generator that can be applied to mutlple instances giving them each a different number, either with the same number or for different variables.  All this with the condition being based on sound.length. I think a timer might work but I have keep messing with it.

Here is the loop I have so far:

while (my_sound.length) {

     trace(rand);

     var rand:Number = Math.random()*30;

    

     {

{

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 01, 2013 Nov 01, 2013

that loop is problematic and should not be used.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 01, 2013 Nov 01, 2013

do you have better idea or code?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 01, 2013 Nov 01, 2013

normally, you would use something like:

var dragRect:Rectangle = new Rectangle(0,0,duration_mc.slider1.width,0)

duration_mc.slider1.thumbbar.addEventListener(MouseEvent.MOUSE_DOWN,sliderDownF);

function sliderDownF(e:MouseEvent):void{

stage.addEventListener(MouseEvent.MOUSE_UP,sliderUpF);

duration_mc.slider1.thumbbar.startDrag(false,dragRect);

this.addEventListener(Event.ENTER_FRAME,sliderF);

}

function sliderUpF(e:MouseEvent):void{

stage.removeEventListener(MouseEvent.MOUSE_UP,sliderUpF);

duration_mc.slider1.thumbbar.stopDrag()

this.removeEventListener(Event.ENTER_FRAME,sliderF);

}

function sliderF(e:Event):void{

my_channel=my_sound.play(duration_mc.slider1.m*duration_mc.slider1.thumbbar .x+duration_mc.slider1.b);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 01, 2013 Nov 01, 2013

What do you recommend I do for the random number generator loop?

And thanks for dragging example, yours is much cleaner than mine.

One problem is that I have been having issues with putting parameters inside of the play(); function.

Like for:

my_channel=my_sound.play(duration_mc.slider1.m*duration_mc.slider1.thu mbbar .x+duration_mc.slider1.b);

I get an error saying: TypeError: Error #1010: A term is undefined and has no properties.

Even for a fast forward button code I wrote, I actually build it based off of the example in the AS3 Bible. But it doesnt like when I put things inside of the play();, paranthesis.

The code:

fwd_btn.addEventListener(MouseEvent.CLICK, fastForward);

function fastForward(event:Event):void {

          if (my_channel) {

          var newPs:int = my_channel.position + skipRate;

          newPs = Math.min(my_sound.length, newPs);

          play(newPs);

          }

}

It just gives me a


Incorrect number of arguments.  Expected no more than 0.

for the last line: play(newPs);

The books example is:

public function fastForward(event:Event = null):void {

if (_channel) {

var newPosition:int = _channel.position + SEARCH_RATE;

newPosition = Math.min(_sound.length, newPosition);

play(newPosition);

}

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 01, 2013 Nov 01, 2013

1. you have to call paramF() to define m and b and you need a thumbbar movieclip in duration_mc.slider1.  use the trace function to debug

2. play(newPs) makes no sense.  you should be applying the play method to your sound (my_sound) like i showed.  or if you use the play method in your sound's class, that will work.

3. what are you trying to do with random numbers?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 01, 2013 Nov 01, 2013

1)My slider1 is the thumbbar, do I have to convert that into another symbol and name it thumb bar?

2)I got the play(newPosition) thing form an Action Script Book called Action Script 3 Bible.

3)I have a movieclip called EQBar, that has an animated bar(30 frames long), duplicated it and gave each one an instance name like: eqBarLeft1,2,3 and eqBarRight1,2,3, and I basically just said gotoandStop, at random frames in the movieclip. The leftPeak and rightPeak of the SoundChannel (my_channel) is multipled by a random(Math.random), rounded (Math.round) number, that determines the frame that gotoAndStop will apply to in the EQBar movieclip. I want to create a variable to replace the multiplied numbers, in the following code:

So in this line:

eqBarLeft1.gotoAndStop (Math.round(my_channel.leftPeak * 12) );

The number 12 is how high it mutplies. I want to replace the numbers like 12 with a var that is a random number, that cycles to other numbers between 0 and 30, over time, until the song is complete.

// Set up the onEnterFrame Event for EQ

addEventListener(Event.ENTER_FRAME, eqStart);

function eqStart(event:Event):void {

          // ANIMATED EQ BARS CODE

    eqBarLeft1.gotoAndStop (Math.round(my_channel.leftPeak * 12) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight1.gotoAndStop (Math.round(my_channel.rightPeak * 29) ); // 30 is the amount of frames in our EQbar clips

    eqBarLeft2.gotoAndStop (Math.round(my_channel.leftPeak * 17) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight2.gotoAndStop (Math.round(my_channel.rightPeak * 27) ); // 30 is the amount of frames in our EQbar clips

    eqBarLeft3.gotoAndStop (Math.round(my_channel.leftPeak * 18) ); // 30 is the amount of frames in our EQbar clips

    eqBarRight3.gotoAndStop (Math.round(my_channel.rightPeak * 22) ); // 30 is the amount of frames in our EQbar clips

ECT...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 02, 2013 Nov 02, 2013
LATEST

it doesn't matter where you got that play code except to say it's a reputable source so my comment about it appearing in a sound class is applicable.  anyway, it's not going to work the way you're using it.

if i understand your setup correct, duration_mc is your slider movieclip and slider1 is a child of duration_mc that is your thumbbar.  if that's the case, use:

paramF(duration_mc,0,0,duration_mc.width-duration_mc.slider1.width,yoursound.length);

var dragRect:Rectangle = new Rectangle(0,0,duration_mc.width,0)

duration_mc.slider1.addEventListener(MouseEvent.MOUSE_DOWN,sliderDownF);

function sliderDownF(e:MouseEvent):void{

stage.addEventListener(MouseEvent.MOUSE_UP,sliderUpF);

duration_mc.slider1.startDrag(false,dragRect);

this.addEventListener(Event.ENTER_FRAME,sliderF);

}

function sliderUpF(e:MouseEvent):void{

stage.removeEventListener(MouseEvent.MOUSE_UP,sliderUpF);

duration_mc.slider1.stopDrag()

this.removeEventListener(Event.ENTER_FRAME,sliderF);

}

function sliderF(e:Event):void{

my_channel=my_sound.play(duration_mc.m*duration_mc.slider1.x+duration_mc.b);

}

function paramF(mc:MovieClip,x1:Number,y1:Number,x2:Number,y2:Number):void{

mc.m=(y1-y2)/(x1-x2);

mc.b=y1-mc.m*x1;

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines