Solved

Auto Playing song in Flash player...

Posted on 2004-10-13
17
358 Views
Last Modified: 2010-05-18
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);
0
Comment
Question by:kearnguy
  • 9
  • 8
17 Comments
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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?

 
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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.
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
can you post somewhere a fla containing only the music part?
because there's something we're missing but I can't see it
0
 

Author Comment

by:kearnguy
Comment Utility
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);
0
 
LVL 8

Accepted Solution

by:
Cerf earned 400 total points
Comment Utility
everything seems to be fine, and it does work...

let's try this test: add 5 or 6 frames and an empty keyframe, then in that keyframe call the function

playSong(songPath);

see if it works,

Cërf.
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
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?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:kearnguy
Comment Utility
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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?

0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
Ok, let me check the code...
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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.
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
:-)
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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.
0
 

Author Comment

by:kearnguy
Comment Utility
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!
0
 
LVL 8

Expert Comment

by:Cerf
Comment Utility
thank you very much,

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

glad I could help,

Cërf.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

I come across a lot of question about how to access things in the document class from a movieclip, or accessing something from a movieclip in the document class. It took me a while to figure this out but once I did it makes life so much easier. …
I have been doing hardcore actionscripting for some time; and needless to say I have faced a lot of problems in just understanding others' code rather than understanding what the code executes. A programmer's life can become hell when there are a lo…
The goal of the tutorial is to teach the user how to set there setting in Adobe Flash Media Live Encoder and YouTube for optimal video and audio quality.
The goal of the tutorial is to teach the user how to select the video input device. Make sure you have an input device that in connected and work and recognized by Adobe Flash Media Live Encoder and select it in the “video input” menu.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now