Link to home
Start Free TrialLog in
Avatar of kearnguy
kearnguy

asked on

Auto Playing song in Flash player...

I have built a mp3 player in Flash for a webpage.  The mp3 files are embedded in individual SWF files and loaded into a dynamically generated soundObject in Flash.  I use an XML file to communicate between the song files and the player and also generate the playlists.

The only problem that I am having is trying to figure out how to make the first song automatically play when the web page loads.  I tried to call the same function that I use behind the "play" button, but it doesn't work.  Any ideas?

I would paste the entire script here, but it is very, very long.  So I will just post the parts that load the XML file and create the sound object - leaving out all the button functions and non-crucial stuff.  Let me know if you need more code to work with.

Thanks in advance everyone.

//START CODE

songzXML = new XML();  
songzXML.ignoreWhite = true;
songzXML.onLoad = makePlaylist;
songzXML.load("playerSongz.xml");

//Makes the playlist from the XML file
function makePlaylist(success) {
      if (success) {
            sPath = new Array();
            sArtist = new Array();
            sTitle = new Array();
            sSong = new Array();
            sSong = this.firstChild.childNodes;
            songTotal = sSong.length;
            for (i=0; i<songTotal; i++) {
                  if (sSong[i].nodeName == "songz") {
                        sPath.push(sSOng[i].attributes.path);
                        sArtist.push(sSong[i].attributes.artist);
                        sTitle.push(sSong[i].attributes.title);
                  }
            }
            songPath = sPath[0];
            txtArtist = sArtist[0];
            txtTitle = sTitle[0];
            songActual = 1;
            txtCount = songActual+"/"+songTotal;
            txtStatus = "Track loaded";
      } else {
            txtStatus = "Track not loaded";
      }
}

prevUrl = null; // store current url in global variable
isPlaying = false; // store playstate in global variable
prevPos = 0; // store last position in global variable
function showPlayState(){
      var songPos = thisSong._currentframe;
      var songEnd = thisSong._totalframes;
      var loaded = (thisSong.getBytesTotal() > 4 &&
                          thisSong.getBytesLoaded() == thisSong.getBytesTotal());
      if(songPos <= prevPos && !loaded){ // stream song loading
            status = "Loading";
      } else if(songPos == songEnd){ // end of song
            txtStatus = "complete";
            status = "Loaded";
            thisSong.stop(); // prevent looping SWF
            isPlaying = false;
            onEnterFrame = null; // stop tracking playstate
            //continuous play!!!
            nextSong();
            playSong(songPath);
      } else { // song playing
            status = "Playing";
      }
      prevPos = songPos; // store for next loop
}

// assign button events to functions (function code is not shown here)
playBtn.onRelease = function () {playSong(songPath);}
stopBtn.onRelease = stopSong;
pauseBtn.onRelease = pauseSong;
nextBtn.onPress = nextSong;      
prevBtn.onPress = prevSong;

// movie clip a name and set depth
createEmptyMovieClip("thisSong",1);
Avatar of Cerf
Cerf

So, the code for the XML load is working fine, as I read in your post, the only problem is that you need to auto-start the first song.(just double checking)

can you post the playSong() AS?

I mean, if it does work when you click on the play button, and the play button has something like
on (release){
   playSong(songPath);
}
it should work anywhere else.
You might want to check for upper/lower case issues in the code.

Let me know,

Cërf.
Avatar of kearnguy

ASKER

Thanks for the quick reply Cërf.  And yes, everything including the XML load is working.

The code for the playSong function is as follows:

//Start Code
function playSong(url){
      // check playstate
      if(isPlaying){
            return; // deactivate button during play/load
      } else {
            isPlaying = true;
      }
      
      // check if same or new sound
      if(prevUrl != url){ // new sound
            thisSong.loadMovie(url);
            // sound automatically plays after loading
            prevUrl = url;
      } else { // same sound
            thisSong.play(); // start sound at last paused
      }
      onEnterFrame = showPlayState; // start tracking playstate
}

//End Code

Hopefully all this scripting doesn't confuse matters.  What's wierd is that the XML is loading as soon as the web page loads because all my dynamic text boxes show that the first track (author and title) is being read.  Which means that the url is being read as well...so shouldn't I just be able to put my "playSong" function anywhere?  Or do I have to put it in an event handler like onLoad or something?

 
Ok,
Please make sure the XML loading takes place *before* playSong. Why? because songPath is a variable that comes from the parsed XML, so if the XML has not been loaded songPath will be undefined and the function won't work.

That's the only thing that I can think of right now, because it should work anywhere you call it.

Let me know,

Cërf.
I double checked the script and I had the following line placed at the bottom of the code:

playSong(songPath);

The very first things in the code is the XML load.  So the XML has been loaded long before the above function call.  With that line in place something does happen though...

My "status" variable displays "loading".  This is coming from the "showPlaystate" function, so now I am really confused as to what is happening.
can you post somewhere a fla containing only the music part?
because there's something we're missing but I can't see it
My apologies...I should have just done this originally.  I fear that I have made a mess of things. So...

