Skip navigation
AS3ForTheWin
Currently Being Moderated

MP3 Player Problems

Aug 7, 2012 8:55 AM

Tags: #as3 #button #xml #as3.0 #mp3

OK Guys, so I tried to make a MP3 player from a tutorial here http://www.republicofcode.com/tutorials/flash/as3musicplayer/

 

The player and the play, pause, next, previous etc. functions work just fine, but I want to make some improvements

 

1/I want to have a fully-functional loadbar and seekbar for the player

 

2/Could it be possible? I want the player to automatically plays a movie clip(that shows the next song in the playlist) at the last 10 second of every song

 

3/I want to merge both the play and pause buttons, so as to save space

 

Please guys I'm new to AS3 and all these event listeners thingy (because of my old computer, for the last 2 years I do Flash in AS2 - Flash 8 )

 

Here's the code:

 

import flash.net.URLLoader;

import flash.net.URLRequest;

import flash.events.Event;

import flash.media.Sound;

import flash.media.SoundChannel;

import flash.events.MouseEvent;

 

 

var my_songs:XMLList;

var my_total:Number;

 

 

var my_sound:Sound;

var my_channel:SoundChannel;

 

 

var song_position:Number;

var song_paused:Boolean;

 

 

var current_song:Number = 0;

 

 

var myXMLLoader:URLLoader = new URLLoader();

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

myXMLLoader.addEventListener(Event.COMPLETE, processXML);

 

 

function processXML (e:Event):void{

          var myXML:XML = new XML(e.target.data);

          my_songs = myXML.SONG;

          my_total = my_songs.length();

 

          myXMLLoader.removeEventListener(Event.COMPLETE, processXML);

          myXMLLoader = null;

}

 

 

function playSong(mySong:Number):void{

          var myTitle = my_songs[mySong].@TITLE;

          var myArtist = my_songs[mySong].@ARTIST;

          var myAlbum = my_songs[mySong].@ALBUM;

          var myURL = my_songs[mySong].@URL;

 

          title_txt.text = myTitle;

          artist_txt.text = myArtist;

          album_txt.text = myAlbum;

 

          if (my_channel){

          my_channel.stop()

          my_channel.removeEventListener(Event.SOUND_COMPLETE, onNext);

}

 

          my_sound = new Sound();

          my_sound.load(new URLRequest(myURL));

          my_channel = my_sound.play();

          my_channel.addEventListener(Event.SOUND_COMPLETE, onNext);

}

 

 

play_btn.addEventListener(MouseEvent.CLICK, onPlay);

function onPlay(e:MouseEvent):void{

          if (song_paused){

                    my_channel = my_sound.play(song_position);

                    song_paused = false;

          } else if (!my_channel){

                    playSong(current_song);

                    play_mc.gotoAndPlay(1);

          }

}

 

 

next_btn.addEventListener(MouseEvent.CLICK, onNext);

function onNext(e:Event):void{

          current_song++;

          if (current_song>=my_total){

                    current_song = 0;

          }

          playSong(current_song);

          play_mc.gotoAndPlay(1);

}

 

prev_btn.addEventListener(MouseEvent.CLICK, onPrev);

function onPrev(e:MouseEvent):void{

          current_song--;

          if (current_song<0){

                    current_song = my_total-1;

          }

          playSong(current_song);

          play_mc.gotoAndPlay(1);

}

 

 

pause_btn.addEventListener(MouseEvent.CLICK, onPause);

function onPause(e:MouseEvent):void{

          if (my_channel){

                    song_position = my_channel.position

                    my_channel.stop();

                    song_paused = true;

          }

}

 

 

