I originally built this in Flash 8, then moved the files over to CS4.


Hi, I have a list component where I've loaded song files through xml and everything is working great.

I have now been trying to figure out how to make it play one of the 8 files randomly when it starts playing, instead of it always starting with a specified track (currently track one obviously). So each time a visitor comes to the site it is a different song.

I found a few things on math for AS3 but nothing has worked for this AS2 code that I have tried so far. What am I missing?

this._lockroot = true; 
//make textfields autosize 
album_txt.autoSize = "left"; 
artist_txt.autoSize = "left"; 
title_txt.autoSize = "left"; 
//create sound object 
var songInterval:Number; 
var amountLoaded:Number; 
var mySound:Sound; 
var nextTrack:Number; 

//this will contain all the track details from the xml file 
var tracks_array:Array = new Array(); 
var totalTracks:Number; 

//create the XML object and populate with track details 
var jukebox_xml:XML = new XML(); 
jukebox_xml.ignoreWhite = true; 
var RootNode:XMLNode; 

jukebox_xml.onLoad = function(success:Boolean) { 
    if (success) { 
    RootNode = this.firstChild; 
    totalTracks = RootNode.childNodes.length; 
    populateTracksArray(); 
    } else { 
    trace("error loading xml file"); 
    } 
}; 
jukebox_xml.load("tracks.xml"); 

function populateTracksArray():Void{ 
    for(var i:Number=0; i < totalTracks;i++){ 
        tracks_array[i] = RootNode.childNodes[i]; 
        tracks_array[i].source = RootNode.childNodes[i].attributes.source; 
        tracks_array[i].artist = RootNode.childNodes[i].attributes.artist; 
        tracks_array[i].album = RootNode.childNodes[i].attributes.album; 
        tracks_array[i].title = RootNode.childNodes[i].attributes.title; 
        } 


//play first track  
        playTrack(tracks_array[0].source,tracks_array[0].artist,tracks_array[0].album,tracks_array[0].title,true); 
//populate list component with song titles 
        populateList(); 
} 

function playTrack(source, artist, album, title, stream):Void{ 
        artist_txt.text = artist; 
        album_txt.text = album; 
        title_txt.text = title; 
        mySound = new Sound(); 
         
        mySound.onSoundComplete = function():Void{ 
             
//----LETS NEXT SONG PLAY---------  
    if(continous_comp.selected){ 
            if(list_comp.selectedIndex < (totalTracks -1)){ 
    list_comp.selectedIndex +=1; 
    }else{ 
        list_comp.selectedIndex = 0; 
    } 
    playTrack(tracks_array[list_comp.selectedIndex].source,tracks_array[list_comp.selectedIndex].artist,tracks_array[list_comp.selectedIndex].album,tracks_array[list_comp.selectedIndex].title, true); 
    } 
            } 
     
        mySound.loadSound(source,stream); 
        clearInterval(songInterval); 
        songInterval = setInterval(songProgress,100); 
} 

function populateList():Void{ 
    for(var i:Number=0; i<totalTracks;i++){ 
     list_comp.addItem(tracks_array[i].title,tracks_array[i].source); 
     } 
     _root.list_comp.selectedIndex = 0; 
} 

//--------create a listener for the list component------------ 
var compListener:Object = new Object(); 
list_comp.addEventListener("change", compListener); 

compListener.change = function(info:Object):Void{ 
 playTrack(info.target.value,tracks_array[list_comp.selectedIndex].artist,tracks_array[list_comp.selectedIndex].album,tracks_array[list_comp.selectedIndex].title, true); 
}

Dani AI

Generated

This thread shows has the XML parsing and list UI working. The main issues causing the player to always start the same way are (a) picking a random index before the XML has finished loading or using a hard-coded 8 instead of the actual totalTracks, and (b) an index mix-up in the play call (the sample uses n for the source but i when passing artist/album/title). @rajarjan07’s quick random(...) idea is fine for a test, and @gparis’s randRange approach points in the right direction, but both need to be tied to totalTracks and use consistent indexes.

A simple, safe pattern is: pick the start index after populateTracksArray() and after the list has been filled, set the component’s selectedIndex to that same index, then call playTrack with the same index for every field so the metadata matches the audio:

var startIndex:Number = Math.floor(Math.random() * totalTracks);

