views:

45

answers:

2

I am trying to make a simple mp3 player using flash. The songs are loaded using an XML file which contains the song list. I have "play" button with the instance name "PlayBtn". I have an actionscript file named "playctrl", the content of which are listed below:

package classes
{
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.events.*;
    import flash.events.MouseEvent;
    import flash.net.URLRequest; 

    public class playctrl
    {
        private var MusicLoading:URLRequest;                        
        private var music:Sound;
        private var sc:SoundChannel;
        private var currentSound:Sound;
        private static var CurrentPos:Number;                               
        private var xml:XML;
        private var songlist:XMLList;                               
        private static var currentIndex:Number;                     

        public function playctrl()
        {
            music = new Sound();
            currentSound= music;
            CurrentPos = 0;
            currentIndex = 0;   
        }

        public function success(e:Event):void 
        {
            xml = new XML(e.target.data);
            songlist = xml.song;
            MusicLoading = new URLRequest(songlist[0].file);
            music.load(MusicLoading);
        }

        public function playSong(e:Event):void 
        {
            if(sc != null)
                sc.stop();

            sc = currentSound.play(CurrentPos);
            trace("HELLO !!!");
        }

    }
}

I have a second file named "play.as", the content of which is listed below:

import classes.playctrl;

var obj:playctrl = new playctrl();
var XMLLoader:URLLoader = new URLLoader();          //XML Loader

XMLLoader.addEventListener(Event.COMPLETE, obj.success);
XMLLoader.load(new URLRequest("playlist.xml"));

PlayBtn.addEventListener(MouseEvent.CLICK, obj.playSong);

However on clicking the play button, I notice that the function playSong() is called 7-8 times(check by printing an error msg. inside the function) resulting in overlapped audio output and the player crashing as a result. The function should be called only once when the MouseEvent.CLICK is triggered. Please help ...

A: 

Edit:

The title of your question is a bit misleading, the answer I gave you is a solution to the question expressed in the title.

Looking at your code, I would look at separating the concerns, on one hand you want to load the song data, on the other hand you want to control the sounds. I would implement separate classes for each concern. If you create a separate class for your player control, you'll be able to dispatch event within that class without the event bubbling all over your app and calling your functions several times.

//Previous answer You could do this by implementing a Boolean that would be set when the sound is stopped or played.

In any case here's another way to filter unwanted clicks

 private function playSong(event:MouseEvent ):void
 {
     // set up a conditional to identify your button , 
     // here's an example...
     if( event.currentTarget.name is "PlayBtn" )
     {
         //do whatever
         //then...
         event.stopImmediatePropagation();
      }

  }

This being said, in your case , it sounds like a bit of a quick fix since a MouseEvent shouldn't trigger the play function several times...

It would make sense to debug your code in order to understand why several events are dispatched after a Mouse click

 private var _isPlaying:Boolean;

 public function playSong(e:Event):void 
 {
   if(sc != null)
   {
      sc.stop();
      _isPlaying = false;
   }

   if( !_isPlaying )
   {
      sc = currentSound.play(CurrentPos);
      _isPlaying = true;
      trace("HELLO !!!");
   }
 }
PatrickS
That is hardly the problem ... the function itself is being called multiple times with one mouse click ...
Ayan Sen
Your code doesn't say enough to identify exactly what the problem is. I did point out in my answer that the solution given was only a quick fix. There could be several way to fix this problem , you could try event.stopPropagation , you could create a specific class for your PlayButton where you would have more control about the event flow. It's difficult to tell without knowing how the play button is added to the stage.
PatrickS
A: 

interestingly, sound object doesn't have a built-in "isPlaying" boolean property (strange), so you could just create your own.

var isPlaying:Boolean

function playSong():void
     {
     if(!isPlaying)
       sound.play();
     }

function stopSong():void
     {
     if(isPlaying)
       {
       channel.stop();
       isPlaying = false;
       }

just a note: by convention, class names are capitalized camel case while instance names are uncapitalized camel case. so your playctrl.as class file should (or could) be PlayCtrl.as, and your PlayBtn instance should (or could) be playBtn.

TheDarkInI1978
That is hardly the problem ... the function itself is being called multiple times with one mouse click ...
Ayan Sen