I stripped down everything and made a version that works, but only includes code for the player - I removed all the other site functionality so that hopefully the confusion will be limited.

Again, the following code works as a player but the autoplay does not work (I apologize for the length):

//Start Code
songzXML = new XML();  
songzXML.ignoreWhite = true;
songzXML.onLoad = makePlaylist;
songzXML.load("playerSongz.xml");

//Makes the playlist from the XML file
function makePlaylist(success) {
      if (success) {
            sPath = new Array();
            sArtist = new Array();
            sTitle = new Array();
            sSong = new Array();
            sSong = this.firstChild.childNodes;
            songTotal = sSong.length;
            for (i=0; i<songTotal; i++) {
                  if (sSong[i].nodeName == "songz") {
                        sPath.push(sSOng[i].attributes.path);
                        sArtist.push(sSong[i].attributes.artist);
                        sTitle.push(sSong[i].attributes.title);
                  }
            }
            songPath = sPath[0];
            txtArtist = sArtist[0];
            txtTitle = sTitle[0];
            songActual = 1;
            txtCount = songActual+"/"+songTotal;
            txtStatus = "Track loaded";
      } else {
            txtStatus = "Track not loaded";
      }
}

prevUrl = null; // store current url in global variable
isPlaying = false; // store playstate in global variable
prevPos = 0; // store last position in global variable


// show playback and load status
function showPlayState(){
      var songPos = thisSong._currentframe;
      var songEnd = thisSong._totalframes;
      var loaded = (thisSong.getBytesTotal() > 4 &&
                          thisSong.getBytesLoaded() == thisSong.getBytesTotal());
      if(songPos <= prevPos && !loaded){ // stream song loading
            status = "Loading";
      } else if(songPos == songEnd){ // end of song
            status = "Loaded";
            thisSong.stop(); // prevent looping SWF
            isPlaying = false;
            onEnterFrame = null; // stop tracking playstate
            //continuous play!!!
            nextSong();
            playSong(songPath);
      } else { // song playing
            status = "Playing";
      }
      prevPos = songPos; // store for next loop
}

// load and/or play sound
function playSong(url){
      // check playstate
      if(isPlaying){
            return; // deactivate button during play/load
      } else {
            isPlaying = true;
      }
      
      // check if same or new sound
      if(prevUrl != url){ // new sound
            thisSong.loadMovie(url);
            // sound automatically plays after loading
            prevUrl = url;
      } else { // same sound
            thisSong.play(); // start sound at last paused
      }
      onEnterFrame = showPlayState; // start tracking playstate
}

// stop both playback and download
function stopSong(){
      thisSong.stop(); // stop playback
      thisSong.unloadMovie(); // stop download
      isPlaying = false;
      prevUrl = ""; // clear for next load
      onEnterFrame = null; // stop tracking playstate
      status = "Stopped";
}

// pause sound
function pauseSong(){
      thisSong.stop(); // pause sound
      onEnterFrame = null; // stop enterFrame loop
      isPlaying = false;
      status = "Paused";
}

//go to next song in playlist
function nextSong() {
      thisSong.stop(); // stop playback
      thisSong.unloadMovie(); // stop download
      isPlaying = false;
      prevUrl = ""; // clear for next load
      onEnterFrame = null; // stop tracking playstate
      status = "Play";
      if (songActual<songTotal) {
            songActual += 1;
            txtCount = songActual+"/"+songTotal;
            songPath = sPath[songActual-1];
            txtArtist = sArtist[songActual-1];
            txtTitle = sTitle[songActual-1];
            }
};

//go to previous song in playlist
function prevSong() {
      thisSong.stop(); // stop playback
      thisSong.unloadMovie(); // stop download
      isPlaying = false;
      prevUrl = ""; // clear for next load
      onEnterFrame = null; // stop tracking playstate
      status = "Play";
      if (songActual>1) {
            songActual -= 1;
            txtCount = songActual+"/"+songTotal;
            songPath = sPath[songActual-1];
            txtArtist = sArtist[songActual-1];
            txtTitle = sTitle[songActual-1];
            thisSong.stop();
            thisSong.unloadMovie();
            }
};

// assign button events
playBtn.onRelease = function () {playSong(songPath);}
stopBtn.onRelease = stopSong;
pauseBtn.onRelease = pauseSong;
nextBtn.onPress = nextSong;      
prevBtn.onPress = prevSong;

// movie clip a name and set depth
createEmptyMovieClip("thisSong",1);
ASKER CERTIFIED SOLUTION
Avatar of Cerf
Cerf

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
could you please paste a sample of the XML, to see if I can put together the whole thing and try to make it work?
Sure, no problem...

//Begin XML

<?xml version="1.0" encoding= "UTF-8" ?>
<audioFiles>
      <songz path ="song1.swf" artist ="Some Band" title ="First Song"/>
                <songz path ="song2.swf" artist ="Some Band" title ="Second Song"/>
