In this article, David Vogeleer shows you how to create a Flash MP3 player with all of the controls being external with the Teleo Intro module and some basic switches.
Why Teleo and Flash?
When Flash began, it was mostly a vector animation tool, but as time progressed, Flash became more of a development platform with its own ECMA based language ActionScript and its ability to work with several server side languages such as PHP, .NET and Cold Fusion. Teleo modules allow Flash developers to take their applications to a whole new place, beyond the computer screen.
With Teleo modules, Flash developers can create the logic and functionality in Flash as well as certain visual aspects, and then create the controls with Teleo modules and basic electronic parts.
What do I need to get started?
Before you get started with this tutorial, you will need the following:
- Flash component set
- USB driver
- XML Socket server
- Sample file
- Introductory module
- Power supply
- USB cable
First things first, lets set up the introductory module and switches.
The external controls and wiring details
In this section, I will go over the details of the wiring for the controls. It will not go over the basics of wiring up the Teleo Introductory module. For more on the basics of the Teleo Introductory module, click here.
Take a look at the basic wiring layout in the figure below.

As you can see, we take the first 5+ power outlets and split it to wire both of the push button controls, and then wire each push button to its associated digital input connections (Din0 is the Fast Forward/Next button and Din1 is the Rewind/Previous button). After that, take the second 5+ power outlet and split it three ways and wire it to the toggle switch and both potentiometers. The toggle switch can be wired directly to the first analog input connection.
Note: Normally, you would use a toggle switch in conjunction with the Digital Input section, but as there are only two available spots in the Digital in section, and they are both being used, we will use the Analog Input section for the toggle switch.
Once the toggle switch is wired, you will then need to finish wiring the potentiometers. You will have to wire each of them to the ground and to their associated analog input connections. (Ain1 is the volume control and Ain2 is the pan control)
This is an actually picture of what it might look like when wired (little messy):
I used alligator clips to make it easier for me to quickly test different devices.
Now that the wiring is done, we need to create the directory, which holds the MP3s.
When you create the Flash movie, where ever you save it will need a subdirectory called "mp3" which will hold all the mp3s we will be using.
After the directory with mp3s is ready, we can move onto Flash.
Building the Flash MP3 player
This section will cover all the necessary Flash pieces and ActionScript
1. First, create a new Flash file (File/New)
Note: If you are using Flash 2004 (Regular or Pro) you will want to change your publish settings to Flash Player 6, and ActionScript 1.0 as the Teleo components are compiled for this version.
2. Save the new Flash file in the same directory where the "mp3" sub-directory is held
3. Set the stage size as 300x100 and 30 fps (Frames Per Second)
4. After that, you will want to create 2 new layers so that you have 3 in total and they are named from top to bottom like this:
5. In the content layer, create 4 dynamic text fields with the following instance names:
You can also put static text fields beside them labeling what they are like the figure below.
Now we have the all the visual elements on the stage we need, lets move to the Teleo components we will be working with.
1. In the teleo layer, drag the following components onto the stage from the Components panel:
Note: In this project, the interfaces for these components will not be visible at runtime, but if you want them to be, you must drag their associative interface component onto the stage for both the t_intro_ain and the t_intro_din component.
2. Now remove the XMLSocketConnector and the XMLTranslator from the stage because they will be brought back in at runtime by the Teleo Manager
3. Create a second t_intro_din component by copying and pasting
4. Create two copies of the t_intro_ain component by copying and pasting
5. Give the Teleo Manager component the instance name "myManager" and keep the default settings
6. Name the first t_intro_ain component "ain0" and set the manager component parameter to "myManager" and leave the other parameters to their default settings, then name the other two t_intro_ain components "ain1" and "ain2" accordingly, and set their manager parameter to "myManager" as well
7. Name the first t_intro_din component "din0" and set the manager component parameter to "myManager" and leave the other parameters to their default settings and then name the other t_intro_din component "din1" and set the same parameters
8. Make sure all the components are off stage (not for any reason in particular, just so it is easier to see what will be on the stage at runtime)
Also, I shrunk the components so they would not take up as much screen space.
Now we have the visual elements and the components, the last thing we need to do is to add the ActionScript.
1. In the actions layer, open the actions panel in the frame
2. The first thing we will want to do is to initialize the components with the XML sever, and set some initial text for a couple of the text fields, so add these lines:
//initialize the connections
if(!init){
din0.create();
din1.create();
ain0.create();
ain1.create();
ain2.create();
//initial state of some text fields
volume_txt.text = 75;
pan_txt.text = 0;
//set init to true
init=true;
}
3. Next we create a function that will take the milliseconds of our mp3s and convert it to readable time output. We also instantiate a couple variables and the array of mp3s:
//function for formatting milliseconds into actual time
function convert(mSecs){
var seconds = Math.round(mSecs/1000);
var minutes = Math.floor(seconds/60);
var leftOver = (seconds-(minutes*60));
if(leftOver<10){
leftOver = "0"+leftOver;
}
return (minutes+":"+leftOver);
}
//main position that other elements read from
var mainPos = 0;
//this varibale holds the difference between next and FF in milliseconds
var dTime = 500;
//create the array to hold the mp3's
mp3_array = new Array("flashMag.mp3","evo-1.mp3","trance-1.mp3");
//the variable that holds the length of the mp3_array
var mp3Length = mp3_array.length;
//variable to hold which mp3 is playing
var song = 0;
If you have your own mp3’s, you will need to put them in the array, these mp3’s are part of the sample files you can download at the end of this article.
4. After that, we need to create the sound object to be able to play mp3’s. We also create an event that is fired whenever the song reaches the end. It will go to the next song in the list.
//the sound object we will use throughout the application
mp3_sound = new Sound();
//this event is triggered when the mp3 reaches the end of the song
mp3_sound.onSoundComplete = function() {
//this little bit of code checks to see which mp3 should play next
if (song == mp3Length-1) {
song = 0;
} else {
song++;
}
//resets the current position of the song to the beginning
mainPos = 0;
//sets the new song's name to the text field
title_txt.text = mp3_array[song];
//load the new song into the sound object
mp3_sound.loadSound("mp3/"+mp3_array[song]);
//this event is triggered when the song is completely loaded
mp3_sound.onLoad = function() {
//check to see if it should play automatically (if the toggle is true)
if (ain0.valueGet() == 31) {
//get the current length of the song
var dur = convert(mp3_sound.duration);
//start playing
mp3_sound.start(mainPos,0);
//keep track of the position in the song
ain0.onEnterFrame = function() {
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
};
}
//destroy this event because it is no longer needed
delete this.onLoad;
};
};
//load the first song in
mp3_sound.loadSound("mp3/"+mp3_array[song]);
//put the first song in the text field
title_txt.text = mp3_array[0];
5. The next step is to create the listener object for the toggle button which will control the play/pause functionality:
//create the object to listen to the toggle button
playPause = new Object();
//create the event callback for the object receives the event
playPause.reportSwitchState = function(iValue) {
//if the toggle is true
if (iValue == 31) {
//get the total length of the song
var dur = convert(mp3_sound.duration);
//play at the current position
mp3_sound.start(mainPos,0);
//constantly update the text field with the position in the song
ain0.onEnterFrame = function() {
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
};
} else {
//if the toggle is false get the position it was paused at
mainPos = (mp3_sound.position/1000);
//stop the song
mp3_sound.stop();
}
};
//add the event listener to the component
ain0.addCallback("ValueChanged",playPause,"reportSwitchState");
What we did in the above code was to create a generic object that will be the listener object for the toggle switch. We then created an event callback for the reportSwitchState event so that every time the toggle button is toggled, it will trigger an event for this object and run the associated code. And the code that is being run is detecting whether the toggle is turned on or off. If the toggle is turned on, it will play the mp3 from its current position (defaulted to 0 so it will initially start in the beginning of the song), and then it will update the position text field to constantly display the current position. If the toggle is turned off it will grab the current position (so it can start back at that position) and stop the mp3. Finally we added the event callback to the first t_intro_ain component with the instance name of "ain0".
6. Now we have the code for the play/pause toggle switch, we need the code for the fast forward and rewind push buttons. They are a good deal more complex because of what they are doing. They do not just fast forward and rewind, they can also skip to the next or previous song in the list depending on how long the user suppresses the button. Earlier we created a variable called dTime which holds the amount of milliseconds between a "next" call and a "fast forward" call (defaulted to 500 milliseconds, or half a second). Add the following code for the fast forward / next button:
//event for fastforward
ff = new Object();
ff.reportSwitchState = function(iValue) {
//stop the sound from playing
mp3_sound.stop();
if (iValue == 31) {//when the button is pressed
var dur = convert(mp3_sound.duration);
//get the current time
tempTime = getTimer();
// display the new position as you fast forward
myManager.onEnterFrame = function() {
//make sure the button is supressed long enough
if (getTimer()-tempTime>dTime) {
if (mainPos<(mp3_sound.duration/1000)-1) {
mainPos++;
}
pos_txt.text = convert(mainPos*1000)+" / "+dur;
}
};
} else {//when the button is released
//destroy the running event
delete myManager.onEnterFrame;
//check to see how long the button was pressed
if ((getTimer()-tempTime)<=dTime) {
//go to the correct song
if (song == mp3Length-1) {
song = 0;
} else {
song++;
}
//reset the position back to the beginning
mainPos = 0;
//load the next song
mp3_sound.loadSound("mp3/"+mp3_array[song]);
//set the text field
title_txt.text = mp3_array[song];
//creat the event for when the mp3 loads
mp3_sound.onLoad = function() {
//get the length of the song
var dur = convert(mp3_sound.duration);
//this checks if it should play automatically
if (ain0.valueGet() == 31) {
mp3_sound.start(mainPos,0);
myManager.onEnterFrame = function() {
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
};
} else {
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
}
//destroy the unneccesary event
delete this.onLoad;
};
} else {//if when the button is released, it was held down beyong 500 milliseconds
//check to see if the song should play
if (ain0.valueGet() == 31) {
mp3_sound.start(mainPos,0);
}
}
}
};
//add the event listener to the component
din0.addCallback("ValueChanged",ff,"reportSwitchState");
In the preceding code, like before, we first create the listener object, and then set an event callback to that listener object. Inside the event callback, we use conditional statements to check not only whether the button is pressed or released, but also how long the button is pressed. If the button is suppressed for less than 500 milliseconds (half a second) the callback will move to the next song, but if the button is pressed for more than 500 milliseconds, it will begin to fast forward through the song.
7. The rewind / previous button is very similar to the fast forward / next button except it rewinds or moves to the previous song depending on how long the button was pressed.
//event for rewinding
rw = new Object();
rw.reportSwitchState = function(iValue){
mp3_sound.stop();
if (iValue){
tempTime = getTimer();
myManager.onEnterFrame=function(){
if(getTimer()-tempTime > dTime){
if(mainPos >= 1){
mainPos --;
}
pos_txt.text = convert(mainPos*1000)+" / "+convert(mp3_sound.duration);
}
}
}else{
delete myManager.onEnterFrame;
if((getTimer()-tempTime)<=dTime){
if(song == 0){
song = mp3Length-1;
}else{
song--;
}
mainPos=0;
mp3_sound.loadSound("mp3/"+mp3_array[song]);
title_txt.text=mp3_array[song];
mp3_sound.onLoad=function(){
var dur = convert(mp3_sound.duration);
if(ain0.valueGet()==31){
mp3_sound.start(mainPos,0);
myManager.onEnterFrame=function(){
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
}
}else{
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
}
delete this.onLoad;
}
}else{
if(ain0.valueGet()==31){
var dur = convert(mp3_sound.duration);
mp3_sound.start(mainPos,0);
myManager.onEnterFrame=function(){
pos_txt.text = convert(mp3_sound.position)+" / "+dur;
}
}
}
}
}
//add the event listener to the component
din1.addCallback("ValueChanged", rw, "reportSwitchState");
Again, note the similarities between this and the fast forward / next button. The only major difference is it rewinds or goes to the previous song. (that’s why it is not commented)
8. Now the play/pause and the push button controls will work, the next step is to do the volume and pan controls. The two controls we are using are the potentiometers and they will be able to adjust the volume of the Sound object from 0 to 100 and the pan of the Sound object from -100 to 100.
//<--this section is for volume and panning-->
vControl = new Object();
//create the event callback for the object recieves the event
vControl.reportSwitchState = function(iValue){
//get the volume amount
var vAmount = Math.floor((iValue/31)*100);
//set the volume and text
mp3_sound.setVolume(vAmount);
volume_txt.text=vAmount;
}
//add the event listener to the component
ain1.addCallback("ValueChanged", vControl, "reportSwitchState");
//this object is for the panning
pControl = new Object();
//create the event callback for the object recieves the event
pControl.reportSwitchState = function(iValue){
//get the correct panning amount
var myPan = Math.floor(((15.5 - iValue)/15.5)*-100);
//set the pan and the text
mp3_sound.setPan(myPan);
pan_txt.text = myPan;
}
//add the event listener to the component
ain2.addCallback("ValueChanged", pControl, "reportSwitchState");
Because the max value being returned will be 31, we use a little math to create the correct volume and pan amount.
That’s it for the ActionScript, now all we have to do is test the movie.
Testing the MP3 player
Before you test the player, make sure you have installed the driver for the module. Also make sure that the module is connected to the computer through USB and is plugged in. Make sure all the wires are secured to the module and their associated control devices (push buttons, potentiometers and toggle switch).
Once that is all done, go ahead and start the XML socket server from the terminal. (You will find directions on how to do this from the software download at makingthings.com).
After the XML server is running, you can then test your application. You can adjust the volume and pan even before you play any songs.
The last step would be to mount to the controls instead of having them just laying out (like I do).
Downloads:
Related Articles:
Making Things: the coolest tinker toys ever
Next tutorial:
Breadcrumbs: Linking to Flash Frames
Previous tutorial:
Working with dynamic anchors
Everyone to their bases - Flash is under attack!
Flash on the beach 2009 - Day 1
Stay current on what's happening in Flash business. Sign up now for the Flashzine newsletter.