play_mc.gotoAndStop(1);

 
Replies
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 7, 2012 9:40 AM   in reply to AS3ForTheWin

    1.  the sound class has a progress event and bytesLoaded/bytesTotal properties you can use for your loadbar.  it also has a length property and with the soundchannel's position property, you can create your playbar.

    2.  to autoplay, call onNext when a soundchannel soundcomplete event is dispatched.  (you can pass null or assign it as a default event in onNext.)

    3.  what's the problem?

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 9, 2012 10:39 AM   in reply to AS3ForTheWin

    typically you would have a progressbar with a child fill (eg, fillbar which is, by default, at 100%) and use:

     

     

    my_sound.addEventListener(ProgressEvent.PROGRESS, prog);

    function prog(e:Event):void{

              var loadtime:Number = my_sound.bytesLoaded / my_sound.bytesTotal; // not a suggestive variable name

      progressbar.fillbar.width =loadtime*progressbar.width;

    }

     

    2. I mean at the last 10 seconds of every song there should be a movie clip instance playing that shows the next song's name, artist, album... not automatically play the next song when one ends?

    use a loop (like enterframe) to compare the sound's length property and the soundchannel's position property.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 10, 2012 7:16 AM   in reply to AS3ForTheWin

    1. no.  you create your progressbar movieclip in the ide.  progressbar typically is a rectangle with a border and a fill.  convert the fill to a movieclip.

    2. a sound isn't going to dispatch an enterframe event.  use a displayobject (like a movieclip or sprite):

     

    this.addEventListner(Event.ENTER_FRAME,playprogressF);

    function playprogressF(e:Event):void{

    if(my_sound.length-my_channel.position<10000){

    yourmovieclip.visible=true;  // change this to suit your code.

    }

    }

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 10, 2012 11:02 PM   in reply to AS3ForTheWin

    did you pay attention to:

     

    yourmovieclip.visible=true;  // change this to suit your code.

     

    ????

     

    if yes, copy and paste the code you used.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 11, 2012 8:57 AM   in reply to AS3ForTheWin

    click file/publish settings/swf and tick "permit debugging".  retest.

     

    the problematic line number will be in the error message.  indicate which line of code that is.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 12, 2012 9:53 AM   in reply to AS3ForTheWin

    you can't add the two event listeners (progressevent and enterframe) until your sound is instantiated.  ie, add those after your

     

    my_sound=new Sound()

     

    line of code.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 12, 2012 8:21 PM   in reply to AS3ForTheWin

    use the trace function to determine where your code fails.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 13, 2012 11:07 AM   in reply to AS3ForTheWin

    copy and paste your updated code and show what each trace returns.

     
    |
    Mark as:
  • kglad
    72,235 posts
    Jul 21, 2002
    Currently Being Moderated
    Aug 14, 2012 3:19 AM   in reply to AS3ForTheWin

    you're nesting named functions.  that's not going to work.  and your code is a mess.  format it so it's legible and you can debug it.

     

    use:

     

     

     

     

    import flash.net.URLLoader;

    import flash.net.URLRequest;

    import flash.events.Event;

    import flash.media.Sound;

    import flash.media.SoundChannel;

    import flash.events.MouseEvent;

    import flash.events.ProgressEvent;

    import flash.display.MovieClip;

     

    var my_songs:XMLList;

    var my_total:Number;

    var my_sound:Sound;

    var my_channel:SoundChannel;

    var song_position:Number;

    var song_paused:Boolean;

    var current_song:Number=0;

    var myXMLLoader:URLLoader = new URLLoader();

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

    myXMLLoader.addEventListener(Event.COMPLETE, processXML);

    function processXML(e:Event):void {

        var myXML:XML=new XML(e.target.data);

        my_songs=myXML.SONG;

        my_total=my_songs.length();

        myXMLLoader.removeEventListener(Event.COMPLETE, processXML);

        myXMLLoader=null;

    }

    function playSong(mySong:Number):void {

        var myTitle=my_songs[mySong].@TITLE;

        var myArtist=my_songs[mySong].@ARTIST;

        var myAlbum=my_songs[mySong].@ALBUM;

        var myURL=my_songs[mySong].@URL;

     

        title_txt.text=myTitle;

        artist_txt.text=myArtist;

        album_txt.text=myAlbum;

        if (my_channel) {

            my_channel.stop();

            my_channel.removeEventListener(Event.SOUND_COMPLETE, onNext);

        }

        my_sound = new Sound();

        my_sound.load(new URLRequest(myURL));

        my_channel=my_sound.play();

        my_channel.addEventListener(Event.SOUND_COMPLETE, onNext);

        my_sound.addEventListener(ProgressEvent.PROGRESS, prog);

        this.addEventListener(Event.ENTER_FRAME,playprogressF);

    }

    function playprogressF(e:Event):void {

        var cpoint:Number=my_sound.length-my_channel.position;

        trace(cpoint);//trace returns a range of number counting down

        if (cpoint<10000) {

            next_mc.visible=true;

            // change this to suit your code.

        }

        trace(next_mc.visible);//trace always returns "true". that's expected because you never assign next_mc.visible=false.

    }

    function prog(e:Event):void {

        var loadtime:Number=my_sound.bytesLoaded/my_sound.bytesTotal;

        trace(loadtime);//trace returns numbers ranging from 0.1 to 1

        progressbar.fillbar.width=loadtime*progressbar.width;

        trace(loadtime * progressbar.width);//trace always returns the original width of the progressbar: 250. that's impossible.

    }

    play_btn.addEventListener(MouseEvent.CLICK, onPlay);

    function onPlay(e:MouseEvent):void {

        if (song_paused) {

            my_channel=my_sound.play(song_position);

            song_paused=false;

        } else if (!my_channel) {

            playSong(current_song);

            play_mc.gotoAndPlay(1);

        }

    }

    next_btn.addEventListener(MouseEvent.CLICK, onNext);

    function onNext(e:Event):void {

        current_song++;

        if (current_song>=my_total) {

            current_song=0;

        }

        playSong(current_song);

        play_mc.gotoAndPlay(1);

    }

    prev_btn.addEventListener(MouseEvent.CLICK, onPrev);

    function onPrev(e:MouseEvent):void {

        current_song--;

        if (current_song<0) {

            current_song=my_total-1;

        }

        playSong(current_song);

        play_mc.gotoAndPlay(1);

    }

    pause_btn.addEventListener(MouseEvent.CLICK, onPause);

    function onPause(e:MouseEvent):void {

        if (my_channel) {

            song_position=my_channel.position;

            my_channel.stop();

            song_paused=true;

        }

    }

     

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points