</audioFiles>

//End XML

Just to verify, this file is named "playerSongz.xml".
Thanks

I will test your suggestion now.
Oh wow!

I just added 4 frames, and on the last frame (frame 5) I put the following code:

//Starte Code

playSong(songPath);
stop();

//End Code

It now works perfectly!!  Could it be that it takes that long to fully load the XML file and sound container, and therefore couldn't execute my function while it was on the first frame?  Sounds weird to me...but then again, I am relatively new to actionScripting.  

The main things is that it works now. Thank you very much!  The 250pts will go to you Cërf, however...

**For a Bonus 100 Points**
Before I close the question though, would you by any chance know how I can get the player to loop through the XML playlist?  I have it set to auto play the next track, but when it gets to the last track it just keeps playing that one over and over.  How do I get it to go back to the first track and cycle through again?

Ok, let me check the code...
Try replacing the code for nextSong and prevSong with these:

//go to next song in playlist
function nextSong() {
     thisSong.stop(); // stop playback
     thisSong.unloadMovie(); // stop download
     isPlaying = false;
     prevUrl = ""; // clear for next load
     onEnterFrame = null; // stop tracking playstate
     status = "Play";
     if (songActual<=songTotal) {
          if (songActual=songTotal) {
                         songActual = 1;} else {songActual += 1;}
          txtCount = songActual+"/"+songTotal;
          songPath = sPath[songActual-1];
          txtArtist = sArtist[songActual-1];
          txtTitle = sTitle[songActual-1];
          }
};


//go to previous song in playlist
function prevSong() {
     thisSong.stop(); // stop playback
     thisSong.unloadMovie(); // stop download
     isPlaying = false;
     prevUrl = ""; // clear for next load
     onEnterFrame = null; // stop tracking playstate
     status = "Play";
     if (songActual>=1) {
              if (songActual=1) {
                          songActual=songTotal} else {songActual -= 1;}
          txtCount = songActual+"/"+songTotal;
          songPath = sPath[songActual-1];
          txtArtist = sArtist[songActual-1];
          txtTitle = sTitle[songActual-1];
          thisSong.stop();
          thisSong.unloadMovie();
          }
};

You will maybe need to tune up a bit by adding a (-1) where songActual = 1 and/or songActual = songTotal

Cërf.
Well, I tried it and here's what happened:

My next and previous buttons switched...the next button goes to track one skipping all tracks in between, and my previous button goes to the last track skipping all in between.

It works in one aspect...if I let the last track play, it will automatically go to the first track when done.

I'm not sure what you meant by "tune up" though.  Could you maybe shed a little more light on the subject?

Thanks again for all your help.
:-)
Sorry!
Please change this:
//next button
if (songActual=songTotal) for if (songActual==songTotal)
//prev button
 if (songActual=1) for  if (songActual==1)

and try again... hehe, sorry about that, I guess I am very used to delphi :-)
Cërf.
No need to apologize...you are the one helping me. :0)

Speaking of help...I hate to be annoying, but I am still learning this actionScript stuff.  I tried plugging in the code you just gave me but keep getting a "syntax error".  I have tried it several different ways, but can't seem to get it to work.

Could you plug it into the original code that you pasted a couple posts up (the post with the whole revised 'next' and 'prev' functions typed out).  That way I can see how it is supposed to fit in.  Again, I am sorry to keep bugging you.  If you put up with me a little longer, I will make it worth your time.

Thanks.
Nevermind...

Your script once again released some hidden knowledge of mine.  It got me thinking of how to use an 'if' loop better.  Then I realized I could do exactly what I needed by just changing the "next" function using an 'if...else if' loop.  Here's what I did:

//next button
function nextSong() {
      thisSong.stop(); // stop playback
      thisSong.unloadMovie(); // stop download
      isPlaying = false;
      prevUrl = ""; // clear for next load
      onEnterFrame = null; // stop tracking playstate
      status = "";
      if (songActual<songTotal) {
            songActual += 1;
            
            txtCount = "Track "+songActual+" of "+songTotal;
            songPath = sPath[songActual-1];
            txtArtist = sArtist[songActual-1];
            txtTitle = sTitle[songActual-1];
            txtStatus = "Press Play";
            
      } else if (songActual==songTotal){
            songActual -=songTotal;
            songActual = 1;
            
            txtCount = "Track "+songActual+" of "+songTotal;
            songPath = sPath[songActual-1];
            txtArtist = sArtist[songActual-1];
            txtTitle = sTitle[songActual-1];
            txtStatus = "Press Play";
      }
};

//end

It works perfectly.  Thank you so much for all your amazing help.  I think sometimes to figure something out, you just got to talk out with someone that understands. :0)
I am giving you a total of 400 points for being so helpful and patient!
thank you very much,

the best part is always to know that someone has one less headache :-)

glad I could help,

Cërf.