This user is yet to take control of their account and provide a biography. If you are the author of this article, please contact us via support AT actionscript DOT org. Multimedia is great. Things move, whiz, bang, beep, explode? well you get the idea. Sounds are one of the coolest things that we can add to a site that elevates what we do above the world of text and animated GIFs.
We will be developing these Flash MX files: media-controller.fla (42kb), sound.fla (1787kb), test.fla (1805kb), and test-audio.fla (10kb). Apologies for the larger files, but they have a largish audio sample imbedded in them. When they are published as SWF files, they come in at 3kb, 24kb, 22kb, and 3kb, respectively.
But how do we implement all of those larger sounds? (The ones that you can't just tag on to a button press.) And how do you make them stream nicely? All too often an otherwise great online multimedia presentation grinds to a halt when audio files are played. It's also annoying that you can't usually scrub back or forward to an interesting bit (or skip over the boring parts).
This time we are going to develop an audio player in Flash MX, allowing your visitors to listen to all the samples you want to publish. Specifically, we will:
Here's a big warning: there's a large chunk of tutorial to do bits 2 and 3 first before we get on to developing the controls. And this is a long tutorial. So, if you want to find out if this is worth reading, finish this introduction, check out the "how to use this" bit at the end, and see if you want to read the rest. (That's how I did all my study at University! Ha, hah!)
This tutorial comes in three parts:
What we will not discuss is how to record and mix audio. You will need to supply your own samples to play with.
Before we go any further, I would like to point out that some of the screen shots are from the Western Australian Museum's "Western Australia: Land and People" exhibition. Included in that project were over eighty audio files: mostly commentary by the curators of the exhibition. Now we can all get that "behind the scenes" and "making of" info that is usually reserved for Discovery Channel or the extra audio tracks on DVDs! The Western Australian Museum's great content and our stylish Flash MX work produced an inspiring virtual exhibition.
I am assuming that you have had a glance through the Using Flash help file, and that you have completed the online Flash tutorials "Introduction to Flash MX Tutorial" and "Introduction to ActionScript Tutorial" that come with your copy of Flash MX. You should also be familiar with creating audio files. You may find our other tutorials useful. "Yet Another Flash MX Loader" discusses the creation of the GMG loader. And "Object VR In Flash MX" covers playing back 3D Object VR movies without using the QuickTime player.
What should the media player do?Here's my list of features for our player:
You may want your player to do more: we certainly do. We now have a cool way of buffering content at certain points in a commentary, and it's seriously cool to include closed captions for hearing impaired visitors. You may have other ideas! Add them to the list.
How should the player be structured?The structure for the player is very simple:
|
| We will end up with a control that can play media using some basic interface elements (play/pause, rewind, and a progress bar slider to position the playhead) like this:
|
We will then include the media-controls movie in any file that we want to control our audio media in.
|
| This will be published as our audio SWF file which may be loaded in to any container movie.
|
This is the essence of the container movie:
|
| And it doesn't get much cleaner than that! |
And repeating all that once again for good luck:
![]()
From left to right: we have a media-controller SWF file sharing out our controls to a second SWF file that has our audio media in it which is loaded and displayed by a third SWF file. Get it? Got it! Good.
A little later on in this tutorial we will be importing sound resources, so now would probably be a good time to have a quick look at how to import audio into Flash MX. You will find it in "Using Flash > Adding Sound > Importing sounds" in the contents of your online help. In fact, the whole "Adding Sound" section is probably worth at least a quick glance!
Buttons will play a big part in our media controller. See "Using Flash > Using Symbols, Instances, and Library Assets > Creating buttons" in your help file for more info. Ah, what the heck... spoil yourself: read all of the "Using Symbols, Instances, and Library Assets" section.
Since we will be sharing our controller between all of our audio files, a glance at "shared libraries" in your online Flash MX documentation would be beneficial. You will find it in the "Using Flash > Using Symbols, Instances, and Library Assets > Using shared library assets" in the contents of your online help.
We will also be animating a box-shaped mask. This part of the tutorial is optional, but if you're interested you may want to check out "Using Flash > Creating Animation > tweening shapes" and "Using Flash > Creating Animation > Using mask layers".
Part 1: Start with some easy audioOur first task is to get some audio in to Flash and have it play.
Create a new FLA file. Save it as "test.fla".
Rename "Layer 1" to "media".

Import your audio by selecting "File > Import..." (Ctrl+R). Select your favourite audio file in the Import dialog. If you now open your Library window (F11), you will see your imported audio file ready for use. Well, it's nearly ready... let's check out the Sound Properties.
Double-click on the speaker icon in the Library next to the sound file that you just imported. You should see this dialog:

The Compression combo box contains a list of all of the different types of compression settings that Flash can use. By playing with these settings, you can get a feeling for the final file size you will end up with.

And clicking on the Test button will let you hear what the compression will do to the sound. Click on OK when you have it to your liking.
Try it now. I'm going to make a coffee. I'll be right back.
Putting the sound on the stageAhh, that's better. Good coffee.
To get sound to play correctly for this tutorial we need to add sound to a layer and set it up to stream. This means that the whole sound does not need to download before it starts to play.
Select the media layer. At the bottom of your Flash MX application you will see your Properties window. Drop down the Sound combo and you should see the sound file you have imported. Select your sound and make sure that the Sync combo is set to Stream. This means that your sound will be downloaded and played frame by frame. Don't worry. The sound comes out sounding nice and smooth, it's just that you don't have to wait for the whole sound to download before you can start listening to it. You also have the added bonus of being able to jump to any frame (or position) in the sound by using a gotoAndPlay command.

Right now, though, your media layer will probably have only one frame. This is bad when we are trying to stream the sound. We need enough frames to play all of it. Right-click on the media layer timeline somewhere to the right of frame 1. Select Insert Frame. You should see your sound wave drawn in the frames that you have created. Keep inserting frames until you can see all of your sound.
![]()
Delete any extra frames that have no sound in them so that we don't end up with silent frames at the end of the sound.
Now if you click and drag the playhead (pinky-red rectangle in the timeline) you should hear the sound you imported. It will sound jerky here.
Test your movie (Ctrl+Enter) to hear your sound correctly.
Adding a sample graphicIt's great to hear a sound, but we're going to add an image of the waveform for people to look at while the sound plays. This gives a visual indication of what the audio will sound like. We will look at a simple method for generating a waveform and add it to our sounds.
This section is not critical to developing the audio controllers, so feel free to skip it if you are not really interested. You can animate anything you like over the duration of the sound. Feel free to experiment!

In the Library, when you have your sound selected, the wave form for the sound is shown. My sound is stereo; yours may be mono (you may only see one wave). If you make sure that your stage is shown at 100%, you can resize the Library window (and the area that the waveform is shown in) to a size that you would like to show the wave at.
Do a Print Screen to copy the screen to the clipboard. Start your favourite paint program. Paste in the image of the screen. Crop the waveform to an appropriate size. Adjust the colours of your wave so that it is a black wave on a white background. Save your waveform image as a GIF with white as your background transparent colour (so that we can easily tint the waveform later). I saved it as sample.gif.
This is what I ended up with for my audio file:

Import your GIF into the Library ("File > Import to Library..."). Don't do the Ctrl+R thing this time. We don't want the image on the stage yet.
Now create two new layers above the media layer. Name them "sample grey" and "sample black". You should now have this in your timeline:

What we are going to do here is have a greyed-out waveform of our sample which will slowly turn black as the sample plays.
Select the sample grey layer and drag your GIF bitmap on to the stage. Put it roughly in the centre. Done that? Good. In order to tint the GIF, we first need to convert it to a graphic. So, with the GIF bitmap selected on the stage, do an "Insert > Convert to Symbol..." command (F8), name it "sample" and give it a Graphic behaviour. Like this:

Down in your Properties panel you should now see a Color combo box. Set this to Tint and pick a colour and a percent to tint. I chose grey at 100%. (I did name the layer "sample grey", but you may choose anything you like!)

With your sample symbol still selected (sorry for the alliteration), do an "Edit > Copy" command (Ctrl+C), select the "sample black" layer, and do an "Edit > Paste in Place" command (Ctrl+Shift+V). This will put a copy of the waveform sample symbol in the same position that we had in the "sample grey" layer. Set the Color of the newly pasted sample to a black Tint (or set the Color to None, which is what I did).
We need these GIF bitmaps to line up so that when we reveal the black sample using a mask, we don't get the waveform wobbling. Doing a Paste in Place solves this nicely, but you could also do it with your Align panel.
We're now going to add a mask to the "sample black" layer and reveal it as the sound is streaming from the first frame to the last. This will result in a waveform that starts out grey and swipes to black as the media plays.
Select the "sample black" layer and insert a layer. Name the new layer "sample mask". Select the "sample mask" layer and use the "Modify > Layer..." command to call up the Layer Properties dialog and select the Mask Type for the layer like this:

Select OK and we're nearly there.

Click and drag the "sample black" layer. When you get it right, the dotted green oval will go dark green.

And release the drag so that it is under the "sample mask" layer.

Now anything that is drawn on the "sample mask" layer will reveal anything that is indented under it (with the dotted green page icons). So, to reveal the black waveform, we are going to Shape Tween a box in the mask layer to slowly cover (and thus, reveal) the black waveform. Let's do it.
Select the "sample mask" layer. Select the Rectangle Tool (R) and draw a rectangle. Double-click on the rectangle frame and delete it (it's not really useful to us for this). Click to select the rectangle fill (it will get dots on it). Click and drag the top left corner of the rectangle until the drag outline snaps to the top left corner of the waveform sample.

Now select the Free Transform Tool (Q) and drag the bottom right corner of the rectangle so that it snaps to the bottom right corner of the waveform sample. If you lock the masked layers (click on the dots under the padlock in the timeline) you will only see the black waveform. If you unlock the layers again and drag the right hand side of the rectangle to about half its width, you will see left half black and right half grey when you lock them again.

OK. Unlock the layers and drag the right hand side of the rectangle back again. Now add a keyframe in the last frame of your "sample mask" layer and select frame 1.
In your Properties panel for frame 1 choose a Shape Tween. Free Transform the right hand side of the rectangle to the left until you can't see the rectangle any more (you may need to zoom in to do this properly - try Ctrl+Shift-rolling your mouse wheel to zoom in). Transforming the rectangle like this should give it a width of zero.
Now lock the mask layers again. If you click and drag the playhead you should hear the sound you imported playing and the waveform will transform from grey to black as you scrub back and forth.

I have also added a playhead indicator using shape tweening, but I will leave that as an exercise for you to try at home!
Save now. Have a break. Next up we are going to do some coding!
Part 2: Planning our controlsWhat do we want to end up with? For the "Western Australia: Land and People" exhibition we needed a movie control that we could just drag and drop on any file that had audio in it (we had over 80 files to add controls to, so it had to be quick and simple). This means that everything has to be put in to a single movie so that we can just drag and drop the controls onto our sound. So first up:
Within that we needed Play/Pause and Rewind buttons, giving:
A slider would be nice, for selecting a point to play from:
And the slider should have a Drag button for positioning the playhead:
The slider should probably also contain a preload or streaming indicator to give some feedback on how much of the sound has been loaded so far:
This image shows the slider (on the left) with the dragger and a light grey preload indicator. On the right are the rew, play, and pause buttons. All these elements will be contained in a single movie clip ready for us to drop on to a sound.
![]()
That'll do for now. We're going to build and test the controls in test.fla and then, when it all works, we'll rip out the control movie and dump it into a media-controller.fla where we will make it available as a shared resource. That way, we'll be able to use it anywhere.
All right, easy bits first.
Getting the sound to play, pause and rewindFirst, we'll get the container movie out of the way. Create a layer in test.fla for our controls. I put the layer at the bottom and named it "controller". Select the "Insert > New Symbol..." command (Ctrl+F8) and name it "media-controls", giving it a Behaviour of Movie Clip.
Select the controller layer you created and drag the media-controls movie clip on to the stage just under your waveform image. All right, you may put it wherever you want. It doesn't make much difference for now.
Open your media-controls movie and create three buttons: "play", "pause", and "rew". We gave them some standard-looking icons and some clicky sounds for mouse-overs and presses. And I'm not going into details about how to make buttons. That stuff is in your help files - just don't use components. They are rather large (too many bytes) and tend to load in the first frame.
Put your buttons on layers named "play", "pause", and "rew", and align them with your sample waveform as you like! This is what I did:

I have placed the buttons on the right to leave room for the slider that we will add later.
Now for the button code. Because our sound is streaming on the timeline of our parent movie, all we have to do to control our sound is to control our parent movie as we would for any other movie.
Paste this code on the Rewind button:
[as]on (release) { //rew
_parent.gotoAndStop(1);
}
[/as]
Paste this code on the Pause button:
[as]on (release) { //pause
_parent.stop();
}
[/as]
Paste this code on the Play button:
[as]on (release) { //play
_parent.play();
}[/as]
All of this is standard movie clip control code.
Test your movie (Ctrl+Enter). The sound should play and animate the waveform as it goes along. And the three buttons should operate as expected. This will give you the basic functionality, but we can do better than this. Let's make the Play/Pause buttons seem like one button that toggles between play and pause states, and get the Rewind button to rewind-and-play (if the sound is currently playing) or rewind-and-stop (if the sound is paused).
What we will do is hide the Play button (set its _visible property to false) if the sound is playing or show the Play button (set its _visible property to true) if the sound is paused. If we align the Play and Pause buttons so that the Play covers the Pause, we will get our toggling effect!
Because we will be accessing the Play button's _visible property, we need to give our Play button an Instance Name. Select the Play button on the stage and look at your Properties panel. You will see a text box with "

Make the changes to the code for our three buttons.
Paste this code on the Rewind button:
[as]on (release) { //rew
if (playBTN._visible) { //paused
_parent.gotoAndStop(1);
} else { //playing
_parent.gotoAndPlay(1);
}
}
[/as]
Paste this code on the Pause button:
[as]on (release) { //pause
_parent.stop();
playBTN._visible = true;
}
[/as]
Paste this code on the Play button:
[as]on (release) { //play
_parent.play();
playBTN._visible = false;
}
[/as]
Then realign the buttons by dragging the Play button over the Pause button.
Now test it. Working? Really? Here's the problem: the parent movie (our sound) starts out playing, but the Play/Pause button defaults to a state that is appropriate for a paused parent movie.
We have two options: (1) only add code to stop the parent movie and just leave the rest as it is, or (2) put the Pause button above the Play button in the layers and recode to show and hide the Pause button. I chose the first option, added an actions layer and put a stop command in frame 1 to stop the parent movie from playing. Like this:

Test it now! And save.
Adding a load indicatorWe could use a preloader for this, but that wouldn't make the best use of Flash's streaming capabilities. What we are going to do is show how much has loaded and then let the visitor play any part that Flash has cached. We thought this would be best achieved with a slider. So let's make one.
Our first task is to create a progress bar movie clip to contain our slider.
Create a layer in the media-controls movie clip in test.fla for our slider. I put the layer between the actions and rew layers and named it "slider". Select the "Insert > New Symbol..." command (Ctrl+F8) and name it "progress-bar", giving it a Behaviour of Movie Clip.
Select the slider layer you created and drag the progress-bar movie clip on to the stage to the left of the buttons we have completed (or put it anywhere else you feel is appropriate).
Open the progress-bar movie clip and now draw the background rectangle that will form the basis for our slider. I made mine with a black fill and border. My dimensions for the rectangle were 171 wide and 4 high. Rename "Layer 1" to "base" ('cos it's the base of our slider). You should have this (the stage is zoomed in a bit):

Now for the highlight that will grow within this base as more and more of the audio file is loaded.
Create a layer above the base layer and name it "highlight". On the highlight layer, draw a rectangle (any colour you like), select and delete the rectangle's border, and align it with the start of the base layer's rectangle. Like this:

To be able to change the size of this in code, it needs to be a movie clip, and it needs to have an Instance Name.
Select your grey (or whatever colour you chose) rectangle and use the "Insert > Convert to Symbol..." command (F8). Name it "frames-loaded" and give it a Behaviour of Movie Clip.
Make sure that your new frames-loaded movie clip is selected. In the Properties panel, set the
Time for a slight diversion.
The code for the slider will get a little tricky. To minimise confusion and to make code maintenance easier, we are going to keep as much of our code in one place as we can. That place will be a functions layer that will contain our ActionScript code. So create a new layer at the top of the timeline and name it "functions".
Out of habit, we usually have some standard layers in all of our FLA files:
| Layer name | What we use it for |
| labels | Contains a whole bunch of labelled keyframes and nothing else. This makes it easy to see where our labels are and what they are called. |
| actions | ActionScript that needs to be executed as the movie is playing. We don't put any functions in this layer, just code that needs to be executed on a keyframe. |
| functions | This is for ActionScript functions that we call from the actions layer or in event handlers on movie clips or buttons. When we have the majority of code in one place, it makes debugging much easier because it is easy to find the code. |
That's it. Diversion over. Back to our progressBar code.
Our first function will set the size of the progress bar according to the sound download progress. This code needs to go into your newly created "functions" layer:
[as]function setProgressBar() {
var parentLoaded = 170 * _parent._parent._framesloaded / _parent._parent._totalframes;
progressBar._width = parentLoaded;
}
[/as]
We are setting the _width of the progressBar movie clip to a fraction of the width of our rectangle on the base layer. I made the rectangle 171 wide and indented the progressBar movie clip by 0.5 from the left, so I want the same distance in from the right, giving 171 - 0.5 - 0.5 = 170. The fraction of 170 that we want is given by the usual _framesloaded / _totalframes. No new stuff here! The only tricky thing is that we have to go up far enough so that _framesloaded and _totalframes will refer to the Flash movie that has the sound streaming on the timeline.
The following table shows what code accesses which movie clip:
| Variable | Movie clip |
| _framesloaded | progress-bar |
| _parent._framesloaded | media-controls |
| _parent._parent._framesloaded | Main timeline |
And now back to the progressBar movie clip. This is the code that needs to go on it to call the setProgressBar function:
[as]onClipEvent (enterFrame) {
_parent.setProgressBar();
}
[/as]
Test this (Ctrl+Enter) with streaming (Ctrl+Enter again). As Flash simulates the download, you should see the grey bar in the black slider background growing until all of your sound has loaded.
Save now.
Time to add a button to our slider that we can drag back and forth to position the playhead. To do this, we will need a button to drag. So create a button named "dragger", create a layer above the highlight layer and name it "dragger" as well, and put your new dragger button on that layer. Give it an Instance Name of "draggerBTN". We will need this to access our dragger in code to find out where it is and to move it.
For starters, we will just make it move along the slider as the sound plays. When we have that working, we will add code to let us control the sound playback by dragging the slider.
To keep the next bit of math simple when we work out where to put our dragger when the sound is playing, we need to align the registration point of the dragger with the top left of our highlight, like this:

When it is aligned, double-click on the dragger button to edit the graphics and put it where you want it. Make sure that you move all of your keyframed graphics when you do this!

Now that we have done our alignment visually, we won't have to compensate by doing weird coding! Using this approach, we don't need to add corrections to our formulas to compensate for where the registration point is for the dragger. We get rid of a lot of "+4.5" and "-5" sort of things from the code that never make sense when you go back and try to modify it later.
Flash is a visual tool: try to work visually as much as you can and only add code as a last resort.
The code we need is basically the same as the code that we used for the progress bar. We have to go up from the mover movie clip to where our sound is, work out what the current frame is as a fraction of the total frames, and calculate where that position is along our 170 wide progress bar. Once we have that value, we need to go up to our draggerBTN and move it to that position.
Time to add another function to our functions layer:
[as]function setDraggerPosition() {
var targetPosition = 170 * _parent._parent._currentframe / _parent._parent._totalframes;
draggerBTN._x = targetPosition;
}
[/as]
Now we need to create a dummy movie that won't be seen and will simply hold a bit of onEnterFrame code that will call our setDraggerPosition function to move our dragger as the sound is playing. So go back up to the progress-bar movie clip and create a layer named "movieMover", draw in a rectangle, convert the rectangle to a symbol (F8) named "mover".
This code needs to go on the mover movie clip to call the setDraggerPosition function:
[as]onClipEvent (enterFrame) {
_parent.setDraggerPosition();
}
[/as]
I don't really want the mover movie clip to be visible, so let's set its Alpha to 0% in the Properties panel and we're done.
Test the movie (Ctrl+Enter). When you hit play, the slider should move across as the sound plays. We haven't got any code on the dragger yet to handle dragging: we're going to do that next! But we have a little problem when we get to the end of the sound: it loops back to the start again and continues playing. If you want to, this may be fixed by replacing the setDraggerPosition function with this code:
[as]function setDraggerPosition() {
var targetPosition = 170 * _parent._parent._currentframe / _parent._parent._totalframes;
draggerBTN._x = targetPosition;
if (_parent._parent._currentframe == _parent._parent._totalframes) {
_parent._parent.gotoAndStop(1);
_parent.playBTN._visible = true;
}
}
[/as]
The "if" statement checks to see if the playhead is at the end of the sound. When it gets there we put it back to the beginning and stop playing. We also show the Play button again for the visitor.
As an exercise, you could add a Loop button toggle that works similarly to the Play/Pause button. When the Loop button is active, the movie would loop continuously; when the Loop button is inactive, the sound playhead would return to the beginning of the sound and stop.
Save now.
Dragger statesOur dragger will need to perform two tasks. When the visitor is not dragging the slider control, we need to move the dragger so that it matches where the sound playhead is. When the visitor is dragging the slider control, we will need to stop playing the sound and move the sound playhead to match the movement of the slider. Let's call the first task (also known as a "state" in geek-talk) "mediaPlaying" and the second task "moveMedia".
We have already done the first bit: our dragger is being moved around when the sound is playing or paused. When we do the second bit, we need to stop moving the dragger and let the visitor do the dragging. While the visitor is dragging the slider control around, we need to work out where the dragger is and move the sound playhead to the appropriate frame.
Currently, our mover movie clip on the movieMover layer has onClipEvent code that works well for our mediaPlaying state.
The easiest way to give our slider two states is to use two frames in the progress-bar movie clip: frame 1 for the mediaPlaying state and frame 2 for the moveMedia state. If we keyframe our movieMover layer on both frame 1 and frame 2, we can have different onClipEvent code for mediaPlaying and moveMedia.
Our mediaPlaying code stays the same (it moves the dragger to a position that is appropriate for where the sound playhead is). Our moveMedia code will be new (it will move the sound playhead to a frame that is appropriate for where the dragger is dragged to).
We will give frames 1 and 2 Frame Labels so that our gotoAndStop commands that we add soon will be easier to understand. Instead of gotoAndStop(1) we will be able to write gotoAndStop("mediaPlaying") if we use labels.
How do we do this? Add a "labels" layer to the top of the progress-bar timeline.
Select frame 2 for all of the layers and do an "Insert > Frame" command (F5).
Select frame 2 of the labels layer and "Insert > Keyframe" it.
Select frame 2 of the movieMover layer and "Insert > Keyframe" it as well.
Select frame 1 of the labels layer and in the Properties panel, enter "mediaPlaying" in the text box.

Select frame 2 of the labels layer and in the Properties panel, enter "moveMedia" in the text box.
Select frame 2 of the movieMover layer and click on the mover movie clip. In the Actions panel, you should see a copy of the onClipEvent code that we entered before (the code to move the dragger to a position that is appropriate for where the sound playhead is). Select all of the code in the Actions panel and delete it. We don't want this code trying to keep the dragger in one place while the visitor is trying to drag it!
Check that the code for frame 1 of the movieMover layer is still there. Select frame 1 of the movieMover layer and click on the mover movie clip. In the Actions panel, you should see a copy of the onClipEvent code that we entered before (the code calls setDraggerPosition).

To finish this off, we need to add an "actions" layer between labels and functions. Add a keyframe to frame 2. Put a stop() command on actions frame 1. Also put a stop() command on actions frame 2. This will make sure that whenever we change state, our progress bar movie won't repeatedly play through all of our states and cause hard-to-track-down bugs.
In this section, we have only prepared our slider for the playhead positioning code. We did this by making our controller movie (movieMover) execute different code in frame 1 and frame 2. This way the ActionScript we develop in the next two sections can be simpler.
It's time to start working on the dragger. Our dragger will ultimately control what frame of our sound the playhead is on.
We will need to limit its movement to horizontal movement so it can't move up and down, and additionally limit its horizontal movement to only what has been downloaded so far (that will be defined by the current width of our progressBar).
Nothing fancy here, just making use of the various dragger methods in Flash. Here is the code to add to the functions layer:
[as]function startDragger() {
gotoAndStop("moveMedia");
var leftLimit = progressBar._x;
var rightLimit = progressBar._width + progressBar._x;
startDrag("draggerBTN", false, leftLimit, progressBar._y, rightLimit, progressBar._y);
}
function stopDragger() {
gotoAndStop("mediaPlaying");
stopDrag();
}
[/as]
When the visitor starts dragging, we move to the frame labelled moveMedia so that our mover movie clip stops trying to update the slider. When the visitor stops dragging, we go back to the mediaPlaying frame label so that our mover movie clip starts updating the slider again as the sound plays.
This code needs to be placed on your draggerBTN:
[as]on (press) {
startDragger();
}
on (release, releaseOutside) {
stopDragger();
}
[/as]
Time to test it (Ctrl+Enter). Your dragger should now drag okay, but it won't be affecting anything because we haven't written any ActionScript for this yet. And when you release the dragger, it will snap back to the position that is appropriate for the position of the sound playhead because we haven't been changing the playhead position when you were dragging the slider.
Test the streaming (Ctrl+Enter again). You should only be able to drag within the bit that has been loaded.
One more bit to code and we've finished with our slider.
Setting the sound's playhead positionThe mover movie clip on the movieMover layer controls two things: (1) it moves the dragger to a position that is appropriate for where the sound playhead is, and (2) it moves the sound playhead to a frame that is appropriate for where the dragger is dragged to.
We've got bit 1 working: time to work on bit 2.
This is the code to move the sound playhead:
[as]function setMediaFrame() {
var targetFrame = int(draggerBTN._x / 170 * _parent._parent._totalframes) + 1;
_parent._parent.gotoAndStop(targetFrame);
_parent.playBTN._visible = true;
}
[/as]
We take the _x position of the dragger, work out its fraction along our slider, and convert that to a portion of our sound's total frames. This will give values from zero to less than the _totalframes property, so we add one because we need targetFrame to start at 1 just like the timeline does. And because we have stopped playing the sound (because we used gotoAndStop), we need to make our Play button visible.
This code needs to go on the mover movie clip in frame 2 to call the setDraggerPosition function:
[as]onClipEvent (enterFrame) {
_parent.setMediaFrame();
}
[/as]
Test it now. We're all done here with the major development! Save it and go get a beer. Get one for me too while you're up. Guinness, if you've got one. Thanks!
Making the media controls ready for sharingSo far we have a good set of controls in a movie, but they're not going to be easy to reuse as they are. If you've done any of our other tutorials, you will know that our next step will be to share the resources for use in other files.
Using the "File > Save As..." command (Ctrl+Shift+S), save the test.fla file as media-controller.fla. This will be the file that we will get media controls from after we have finished this section.
You should now have two Flash MX files:
| test.fla | Where we did all our initial development and testing of our media controls. |
| media-controller.fla | The file that we will tidy up and get ready for sharing out our completed media controls to other Flash files. |
From now on we are only working on the media-controller.fla file
Go back to your main timeline: the one with the sound and waveform graphics on it. Now delete all of the layers except the controller layer. Really. Do it. And delete all additional frames on the controller layer, leaving only frame 1.
And save it. We don't need those bits any longer. They were just for development. It's difficult to build media controllers without any media to control!
And we need to dump all of that media from the Library as well. So open the Library (F11) and let's get started. I deleted the sound resource, the sample GIF and the graphic we made from the GIF. That left all this stuff:

So I tidied it up a bit:

The next bit of preparation involves exporting our resources for runtime sharing (look it up in the online help, or check out our other tutorials). Right-click on the media-controls movie clip and select "Linkage..."

The Linkage Properties dialog opens. Fill it out like this:

Do the same to all resources in the Library. You will find that once you have set up one resource for runtime sharing, when you go to do the others, all of the fields will be filled in automatically. The Identifier text box will change to the name of each resource you export.
Save the file.
Do a quick test (Ctrl+Enter). This will create the media-controller.swf file for us. Have a look at the size of the media-controller.swf file: mine came out to 2,836 bytes! Not bad! And our site visitors will only have to download this sucker once.
Next up, I will demonstrate how to use the controls.
Our approach to using the media controls is simple:
I'm not going to go through steps 1, 2, and 3 in detail 'cos it's exactly the same as the stuff we did earlier in this tutorial. See sections "Start with some easy audio", "Putting the sound on the stage", and "Adding a sample graphic" for the specifics. Here's a quick recap of that material:
For longer sound files, we found that the waveforms looked too complicated to be meaningful, so we replaced them with a couple of simple microphone images (one in colour and the other in duotone), and then tweened them like this:

That's it for the quick revision on how to prepare the sound with the animation. Now we're going to add the media controller.
Open your Library (F11) and add a folder named "utilities". This folder will keep any bits and pieces that we add to the file. It's always a good idea to keep your library organised on larger projects.
Make sure that your media-controller.fla file is open and that the Library for it is also open. Now drag the media-controller movie clip from the media-controller.fla file and drop it into the utilities folder in the sound.fla file.

That makes the sound.fla file go looking for the media-controls movie clip in the media-controller.swf file when it needs to use it. Close the Library for the media-controller.fla file.
Go back to the sound.fla file and create a new layer at the bottom of the layers and name it "controller". Select the controller layer. Drag the media-controls movie clip on to the stage. Position it to your liking. We also reduced the size of the stage so that our sound animation and controller just fit on it.

Save the sound.fla file and test it (Ctrl+Enter). You will find that you have a fully functioning audio player. Testing will also create the SWF file (sound.swf) for us.
Finally, we are going to build a main Flash MX file to host our sound file. When we split our Flash sounds into a main file, a sound file, and a controller file, we get several benefits:
Create a new Flash MX file and save it as "test-audio.fla". The only important thing to do to the file is add an empty movie clip that you can load the sound.swf movie into and a bit of code to do the loading.
Use the "Insert > New Symbol..." command (Ctrl+F8) to create a new movie clip resource. Name it "movie-container". Create a new layer named "audio" and drag the container movie clip on to the stage where you would like your sound animation and controller to be loaded. Make sure that your movie-container movie clip has an Instance Name of "container" so that we may refer to it easily with ActionScript.

Now add an actions layer for the code to load our sound.swf file. This is the code to do it:
[as]stop();
container.loadMovie("sound.swf");
[/as]
We also added some text and colour to finish things off.

That's it! Save and publish. Nothing more to do (unless you would like to test it).
Anything else?
No. Don't be greedy. But if you are interested in other tutorials that we have written go check out "Yet Another Flash MX Loader", "Object VR In Flash MX", and "Flash MX Skip Intro" elsewhere on this site. You'll be glad you did!
ConclusionIn the online exhibition, we really wanted to deliver something that most people just couldn't get from going down to the Western Australian Museum in Perth, Western Australia, and checking out the "Western Australia: Land and People" exhibition in Hackett Hall. It was just fantastic that the curators of the physical exhibition could share their thoughts for the online version. Once all of the commentary was recorded by Darren Mok, we needed a quick and simple procedure for publishing all of the files in the online exhibition. This is it. Well, it's sort of what we used.

In our final implementation of this audio player in the "Western Australia: Land and People" site, we did the usual trick of loading all window, caption, and text elements as early as we could, then when we hit the sound, we used our loader to indicate progress. Because we can put the loader anywhere we like, we can make the best use of the streaming capabilities of Flash MX and just when things start to stall (when it hits the audio) we whack in a loader so that the site visitor still sees something happening. And when the audio is playing we have another progress bar to let them know how far through the sample they are.
The audio player we developed here is more like the video player we developed for the Western Australian Museum. It's a bit more complicated, a lot more flexible, and better for reuse.
Hmm. Video player. I think that will be the next tutorial off the ranks!
See you soon.
About the authorsThe Glasson Murray Group, Pty. Ltd. creates and presents high quality and engaging content for delivery across a range of media. They designed and developed the virtual exhibition in conjunction with the Western Australian Museum, producing a truly compelling and unparalleled presentation.
CopyrightMaterials are copyrighted and are protected by worldwide copyright laws and treaty provisions. Copyright law in Australia is contained in the Copyright Act 1968 (Cth) and in decisions of courts, with further amendments in the Copyright Amendment (Moral Rights) Act 2000. They may not be copied, reproduced, modified, published, uploaded, posted, transmitted, or distributed in any way, without GMG's prior written permission. Except as expressly provided herein, GMG and its suppliers do not grant any express or implied right to you under any patents, copyrights, trademarks, or trade secret information. Other rights may be granted to you by GMG in writing or incorporated elsewhere in the Materials.
© 2003 Glasson Murray Group Pty Ltd (ACN 098 651 542), Western Australia. All rights reserved.