The Problem
Last week a student of mine was putting together a project where we wanted to play multiple audio files on the web. Naturally the first thing I reached for was Flash and XML. No problem. Well there was a twist. He wanted to have sets of files available by genre only. Which calls for one the best improvements of ActionScript 3.0 and thats E4X.
E4X allows you to “query” or “filter” if you will the data xml document so you can use just a small part of it instead of the whole thing.
The Solution
What I developed was a flash file that
- loads in the xml
- creates a sound object
- creates a sound channel
- on mouse click
- set a search parameter based on which button is clicked
- “filter” the xml by genre based on the search parameter
- store the “filtered” data in an array containing object value you name pairs
- play the first song
- There are a few other things in there like stops just to avoid sound vomit
The end result is a solution that dynamically loads sound, manages the sound files through xml, and can expand to filter songs by genre.
The Working Solution
View the working solution
Download the project file
ActionScript
-
// xml switch demo
-
// this demo is to switch xml files on button click for
-
// sound output
-
-
// init variables
-
var xmlLoadFilter:URLLoader = new URLLoader()
-
var xmlFilter:XML
-
// temp array to store queried songs from the xml file
-
var songs:Array
-
// creation of sound object and sound channel object
-
var soundFile:Sound
-
var sc:SoundChannel = new SoundChannel();
-
-
// default xml
-
xmlLoadFilter.load(new URLRequest("master.xml"))
-
xmlLoadFilter.addEventListener(Event.COMPLETE, onLoadXMLFilter)
-
-
// register button events
-
comedy_btn.addEventListener(MouseEvent.MOUSE_DOWN, onDownFilter)
-
rock_btn.addEventListener(MouseEvent.MOUSE_DOWN, onDownFilter)
-
stop_btn.addEventListener(MouseEvent.MOUSE_DOWN, onStop)
-
-
// events
-
// listener for comedy and rock button
-
function onDownFilter(e:MouseEvent):void{
-
// stops any audio in the sc track
-
sc.stop();
-
// this array gets replaced everytime the mouse is clicked
-
var songs = new Array()
-
// temp string to store the genere for searching the xml file
-
var g:String
-
// this changes the search element based on the button clicked
-
switch(e.target.name){
-
case "comedy_btn":
-
g="comedy"
-
break;
-
-
case "rock_btn":
-
g="rock"
-
break;
-
}
-
// seaches through the xml based on genre
-
for each(var p:XML in xmlFilter.music.(@genre==g)){
-
songs.push({artist:p.artist, path:p.path})
-
//trace("test: "+p.path)
-
}
-
// loads the song
-
soundFile = new Sound(new URLRequest("songs/"+songs[0].path))
-
// plays the song
-
sc = soundFile.play();
-
}
-
// xml complete listener
-
function onLoadXMLFilter(e:Event):void{
-
xmlFilter = new XML(e.target.data)
-
}
-
// stops the audio
-
function onStop(e:MouseEvent){
-
sc.stop();
-
}
XML Document
-
-
<songs>
-
<music genre="rock">
-
<artist>Josh Sager</artist>
-
<path>Last Show.mp3</path>
-
</music>
-
<music genre="comedy">
-
<artist>Josh Sager</artist>
-
<path>RockStar.mp3</path>
-
</music>
-
<music genre="comedy">
-
<artist>Josh Sager</artist>
-
<path>Back in Time.mp3</path>
-
</music>
-
</songs>