populateList();               // fill visual list first
_root.list_comp.selectedIndex = startIndex;
playTrack(
  tracks_array[startIndex].source,
  tracks_array[startIndex].artist,
  tracks_array[startIndex].album,
  tracks_array[startIndex].title,
  true
);

Notes and gotchas: the posted randRange used (max - min + 0) which never returns the maximum; use (max - min + 1) for an inclusive range or prefer the Math.floor(Math.random() * totalTracks) pattern shown above. If the intent is to start randomly but then play sequentially, keep the current onSoundComplete logic. If the intent is a shuffled playlist, run a Fisher–Yates shuffle on tracks_array once after loading and then iterate through it. Also call mySound.stop() (or reuse a single Sound instance cleanly) before loading another track, clear intervals when appropriate, and trace(totalTracks, startIndex) while debugging to confirm values.

Recommended Answers

All 2 Replies

Member Avatar for Member #334542

It is very easy to generate random numbers in AS2.

#
function populateTracksArray():Void{
#
for(var i:Number=0; i < totalTracks;i++){
#
tracks_array[i] = RootNode.childNodes[i];
#
tracks_array[i].source = RootNode.childNodes[i].attributes.source;
#
tracks_array[i].artist = RootNode.childNodes[i].attributes.artist;
#
tracks_array[i].album = RootNode.childNodes[i].attributes.album;
#
tracks_array[i].title = RootNode.childNodes[i].attributes.title;
#
}
#
 
#
 
#
//play first track
#
[B]k=random(8);
playTrack(tracks_array[k].source,tracks_array[k].artist,tracks_array[k].album,tracks_array[k].title,true);
[/B]#
//populate list component with song titles
#
populateList();
#
}

Hope this helps!

I really appreciate your help with this rajarjan07. I came to an answer thanks to some help I had with another really nice person like yourself (gparis at Flashkit) by using code like this:

var n:Number = randRange(0, 8);
function randRange(min:Number, max:Number) :Number{
   var randomNum:Number = Math.floor(Math.random() * (max - min + 0)) + min;
return randomNum;
}

function populateTracksArray():Void{
    for(var i:Number=0; i < totalTracks;i++){
        tracks_array[i] = RootNode.childNodes[i];
        tracks_array[i].source = RootNode.childNodes[i].attributes.source;
        tracks_array[i].artist = RootNode.childNodes[i].attributes.artist;
        tracks_array[i].album = RootNode.childNodes[i].attributes.album;
        tracks_array[i].title = RootNode.childNodes[i].attributes.title;
        }

//play first random track  
        playTrack(tracks_array[n].source,tracks_array[i].artist,tracks_array[i].album,tracks_array[i].title,true); 


//----LETS NEXT SONG PLAY---------  
    if(continous_comp.selected){
            if(list_comp.selectedIndex < (totalTracks -1)){
    list_comp.selectedIndex +=1;
    }else{
        list_comp.selectedIndex = n;
    }
    playTrack(tracks_array[list_comp.selectedIndex].source,tracks_array[list_comp.selectedIndex].artist,tracks_array[list_comp.selectedIndex].album,tracks_array[list_comp.selectedIndex].title, true);
    }
            }
     
        mySound.loadSound(source,stream);
        clearInterval(songInterval);
        songInterval = setInterval(songProgress,100);
}

function populateList():Void{
    for(var i:Number=0; i<totalTracks;i++){
     list_comp.addItem(tracks_array[i].title,tracks_array[i].source);
     }
     _root.list_comp.selectedIndex = n;
}

Is there anything I could change to make it a little cleaner or better do you think?

It is very easy to generate random numbers in AS2.

#
function populateTracksArray():Void{
#
for(var i:Number=0; i < totalTracks;i++){
#
tracks_array[i] = RootNode.childNodes[i];
#
tracks_array[i].source = RootNode.childNodes[i].attributes.source;
#
tracks_array[i].artist = RootNode.childNodes[i].attributes.artist;
#
tracks_array[i].album = RootNode.childNodes[i].attributes.album;
#
tracks_array[i].title = RootNode.childNodes[i].attributes.title;
#
}
#
 
#
 
#
//play first track
#
[B]k=random(8);
playTrack(tracks_array[k].source,tracks_array[k].artist,tracks_array[k].album,tracks_array[k].title,true);
[/B]#
//populate list component with song titles
#
populateList();
#
}

Hope this helps!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.