PDA

View Full Version : Buttons to play audio



Marblez
June 6th, 2009, 08:08 PM
Hi all,

Is there a way to import audio into Flash and use it in a way similar to a movie clip (give it an instance name and use a button to play it etc.)

Thanks, everyone

Marblez

Navee
June 7th, 2009, 10:16 AM
This routine allows you to play a sound, but also when you click the button over and over the sound restarts due to stopping the sound channel and calling the new Sound constructor (in case you're wondering why it is there twice.) If not, when you click the sound would just stack and double or triple itself (depending on how many clicks were executed!)



button.addEventListener(MouseEvent.CLICK, PlaySound);

function PlaySound(evt:MouseEvent):void {
var snd_channel:SoundChannel = new SoundChannel();
var snd_sound:Sound = new Sound();
snd_channel.stop();
snd_sound = new Sound();
snd_sound.load(new URLRequest("yourfile.mp3"));
snd_channel = snd_sound.play();
}
If you want to play multiple sounds or have one sound playing and perhaps mix or blend another sound; move the sound routine to a method and call it a such:


////////////////////////////////////////////////////////////// | VARIABLE DECLARATION
var snd_channel:SoundChannel = new SoundChannel();
var snd:Sound = new Sound();
var snd_path:String;
var mc_button_name:String = "button";
var button_num = 4;

////////////////////////////////////////////////////////////// | INITIALIZATION
SetButtons(mc_button_name);

////////////////////////////////////////////////////////////// | SetButtons("string");
function SetButtons(mc_button_name:String):void {
for (var i:int= 1; i<button_num+1; i++) {
this[mc_button_name+i].buttonMode = true;
this[mc_button_name + i].addEventListener(MouseEvent.CLICK, PlaySound);
}
}

////////////////////////////////////////////////////////////// | PlaySound(MouseEvent);
function PlaySound(evt:MouseEvent):void {
var selected_button:int = evt.currentTarget.name.substr(mc_button_name.lengt h+1, 1);
SoundRoutine(snd_path+selected_button.toString()+".mp3");
}

////////////////////////////////////////////////////////////// | SoundRoutine("string");
function SoundRoutine(snd_path:String):void {
channel.stop();
snd = new Sound();
snd.addEventListener(Event.COMPLETE, LoadComplete);
snd.load(new URLRequest(snd_path+".mp3"));
channel = snd.play();
channel.addEventListener(Event.SOUND_COMPLETE, SoundComplete);
}

////////////////////////////////////////////////////////////// | LoadComplete(Event);
function LoadComplete(evt:Event):void {
trace("Song has loaded!");
}

////////////////////////////////////////////////////////////// | SoundComplete(Event);
function SoundComplete(evt:Event):void {
trace("Song has finished playing!");
}
I wrote this on-the-fly (hopefully there are no errors...it looks fine though!)

What's going on?

There is a variable declared called mc_button_name where you simply assign the naming convention you use for your movieclip button or button. Meaning button1, button2 or btn1, btn2 or clip1, clip2...does not matter just as long at they have numeric sequential endings (it is for the purpose of looping using the for statement else we could use for each, but numbers are loops best friends and it is easier to count how many numbers verses how many names.)

There is a variable declared called button_num where you set how many buttons you are using. The loop is already set to iterate the button numbers value plus 1. So if you have 6 buttons put 6.

The SetButtons methods sets up all the buttons with a handcursor on mousing over and a CLICK event to the handler PlaySound). It also enables the ability to set different button names/collections due to the 1 parameter/argument.

PlaySound returns the selected numeric index of the button name you set. For instance, if you name the buttons "btn" the substr() method hardcoded would be substr(3,1); Meaning it would only grab the number (the 3rd index of the name btn1, etc) b=0, t=1, n=2 (the number = 3) of the length of 1...but if you had more than 9 buttons then it would be for the length of 2, ie...substr(3,2); So you don't have to fool with it much I would set a variable for the length argument and create an if condition.

I.e. ...substr(mc_button_name.length+1, this_length);

if(selected_button > 9 < 100) {
this_length = 2;
}else if (selected_button > 99 < 1000) {
this_length = 3;
}else{
this_length = 1;
}

This assures you don't have to tweak it if you use more than 9 buttons...I doubt 100, but who knows because it could be a list of links like craigslist but songs. Meaning the button_num value could be stemming from and Array, XML or ServerScript/Database.

Anyway, the custom method SoundRoutine() which was built by removing the guts (lack of better words) from the first example within the mouse event handler PlaySound(). Now we just call it and assign the path to the SetRoutine() method depending on which button is selected.

Let's say your snd_path is "music/mp3_" and your files are sequentially named mp3_1.mp3, mp3_2.mp3, etc. If you selected button 1 snd_path+1.mp3 would play otherwise "music/mp3_1.mp3". If you selected another button it would cut off the first sound and play the next. If you DO NOT call the new Sound() constructor after calling SoundChannel's stop() property (although defined at the top of the script) your sounds will stack as you click other buttons--creating a less desired intention. You could just use the Sound method alone, but the SoundChannel in addition gives you a bit more power with manipulating the sound.

Last: You have 2 Complete events Load and Sound. You could do without them but it is nice to have them, because you may want to do something when the sound has loaded. Ie. fade or tween a menu...Also when the sound has finished playing. Ie. play the next sound/song, close the menu, fade in a screen to rate the sound, skip, replay, the ideas are endless.

I know this is a bit more than you initially asked, but it is always good to throw in a best practice where applicable. On another note speaking best practices...if you are not using the buttons anymore or navigating to a different page for example...then copy the SetButtons() method and paste >change to RemoveButtons() and change the addEvent... to removeEventListener...and simply call SetButtons() again when from the navigation menu that leads to the page where sounds or music will be playing.

If you really see the matrix in this you can package it in your own custom class and reuse your sound playing class in other projects and reduce the headaches from having to write or remember the script. Of course the proper class imports within the class are necessary, but it would be something like this in your actions panel from that point on:

import com.custom.MyClass;
var snd_play:MyClass = new MyClass();
snd_play.SoundRoutine("sound path.mp3");

It is far less code to write in the end...and leads to a cleaner script and less URLRequests, etc. to remember and keep up with.


Cheers

Marblez
June 9th, 2009, 11:17 PM
Thank you so much for the comprehensive response, Navee. I will give it a shot tomorrow. I am basically trying to build an mp3 player with a playlist. I know how to build the basic one with the play, stop, next and previous button. Found a tutorial on xml in flash for creating a player with a playlist but i found it a bit confusing so I was trying the other way out. Many thanks for this.

Marblez

Marblez
June 16th, 2009, 12:49 AM
Hi Navee,

this worked wonderfully for me and i am new to actionscript so it was much appreciated. I do have to be a pest and ask you one more question: would you happen to know the script for putting in
- play and pause buttons
- volume and seek slider
- id3 into the dynamic text field
what happened is that I tried to incoroporate the script I had for an mp3 player (one that doesn't have a playlist) so things went madly awry.
If you could help me out with this, it'd be much appreciated.

Thank you in advance