Copy link to clipboard
Copied
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:

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;
}
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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 95 | 1059: Property is read-only. |
(refereing to "my_channel.position=duration_mc.slider1.m*duration_mc.slider1.thumbbar.x+duration_mc.slider1.b"
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
{
{
Copy link to clipboard
Copied
that loop is problematic and should not be used.
Copy link to clipboard
Copied
do you have better idea or code?
Copy link to clipboard
Copied
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);
}
Copy link to clipboard
Copied
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);
}
}
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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...
Copy link to clipboard
Copied
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;
}
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more