IntroductionWelcome| 00:00 | (Music plays.)
| | 00:07 | Welcome to Flash CS4
Professional Audio Techniques.
| | 00:11 | I am Todd Perkins and I will be
walking you through this title, teaching you
| | 00:14 | how to use object-oriented programming
techniques to manipulate audio in Flash Player.
| | 00:21 | We will look at how to load external
sound files, how to control their playback.
| | 00:26 | We'll work with building an XML
playlist, controlling sound volume, sound
| | 00:34 | progress and we will even talk about how
to share your application over the web.
| | 00:38 | We have a lot to learn
here, so let's get started.
| | Collapse this transcript |
| Using the exercise files| 00:00 | If you are a premium subscriber to Lynda.com
or if you purchased this title on a disk,
| | 00:05 | you have access to the
exercise files for this title.
| | 00:09 | The exercise files for this
title are organized by chapters.
| | 00:14 | Each chapter is organized by movie.
| | 00:20 | For each movie, you will have the starting
files as well as the files that I end up with.
| | 00:27 | That way, in case something goes
wrong in your code, you can have the
| | 00:30 | final files as a backup.
| | 00:35 | Generally, all chapters
are organized in that way.
| | 00:39 | The last chapter, however, just
has all the files in there by itself.
| | 00:45 | As we are going through the title,
you will see what files you need to work
| | 00:48 | with on your screen.
| | 00:51 | If you don't have the exercise
files, you can still follow along.
| | 00:54 | I will show you what you need to do to
set up your FLA and ActionScript files in
| | 00:59 | the way that you need so you
can follow along with every step.
| | 01:04 | So let's get started.
| | Collapse this transcript |
| Prerequisites| 00:00 | Since this is a pretty advanced title,
you should come into it knowing a lot
| | 00:05 | about Flash and ActionScript.
| | 00:08 | In this movie, we will talk about
the prerequisites for this title.
| | 00:11 | You should be familiar with the basics
of Flash, equivalent to that taught in
| | 00:15 | Flash CS4 Essential Training.
| | 00:17 | So you should be very
comfortable with the interface.
| | 00:20 | You know how to navigate through
movie clips and the Library, and the
| | 00:23 | Properties panel, etcetera.
| | 00:25 | You should be familiar with publishing Flash
files including creating SWFs and HTML files.
| | 00:31 | You should have some basic
ActionScript training at the very least.
| | 00:36 | ActionScript 3.0 for designers is a
title that's designed to teach programming
| | 00:41 | to people that are new to programming.
| | 00:44 | So if you don't know any
ActionScript at all, I suggest starting there.
| | 00:48 | Finally, we are going to be doing a lot of
object-oriented programming in this title.
| | 00:53 | If you don't know object-oriented
programming, I highly recommend watching my
| | 00:57 | title in object-oriented
programming in ActionScript 3.0.
| | 01:02 | So if you feel comfortable with Flash
CS4 and ActionScript 3.0, you are ready to
| | 01:07 | start working with audio in this title.
| | Collapse this transcript |
| Course overview| 00:00 | Throughout this title we are going to
look at making all of the individual
| | 00:04 | elements of a full featured audio player.
| | 00:07 | Here is an example of some of the
features that you are going to learn.
| | 00:13 | You will learn how to play
an external audio file.
| | 00:15 | (Music Playing)
| | 00:17 | You will learn how to
manipulate a song's volume.
| | 00:22 | (Music Playing)
| | 00:29 | Take sound wave data from a
song and display it visually.
| | 00:35 | (Music Playing)
| | 00:37 | And add elements to share
your songs over the web.
| | 00:38 | We will also talk about how you can
put links to buy songs through iTunes.
| | 00:49 | By the time you are done with this
title and you will have all the skills
| | 00:52 | that you need to add object oriented
programming audio elements to your own applications.
| | Collapse this transcript |
| About the music| 00:00 | The music for this title has been
provided by a friend of mine and fellow and
| | 00:04 | Lynda.com author Garrick Chow.
| | 00:08 | He is in a band called The Jellybricks.
| | 00:10 | He has provided one of their
full-length albums for us to work with.
| | 00:15 | So I thought I would take a movie to
thank him for providing that and show you
| | 00:18 | guys where you can find more
information about his band.
| | 00:23 | The band is called The Jellybricks,
and their website is thejellybricks.com.
| | 00:27 | So, you can go there and find all of the
information about the band that you need.
| | 00:31 | So, thank you very much Garrick, we are
glad to be using your music in this title.
| | Collapse this transcript |
|
|
1. Audio BasicsSetting up your FLA and other files| 00:00 | Before we start creating our music
player, let's take a look at how to organize
| | 00:04 | your FLA file and the other
files that you will be working with.
| | 00:09 | In the exploring-fla folder,
I have a folder called start.
| | 00:13 | That's where the files are that you
will be working with for this exercise.
| | 00:16 | I have a music file called 01 Eyes Wide.mp3.
| | 00:20 | If you don't have the Exercise
Files, you can use any MP3 file here.
| | 00:25 | In addition to that file, I have an
FLA file called player.fla, which we
| | 00:29 | will explore later on.
| | 00:31 | And a folder called com.
| | 00:33 | Note that it is all lowercase.
| | 00:35 | Inside of the com folder is a
folder called lynda, also all lowercase.
| | 00:39 | Inside of the lynda folder is a
folder called audio, also all lowercase.
| | 00:44 | And inside of there is a lone action script
file Player.as, note that it starts with a P.
| | 00:50 | If you don't have the Exercise Files, now it
is probably a good time to create that file.
| | 00:54 | So, create Player.as and
just save it in that folder.
| | 00:58 | Let's take a look at player.fla in Flash.
| | 01:02 | This file is actually pretty simple,
on the stage here there is only one
| | 01:06 | layer and one frame.
| | 01:07 | If I select the artwork on that layer,
you will see that it's a single movie clip.
| | 01:12 | I will expand the Properties
panel and we will take a look.
| | 01:15 | Note that it is called player_mc.
| | 01:18 | And if I double-click that movie
clip, I can enter its Timeline.
| | 01:23 | Inside its Timeline, you will see three layers.
| | 01:26 | There is the pause layer, the play
button layer, and the background layer.
| | 01:30 | The pause layer contains a
movie clip called pause_mc.
| | 01:36 | The movie clip is actually just a
simple Bitmap graphic of a pause button.
| | 01:41 | I will zoom in a little bit so
you can see it. It is right there.
| | 01:46 | It looks kind of funky because
the play button is right behind it.
| | 01:49 | But it is just a Bitmap graphic, and
you don't have to use a Bitmap graphic.
| | 01:52 | You can just make your own little
quick vector graphic if you would like.
| | 01:55 | So, back to the player, I will hide the
pause button, and then double-click the
| | 02:01 | play button to enter its Timeline.
| | 02:04 | The play button is also a simple Bitmap graphic.
| | 02:07 | Back to the player movie clip, note that the
play button has an instance name of play_mc.
| | 02:13 | The background is actually just
a rectangle with a Bitmap fill.
| | 02:18 | In other words, I imported a Bitmap
image I created in Photoshop, I drew a
| | 02:22 | rectangle and using the Fill Color menu I
selected the Bitmap that I imported there.
| | 02:30 | And that's really all there is to this FLA file.
| | 02:33 | So, once you have your FLA file setup, you are
ready to start writing the code for our application.
| | Collapse this transcript |
| Creating the Player class| 00:00 | In this movie we will look at creating the
main ActionScript class for our audio player.
| | 00:05 | The first thing I want you to do is go
to the Library, right-click or Ctrl+Click
| | 00:10 | the Player movie clip and choose Properties.
| | 00:15 | Note that I have this movie clip
Exported for ActionScript, and the Class I am
| | 00:20 | using is com.lynda.audio.Player.
| | 00:24 | If your player ActionScript file is
just a blank ActionScript file, then Flash
| | 00:29 | is going to get mad at you for doing this.
| | 00:32 | If your player Class file does not have
any code in it yet, this may not work.
| | 00:37 | So, you may want to write the code and
then come back to Symbol Properties, and
| | 00:41 | type in the name here.
| | 00:43 | Notice it's the fully qualified
class name, which includes the package
| | 00:46 | com.lynda.audio, and just as a
refresher the package name corresponds to
| | 00:52 | that folder structure.
| | 00:53 | So, there's the com folder, inside of
the com folder is lynda, inside of the
| | 00:57 | lynda folder is the audio folder,
which contains the file Player.
| | 01:01 | So, I am going to click OK.
| | 01:05 | So, once you have done
that, go over to Player.as.
| | 01:08 | Now, I have already started building
this Class file and I am just going to get
| | 01:12 | a little bit more room here
by minimizing the other panels.
| | 01:15 | Now, I just wrote the
basic skeleton of a Class file.
| | 01:18 | If you don't have the Exercise
Files, just copy the code I have here.
| | 01:22 | Make sure to declare the com.lynda.audio package,
and import the main classes we will be using.
| | 01:29 | All the display classes, all the
event classes, all the geometry classes
| | 01:35 | which is flash.geom, media classes for the
sound, and the net classes for the URL request.
| | 01:41 | I have my class declaration here.
| | 01:44 | I am extending the MovieClip
class, and inside of there I have my
| | 01:49 | constructor defined.
| | 01:50 | So, let's start defining a few properties.
| | 01:53 | In order to work with sound, you need a
sound object and a sound channel object.
| | 01:58 | So, first I will create a public property.
| | 02:00 | So, public var channel,
datatype it to a SoundChannel.
| | 02:04 | Remember the SoundChannel class is used
to play the sound, and stop a sound, to
| | 02:11 | get the sounds position and everything.
| | 02:13 | The sound class basically just loads the sound.
| | 02:17 | Another public property called sound,
datatype it to an instance of the Sound class.
| | 02:23 | And one more property, this will
also be public and we will call this
| | 02:27 | resumeTime, datatype it to a
Number and set it's initial value to 0.
| | 02:33 | This will represent the time in
milliseconds that the file will resume at when
| | 02:39 | you click the play button.
| | 02:40 | So, 0 would be the very beginning of
the song and a thousand would be 1000
| | 02:46 | milliseconds or 1 second into the song.
| | 02:48 | We will look at that in a
little more detail later on.
| | 02:53 | Inside of the constructor, we are
going to set play_mc.buttonMode = true.
| | 03:00 | So, buttonMode = true, same thing for pause_mc.
| | 03:08 | Remember that button mode is what makes a
movie show the hand icon when you roll over it.
| | 03:13 | And then finally what we will do is set
the pause_mc to hide at the beginning.
| | 03:19 | So, we won't have the music playing
until the person clicks the play button, and
| | 03:22 | when the play button shows I don't want
the pause button to show and vice versa.
| | 03:26 | So, pause_mc.visible = false.
| | 03:32 | And there's the basic setup for our Class.
| | 03:34 | Now, just to make sure everything is
working, just save this file and test the
| | 03:38 | movie straight from the class file as
long as your Target is set to the proper
| | 03:42 | FLA file you should be good.
| | 03:44 | Test the movie, and you should see the
hand cursor when you roll over the play
| | 03:48 | button, and no file should play yet.
| | 03:51 | All right, looks like
everything is working properly.
| | 03:53 | So now our player class is officially set up.
| | Collapse this transcript |
| Playing audio| 00:00 | Now that our player class is set up, we
can take a look at loading an external
| | 00:04 | sound file and playing it in the Flash Player.
| | 00:08 | Now, this may be a review for you but it's
good to go over it again just as a refresher.
| | 00:13 | The first thing I am going to do is at
the bottom of the constructor method, I
| | 00:17 | am going to type play_mc.
addEventListener and we will add a MouseEvent.CLICK
| | 00:24 | listener, so MouseEvent.CLICK and
we will run a method called playSong.
| | 00:33 | And now I'll define a public method called playSongs.
| | 00:35 | So, public function playSong, we will
receive an event with the datatype of
| | 00:41 | MouseEvent and I am actually going
to give this a default value of null.
| | 00:49 | So, let's set that MouseEvent = null.
| | 00:51 | That way we can run playSong
somewhere else if we want to.
| | 00:55 | We don't have to rely on that MouseEvent.
| | 00:57 | So, close out the parenthesis, :void, make
sure the V is lower case and some curly braces.
| | 01:05 | So, in here we will create a
variable called soundFile, datatype it to a
| | 01:10 | String, and we will set it equal to the name
of the audio file that we are going to load.
| | 01:17 | Now, my file is called 01 Eyes Wide.mp3.
| | 01:26 | So, I have that file there, and now
let's set sound equal to a new instance of
| | 01:32 | the sound class using that new
constructor, and then I will have the sound
| | 01:38 | load the sound files.
| | 01:39 | So, sound.Load and in the parenthesis
here I am going to create a new URLRequest.
| | 01:44 | And I will pass in soundFile.
| | 01:51 | Now, of course soundFile could have been
a URL request and we could have created
| | 01:55 | the URL request right here.
| | 01:56 | But I am just doing it this way, just a
matter of personal preference, there's
| | 02:00 | really no advantage to doing it this way.
| | 02:02 | So, on the next line we
will set, channel = sound.play.
| | 02:10 | So, remember when you are working with audio,
the channel is what controls all the sound.
| | 02:17 | Even though this sound object has the
play method, we put all of the control
| | 02:22 | inside to that channel object.
| | 02:23 | Because basically, all you can do
with the sound is load it and play it.
| | 02:27 | But with the channel, we can pause, we
can resume, and we can even check the
| | 02:32 | position of the sounds.
| | 02:34 | So, all of that functionality is
reserved to the sound channel class.
| | 02:38 | And that's why we are setting the
channel equal to the playing sound, or in
| | 02:42 | other words sound.play.
| | 02:44 | Because that method returns a sound
channel instance that we can then control.
| | 02:48 | And finally, inside of this
method set, play_mc.visible = false.
| | 02:54 | We don't want the play movie clip
showing when the sound is playing, we want the
| | 02:57 | pause movie clip showing.
| | 02:59 | So we will set, pause_mc.
visible = true, and that's it.
| | 03:04 | So, save the file, and again we will
just test it straight from this class.
| | 03:09 | And we should be able to play this sound
when we click the play button.
| | 03:14 | (Music playing.)
| | 03:20 | And looks like the sound is playing just fine.
| | 03:22 | So, we now have successfully set
up playing our external sound file.
| | 03:28 | And by the way, if you load this sound
and play it at the same time, then the
| | 03:33 | sound will play before it's done loading.
| | 03:36 | So, this is how you see sites, maybe
like YouTube or other sites that have an
| | 03:41 | external file playing
before it's finished loading.
| | 03:45 | You just tell it to play early, and as
soon as there is enough data to play it,
| | 03:51 | then the sound will just play.
| | 03:53 | And will continue to
load as the sound is playing.
| | Collapse this transcript |
| Pausing audio| 00:00 | In this movie, we'll finish
our Bare Bones audio player.
| | 00:03 | By adding the functionality
to pause and resume the sound.
| | 00:08 | So let's scroll down to the constructor method.
| | 00:13 | And right where we add the event
listener, to play_mc, or to copy that line of
| | 00:18 | code, and then paste it on the next line.
| | 00:21 | In the pasted code, change play_mc to
pause_mc and change playSong to, you
| | 00:28 | guessed it, pauseSong.
| | 00:30 | Right below the playSong method we'll
define another public method called pauseSong.
| | 00:37 | Just like playSong, you will receive an
event with the data type of MouseEvent
| | 00:42 | and we'll initialize to null, so that
we can run this method whenever we want
| | 00:46 | and we don't have to rely on
a MouseEvent to trigger it.
| | 00:49 | Inside of the method, we will set
resumeTime equal to the position of the sound channel.
| | 00:57 | Remember again, the Sound channel is the
object that tracks the playback of the sound.
| | 01:02 | So resumeTime=channel.position,
remember that's going to be in milliseconds.
| | 01:09 | Then we'll stop the sound, so channel.stop.
| | 01:15 | By the way when you run channel.stop,
the sound actually resets to 0.
| | 01:20 | That's why you need to capture the sounds
position in some sort of variable or property.
| | 01:26 | So if you were to stop it, and then just play
it again, it would reset from the beginning.
| | 01:30 | Next, we'll set the visibility of
play_mc to true, and pause to false.
| | 01:42 | So pause_mc.visible=false.
| | 01:44 | All right, once we stop the song, we want to
show the play button, and hide the pause button.
| | 01:50 | Now if you were to save the file, and
test the movie, you would see that the
| | 01:55 | sound would play again from the
beginning, once you clicked play again, after
| | 02:01 | you've clicked pause. So play.
| | 02:03 | (Music Playing).
| | 02:06 | Then pause, and then play again.
| | 02:10 | And notice it starts from the beginning.
| | 02:12 | (Music Playing).
| | 02:19 | So what we will do is when we run this
sound.play method in playSong, we will
| | 02:25 | pass in the resumeTime to that method.
| | 02:27 | So right in the parenthesis there,
pass in resumeTime, capital T.
| | 02:32 | So the Play method actually takes the
parameter where you can tell it where to start.
| | 02:37 | So we actually want to start in the middle
of the song, wherever the person paused it.
| | 02:41 | That's why we've captioned it, in the
resumeTime property, and then we will
| | 02:44 | resume from there when you
click the play button again.
| | 02:47 | So Save the file, and you may
notice another glitch when you test it.
| | 02:54 | So play (Music Playing), and
then pause, and then play again.
| | 03:00 | (Music Playing).
| | 03:08 | Now one thing that could happen if you
click and play and pause over and over
| | 03:12 | and over again is that the
original sound channel may not stop.
| | 03:18 | You may just create a new sound
channel every single time when you do that.
| | 03:23 | So basically you have all these
sounds layering on top of each other.
| | 03:27 | And you don't want that to happen.
| | 03:29 | And so here is how you prevent that.
| | 03:31 | Go to the playSong method, and right
below where we create that soundFile
| | 03:35 | variable, use an if statement
to see if channel exists already.
| | 03:42 | So if channel exists, this basically
just checks to see if it's undefined,
| | 03:48 | then we'll stop it.
| | 03:50 | So channel.stop, just to insure that we
don't have any sounds playing over each
| | 03:58 | other, because not only is that bad
for memory, it's bad for people's ears.
| | 04:03 | So let's save the file, and
then just do a final test.
| | 04:09 | So play and pause, and play and pause.
| | 04:11 | (Music Playing).
| | 04:22 | So it's resuming from the right time, and we
don't have any sounds layering over each other.
| | 04:28 | So our Bare Bones player is now complete.
| | 04:32 | And just remember that whenever you
want to resume a sound after you pause it,
| | 04:38 | make sure to capture that resumeTime in a variable,
and then pass that in when you play the song again.
| | Collapse this transcript |
|
|
2. Controlling Sound ProgressViewing the FLA file| 00:00 | In this chapter we are going to add a Progress
Bar and time tracking through our audio player.
| | 00:06 | To start out, let's take a look at our FLA file.
| | 00:09 | It's essentially the same file that we
worked with in the previous chapter, with
| | 00:14 | just a few additions.
| | 00:15 | So on the stage here, I have my movie
clip player_mc, and if I double-click it,
| | 00:21 | I can enter its timeline.
| | 00:22 | I'll zoom into the player, and then
you could see that we have one movie clip
| | 00:28 | called prog_mc, and then a
text field called time_txt.
| | 00:34 | Note that the time text
field is a Dynamic Text field.
| | 00:37 | I set the anti-aliasing to Bitmap text.
| | 00:44 | And I'll make sure that
the characters are embedded.
| | 00:48 | Next, we'll double-click
prog_mc to enter its timeline.
| | 00:53 | Inside of prog_mc, there are two elements.
| | 00:57 | The dragable element called drag_mc,
and then the bar in the background, which
| | 01:05 | is called the bar_mc.
| | 01:07 | These are just simple bitmap graphics.
| | 01:10 | Again, you can just use your
own vector graphics if you like.
| | 01:13 | And that's really all that
there is to this FLA file.
| | 01:16 | So it's the same one we worked within
the last chapter, with the addition of
| | 01:21 | this movie clip prog_mc,
and this text field, time_txt.
| | Collapse this transcript |
| Creating the Progress class| 00:00 | Now let's start looking at, how to
use ActionScript to track the playback
| | 00:04 | progress of our song.
| | 00:07 | The first thing, I'm going to do
is jump over to ProgressDisplay.as.
| | 00:11 | This file is in the same package as
the player class, so com.lynda.audio and
| | 00:18 | should thus be into the exact same folder.
| | 00:20 | Make sure you name it ProgressDisplay,
capital P and capital D. I'm importing
| | 00:27 | a bunch of classes here, so that all the
display, events, text and geometry classes.
| | 00:33 | I have my class definition here, note
that it's not extending any class, and
| | 00:37 | then I have my constructor method.
| | 00:40 | Let's create some properties.
| | 00:42 | So first, public property called resumeTime.
| | 00:44 | Remember, we created a
resumeTime property in the last chapter.
| | 00:51 | This property is actually going to
take the place of that property, so public
| | 00:56 | var resumeTime:Number = 0.
| | 01:00 | The other public property called drag
and that's going to be a movie clip.
| | 01:06 | Public property called bar.
| | 01:08 | Also a movie clip, a public
property called time_ txt.
| | 01:13 | That's going to be the time text field.
| | 01:15 | So it's a TextField.
| | 01:16 | And then finally, a public property
called player, datatype that too, Player
| | 01:24 | capital P. That's going to refer to
an instance of the audio player that we
| | 01:29 | created in the previous chapter.
| | 01:32 | In the constructor method,
we'll accept some parameters.
| | 01:34 | p will be a Player, d will be a movie
clip, short for drag, b will be a movie
| | 01:44 | clip that's short for bar, and
finally t will be a TextField.
| | 01:52 | And as you may have guessed, we're just
capture all of these parameters in our properties.
| | 01:57 | So player = p;
| | 02:01 | drag = d; bar = b; and time_txt = t;
| | 02:11 | and finally, we'll set drag.buttonMode = true.
| | 02:14 | Remember that's going to show a
hand cursor when you roll over it.
| | 02:18 | Now, we'll define the skeletons of two
public methods, one to initialize this
| | 02:24 | object and one to disable it.
| | 02:27 | So public function init():
void, so no return data.
| | 02:34 | And then, I'm just going to copy and
paste this method, and change init to disable.
| | 02:39 | So we'll save the file, then
we'll jump over to Player.as.
| | 02:48 | The first thing we'll do in our Player
class is delete that resumeTime property.
| | 02:52 | After you delete resumeTime, scroll at
the top of your code and create another
| | 02:56 | public property, and call this one
progDisplay, datatype it to ProgressDisplay.
| | 03:08 | And scroll down to the constructor,
and we'll initialize that property right
| | 03:12 | below, where we set the
visible property for pause_mc.
| | 03:15 | So progDisplay = new
ProgressDisplay, capital D capital P, and in the
| | 03:25 | parenthesis we're going to pass in this-
that's the player- and prog_mc.drag_mc,
| | 03:37 | prog_mc.bar_mc and then finally, time_txt.
| | 03:44 | Remember that drag_mc and bar_mc
are both in that movie clip prog_mc.
| | 03:49 | Now we're going to through, and find
out those references to resumeTime and
| | 03:53 | change it to progDisplay.resumetime.
| | 04:00 | So in the playSong method, we'll
change channel = sound.play(resumeTime) to
| | 04:04 | channel = sound.play(progDisplay.resumeTime).
| | 04:09 | And then, we'll add progDisplay and a
dot right before resumeTime in pauseSong.
| | 04:17 | And last, we'll initialize progDisplay
in playSong and disable it in pauseSong.
| | 04:23 | I'm going to initialize it, right
above play_mc.visible = false in playSong.
| | 04:28 | So progDisplay.init().
| | 04:34 | And then in pauseSong, right
below progDisplay.resumeTime,
| | 04:38 | progDisplay.disable(). That's it.
| | 04:47 | Save the file and if you test the movie,
you should get the same functionality
| | 04:51 | that you had before.
| | 04:52 | You should be able to play and pause, and
it should work just like you'd expected to.
| | 04:57 | So test the movie.
| | 04:58 | Click Play to play, and Pause to pause.
| | 05:03 | (Music Playing)
| | 05:05 | And then Play again to resume.
| | 05:07 | (Music Playing)
| | 05:11 | So now we have the progDisplay object
controlling the progress of the song, the
| | 05:16 | class is setup, and working properly.
| | Collapse this transcript |
| Showing progress in a text field| 00:00 | In this movie, we will look at
showing the progress of the playing sound.
| | 00:04 | Both in the progress bar and in the text field.
| | 00:07 | Scroll down to the init method.
| | 00:10 | In the init method we are going to add
an event listener to the player, so type
| | 00:14 | player.addEventListener and for the
event listener it will be Event.ENTER_FRAME,
| | 00:22 | make sure that's all caps.
| | 00:23 | And we will run a method
called showPlayProgress.
| | 00:26 | Play should have a
capital P as well as progress.
| | 00:35 | Just copy this code and then paste it
inside of the disable method and just
| | 00:39 | change addEventListener to removeEventListener.
| | 00:43 | Below disable, define a private
method called showPlayProgress.
| | 00:52 | Make sure to make it receive an event
with a datatype of Event, now return data
| | 00:57 | and write some curly braces.
| | 01:00 | The first thing you want to
do is create an if statement.
| | 01:02 | So, create the skeleton of an if
statement, make some curly braces, and inside
| | 01:07 | of the if statement we are going to
see if player.channel exists or if there
| | 01:12 | is a sound channel.
| | 01:14 | And if player.sound.length != 0.
| | 01:24 | So, we want to make sure that some of
the sound at least is downloaded before
| | 01:28 | we start tracking any progress
because as the sound downloads, that length
| | 01:33 | property increases.
| | 01:35 | And we want to make sure that
the sound channel exists as well.
| | 01:38 | So, if those two conditions are true, then we
will do the quotes and the curly braces here.
| | 01:43 | So, the first thing we will do is
create some variables, the first one will be
| | 01:46 | called p and it will be equal to a
number, this represent the sounds position.
| | 01:52 | So, we will set that equal to player.
channel.position, and we want in seconds,
| | 01:58 | so we are just going to divide it by a thousand.
| | 02:02 | And then on the next line, create a
variable called and this will represent the
| | 02:05 | length of the sound.
| | 02:06 | It will be number as well.
| | 02:09 | It will be equal to player.sound.length.
| | 02:14 | So, if you want to know the total
length of the sound, you need to get it
| | 02:17 | through the sound object, not the sound channel.
| | 02:20 | We are going to divide that by a
thousand as well to get the value in seconds.
| | 02:24 | Now, what we will do is set the position
of the draggable part of the progress bar.
| | 02:29 | So go down a few lines, and then type
drag.x = (p/l), and so just a standard
| | 02:40 | showing of a percentage of something.
| | 02:42 | You just take the current value divided by
the total value and that gives you the percent.
| | 02:49 | And then you multiply it by
the maximum value that you want.
| | 02:54 | So, we are going to multiply it by the
draggable object being all the way at the
| | 02:58 | right and that's going to make a
display just in the right spot based on the
| | 03:04 | percentage that the song is played.
| | 03:07 | So type (bar.width - drag.width) and
that will align the draggable element with
| | 03:15 | the right edge of the
progress bar and that's it for that.
| | 03:19 | So, save the file and then test the movie.
| | 03:24 | You should be able to play this
song and watch the progress bar move.
| | 03:25 | (Music Playing)
| | 03:26 | So we can pause this song and then resume
and watch it resume at the right place.
| | 03:33 |
(Music Playing)
| | 03:38 | All right, now we will have the
text field display of the current time.
| | 03:48 | This is a little bit more
complicated than adjusting the position of
| | 03:52 | the draggable element.
| | 03:53 | So, right below our p and l variables, we
are going to get the position in minutes.
| | 04:00 | And to do that we are going to make
a variable called, pMin, set it as an
| | 04:05 | integer and this will automatically
truncate any floating point value.
| | 04:11 | And to get that, we will just take p /60.
| | 04:17 | That's pretty easy, right?
| | 04:19 | And then to get the seconds, create a
variable called pSec, set it to an integer.
| | 04:24 | And instead of p / 60, we will do p % 60.
| | 04:31 | Perfect tool for this.
| | 04:33 | The percentage divides p by 60 and the
percentage gives you the remainder that's left over.
| | 04:41 | So, we are dividing that time in
seconds by 60, we got the minutes.
| | 04:45 | We will use the percent 60 and
then we get whatever is left over,
| | 04:49 | whatever seconds we have.
| | 04:51 | Perfect tool for this situation.
| | 04:53 | Go down a few more lines, create a
variable called pStr, this is going to be
| | 04:59 | our position string.
| | 05:01 | So datatype it to a String, we are
going to set it equal to a shorthand
| | 05:05 | conditional statement here.
| | 05:06 | So it's equal to pMin < 10, so if it's less
than 10, we want it to start out with a zero.
| | 05:14 | So we want it to say 01, 02,
etcetera instead of just 1, 2.
| | 05:18 | All right, after that you put a question
mark and the question mark kind of means then.
| | 05:26 | So, in there we are just going to
put a 0 and then a colon. That's else.
| | 05:31 | And then just put quote after that.
| | 05:33 | So we are either going to
start it out with 0 or nothing.
| | 05:35 | Go to the next line and we are
going to concatenate the value of our p
| | 05:39 | string, so pStr += pMin.
| | 05:44 | So, we start out by displaying the
minutes and then we will add a colon on to
| | 05:48 | it, so pStr += :, and then we will
add on the second, so pStr +=, and then
| | 06:00 | another shorthand
conditional statement in there.
| | 06:02 | We will see if, pSec < 10.
| | 06:06 | Same thing we did for the minutes, if so,
we are going to tack on a 0, if not we
| | 06:11 | will tack on nothing.
| | 06:13 | And then we will put the seconds in that
string, so pStr += pSec. Not so bad, right.
| | 06:20 | So just copy these lines of codes
that we just wrote, all the way from pMin
| | 06:24 | down to pStr += pSec.
| | 06:27 | So, copy that and then we will
paste it and basically follow the same
| | 06:30 | formula for the length.
| | 06:33 | So in the pasted code, change all the ps to ls.
| | 06:37 | This is almost too easy, isn't it?
| | 06:48 | All right, so just change all of those
ps to ls and once you have done that,
| | 06:55 | just double check, but
make sure you didn't miss any.
| | 06:58 | So basically, we are calculating the
length text value in the exact same way we
| | 07:04 | calculated the position value.
| | 07:06 | So that's not too bad.
| | 07:08 | And then right below that we will set
the time text field to display the time.
| | 07:12 | So time time_txt.text = pStr + "/" + lStr.
| | 07:23 | So position forward slash length. That's it.
| | 07:29 | Save the file, test the movie, and you
should be able to click the play button
| | 07:34 | and see the progress bar move and
the time update in that text field.
| | 07:37 | (Music Playing)
| | 07:46 | And that looks just right.
| | 07:47 | So, I paused it, and I will resume it
just to make sure it's still correct.
| | 07:53 | (Music Playing)
| | 07:55 | Nice.
| | 07:57 | So that it's working successfully.
| | 07:59 | So, the main thing that you have
learned in here that was probably new was how
| | 08:02 | to use this percentage operator.
| | 08:04 | Remember that you can get the
remainder of something that you divide, so we
| | 08:09 | divide l by 60 and we get the left over here
and that's really useful for calculating seconds.
| | Collapse this transcript |
| Controlling progress| 00:00 | Now that we've added the functionality
to display the playback progress, we'll
| | 00:05 | look at how to control the playback
progress by clicking and dragging the
| | 00:09 | dragable element on the progress bar.
| | 00:12 | Scroll down to the init method, right
below where we add the event listener to
| | 00:16 | the player, add an event listener to drag.
| | 00:21 | So, drag.addEventListener(MouseEvent.
MOUSE_DOWN, run a method called dragProg.
| | 00:30 | Copy and paste that line of code, enter
the disable method right below where you
| | 00:35 | removed your event listener from the player.
| | 00:37 | Change addEventListener and the
pasted code to removeEventListener.
| | 00:41 | Right below the disable method, create
a new private method called dragProg.
| | 00:46 | It will receive an event
with the datatype of MouseEvent.
| | 00:59 | In the method, first thing
we'll do is set the resume time.
| | 01:01 | So, resumeTime = player.channel.position.
| | 01:10 | We're basically doing here is
capturing the resumeTime and pausing the song.
| | 01:16 | So, on the next line, we'll actually
pause the song, so player.pauseSong.
| | 01:20 | Now, we'll start dragging the
handle of the progress bar, so
| | 01:26 | drag.startDrag(false, so we don't
want to lock the center that way.
| | 01:34 | That way the registration point of
the dragable element, the top left of it
| | 01:39 | won't lock to the center of your
mouse, you don't want that to happen.
| | 01:41 | So, false, and then we define the
balance in the form of a rectangle.
| | 01:45 | So, we'll actually create
that rectangle right here.
| | 01:47 | So, new Rectangle, and make sure to
close up the parentheses for both the
| | 01:53 | rectangle and for the startDrag method.
| | 01:57 | And in the Rectangle constructor will
pass in 0 for the X, 0 for the Y position.
| | 02:03 | For the width we'll pass
in bar.width - drag.width.
| | 02:09 | That's the maximum X position we
can drag a handle here, and then for
| | 02:15 | height, we'll put in 0.
| | 02:18 | So then I'll start dragging.
| | 02:19 | Then we want to remove the event
listener from drag, so we'll copy that
| | 02:25 | drag.removeEventListener line of code
from disable, paste it right below startDrag.
| | 02:31 | Stop listening for that.
| | 02:34 | Then we'll add an event listener
to stage listening for mouse up.
| | 02:37 | Remember you don't want to listen for
mouse up on drag, in case the person
| | 02:40 | moves their mouse up or down, then they will be
off of that drag movie clip and it won't register.
| | 02:47 | So, you want to add it to the stage so
wherever they release their mouse, it
| | 02:51 | will register and stop dragging that element.
| | 02:54 | So, player.stage.addEventListener,
then it's going to be MouseEvent.MOUSE_UP,
| | 03:04 | make sure that's all caps.
| | 03:07 | And we'll run a method called stopDragging.
| | 03:11 | And now we'll define the private
method stopDragging right below dragProg.
| | 03:16 | So, private function stopDragging,
receive an event with a datatype of MouseEvent.
| | 03:21 | No return data, so :void.
| | 03:29 | And in stopDragging we will set the resumeTime.
| | 03:35 | The resumeTime is going to be
based on the position of the handle.
| | 03:39 | So, what we're going to do is put some
parentheses in to find out the percentage
| | 03:46 | position of the dragable object
relative to the full dragable area.
| | 03:54 | So, we just take its position, we
divide it by the total dragable area and then
| | 03:58 | we get its percentage position.
| | 04:00 | And then we multiply that by
the total length of the sound.
| | 04:04 | Remember this is common math, you take
the percentage, then you multiply by the
| | 04:08 | maximum value and that gives
you the value that you want.
| | 04:11 | So, in the parentheses type
drag.x, so that's the position.
| | 04:17 | We're going to divide that by another
value in parentheses, so I have two sets
| | 04:23 | of parentheses here, and divide that
by the maximum position for the drag.
| | 04:27 | So, it's going to be bar.width - drag.width.
| | 04:31 | So, that's the maximum X position.
| | 04:33 | We're going to take that a whole value
in both parentheses and we're going to
| | 04:38 | multiply that by player.sound.length.
| | 04:44 | So, to get the resumeTime we take
the percentage position of the dragable
| | 04:48 | element and we multiply that by the
total sound length, and that's how you get
| | 04:53 | where the sound should resume.
| | 04:55 | Next, we'll play the song, so
player.playSong and then drag.stopDrag.
| | 05:02 | Then we'll add the event listener to be
able to drag it again, so I'm just going
| | 05:09 | to copy and paste that line since
we already wrote in the init method,
| | 05:13 | player.addEventListener.
| | 05:14 | That line right there.
| | 05:16 | Paste it at the bottom of
stopDragging, and then we'll remove that event
| | 05:20 | listener from the stage listening for MOUSE_UP.
| | 05:24 | So, just copy that line of code from
dragProg at the bottom and paste it at the
| | 05:29 | bottom of stopDragging, change
addEventListener to removeEventListener in the
| | 05:34 | pasted code, and that's it.
| | 05:37 | So, save the file and you should be
able to test the movie and play the song.
| | 05:43 | Once it's playing you should be able
to click and drag that little handle to
| | 05:47 | change the position of the song.
| | 05:48 | (Music Playing)
| | 05:57 | Looks like it's working just like it should.
| | 06:00 | So, now we've successfully set up
dragable functionality, so we can control the
| | 06:05 | playback of the song.
| | 06:06 | Now remember, the recipe for figuring
out where the resumeTime should be is you
| | 06:12 | take that percentage of where the
dragable element is by dividing its current
| | 06:18 | position by its maximum position, and
multiplying that percentage value by the
| | 06:24 | total length of the sound.
| | Collapse this transcript |
|
|
3. Controlling VolumeViewing the FLA file| 00:00 | In this chapter, we will add a volume
slider to our MP3 player and as usual, we
| | 00:06 | will start out looking at our FLA file.
| | 00:09 | So when you have your FLA file open,
double click the player on the stage
| | 00:13 | to enter its timeline.
| | 00:15 | Inside of the player, I am going to
zoom in, using the Zoom tool, right on
| | 00:20 | that volume slider.
| | 00:21 | So let's go to the volume slider and you
will notice that it's a movie clip with
| | 00:26 | an instance name of volume_mc.
| | 00:29 | The movie clip is an instance of
a movie clip called VolumeControl.
| | 00:32 | So, if I double click that,
I can enter its timeline.
| | 00:38 | Notice that big, red block right there.
| | 00:41 | That's actually the mask, so we are
going to use that as a mask for the
| | 00:45 | slider knows it's not set as a mask
on the timeline but we will set it as a
| | 00:49 | mask in ActionScript.
| | 00:52 | For the record, that's always the best
policy for items that you are going to
| | 00:56 | animate using ActionScript, like we
are going to do with the volume slider.
| | 01:00 | So you can see it's just a
movie clip that I called it mask_mc.
| | 01:04 | There is really nothing special to it.
| | 01:06 | You enter its timeline, you
will see that it's just a shape.
| | 01:09 | So I have that and there is this slider
that's called slider_mc as an instance
| | 01:16 | of the volume slider movie clip.
| | 01:19 | If you double click it, you can enter
its timeline and you see that there is
| | 01:23 | not too much to it.
| | 01:24 | There is a movie clip called drag_mc.
| | 01:25 | It's just a bitmap and then there is
the bar, which is called bar_mc, another
| | 01:33 | bitmap, pretty straightforward and then the
background is just a shape, just a black rectangle.
| | 01:40 | Back to VolumeControl, and then if I
hide the slider, you can see that there is
| | 01:45 | the icon movie clip.
| | 01:46 | That's a little sound icon and there is
the background, which you can't really
| | 01:50 | see unless you select it.
| | 01:52 | It's just a rectangular background for
the sound icon so that you get a little
| | 01:56 | bit more hit area and that's it.
| | 02:01 | So that's to look at our FLA file.
| | 02:03 | For those of you, who don't have the
exercise files, make sure to go through
| | 02:07 | this movie very carefully, setting
up your files in exactly the same way.
| | 02:11 | Once your files will set up, you are ready to
start writing the code for our volume slider.
| | Collapse this transcript |
| Creating the VolumeSlider class| 00:00 | Now we will look at initializing the
VolumeSlider class by adding some basic
| | 00:04 | properties and writing some
code in the constructor method.
| | 00:08 | So, if you don't have access to the
exercise files, make sure you declare the
| | 00:11 | package com.lynda.audio and save the
VolumeSlider file in that same folder.
| | 00:18 | That would be the audio folder.
| | 00:21 | Also make sure that you call it
VolumeSlider with a capital V, capital S, same
| | 00:26 | thing for the class name
and the constructor method.
| | 00:29 | Let's look at our import statements,
importing flash.display.*, flash.events.*,
| | 00:36 | flash.geom.*, flash.media.*, those
are the sound classes and then gs.*.
| | 00:43 | Now, if you have watched a lot of my
training for Flash CS4, I have talked
| | 00:48 | about TweenLite that's an ActionScript
twining engine that an independent developer made.
| | 00:56 | I use that for all of my ActionScript
animation because it's very easy to use.
| | 01:01 | So if you don't have that code and you
are not familiar with it, I recommend
| | 01:05 | going to tweenlite.com and then
just download the TweenLite engine.
| | 01:11 | When you download TweenLite,
you will find a folder called gs.
| | 01:15 | Take that gs folder and drop it into
the same folder that you are using for the
| | 01:19 | FLA file in this exercise.
| | 01:22 | So, your file should look just like mine.
| | 01:29 | So in your main folder, you will have
the player, the song that you are going to
| | 01:34 | load, the com folder and the gs folder.
| | 01:37 | All right, let's declare some properties.
| | 01:41 | So I will create a public property called vol.
| | 01:44 | It's going to represent the main volume
movie clip because we are not going to
| | 01:49 | extend the MovieClip class or
connect to this class to the VolumeSlider.
| | 01:55 | We are actually going to just use it
in the player class and pass all these
| | 02:00 | values in as properties.
| | 02:02 | So, I will create another
public property called volDrag.
| | 02:05 | This will be the dragable element.
| | 02:07 | So, that's going to be a movie clip.
| | 02:09 | Another public property called volBar.
| | 02:12 | That's the bar in the background.
| | 02:15 | It's going to be a movie clip as well.
| | 02:16 | We are going to save the bar's X position.
| | 02:19 | So, create a property called volBarX.
| | 02:22 | That will be a number and then finally,
create one more public property called player.
| | 02:28 | This will represent the player that we
are using which in this case is going to
| | 02:32 | be Player.as or player class.
| | 02:34 | It's going to be an
instance of the player class.
| | 02:36 | That way we can retain a reference
to the player inside of this class.
| | 02:42 | So, in the constructor method, we
are going to take two parameters.
| | 02:45 | p, that's going to be the player, and
then v, which is going to be MovieClip.
| | 02:51 | That will be the
VolumeController movie clip from our FLA.
| | 02:55 | So, we will just
initialize it here. So player = p;
| | 03:00 | vol = v;
| | 03:03 | vol.slider_mc.mask.
| | 03:05 | So we are setting the mask
right here equal to vol.mask_mc.
| | 03:13 | Set volDrag = vol.slider_mc.drag_mc.
| | 03:21 | Set volBar = vol.slider_mc.bar_mc.
| | 03:31 | Set volBarX = volBar.X and we will finally
set the button mode of vol equal to true.
| | 03:42 | So vol.buttonMode = true and remember
that buttonMode just makes it so when
| | 03:47 | you roll over a movie clip, it shows the
hand cursor instead of just the regular pointer.
| | 03:52 | So, we are just about ready to test.
| | 03:54 | So save this file and then we are
going to need to jump over to Player.as and
| | 03:59 | adjust the code there.
| | 04:02 | So, in my properties area, I am
going to create a new public property.
| | 04:06 | So, right below progDisplay, we will
create another property called volSlider.
| | 04:15 | Datatype it to a VolumeSlider and
then we will initialize it in our
| | 04:22 | constructor method.
| | 04:23 | We will do that right below
where we initialize progDisplay.
| | 04:26 | So right below that volSlider = new
VolumeSlider and inside of the parenthesis,
| | 04:39 | passing this with reference to this
player and volume_mc that's the reference to
| | 04:48 | the VolumeControl movie clip and that's it.
| | 04:51 | So save the file and we will test it
right from here, just to make sure your
| | 04:56 | target is player.fla.
| | 04:58 | You can test the movie and you
really shouldn't see anything special.
| | 05:02 | Everything should work as it did before.
| | 05:04 | (Music Playing)
| | 05:06 | And then you should see that the red area has
become the mask and has hit in the volume slider.
| | 05:15 | So we just have the volume slider and
when you roll over the volume movie clip,
| | 05:19 | you should see the hand cursor.
| | 05:20 | It looks like everything is working properly.
| | 05:23 | So now our basic VolumeSlider
class is set up and ready to work with.
| | Collapse this transcript |
| Animating the slider| 00:00 | Now, we'll add the functionality so
that when you roll over the sound icon in
| | 00:04 | the Music Player, the Volume slider
will slide up and that when you roll out,
| | 00:09 | the Volume slider will slide down.
| | 00:11 | We'll start out in player.as.
| | 00:14 | In that file, find the playSong method.
| | 00:17 | In the playSong method, right above
progDisplay.init we'll initialize the Volume slider.
| | 00:23 | So type volSlider.init and some
parenthesis and a semicolon and we'll define the
| | 00:32 | Init method right now.
| | 00:33 | So save the file and jump
over to VolumeSlider.as.
| | 00:38 | Right below the constructor method,
go down a few lines and define a public
| | 00:42 | method called init.
| | 00:44 | No parameters, no return data.
| | 00:48 | In the Init method, we'll add an event
listener to vol, so when you roll over
| | 00:52 | it, we'll run a method called volOver.
| | 00:55 | So vol.addEventListener, event is
going to be MouseEvent.ROLL_OVER, and the
| | 01:02 | method will be volOver.
| | 01:05 | Right below the Init method, we'll
define a private method called volOver, or
| | 01:12 | receive an event with a data type of
MouseEvent, no return data and in volOver,
| | 01:19 | we are going to use TweenLite
to animate the Volume slider.
| | 01:24 | The syntax is TweenLite.
to, and some parentheses.
| | 01:31 | Now, if you are unfamiliar with the
TweenLite engine, you'll see here that it's
| | 01:35 | actually pretty easy to
use and to get used to it.
| | 01:38 | The TweenLite.to method takes an
object's current properties and then animates
| | 01:43 | them to whatever values you pass in.
| | 01:46 | So the first parameter is going to
be the object that you want to tween.
| | 01:50 | That's going to be vol.slider_mc.
| | 01:55 | The second parameter is
the duration of the tween.
| | 01:58 | So we want the tween to be 0.5
seconds, so just type in .5 and the third
| | 02:02 | parameter is an object.
| | 02:03 | So I am going to create a shorthand object here.
| | 02:06 | Here you can pass in the Tween properties.
| | 02:08 | So if you want to animate the Y
position, you just pass in where you want the
| | 02:13 | object to end up on the Y-axis.
| | 02:17 | You do that by just specifying a
Y property inside of the object.
| | 02:20 | So Y:-vol.slider_mc.height.
| | 02:29 | So it's going to end up at the vol
slider's negative height, which means the
| | 02:33 | slider is going to be at the
top of the volume movie clip.
| | 02:38 | So again, that Y property is just
saying where we want the Y property to end up
| | 02:42 | at the end of the tween.
| | 02:44 | The next property we'll
passed in is called onUpdate.
| | 02:48 | This allows you to identify a method that
will run every time the tween updates.
| | 02:53 | So onUpdate:volTweenUpdate and we'll add
an event listener to vol, listening for
| | 03:04 | MouseEvent.ROLL_OUT, run a method called volOut.
| | 03:11 | So I am just going to copy and
paste volOver and change it to volOut.
| | 03:21 | Change the Y position from -
vol.slider_mc.height to 0.
| | 03:27 | That will animate the slider's Y
position to 0 when you roll out.
| | 03:32 | Then just delete that last line of code.
| | 03:33 | Now, all we have to do is define the
volTweenUpdate method that we specified
| | 03:39 | in the volOver method.
| | 03:40 | So create another private method,
call it volTweenUpdate, no parameters, no
| | 03:50 | return data and in here, all we are going
to do is just reset the mask for the slider.
| | 03:58 | Remember that when you animate an
element with ActionScript or move it at all,
| | 04:03 | if that element is masked, it's going
to be unmasked as soon as you move it.
| | 04:07 | So you need to reset that mask
every time you move the object.
| | 04:11 | So I am just going to copy
that code where I set the mask.
| | 04:14 | That's inside the constructor method.
| | 04:16 | So it's with vol.slider_mc.mask,
and I'll paste it right inside of
| | 04:22 | volTweenUpdate and that's all we have to do.
| | 04:25 | So save this file and you should be
able to test it and because the volume
| | 04:32 | doesn't initialize until a sound is
playing, you have to play the sound first.
| | 04:36 | (Music Playing).
| | 04:41 | And you can even pause
it and it will still work.
| | 04:42 | So I am going to pause it and I will
roll over that movie clip and you will see
| | 04:45 | the slider go up, roll out,
and see the slider go down.
| | 04:49 | All right, our Volume slider is
successfully animating using TweenLite.
| | Collapse this transcript |
| Adding the slide effect| 00:00 | Up to this point our volume slider
itself doesn't have any real interactivity.
| | 00:05 | In this movie, we'll add the
interactivity so you can click and drag the
| | 00:08 | volume slider up and down.
| | 00:11 | Let's go to the constructor
method in the VolumeSlider class.
| | 00:15 | At the very bottom of the constructor
method, add an event listener to volDrag.
| | 00:19 | So volDrag.addEventListener, and the
event is going to be MouseEvent.MOUSE_DOWN.
| | 00:27 | And we'll run a method called dragVol.
| | 00:31 | We'll define dragVol right below
init, so scroll down below init.
| | 00:37 | Create a private method called dragVol.
| | 00:40 | It will receive an event with the
data type of MouseEvent, no return data.
| | 00:48 | And instead of the method we'll type
volDrag.startDrag, and for the first
| | 00:54 | parameter we'll pass in false,
remember that's lock center.
| | 00:57 | It will lock the mouse to the
registration point of the object, which we don't
| | 01:00 | want to do in this case.
| | 01:02 | The next parameter is a rectangle
and that's the balance for the drag.
| | 01:07 | So create a new rectangle right here
in line, and for the rectangle make sure
| | 01:14 | you have closed parenthesis
for both rectangle and startDrag.
| | 01:17 | We'll start out with rectangle's X
position 0, the Y position is volBar.y, the
| | 01:25 | width will be 0, and the height
will be volBar.height - volDrag.height.
| | 01:35 | That will bring that dragable part
to the very bottom of the volBar.
| | 01:40 | Next, we'll remove that rolloverEventListener.
| | 01:44 | So vol.removeEventListener(MouseEvent.
ROLL_OVER, make sure that's all caps, and
| | 01:53 | the method is volOver.
| | 01:56 | On the next line we'll add an event
listener to the stage to listen for
| | 01:59 | MouseEvent.MOUSE_Up.
| | 02:00 | Remember that when you are dragging
something, you always want to add the up
| | 02:04 | listener to the stage not the object.
| | 02:07 | That way you could be sure
to capture any MOUSE_UP event.
| | 02:10 | So player.stage.addEventListener.
| | 02:16 | That's going to be MouseEvent.MOUSE_UP.
| | 02:22 | Run a method called dropVolBar
and we'll define that right now.
| | 02:29 | So right below dragVol, create a
private function called dropVolBar.
| | 02:38 | It will receive an event with the
datatype of MouseEvent, no return data.
| | 02:47 | The first thing we'll do is stop
dragging the volume bar, so volDrag.stopDrag,
| | 02:54 | no parameters there.
| | 02:56 | Remove the event listener from the stage.
| | 02:58 | I am just going to copy
that line of code and paste it,
| | 03:01 | player.stage.addEventListener from
dragVol, right below volDrag.stopDrag.
| | 03:08 | And then I will just change
addEventListener in the pasted code to
| | 03:12 | removeEventListener.
| | 03:14 | Then whenever you drop the volume
bar, I want the volume slider to
| | 03:19 | automatically slide down.
| | 03:21 | So I am going to run volOut.
| | 03:28 | Now I am going to have to modify the
volOut method in my code on line 54.
| | 03:32 | I am making this so I can run this
method without requiring an event.
| | 03:39 | To do that, I simply have to initialize
the event parameter to null, so I will
| | 03:43 | just set event:MouseEvent = null.
| | 03:47 | That way we can run this method without
needing an event and we just have to add
| | 03:51 | one more line of code to complete this step.
| | 03:54 | So scroll up and find the dragVol method.
| | 04:00 | In the dragVol method we will remove
the event listener from vol so we'd no
| | 04:04 | longer listen for the
MouseEvent.ROLL_OVER event.
| | 04:07 | What do we want do is add that event
listener again when you drop the volBar, so
| | 04:12 | copy that line of code and paste it at
the bottom of the dropVolBar method and
| | 04:17 | change removeEventListener to addEventListener.
| | 04:21 | So after you do that, save the file.
| | 04:24 | So I will test the movie and
everything should work just as you would expect.
| | 04:28 | You should be able to play the song,
move the slider, and then show and hide the
| | 04:33 | slider at your will.
| | 04:35 | (Music Playing)
| | 04:45 | And looks like it's working great.
| | 04:47 | So that completes that step and we have
successfully added slide to our slider.
| | Collapse this transcript |
| Controlling volume| 00:00 | In this movie, we'll complete our
volume slider by actually making and control
| | 00:04 | the volume of our sounds.
| | 00:06 | So the first thing, I wanted you to
do is scroll down in Player.as down to
| | 00:11 | the playSong method.
| | 00:13 | And right above volSlider.init, we'll
call a method that we haven't defined yet,
| | 00:17 | but we will define later in this movie,
called volSlider.updateVolume, and of
| | 00:26 | course that method is going to
update the volume of the sound.
| | 00:29 | Now the thing is every time we play
this song, we want to run Update Volume to
| | 00:34 | make sure that the volume is the
same as it was for the last song.
| | 00:39 | That's because every time we play a song,
we're creating a new instance of the
| | 00:42 | sound class, so we need to
reset that volume every time.
| | 00:46 | So, let's save this file, and
then head on over to VolumeSlider.
| | 00:51 | In VolumeSlider scroll down
and find the dragVol method.
| | 00:58 | At the bottom of this method, it's
adding event listener to the player.
| | 01:02 | This is going to be EnterFrame event.
| | 01:03 | So player.addEventListener, events
going to be event.ENTER_FRAME, and we run a
| | 01:11 | method called updateVolume.
| | 01:14 | And before we define updateVolume, I am
just going to copy and paste this line
| | 01:19 | of code at the bottom of the dropVolBar,
and there I'll change addEventListener
| | 01:26 | to removeEventListener.
| | 01:27 | We don't want this EnterFrame event
listener on forever, we want definitely
| | 01:32 | remove the event listener when we are
done, because that's going to use a lot of
| | 01:35 | memory that we don't need to be using up.
So, right below dropVolBar, I am going
| | 01:40 | to define a public method called updateVolume.
| | 01:43 | Remember that we are running this from
the player class file so we'll need to
| | 01:49 | make this method able to run
without an event being triggered.
| | 01:53 | So event:Event, I'll set it equal to null,
so we can run it from the other class.
| | 02:01 | Now return data, and here we'll
create a variable called trans, I'll set it
| | 02:07 | equal to SoundTransform
object, and that object will be
| | 02:12 | player.channel.soundTransform.
| | 02:17 | And that's the object that holds
the sound transform for the songs.
| | 02:21 | We are going to hold it in that trans
variable here, and then we'll manipulate
| | 02:24 | it, and then reapply it to the sound object.
| | 02:28 | So go to the next line and create a
variable called volPercent, this is going to
| | 02:33 | be a number, and what I am going to
do is I am going to set it equal to
| | 02:39 | volDrag.y - volBar.y, so this is it's
positioned relative to the volBar, and we
| | 02:51 | are going to divide that by a value of
parenthesis and so in the parenthesis put
| | 02:57 | volBar.height - volDrag.height.
| | 03:04 | That's the maximum value
that a volDrag can be down.
| | 03:07 | So, we are seeing its
position from top to bottom.
| | 03:10 | So, the top value is going to be zero ,
and the bottom value is going to be 100.
| | 03:14 | That's kind of exactly the opposite
of what we want, so when we apply this
| | 03:18 | transformation of the sound, we are going
to need to work with it just a little bit.
| | 03:22 | So go down to the next line, and I
will say trans.Volume = and put a value in
| | 03:27 | parenthesis here, make it negative,
and we'll put, volPercent - 1.
| | 03:30 | Let me show you my logic on that.
| | 03:35 | So we have that 0 to 1, so 0
at that point, 1 at the bottom.
| | 03:38 | We are actually wanted to be 1 at the
top, 0 at the bottom, so we are reversing
| | 03:43 | it when we set the volume.
| | 03:44 | Here is how that works.
| | 03:45 | You take that volPercent we subtract 1 from it.
| | 03:48 | So, let's say it's 1.
| | 03:51 | We subtract 1 at 0 and if it's 0, we subtract 1.
| | 03:54 | That's a negative 1.
| | 03:54 | So that gives us the exact values
that we want except for their negative.
| | 03:58 | So we multiply that by negative 1 here.
| | 04:01 | So that changes that negative value
to a positive value and gets it in that
| | 04:06 | correct range that we are looking for.
| | 04:07 | And now we use some if statements to
make sure that the volume doesn't go
| | 04:11 | above 1 or below 0.
| | 04:13 | So we'll check to see if
trans.volume is greater than 1.
| | 04:17 | We just set it equal to 1.
| | 04:20 | So trans.volume = 1, and then below
that, if statement, create an Else if
| | 04:24 | statement and check to see if trans.
volume is less than zero , and if so we'll
| | 04:31 | set trans.volume equal to zero.
| | 04:34 | I recommend to always doing this when
you are working with sounds, because if
| | 04:37 | the volume is greater than 1 or less
than 0, it's going to sound distorted.
| | 04:42 | So, you always want to make sure
that it's staying between 0 and 1.
| | 04:47 | And finally, we just have to reapply
that transformation to our sound, and to do
| | 04:51 | that type player.channel.soundTransform = trans.
| | 05:00 | So remember that after you adjust
the volume of a sound, you need to
| | 05:03 | reapply that adjusted volume to the
soundTransform property of your sound channel object.
| | 05:10 | So once you do that, you are ready to
save the file, and then test the movie to
| | 05:14 | see the volume control in action.
| | 05:16 | So I am going to play this song, and
then I am going to control the volume.
| | 05:21 | (Music Playing)
| | 05:28 | So, you can see that it
works just as you'd expect.
| | 05:31 | So now we have complete control with our
volume slider, and that completes our volume slider.
| | 05:38 | Now I want you to remember that
whenever you are working with sound, make sure
| | 05:42 | that you adjust the volume between 0 and 1.
| | 05:45 | Make sure it never goes below 0, or above 1.
| | 05:49 | Finally, once you make an adjustment to
the volume, you'll need to reapply it to
| | 05:54 | the soundTransform property
of your sound channel object.
| | Collapse this transcript |
|
|
4. Working with an XML PlaylistViewing the working files| 00:00 | In this chapter, we are going to
apply an XML playlist to our MP3 player.
| | 00:06 | We'll start out by looking at
the files we'll be working with.
| | 00:09 | First we'll look at data.xml, this XML
file has all of the XML data we'll be
| | 00:15 | working with, throughout this chapter.
| | 00:18 | Let's take a look at how it's structured.
| | 00:19 | The outer root node is called Album.
| | 00:23 | So, you can see the opening tag there
where I have that highlighted and then the
| | 00:27 | closing tag at the bottom.
| | 00:29 | Then there is repeating element called Song.
| | 00:32 | So each song has its own element.
| | 00:37 | Inside of each Song, there is an element
called File, and an element called Name.
| | 00:43 | The File element contains
the file name of that Song.
| | 00:46 | For example, we have 01 Eyes Wide.mp3
here and the name corresponds to the name
| | 00:55 | of the song, which is just Eyes Wide.
| | 00:59 | So, that goes for each song in this XML file.
| | 01:03 | So, if you don't have the exercise files,
create an XML file in a Text Editor.
| | 01:09 | Do not use Microsoft Word to do this.
| | 01:13 | Use Text Editor on the Mac, or
Notepad on the PC, if you are not sure which
| | 01:19 | Text Editor to use.
| | 01:21 | The reason why I tell people not to
use Microsoft Word is because Microsoft
| | 01:24 | Word puts a bunch of extra content inside of the
text files, what you want is a plain text file.
| | 01:32 | So, whether you're using TextEdit,
Notepad or some other application, make sure
| | 01:35 | you're not in Rich Text mode but
that you are in Plain Text mode.
| | 01:39 | So, when you have your file, just save
it as data.XML and save it in the same
| | 01:43 | folder as your FLA file.
| | 01:45 | And speaking of FLA files, let's
take a look at the one we have here.
| | 01:49 | So here I am in player.fla and on the
stage I have my player and there are
| | 01:55 | some new elements in it.
| | 01:56 | So I am going to double-click the
movie clip to enter its Timeline.
| | 01:59 | I added two buttons a Back
Button or a Forward Button.
| | 02:04 | The Back Button is called prev_mc, just a
simple graphic, and the same thing for the next_mc.
| | 02:12 | It's a simple graphic called next_mc.
| | 02:14 | If you want me to prove it, I can
double-click it to enter its timeline, and you
| | 02:19 | can see it is just a simple grouped
object, and if you were to ungroup it, you'd
| | 02:24 | see that there is two bitmap images.
| | 02:26 | It's actually just a copy of the
Play button. Very simple there.
| | 02:30 | So, those buttons are new and then
on the right side, we have info_btn.
| | 02:36 | This is just a button that's going
to show and hide info_mc and if you
| | 02:42 | double-click info_mc, you can see there
is a black shape in the background, and
| | 02:47 | there is a text field in the
foreground called info_txt.
| | 02:53 | As with all text fields which you are
using that are dynamic, if you want to
| | 02:58 | have them fade-in or fade-out or
rotate or anything, you have to embed the
| | 03:02 | font in that text field.
| | 03:03 | So, that's how our FLA file is setup.
| | 03:08 | Once you have your XML file and FLA
file setup, you're ready to start writing
| | 03:12 | the code for this application.
| | 03:14 | Once you've your file setup properly,
you are ready to start writing the code to
| | 03:19 | add XML data to your MP3 player.
| | Collapse this transcript |
| Creating the PlayerModel class| 00:00 | When you are creating a complex
application, like our MP3 player, it's good
| | 00:05 | to keep data separate from interactivity and
data and interactivity separate from design.
| | 00:13 | One way to do that is by using something
called the Model View Controller Design Pattern.
| | 00:20 | In my title on Object Oriented
Programming, I showed you how to use the Model
| | 00:26 | View Controller Design Pattern.
| | 00:28 | In this title we will use that pattern
but I won't discuss it in as much detail.
| | 00:34 | So, if you are hungry for more information on
that, go to the Object Oriented Programming title.
| | 00:40 | In the Model View Controller Pattern,
the model holds data for an application.
| | 00:46 | So, in our music player, we are going to
have the player model class control the
| | 00:52 | XML data for our application.
| | 00:54 | So, let's create a few properties here.
| | 00:56 | First, I will create a public property
called currentIndex, data type it to an
| | 01:05 | integer and set it equal to 0.
| | 01:09 | Create another public
property called totalItems.
| | 01:14 | That will also be an integer.
| | 01:16 | Another public property called
Loader, data type it to URLLoader.
| | 01:23 | Another public property
called data, data type that to XML.
| | 01:27 | Notice data is a reserved keyword in Flash.
| | 01:31 | If you don't like using reserved
keywords, feel free to use something else.
| | 01:35 | I just like using Data because it's
very intuitive for me when I am using this
| | 01:39 | class in another application.
| | 01:42 | I always think data is going to
hold the XML data for my application.
| | 01:47 | Again you can use whatever you want.
| | 01:48 | It's not really important what you call it.
| | 01:50 | I just prefer data and finally I am
going to skip a few lines and then create a
| | 01:56 | Public Static Constant called MODEL_CHANGE.
| | 02:02 | We will use this with our event dispatching.
| | 02:05 | This is going to be a String
and I am going to set it equal
| | 02:08 | to playerModelChanged.
| | 02:15 | In the Constructor method, I will set
it the loader equal to a new instance of
| | 02:19 | the URLLoader class.
| | 02:21 | Then I will add an event listener to
the loader to listen for Event.Complete.
| | 02:30 | Then I will trigger a method called dataLoaded.
| | 02:33 | Now, I will define the dataLoaded
method as a private method, just going to
| | 02:42 | receive an event with a data type
of Event, no return data, and inside
| | 02:50 | dataLoaded, I am going to set data
equal to a new instance in the XML class and
| | 02:57 | then pass in loader.data.
| | 03:01 | So, that will create an XML data
out of the loader's data and I will
| | 03:05 | set totalItems = data.*
| | 03:12 | That gives you an XML list of all of the
child nodes of the root node of our XML object.
| | 03:20 | .length and some parenthesis
because length is a method when you are
| | 03:25 | working with an XML list.
| | 03:28 | Then I am going to run a
method called setCurrentIndex.
| | 03:29 | We will define that in just a minute,
I am going to pass in currentIndex.
| | 03:38 | And finally I am going to dispatch
the complete event. So dispatchEvent.
| | 03:44 | That's why I have extended the
EventDispatcher class for my player model, so I
| | 03:49 | can dispatch events.
| | 03:51 | And in the parenthesis, I will create a
new event and inside of the parenthesis,
| | 03:56 | I will type Event.COMPLETE.
| | 03:58 | So, I am going to dispatch that complete event.
| | 04:02 | Now, I will define setCurrentIndex.
| | 04:04 | I will do that right below dataLoaded.
| | 04:07 | This is going to be a public method.
| | 04:09 | So type public function setCurrentIndex.
| | 04:15 | A receiver parameter called index.
| | 04:18 | That's going to be an integer, no return data.
| | 04:22 | See here also the value of currentIndex, so
currentIndex = Index, whatever is passed in.
| | 04:31 | And then what we want to do is just
make sure that if index value is too high,
| | 04:36 | it will loop around.
| | 04:37 | So, if somebody is like skipping
tracks forward and there at the last track,
| | 04:41 | and then go to skip to the next one, it will
just loop around and go back to the first one.
| | 04:46 | So, if(currentIndex >= totalItems)
currentIndex = 0;
| | 05:00 | else if (currentIndex < 0)
currentIndex = totalItems - 1;
| | 05:13 | Remember we are subtracting 1 to offset
that value because totalItems is going
| | 05:17 | to start at 1 and the index
values are going to start at 0.
| | 05:22 | So, we need to offset that by subtracting 1.
| | 05:24 | So, the highest value is 1 less
than the total number of items.
| | 05:30 | And then we will dispatch the change
event because the current index has changed.
| | 05:34 | So, dispatchEvent, new Event and in the
parenthesis for newEvent, I am going to
| | 05:43 | type PlayerModel.MODEL_CHANGE in
all caps just like I typed it above.
| | 05:51 | You could even copy and paste it
if you would like. And there we go.
| | 05:56 | So we have written a lot of code here.
| | 05:59 | I just want to make sure that this
class is running properly so, I am going to
| | 06:02 | add a trace statement at the bottom here.
| | 06:05 | So, we will trace player model running.
| | 06:10 | We will save the file and then jump
over to Player.as and create a public
| | 06:18 | property called model.
| | 06:21 | Data type it to a PlayerModel and in
the constructor, we will initialize it.
| | 06:29 | Model = new PlayerModel.
| | 06:35 | Now, you should be able to save this
file and test the movie and just see the
| | 06:39 | PlayerModel class is running properly.
| | 06:41 | So, we have the trace
statement and looks like we are good.
| | 06:46 | So, now we have set up our
PlayerModel class and it has all the methods
| | 06:52 | necessary to work with XML data.
| | Collapse this transcript |
| Loading XML data into the player| 00:00 | In this movie, we will look at
loading XML data into our music player.
| | 00:04 | The first thing I am going to do is
move over to PlayerModel.as and just
| | 00:08 | delete that trace statement
that we wrote in another movie.
| | 00:11 | It is on line 19 in my code.
| | 00:13 | So, I will save that and then go to Player.as.
| | 00:19 | In the Player file, right below where
I define the model and of constructor
| | 00:24 | method, I am going to add an
event listener to the model.
| | 00:27 | And I will listen for Event.COMPLETE
and when that event occurs, I will run a
| | 00:35 | method called xmlLoaded.
| | 00:41 | So, I am going to scroll down toward
the bottom of my code, create a private
| | 00:45 | method called xmlLoaded.
| | 00:50 | Remember that it will receive an event
with a data type of Event and inside of
| | 00:55 | the method I am going to add an
event listener to the model to listen for
| | 01:01 | PlayerModel.MODEL_CHANGE and then
run a method called modelChanged.
| | 01:14 | Now, I will define modelChanged, so a
private function, modelChanged and this
| | 01:23 | is a reserved Flash keyword, but it doesn't
apply to movie clip, so it is okay to use that here.
| | 01:31 | Again if you don't want to use reserved
keyword, feel free to use something else.
| | 01:37 | So, I will listen an event with the
data type of Event, void for no return data
| | 01:42 | and in here we will set
progDisplay.resumeTime equal to 0.
| | 01:49 | So, every time the model changes we
will reset the resume time and then we will
| | 01:55 | run the playSong method.
| | 02:00 | And then we will scroll up to playSong.
| | 02:02 | Now, instead of the sound file being a
direct string, we are going to get that
| | 02:08 | data from the XML file.
| | 02:11 | So, in playSong, I am going to change soundFile.
| | 02:12 | I am going to set it to model.data.
| | 02:16 | That's our XML object .
song and then square brackets.
| | 02:23 | This is going to be the
index number of the song.
| | 02:26 | We will have to remember
song is a repeating element.
| | 02:28 | So, an XML repeating
element is called an XML list.
| | 02:33 | When you are working with an XML
list in ActionScript, you can access the
| | 02:37 | individual entices of that list using
array-access notation, which is why I am
| | 02:42 | using square brackets here.
| | 02:44 | So, inside of the square brackets, I am
going to type model.currentIndex.file.
| | 02:52 | Now, because we are relying on the
XML data when we play the song, when we
| | 02:57 | add the event listeners to the play
and pause buttons, we should do that
| | 03:00 | after the XML data is loaded.
| | 03:02 | So, I am going to scroll up and I am
going to find play_mc.addEventListener and
| | 03:07 | pause_mc.addEventListener in the
constructor method and I am going to cut them
| | 03:13 | and paste those two lines at the bottom
of the xmlLoaded method that I created
| | 03:18 | earlier in this movie.
| | 03:19 | So, once the XML is loaded, then you can push
the Play and Pause buttons to work with song.
| | 03:25 | Last thing we are going to do to get
this to work is we will load the XML
| | 03:29 | data into the model.
| | 03:34 | Right below where we add the event
listener to the model, we will have the
| | 03:36 | model load in XML file.
| | 03:38 | So, model.load and in the parenthesis
we will pass in a new URLRequest and the
| | 03:47 | request will be for data.xml.
| | 03:51 | Save the file and jump over to PlayerModel.
| | 03:59 | In here, we will define the load
method that we just referenced.
| | 04:05 | So, I will create a public method called load.
| | 04:07 | Again this is a reserved keyword,
but it is very intuitive for me to use
| | 04:11 | a method called load.
| | 04:12 | So, I am using it anyway and we will
receive a parameter called req, which is a
| | 04:17 | URLRequest, no return data and this
will make the loader load that request.
| | 04:27 | Now, the XML file will load, the
data loaded method will trigger in here,
| | 04:33 | triggering the complete event,
setting the current index and everything
| | 04:39 | should work properly.
| | 04:40 | So, let's save the file and you should
be able to test the movie and not have
| | 04:44 | any errors and then click the Play
button and the song should play.
| | 04:46 | (Music Playing)
| | 04:54 | All right, so now we know that
it is loading from the XML file.
| | 04:59 | And the last thing to do with our XML
data is display the name of the song in
| | 05:05 | the info text field.
| | 05:06 | So, I am going to go Player.as and near
the top of the constructor right above
| | 05:15 | where we set the model, I am going
to set info_mc.visible equal to false.
| | 05:24 | Then once the XML is loaded, I am
going to add an event listener to
| | 05:30 | Info_btn.addEventListener.
| | 05:34 | Event is going to be MouseEvent.ROLL_OVER.
| | 05:38 | I will call this showInfo and then I
am going to copy and paste that line of
| | 05:48 | code, change the event to ROLL_OUT
and showInfo to hideInfo and Right below
| | 05:57 | xmlLoaded, I will define showInfo
and hideInfo as private methods.
| | 06:05 | So, showInfo will receive an event with
the data type of MouseEvent and inside
| | 06:14 | of showInfo I will set info_mc.
visible property equal to true.
| | 06:22 | Then I will set that text field.
| | 06:23 | So, info_mc.info_txt.text =
model.data.song some brackets,
| | 06:35 | model.currentindex inside of the
brackets and then after the closed bracket,
| | 06:41 | I am going to type .name.
| | 06:43 | That's going to be the name of the song.
| | 06:45 | So, it is going to go on that text field.
| | 06:47 | I am going to copy and paste this
method, change the name of the method to
| | 06:53 | hideInfo, change visible equal to
false and then delete that second line
| | 07:00 | inside of the method.
| | 07:02 | So, let's save the file and we should see
that song name appearing in that info text field.
| | 07:08 | Test the movie, play the song.
| | 07:09 | (Music Playing)
| | 07:09 | I am going to pause this song and then
roll over the info box and then it shows
| | 07:19 | the name of the song.
| | 07:20 | So, now our player is connected to
XML data instead of having to update the
| | 07:28 | songs inside of our ActionScript, we
can do everything through the XML file
| | 07:33 | making a much more efficient application.
| | Collapse this transcript |
| Creating the PlayerController class| 00:00 | In this movie, we'll look at
making the PlayerController class.
| | 00:04 | The PlayerController class will
manipulate the XML data in the player model.
| | 00:09 | This will allow us to add
functionality like forward and back buttons to go
| | 00:14 | through tracks in the playlist.
| | 00:16 | if you don't have the exercise files,
make sure to create PlayerController.as in
| | 00:21 | the same folder as your other classes.
| | 00:23 | That's the com.lynda.audio package.
| | 00:26 | Make sure that you capitalize the P
in Player and the C in Controller.
| | 00:31 | The first thing I am going to do is
create a public property called model.
| | 00:35 | I am going to data type that to a PlayerModel.
| | 00:39 | Notice that I don't need to import the
PlayerModel class, because it's in the
| | 00:42 | same package as PlayerController.
| | 00:44 | In the constructor method, I am going
to receive one parameter called m. That's
| | 00:49 | going to be a PlayerModel.
| | 00:52 | And then in the constructor, I
am just going to set model = m;.
| | 00:55 | Now I am going to define some
public methods, one called addNextButton.
| | 01:00 | It's going to receive a property
called btn that's a DisplayObject.
| | 01:14 | In there, I am going to type
btn.addEventListener and the event is going to be
| | 01:19 | MouseEvent.CLICK and we'll
run a method called nextItem.
| | 01:24 | And I am just going to
copy and paste this method.
| | 01:30 | Change addNextButton to
addPrevButton and the same thing for the nextItem
| | 01:37 | method, we'll just change it to prevItem.
| | 01:41 | So now that find some private
methods called nextItem and prevItem.
| | 01:52 | So nextItem is going to receive an
event with the datatype of MouseEvent.
| | 01:54 | Now we return data.
| | 01:57 | And in here, we'll run model.
setCurrentIndex, and in the parenthesis, we will
| | 02:04 | just pass in model.currentIndex + 1.
| | 02:11 | Copy and paste this method.
| | 02:14 | In the pasted code, change nextItem to
prevItem, and change the plus to a minus.
| | 02:22 | So basically this class simply
takes a button that you pass in through
| | 02:26 | addNextButton or addPrevButton,
and adds the event listener to it.
| | 02:31 | Whenever you click that button, it just
manipulates the model forward one or back one.
| | 02:36 | Since the model is connected to the
player, when the model changes, the model
| | 02:42 | change event will occur and
change the player's track.
| | 02:47 | So let's save the file
and then open up Player.as.
| | 02:51 | So in Player.as, I am going to create a
new public property called controller,
| | 02:59 | datatype it to PlayerController, and
then I'll initialize it right after I
| | 03:04 | initialize the model in the constructor method.
| | 03:08 | So controller = new PlayerController,
pass in the model, and then I'll set the
| | 03:19 | controller's next button and previous button.
| | 03:22 | So controller.
addNextButton passing in next_mc and
| | 03:31 | controller.addPrevButton, passing in prev_mc.
| | 03:40 | And then I want to see the hand cursor
when I roll over the next and previous button.
| | 03:43 | So next_mc.buttonMode = true;
| | 03:49 | and prev_mc.buttonMode = true;. That's it.
| | 03:54 | So save the file and then test the movie,
and you'll have to play the song first
| | 04:01 | for this to work, but you should be
able to change tracks when you click the
| | 04:04 | next and the previous buttons.
| | 04:06 | (Music Playing).
| | 04:12 | And notice that you can change the
tracks and you can still view the MP3
| | 04:16 | information, from the XML file
when you roll over the Info button.
| | 04:19 | (Music Playing).
| | 04:21 | So that completes adding the
XML functionality to our player.
| | 04:34 | So instead of making changes like song
information, playlist information, all of
| | 04:41 | that using ActionScript, you can make
all of the changes to the XML file and
| | 04:46 | everything in the Flash
application will automatically update.
| | Collapse this transcript |
|
|
5. Accessing Sound Wave DataViewing the working files| 00:00 | In this chapter we are going to look
at how to display sound wave data in
| | 00:04 | a Flash application.
| | 00:05 | We'll start by looking at the
file we are going to be working with.
| | 00:08 | First we'll look at player.fla.
| | 00:11 | As with all of the files we've have been
working in this title, the player is on
| | 00:15 | the main timeline and called player_mc.
| | 00:18 | If I double-click the player,
I can enter its timeline.
| | 00:22 | Really there is nothing that I have
added to this file for this chapter.
| | 00:26 | I have just left an empty space on the
right side and that's where the sound
| | 00:30 | waves are going to go.
| | 00:31 | All of the sound waves are going to be
generated dynamically using ActionScript
| | 00:36 | with the drawing API.
| | 00:38 | API stands for
Application Programming Interface.
| | 00:42 | It's basically a group of
methods that you can use to draw shapes
| | 00:46 | using ActionScript.
| | 00:47 | That's it for player.fla.
| | 00:49 | Let's go over to SoundWaveData.as.
| | 00:53 | Now notice this file is
in com.lynda.audio package.
| | 00:56 | So if you don't have the Exercise files, go
ahead and create this file now. SoundWaveData.
| | 01:00 | Make sure to name everything properly.
| | 01:06 | Import these classes all the display,
events, media and utils classes.
| | 01:12 | Create some properties, a
public property called height.
| | 01:16 | This will represent the
height of the sound waves.
| | 01:19 | That's going be 12.
| | 01:19 | Width, which will represent the width
of the sound waves, which will be 16.
| | 01:24 | Again, I am using reserved keywords,
because it's intuitive for me to do.
| | 01:28 | If you don't want to use these reserve
keywords, then feel free to use something else.
| | 01:33 | Just make sure to substitute later on.
| | 01:36 | So then we have colorL, this is
the color for the left channel line.
| | 01:41 | I chose white there.
| | 01:43 | This is the color for the right channel line.
| | 01:46 | I also chose white.
| | 01:47 | So you can feel free to put in any
hexadecimal color you want right here.
| | 01:50 | If you want to mix it up a little bit.
| | 01:52 | I have a public property called Sprite,
public property called Player that is a
| | 01:56 | instance of the Player class, and
then a private property called allBytes,
| | 02:02 | which is a ByteArray.
| | 02:03 | We'll talk about byte arrays in just a minute.
| | 02:07 | So, here is a constructor
method for SoundWaveData.
| | 02:09 | It receives two parameters.
| | 02:12 | One is called p, which is the Player,
and then s, which is the Sprite.
| | 02:15 | And the Sprite is going to be the
Sprite that draws all the sound wave data.
| | 02:20 | So that's going to be created in
the player, and then passed into
| | 02:23 | this constructor method.
| | 02:24 | So I am just setting Player and Sprite
equal to p and s respectively, then I
| | 02:28 | create a new instance of a ByteArray.
| | 02:30 | Now basically a ByteArray is just
like the name implies, an array of bytes.
| | 02:36 | So when you are working with sound
wave data, all of the byte information for
| | 02:40 | the sound is transferred into this byte array.
| | 02:44 | Then you can display that data visually
by extracting the data from the byte array.
| | 02:49 | Now we'll looking in
doing that in another movie.
| | 02:51 | But that's just so you
understand what a byte array is.
| | 02:53 | Then I have few methods here, init and disable.
| | 03:00 | And init, as an event listener to
listen for the ENTER_FRAME event, runs
| | 03:04 | showSoundWaves and disable does guess
what, removes that same event listener.
| | 03:09 | Remember that whenever you are working
with an ENTER_FRAME event, you want to
| | 03:12 | make sure to remove the event
listener to optimize your application.
| | 03:15 | So we haven't defined showSoundWaves.
| | 03:17 | Yes we will do that in another movie.
| | 03:18 | Now let's jump over to Player.as.
| | 03:21 | In this file I have added some code to
create a new Sprite, and to create an
| | 03:27 | instance of the SoundWaveData class.
| | 03:31 | In the constructor I create that Sprite add it
to the stage, put it at X of 277 and a Y of 2.
| | 03:38 | These aren't just random numbers.
| | 03:39 | I actually plot it out visually in
the FLA file, and then I wrote down the
| | 03:44 | coordinates, and then put them here.
| | 03:47 | So if you don't have the Exercise Files,
you have to find out where you want
| | 03:50 | the sound waves to be, write down those
coordinates and then plug them in right here.
| | 03:55 | Then I've created the new instance of
SoundWaveData passing in this the Player,
| | 03:58 | and sprite, and if you scroll down at
the bottom of playSong, I initialize the
| | 04:05 | SoundWaveData object, at the
end of pauseSong, I disable it.
| | 04:09 | So once you have your
file setup, and ready to go.
| | 04:12 | You are ready to start writing the code to
display sound wave data through the Flash Player.
| | Collapse this transcript |
| Working with sound wave data| 00:00 | Now, we'll look at taking sound wave
data and displaying it visually using
| | 00:05 | Flash's Drawing API.
| | 00:08 | In my sound wave data class file, we're
going to scroll down to show sound waves.
| | 00:14 | The fist thing I'm going to do here
is create a variable called lineY.
| | 00:17 | This is going to represent the Y
position of the lines that we're going to draw
| | 00:24 | for the left and right sound channels.
| | 00:26 | So, I'm going to set it as a number equal to 0.
| | 00:29 | I'm going to go down a few lines, and
then I'm going to use the method SoundMixer.
| | 00:37 | SoundMixer is in charge of general
sounds for all of the Flash applications.
| | 00:43 | So, this controls all sounds .computeSpectrum.
| | 00:48 | This method takes a Byte Array, and
then puts the sound wave data inside of
| | 00:53 | it, so that you can output it visually
if you want to, or do whatever you want
| | 00:58 | with that information.
| | 00:59 | If you have more than one sound
channel object in your application, this will
| | 01:04 | apply globally to all the sound
channels in your applications.
| | 01:07 | So, just keep that in mind as your using this.
| | 01:10 | So, now the first property that we've
put in is the Output Array, and that's
| | 01:16 | going to be our Byte Array.
| | 01:17 | So, just pass in the Byte Array,
which is going to be allBytes.
| | 01:22 | The next property is called FFT Mode.
| | 01:25 | Now, what this does is the default
value is false, so I'm going to leave it at
| | 01:30 | false, and just close up the parentheses.
| | 01:32 | This displays the sound wave data as a waveform.
| | 01:37 | Each byte will have a value between -1 and +1.
| | 01:42 | If you put a value of true, then the
bytes will represent sound frequency and
| | 01:49 | give you values between 0 and about 1.4.
| | 01:54 | For this exercise, I'm
just going to set it false.
| | 01:56 | You can definitely experiment
setting it to true, and see what you get.
| | 02:00 | So, I'm going to go down a few lines,
and then I'm going to clear the graphics
| | 02:05 | that are currently inside the sprite.
| | 02:06 | So, sprite.grapics.clear.
| | 02:09 | You can use the Drawing API by
accessing any sprite's graphics property.
| | 02:14 | So, that goes for removing clips in the main
time, and they'll have the graphics property.
| | 02:19 | So, we're clearing it to erase
any graphics that already exist.
| | 02:24 | Then I'm going to set the line styles.
| | 02:26 | So, sprite.graphics.lineStyle, and
first we've to put in the thickness of the
| | 02:33 | stoke, which I'm going to put 1,
for the color I'm going to use colorL.
| | 02:38 | That's the color for the left channel.
| | 02:40 | Then for alpha the default value
is 1, so I'm just going to close in
| | 02:43 | the parentheses there.
| | 02:44 | Let's go to the next line, and then I'm
going to use the moveTo method to define
| | 02:49 | where I'm going to start drawing a line.
| | 02:51 | So, sprite.graphics.
moveTo and then I'll pass in 0.
| | 02:56 |
| | 02:57 | So, it'll be an X of 0 and then
the Y, which is just going to height.
| | 03:04 | So, we'll start drawing from there.
| | 03:06 | Next, I'm going to create a for loop,
to that i variable, and as i is less
| | 03:14 | than width, do i++.
| | 03:17 | Then I'm going to use a loop along
with our Byte Array to display the
| | 03:24 | left channel visually.
| | 03:26 | So, type for var i:uint = 0; i<width; i++.
| | 03:33 | In the loop we'll set lineY equal to
height minus, now put some parentheses
| | 03:41 | here, and going to subtract allBytes.readFloat.
| | 03:49 | It gives us a floating point number.
| | 03:51 | It's going to between -1 and +1.
| | 03:52 | I'm going to multiply that by height.
| | 03:56 | So, this will give us a value between
negative height and positive height, or in
| | 04:01 | other words -12 and +12.
| | 04:05 | And of course, you can change the width and
the height of these values if you ever want to.
| | 04:11 | So, by subtracting that value from height,
it's going to go up or down from height.
| | 04:19 | So, after that, sprite.graphics.lineTo,
and then pass in i, and then pass in
| | 04:30 | i and then lineY.
| | 04:33 | For lineTo you just pass in X and Y
coordinates and Flash will just draw a line
| | 04:38 | from wherever the line is currently.
| | 04:40 | So, moveTo starts right there, at 0 and height.
| | 04:43 | Then lineTo for each byte will go
through to whatever i is for the X position,
| | 04:48 | and the lineY which corresponds to
the byte, after readFloat is run.
| | 04:53 | Now, it's important to note that
this readFloat method is actually what's
| | 04:57 | looping through the Byte Array.
| | 04:59 | The i variable is just for plotting
the X position of our line, and we're
| | 05:05 | getting the Y position from looping
through the bytes using readFloat here.
| | 05:11 | So, if we test this out, we should be
able to see just the left channel in action.
| | 05:15 | So, save the file.
| | 05:17 | Then test the movie.
| | 05:18 | You'll have to play the song to see the
sound wave data over here on the right.
| | 05:21 | (Music Playing)
| | 05:33 | There you go.
| | 05:35 | That's the left channel right there.
| | 05:37 | Now, if you want to you can decrease the
volume and you can watch the sound waves update.
| | 05:41 | (Music Playing)
| | 05:49 | Nice, looks like it
working just as it's supposed to.
| | 05:52 | For the right channel, I'll pretty
much going to copy and paste this code and
| | 05:55 | just modify it slightly.
| | 05:57 | So, just copy everything
below sprite.graphics.clear.
| | 06:01 | Then go down a few lines and paste that code.
| | 06:04 | Now, in the pasted code, right above
sprite.graphics.lineStyle, I'm going to
| | 06:10 | use the lineTo method.
| | 06:11 | So, sprite.graphics.lineTo,
then I'll pass in width and height.
| | 06:21 | So, we're going to just move that line
which draws a line to X of 16 and a Y of
| | 06:31 | 12, or whatever values we have
in that for width and height.
| | 06:35 | We're going to change that
color from colorL to colorR.
| | 06:39 | That's the color for the right channel.
| | 06:40 | Again, you can feel free to mix
up the colors however you want.
| | 06:44 | Then when it says moveTo 0 and height.
| | 06:46 | We're going to change 0 to width.
| | 06:49 | When the bytes come into the Byte
Array, they're actually 512 bytes.
| | 06:53 | The left channel has bytes 1 to 256 and
the right channel has the rest of them.
| | 06:59 | So, what we're going to do is we
plotted it from the left to the right for the
| | 07:02 | left channel we would plot it from
right to the left, for the right channel.
| | 07:06 | So, we're going to start all the way
the right here with that width property.
| | 07:09 | So, for the For loop, we don't
need to declare the variable again.
| | 07:14 | We'll set i = width , so
I'm going to backwards now.
| | 07:18 | As long as i is greater than 0,
we're going to run this loop.
| | 07:21 | Instead of i++ it's going to i--.
| | 07:24 | This is going to be exactly
the same thing for this loop.
| | 07:30 | So, we don't need to change
anything inside of the loop.
| | 07:32 | The last thing we're going to do is
right below this loop, I'm going to have
| | 07:36 | that draw a line to X of 0 and a Y of height.
| | 07:39 | So, sprite.graphics.lineTo,
I'll pass in 0 and then height.
| | 07:49 | So, that will basically reset our line.
| | 07:51 | So, save the file, and then test the movie, and play
the song to see the sound wave data for both channels.
| | 07:58 | (Music Playing)
| | 08:11 | There is our sound wave data.
| | 08:13 | So, feel free to change the colors,
change the width and height, and customize
| | 08:16 | this however you want.
| | 08:19 | For more information about Byte Arrays
and working with sound wave data, you
| | 08:23 | can see Flash Help.
| | 08:25 | Actually, much of the code that I
show here is from the Flash help, about
| | 08:30 | accessing raw sound wave data.
| | 08:32 | So, you can find more information there,
and you can apply it to use sound wave
| | 08:37 | data in interesting and creative ways.
| | 08:40 | So, remember that when you work with
sound wave data, you use a Byte Array, and
| | 08:44 | you use the computeSpectrum
method, passing in that Byte Array.
| | 08:51 | Then you can loop through the bytes
using the byte arrays readFloat method.
| | 08:56 | That's how to work with sound wave data.
| | 08:58 | So, now you know how to work with
sound wave data in the Flash Player.
| | Collapse this transcript |
|
|
6. Adding Sharing FeaturesViewing the working files| 00:00 | In this chapter, we are going to
look at sharing our application.
| | 00:04 | So, let's say you want other people to
embed your music player on their website
| | 00:09 | or you wanted them to be able to
share the URL to your music player.
| | 00:14 | In this chapter, we will look at how to do that.
| | 00:16 | We will start by looking at the files
that we are going to be working with.
| | 00:19 | First off, I will start with our XML file.
| | 00:22 | This file is the same XML file we
have been working with for the last few
| | 00:25 | chapters, except I have added
another element at the top called Share.
| | 00:30 | This has an attribute called URL.
| | 00:32 | It's a value of player.html.
| | 00:37 | That serves as the HTML link to the
music player and of course, I have published
| | 00:42 | my FLA file, so I do have that player.html file.
| | 00:46 | Then I have the object tag here,
which you can get if you don't have
| | 00:49 | the Exercise Files.
| | 00:50 | Don't copy all this down.
| | 00:52 | That's going to take a long time.
| | 00:53 | You can publish the FLA file and then
Copy and Paste the object tag in here.
| | 00:58 | What you want to do is just change
allowfullscreen's value to true in two cases.
| | 01:03 | It's going to be in the embed tag.
| | 01:05 | You are going to set it to true and
the param, you will set it to always.
| | 01:08 | So, that's our XML file.
| | 01:10 | Let's go over to Flash.
| | 01:14 | Our FLA files, what we will look at
first in Flash, it's basically the same FLA
| | 01:18 | that we have been working with.
| | 01:19 | I've just replaced the sound
wave with this sharing movie clips.
| | 01:24 | If I double click the player, I can
enter its timeline and I can see there's
| | 01:27 | movie clip in their called share_mc.
| | 01:29 | Now, it's on its own layer called info.
| | 01:34 | Pretty straightforward.
| | 01:35 | If you double click that movie
clip, you can enter its timeline.
| | 01:38 | You'll see that you have two layers
and I will just expand my layer area, so
| | 01:44 | that you can see the name of layers, so
we have share info and the icon that's
| | 01:48 | hidden behind share info.
| | 01:50 | Share info has an instance name of info_mc
and if you could double click it, you
| | 01:54 | can enter its timeline, pretty
straightforward, some set text fields, some
| | 02:00 | dynamic text fields.
| | 02:03 | Dynamic text field tab, instance
name of embed_txt for the bottom one and
| | 02:08 | link_txt for the top one.
| | 02:11 | There are two Copy buttons, so we have
copyLink_mc and then we have copyEmbed_mc.
| | 02:20 | These are actually just very simple
buttons and there's a background element
| | 02:25 | that's locked here and if I select it,
you can see that it's just a transparent
| | 02:29 | rectangle that's basically
just a hit area for this.
| | 02:32 | So, when I rollover that Share button
icon, then when I have to roll out of this
| | 02:38 | large area in order to make it disappear.
| | 02:41 | So, I am just expanding that hit area.
| | 02:44 | So, back to Share, and if I hide share
info, you can see that the icon, very
| | 02:50 | simple it's just a bitmap image,
just a little share icon and that's it.
| | 02:56 | So, let's go over to Share Info.as.
| | 02:59 | I already made a lot of this
class, but it's pretty simple.
| | 03:05 | So, I am declaring the com.lynda.audio package.
| | 03:07 | So, just like everything else in this
title you will need to save it in that
| | 03:10 | package or in that folder called Share
Info.as, import all the display, event,
| | 03:19 | system, and text classes.
| | 03:22 | Create for public properties shareBtn
that's a MovieClip, player is a Player,
| | 03:29 | linkTxt is a TextField, embedTxt is a TextField.
| | 03:34 | The constructor accepts two parameters.
| | 03:36 | p is a Player, s is a MovieClip,
setting player = p, shareBtn = s.
| | 03:45 | That's actually the whole share movie clip
that contains the icon and the info movie clip.
| | 03:51 | Setting buttonMode = true,
setting info visibility to false.
| | 03:56 | So, you will be able to see the share
icon, but not the share info text field
| | 04:01 | and copy buttons and everything.
| | 04:04 | I have a method called init that's public.
| | 04:06 | Looks like it's a lot more
complicated than it really is.
| | 04:09 | I am just setting the values
for a linkTxt and embedTxt.
| | 04:12 | We have a short hand reference to them.
| | 04:13 | I am setting a text inside to the
linkTxt field equal to whatever the URL is in
| | 04:19 | the share element from the XML file.
| | 04:22 | Then I am taking whatever is in that
share element that's everything that's
| | 04:26 | inside of the element, so all that object tag
stuff and I was taking that as an XMLString,
| | 04:33 | I know it's HTML code, but we are just
reading it as XML here and that's fine.
| | 04:38 | So, we get that XMLString there.
| | 04:40 | So, we'll have all that code to work
with inside of the embedTxt field adding
| | 04:45 | an event listener to listen for ROLL_OVER
for the share button and also
| | 04:49 | listening for ROLL_OUT.
| | 04:51 | That's going to show and hide info
movie clip based on when you roll over
| | 04:55 | or when you roll out.
| | 04:56 | Just like you'd expect them to work.
| | 04:58 | So, that's pretty straightforward and
then finally the Player class and I've
| | 05:02 | just added a few lines here.
| | 05:04 | So, I created a public
property called shareInfo.
| | 05:07 | I instantiated it at the bottom of
the constructor passing in this for the
| | 05:12 | player and then share_mc for the
share movie clip which is called the Share
| | 05:19 | button inside of the shareInfo class.
| | 05:23 | Once the XML is loaded, I initialize
shareInfo object by calling its init method
| | 05:30 | at the very bottom of the XML
loaded method and that's it.
| | 05:35 | So, once you've your file set up like
this, you can test the movie and see
| | 05:39 | that it's pretty much the same as we
have been working with except for that
| | 05:43 | movie clip is going to show is going
to show on height when I roll over it,
| | 05:47 | pretty straightforward.
| | 05:48 | All right, once you are ready to go,
you are ready to start adding more
| | 05:51 | functionality to this applications, so
that you can share it with other people.
| | Collapse this transcript |
| Selecting and copying text| 00:00 | In this movie, we will look at how to
select and copy text from the text field.
| | 00:05 | So, we will start by scrolling down to
the init method and at the very bottom of
| | 00:10 | this method, we are going to add
some event listeners to link_txt.
| | 00:16 | In this area we are going to add some
event listeners to our copy buttons.
| | 00:20 | We are going to start in this area by
adding an event listener to our copy buttons.
| | 00:25 | So, shareBtn.info_mc.copyLink_mc.
addEventListener and the event is going to be
| | 00:38 | MouseEvent.CLICK, and the method
that we will run is called copyLink.
| | 00:44 | We will define that in just a minute.
| | 00:47 | Go to the next line and we will
add an event listener to linkTxt.
| | 00:51 | So, linkTxt.addEventListener and event
is going to be MouseEvent.CLICK and the
| | 01:02 | method is going to be called selectLink.
| | 01:06 | So, when you click on the link Text
field, it's going to select that link.
| | 01:10 | If you click the copy button,
it's going to copy the link.
| | 01:12 | So, we are going to do the
same thing for the embed button.
| | 01:16 | So, I am just going to copy those last
two lines of code and I will paste them
| | 01:24 | and in the pasted code, I am going to
change copyLink_mc to copyEmbed_mc and I
| | 01:30 | will change the method name to
copyEmbed as well and then I am going to change
| | 01:39 | linkTxt to embedTxt.
| | 01:43 | I will change the method name to selectEmbed.
| | 01:46 | Now, right below the init method, we'll
define another private method called
| | 01:56 | selectLink, receive an event with the
data type of MouseEvent, void for no
| | 02:06 | return data and in the selectLink
method, we will set linkTxt selectable
| | 02:14 | property = true, make sure that you can
select it and then we will use the code
| | 02:19 | to actually select part of the
text field using ActionScript.
| | 02:24 | Now, remember that when you are
doing this you have to do it inside of a
| | 02:27 | MouseEvent event handler.
| | 02:30 | So, you can't just select a part of
the text field from wherever you want.
| | 02:32 | You have to be responding to a
MouseEvent, same with copying things.
| | 02:37 | So, linkTxt.setSelection and this is
just basically an index space selection.
| | 02:46 | So, 0 would be the first character and
in order to get the last character, we
| | 02:50 | can just access the property length.
| | 02:54 | So, linkTxt.length, so that I will grab
the whole selection inside of the linkTxt.
| | 03:00 | That's all that there is for selecting a link.
| | 03:02 | So, we will define another private
method called copyLink, event, data type of
| | 03:10 | MouseEvent, :void for no return data
and here we are going to set the clipboard
| | 03:17 | to copy the link in the text field.
| | 03:19 | Again, you need to do
this inside of a MouseEvent.
| | 03:22 | There has to be some sort of user interaction
in order to copy something to the clipboard.
| | 03:27 | So, the method we are doing that is
System.setClipboard and then it accepts a
| | 03:35 | string, so you can put whatever string
you want in there and I am going to put
| | 03:38 | in linkTxt.text and that's
really all there is to it.
| | 03:45 | I am just going to copy and paste these
methods and basically do this exact same
| | 03:50 | thing for the embed text field.
| | 03:52 | So, I am going to change selectLink
to selectEmbed and I'm going to change
| | 03:57 | linkTxt to embedTxt.
| | 03:59 | Just copy and paste over that.
| | 04:06 | Then I am going to change
copyLink to copyEmbed and save the file.
| | 04:15 | Now, you should be able to test the
movie and roll over that little shared icon
| | 04:23 | and if I click on let's say player.html
and then click copy, I should be able to
| | 04:30 | go back into Flash or whatever other
application and then just use Command+V or
| | 04:34 | Ctrl+V and then paste that code.
| | 04:37 | So, that works with player.html.
| | 04:40 | Let's test it one more time and it's
going to confirm that it works with
| | 04:45 | the embed text field.
| | 04:46 | So, I will select it by clicking it, click
the copy button and then paste and there we go.
| | 04:54 | And so, I am just going to press Command+Z
to undo that and I will save the file.
| | 05:00 | Now, we have successfully set it up,
so that we can select and copy text
| | 05:05 | using ActionScript.
| | 05:06 | So, our sharable player is pretty much complete.
| | Collapse this transcript |
| Setting up a testing server: Windows| 00:00 | In order to test out our sharing
application on our home computer, we'll need to
| | 00:05 | install something called the testing server.
| | 00:07 | A testing server mimics a web server,
so it's basically like you have your own
| | 00:12 | web server on your home computer.
| | 00:14 | To do that on Windows, I'm going to
use a software package called WampServer.
| | 00:20 | WAMP stands for Windows, Apache, MySQL and PHP.
| | 00:25 | You can install all of these
services in one simple download.
| | 00:30 | This is the quickest and easiest way to get a
Testing Server up and running on your computer.
| | 00:35 | So go to wampserver.com, and
then the default page is in French.
| | 00:41 | I'm going to click this British flag
here, and go to the English version.
| | 00:45 | And then, I'm going to scroll down I am
going to click step 1 to, Download the
| | 00:49 | latest release of Wampserver 2.
| | 00:52 | And then, I'm going to click the
link to Download WampServer 2.0i.
| | 00:57 | When prompted, I'm going
to click to save the file.
| | 01:02 | The file will then download, and
then I'll open it up when it's done.
| | 01:08 | I'll choose to run the application, and
then I have a security warning, I know
| | 01:14 | what application this is and I trust it.
| | 01:16 | So I'm going to click Allow.
| | 01:19 | Click Next to start the install Wizard.
| | 01:22 | Make sure that you read over the
license terms before choosing to accept the
| | 01:27 | License Agreement, I'll do that and click Next.
| | 01:31 | I'm going to choose where to install
Wamp, I'm going to leave the default
| | 01:35 | location here, which is right at
the C drive, so I'll click Next.
| | 01:40 | I'm not going to click to create a
Quick Launch icon or a Desktop icon, but you
| | 01:44 | can feel free to do that if you would like.
| | 01:48 | So I'll click Next and then
I'll click to Install Wamp.
| | 01:51 | Then Wamp will go
through the installing process.
| | 01:55 | Wamp is asking if I want to set Firefox
as a default browser for WampServer 2?
| | 02:00 | I'm going to click Yes.
| | 02:01 | That's purely optional.
| | 02:03 | You can have whatever browser
you want as the default browser.
| | 02:07 | And now it's asking me
to specify an SMTP server.
| | 02:10 | Right now, I'm not really concerned with
that because we don't need this feature
| | 02:13 | for testing our sharing application.
| | 02:15 | So I'm just going to click Next,
and leave it at the default.
| | 02:18 | And then I'm going to Launch WampServer
2 now, by leaving that box checked and
| | 02:22 | clicking the Finish button.
| | 02:23 | Now, you'll need to have WampServer
running before you can use its services.
| | 02:31 | So make sure to remember that whenever you
are going to test an application in the future.
| | 02:36 | And you can find Wamp with your
other program files of course.
| | 02:39 | Another security warning pops-up,
I'm going to click Allow since I know
| | 02:43 | which program this is.
| | 02:45 | The bottom-right corner of my screen,
you could see that WampServer is launching.
| | 02:49 | You could tell that it's ready
when the whole icon is White.
| | 02:53 | To test to make sure that it's running properly.
| | 02:55 | I'm going to create a new tab in Firefox.
| | 02:59 | In the new tab browse to a
http://localhost, all lowercase.
| | 03:12 | When you go there, you should see this
page, not some kind of error message.
| | 03:17 | If you see an error message, make sure
that WampServer is running, and you see
| | 03:22 | the icon in the Taskbar.
| | 03:25 | So now I have confirmed
that WampServer is running.
| | 03:27 | I'm going to go to my C drive, and
I'm going to go into the wamp folder.
| | 03:33 | Anything that you'll need to test on
your testing server will need to be in
| | 03:37 | here, specifically it will need
to be stored in the www folder.
| | 03:42 | This acts as the root of your testing server.
| | 03:45 | So this index.php file is the file that
we're looking at when we go to localhost.
| | 03:51 | In here we will create a file called
ldcaudio, and we'll store the sharing
| | 03:57 | application files in there.
| | 03:58 | So I'm going to right-click, create a New
Folder, call it ldcaudio, all lowercase.
| | 04:07 | And at this point you just copy the
files for this next exercise into this
| | 04:13 | folder, and then you're good to go.
| | Collapse this transcript |
| Setting up a testing server: Mac| 00:00 | In order to get our sharing
application working on your home computer,
| | 00:04 | you're going to want to install
something called a testing server.
| | 00:07 | A testing server mimics a web
server's functionality on your home computer.
| | 00:13 | Before we download a testing server,
I want you to go to System Preferences.
| | 00:19 | In System Preferences, go to Sharing
and make sure that Web Sharing is off.
| | 00:25 | So it should be unchecked.
| | 00:27 | If it's on, it could cause some
problems with the exercise that we'll be doing.
| | 00:30 | So once you have done, you can close
System Preferences, and open up your web
| | 00:35 | browser and then go to mamp.info.
| | 00:40 | MAMP Server is the fastest and
easiest way to get a testing server up and
| | 00:48 | running on your Mac.
| | 00:50 | MAMP stands for Mac, Apache, MySQL and PHP.
| | 00:56 | So you get all of these
service in one easy install.
| | 01:00 | So when you're at the MAMP website,
I'm going to click to download the
| | 01:03 | free version of MAMP.
| | 01:05 | That's the gray one.
| | 01:06 | This takes me to the download page, and
again I'll click to download MAMP, not MAMP PRO.
| | 01:14 | You could download MAMP PRO.
| | 01:14 | It has more services than what
we need for this application.
| | 01:18 | You're then taken to the download page.
| | 01:21 | It actually already
downloaded it to my computer.
| | 01:24 | So I'm going to open up my Downloads
folder, and in there I'll open up MAMP.
| | 01:33 | Now, I'll install MAMP by clicking
and dragging the MAMP folder to the
| | 01:37 | Applications shortcut.
| | 01:41 | And once it's done copying,
you can launch MAMP through your
| | 01:45 | Applications folder.
| | 01:46 | So I just find the MAMP
folder, and then launch MAMP.
| | 01:52 | At this point, you may want to click and
drag MAMP down to the dock for easy use.
| | 01:57 | But I'm not going to, I'm
just going to open the file.
| | 02:01 | This is the file that I trust that I
downloaded, so I'm going to click Open, and
| | 02:04 | that will launch MAMP.
| | 02:09 | And what I want you to do is go to Preferences.
| | 02:12 | Go to the Ports tab, and then click
Set to default Apache and MySQL ports.
| | 02:18 | So Apache should be at
Port 80, and MySQL Port 3306.
| | 02:23 | Go to Apache, and then
you're going to see Document Root.
| | 02:29 | Click Select, and we're
not going to use the default.
| | 02:33 | You're going to select your Sites folder
that's going to be in your User folder,
| | 02:38 | and then click Open.
| | 02:39 | So that's going to be the Document Root.
| | 02:42 | Click OK, and then MAMP will relaunch.
| | 02:47 | It'll ask you to authenticate using your
user Name and Password, so I'll do that.
| | 02:50 | And you should see green lights for
the Apache Server and the MySQL Server.
| | 02:57 | Once you have that, minimize MAMP,
and open up your web browser again.
| | 03:03 | In your web browser, go to http://localhost.
| | 03:15 | You should see this page.
| | 03:17 | This is the default sites page on your
Mac, unless of course you changed it.
| | 03:22 | So now that we have this we're
good to go after one last step.
| | 03:27 | Go on to your Sites folder, and
create a folder called ldcaudio, all
| | 03:35 | lowercase as I have here.
| | 03:38 | In that folder, copy the
files for the next exercise.
| | 03:42 | As you could see that I've done right here.
| | 03:45 | Once you have those ready to go, you're
ready to start working with the sharing
| | 03:49 | application, and seeing it an action.
| | Collapse this transcript |
| Testing sharing features| 00:00 | In this movie we are going to
test our sharing application.
| | 00:03 | Before you go forward it all, make
sure that you have your testing server
| | 00:08 | installed and running.
| | 00:10 | I am going to go to my testing server
folder, on my Mac its in my Sites folder,
| | 00:18 | and in there you should
find your ldcaudio folder.
| | 00:21 | Remember from the PC you can access it
through your C drive in the wamp folder,
| | 00:27 | in there you will have to find the www
folder, and in that folder you should see
| | 00:33 | ldcaudio and your files.
| | 00:35 | The first thing that you need to do is
go to your Player.as file, find the line
| | 00:42 | of code where you load data.xml.
| | 00:46 | Here instead of loading the local file,
you want to give the absolute URL.
| | 00:53 | So, instead of data.xml, it's going to
be http://localhost/ldcaudio/data.xml.
| | 01:08 | Of course when you upload this to your
web server you are going to want to put
| | 01:13 | the full path to the file, so you
should be able to put this URL in your web
| | 01:17 | browser to find your XML file.
| | 01:20 | Then I am going to select
everything up until the forward slash after
| | 01:28 | ldcaudio and copy it.
| | 01:30 | We are going to be pasting this over
and over again, so I want to make sure I
| | 01:34 | don't have to type out
the full thing every time.
| | 01:37 | Save the file, and very
important here, test the movie.
| | 01:41 | So, you are going to need the output
a SWF file with that new URL in it.
| | 01:47 | It should work just as usual.
| | 01:49 | (Music Playing)
| | 01:53 | If you have any problems, make sure
that your testing server is up and running
| | 01:58 | and that there is in fact
localhost/ldcaudio/data.xml.
| | 02:04 | So you can test this URL in your web
browser to make sure it pulls up your XML file.
| | 02:09 | Now that I have created those files,
I don't need the FLA open any more.
| | 02:16 | Also you want to make sure if you are
having already to output an HTML file from
| | 02:20 | that, so you should publish the file.
| | 02:22 | Now let's open data.xml in the Text Editor.
| | 02:28 | Notice all the URLs are relative, in
other words they don't contain the absolute
| | 02:33 | URL which concludes localhost/ldcaudio.
| | 02:38 | So we are going to need to paste
all of these URLs in, so right before
| | 02:41 | player.html I am going to paste in my
long URL, and then in the param value I am
| | 02:49 | going to paste it in the object tag.
| | 02:51 | And then in the embed tag I am going
to paste it in for the source attribute.
| | 02:56 | And then for each song I will
paste it before the song file name.
| | 03:07 | So, once you have done this for all
the songs make sure to save the file.
| | 03:14 | So now Flash is going to be looking for
these in the absolute location, not the
| | 03:20 | relative location because you need the
absolute location when you are going to
| | 03:24 | be sharing a file because the person is
going to embed the SWF on some different domain.
| | 03:30 | It's still going to load from your side,
but you are going to need to this in
| | 03:34 | order to make it work properly.
| | 03:36 | So you can close data.xml, and at this
point you should be able to open up your
| | 03:43 | web browser, paste in the code from
earlier, add on player.html and then hit
| | 03:52 | Enter or Return to see your application.
| | 03:55 | So, you can play the file and
everything should work fine.
| | 04:00 | (Music Playing)
| | 04:04 | And you can see that it's working great.
| | 04:06 | That link is working properly.
| | 04:08 | See that link is updated
right there in that link section.
| | 04:11 | So of course I could click the copy
button and then paste that in my web browser
| | 04:16 | and then try it again, and it works properly.
| | 04:19 | (Music Playing)
| | 04:20 | But let's check out the embed option.
| | 04:24 | So what I want you to do is just click in
that embed field and then click the copy button.
| | 04:28 | So now we have
successfully copied the embed link.
| | 04:32 | Now let's create our own
HTML file and test it out.
| | 04:37 | So what I am going to do is I am going
to close this folder here and I am going
| | 04:41 | to create a file on my Desktop.
| | 04:43 | I am going to use Text Editor.
| | 04:45 | You can use Notepad on the PC.
| | 04:46 | So I am going to save this on my Desktop
as test.html, make sure to use the HTML
| | 04:55 | extension and also make sure that you
are using Plain Text writing mode and not
| | 05:00 | Rich Text writing mode.
| | 05:02 | Now here I am going to create
a ridiculously basic HTML file.
| | 05:06 | So I am going to create the opening
HTML tag, the closing HTML tag, opening and
| | 05:13 | closing Head tags, the
opening and closing Body tags.
| | 05:22 | And inside of the body, I am
going to paste the code that I copied.
| | 05:27 | So there is that object tag in there.
| | 05:29 | So we will save the file,
and then here is the magic.
| | 05:35 | I can test this and notice that it's
not on my testing server, I can just drag
| | 05:39 | it to my web browser, open up the file.
| | 05:42 | You can see that the SWF
file is successfully embedded.
| | 05:46 | I can play the songs and everything.
| | 05:48 | (Music Playing)
| | 05:52 | And it's all being loaded
form the testing server.
| | 05:56 | So, essentially you can put this file
anywhere on the web and it will embed that
| | 06:01 | file into the application.
| | 06:03 | Now of course you don't want to put it on
the web when you are using the testing server.
| | 06:06 | You want to put it on your actual web
server and then the share URLs will work,
| | 06:11 | and people can embed your
music player in their website.
| | 06:14 | So now it's time to take a break, pat
yourself on the back and congratulate
| | 06:21 | yourself for creating an amazing
shareable application that people can embed on
| | 06:27 | their website anywhere on the web.
| | Collapse this transcript |
|
|
7. Viewing an Audio Player ApplicationViewing the finished player| 00:00 | In this chapter we are going to look
at an application that utilizes all the
| | 00:04 | techniques that you
learned throughout this title.
| | 00:07 | Now, my purpose isn't to teach you how
to make everything in here from Scratch,
| | 00:12 | I just want to get you thinking
creatively about what you can do to use what you
| | 00:17 | have learned in this title.
| | 00:20 | So again, we are going to be going
over some of the code in this application
| | 00:24 | but not everything.
| | 00:25 | I am really just showing this to you,
so you can get a feel of what you can
| | 00:30 | create with the things that you know right now.
| | 00:34 | So here I have my files on my testing server.
| | 00:37 | So if you are going to follow along
and you have the files, make sure your
| | 00:40 | testing server is running and that all
of these files are in the right place
| | 00:43 | that is the ldcaudio
folder of your testing server.
| | 00:47 | So I have this little icon that says
Launch Audio Player, when you click on it,
| | 00:52 | the Audio Player launches.
| | 00:53 | So there is some Album artwork and if
you roll over the bottom, you'll see that
| | 00:57 | the Playlist comes up.
| | 00:59 | Now I have that initial thing that
you click because in order to load
| | 01:05 | images externally like this one I have here,
you need to have some user interaction first.
| | 01:10 | So the user has to click in order for
it to initialize loading and that's more
| | 01:14 | of a security precaution for the Flash Player.
| | 01:17 | The reason why I do like that is
because I want to have this be an application
| | 01:22 | that can work entirely off of XML data
instead of requiring a person to go into
| | 01:27 | Flash to change it and that's why I
put that little screen at the beginning.
| | 01:32 | So we see this is an album, The
Jellybricks Goodnight to Everyone.
| | 01:36 | At the bottom of the screen, we have
our player, when you hover over it, the
| | 01:41 | list comes up and you could
select a song that you want to play.
| | 01:43 | (Music Playing)
| | 01:44 | Now, you will notice a lot of things
may look familiar that we have created, we
| | 01:52 | have the Play button and the
progress bar, the time, volume, sound waves,
| | 01:59 | sharing object, all of that.
| | 02:01 | I have added this list, so that you can
control the Playlist through Scrolling
| | 02:06 | menu instead of just clicking back and forward.
| | 02:09 | This way we can see the information for
each song like the name of the song etcetera.
| | 02:13 | There is also a little iTunes button, which
if you click, will go to that song in iTunes.
| | 02:19 | So I am going to scroll down and then
click the iTunes icon for More to Lose.
| | 02:24 | Now, watch iTunes launch and it will go
to this album in iTunes, and then hunt
| | 02:29 | down the More to Lose song.
| | 02:31 | So I can listen to the song
through iTunes if I double-click it.
| | 02:34 | (Music Playing)
| | 02:42 | So you can see this is a
pretty full-featured application.
| | 02:47 | So we have iTunes connectivity, external
images loading, it's all powered by XML data.
| | 02:53 | So if you wanted to change anything
that you work with it, and you just
| | 02:56 | change the XML file.
| | 02:58 | Now, throughout this chapter, we will
have a quick walk through of this application
| | 03:03 | and you will see some of
what I did to create it.
| | Collapse this transcript |
| Walking through the application| 00:00 | In this movie, we will briefly walk
through the application that I demonstrated
| | 00:04 | earlier in this chapter.
| | 00:06 | We will start by looking at the XML file.
| | 00:09 | You will notice that I added a few things.
| | 00:10 | In the opening Album tag also known as
the Root element, I added an attribute
| | 00:17 | called the Cover that holds
the URL to the Album cover.
| | 00:19 | So you can swap this out, if you
wanted to put in a different album.
| | 00:22 | Let's say you have a band, or you
are working on a project for a band, or
| | 00:26 | something, you could put that in here.
| | 00:29 | And here is the link that
contains the link to the album.
| | 00:33 | I am not actually using that in my
application but I have it there just in case, I want to.
| | 00:38 | Notice this, this big iTunes URL.
| | 00:40 | I will show you how to get
that URL in just a few minutes.
| | 00:44 | So we have a share URL that you are
familiar with, and all the songs are exactly
| | 00:49 | the same as they were before, except
they all have an element called Link,
| | 00:53 | another iTunes link.
| | 00:55 | Let's look at how to get
those links from iTunes.
| | 00:58 | It's actually really simple.
| | 01:00 | I am going to tab over to iTunes and then I am
in the Jellybricks' Goodnight to Everyone album.
| | 01:06 | Of course, you can do Search the
iTunes Store, if you want to find it, or you
| | 01:09 | can go to any other album that you would like.
| | 01:12 | Here is what you do.
| | 01:13 | You just right-click.
| | 01:14 | So if I want to link to the album, I
right-click the album artwork, I can choose
| | 01:18 | Copy iTunes Store URL.
| | 01:22 | And then, of course, I can open up a
web browser, paste the URL in, and it will
| | 01:27 | take me to the correct place in iTunes.
| | 01:30 | If I wanted to link to a particular song,
I could right-click, say Put It Down,
| | 01:35 | for example, choose Copy iTunes Store
URL and then go to my web browser,
| | 01:45 | paste in the URL, and I am taken
directly to that song in iTunes.
| | 01:49 | So, that's all you had to
do to get to iTunes links.
| | 01:52 | Take those, put them in the
XML file, and there you go.
| | 01:57 | Links, so people can buy songs in iTunes.
| | 02:00 | This could be a great tool for a
band because you can make money with
| | 02:04 | this little Flash app.
| | 02:06 | So, let's go over to Flash and look at
some of the ActionScript that I used to
| | 02:09 | create this application.
| | 02:11 | So here is that button that I
showed you from the beginning.
| | 02:14 | I am not going to go inside of the
symbol because it's just really simple.
| | 02:18 | It's just a button.
| | 02:19 | I called it play_btn, and then here I
have the music player and then behind
| | 02:26 | that, there is a list box.
| | 02:28 | This list box is something that
I showed how to create in my user
| | 02:32 | interface elements title.
| | 02:34 | So if you want to see how
to create that from scratch.
| | 02:36 | I suggest going there.
| | 02:38 | Of course, you won't see how to
add the iTunes links in that title.
| | 02:41 | That's something that added in this title.
| | 02:43 | But I challenge you to
figure out how to do that.
| | 02:46 | Let's go through some of the classes.
| | 02:48 | Here is the Player Document class,
which is the new class I created to serve
| | 02:53 | as the document class.
| | 02:56 | It basically controls and
connects the list and the player.
| | 03:01 | It controls the animation of the
player, moving up and down, fading in and
| | 03:04 | out using Tween Light.
| | 03:08 | It's pretty straightforward, and the
main thing that I did here that you need to
| | 03:12 | take a note of is that I control all
of the model interaction through this
| | 03:18 | player document class.
| | 03:19 | So I kind of took it out of the player
for the most part and put in the document
| | 03:24 | class so, I can connect the model to
the list and the player and both of them
| | 03:28 | respond when you make a
change on one or the other.
| | 03:36 | So, here is that code.
| | 03:37 | Once you look it over, and you can
feel free to pause the movie and copy it
| | 03:41 | down if you would like.
| | 03:43 | Again, this isn't going to be
all the pieces of the puzzle.
| | 03:46 | If you want to build this application
from scratch, this is just going to be
| | 03:51 | able to get you started.
| | 03:51 | So, whenever you change the element
in the list, the player is updated.
| | 03:54 | When you change a song in the player by
a song ending, then the list is updated
| | 04:00 | because they both control the model.
| | 04:02 | So, I go to my player class and my
player class now initializes once the XML is
| | 04:07 | loaded in the player document class,
and it runs a method called Init and that
| | 04:12 | basically starts out everything.
| | 04:14 | So, we set the model in there,
getting that from player document at the
| | 04:18 | Event listener, listening for the
model change, which updates the song
| | 04:23 | whenever the list is changed.
| | 04:26 | All of this should look pretty familiar
because these are things that we already
| | 04:28 | look at throughout the rest of this title.
| | 04:30 | So I am playing the song, and then I
have this song finish method and let me
| | 04:43 | show you how I check to
see if a song was finished.
| | 04:46 | This is actually something
that's really important to note.
| | 04:49 | The Flash Player is sort of the infamous for
not responding properly when a song is finished.
| | 04:56 | I have seen a lot of people that have
complained that when a sound is sampled at
| | 05:02 | a lower rate, the Sound Complete Event
doesn't trigger at the right time, or it
| | 05:07 | never triggers at all.
| | 05:08 | So that's a pretty big problem.
| | 05:10 | So, what I encourage you to do is to
make your own Sound Complete Event and
| | 05:15 | here is where I did it.
| | 05:17 | In the progress display class, I change
the class to extend the event dispatcher
| | 05:22 | class so that I can dispatch events.
| | 05:25 | So what I do is when the song is playing, I am
constantly checking to see if the song is done.
| | 05:34 | So here's my code right here.
| | 05:37 | Here's how I do that.
| | 05:38 | I check to see if the progress of the
song, that's the progress string, is equal
| | 05:45 | to the length string.
| | 05:46 | So if they are equal, in other words,
the song is at the end,
| | 05:50 | so 340 for the progress and 340 for
the length and to double check, I make
| | 05:58 | sure that the sound is completely loaded
because the sound could have just started loading.
| | 06:02 | It'd be 10 seconds and it only have 10
seconds loaded and triggers this event.
| | 06:06 | I don't want that to happen.
| | 06:07 | So, I make sure that the sound is
completely loaded and it's all the way to end.
| | 06:10 | So I am using that time to check that.
| | 06:13 | Now if you want to get more precise,
you could check it would milliseconds
| | 06:16 | or however you want.
| | 06:17 | But this is just how I did it here.
| | 06:19 | When that happens and both conditions are
true, I dispatch the Sound Complete Event.
| | 06:25 | That's event.sound_complete and then I
listen for that in the player class and
| | 06:31 | run the song finish method.
| | 06:34 | Song finish method disables progDisplay
and goes to the next index of the model,
| | 06:42 | or loops all the way around
depending if the model is done.
| | 06:45 | Now remember the model at the end of
the set current index method dispatches
| | 06:50 | that model change event as well.
| | 06:52 | So, that's what I did to the
classes that we worked within this title.
| | 06:56 | And again I switch up the
list class just a little bit.
| | 07:00 | So if you are trying to make this app
from the UI title, note that you are
| | 07:05 | going to have to make some tweaks here and there
but I am going to leave that challenge for you.
| | 07:09 | I want you to get practiced, creating
complex applications, and I also want you
| | 07:13 | to send them to me when you make them.
| | 07:16 | I have gotten emails from a few of you,
seeing some great applications that
| | 07:20 | you have developed.
| | 07:21 | I got to tell you I am really proud
of you for sending those to me, and for
| | 07:24 | taking those challenges.
| | 07:25 | So, feel free to contact me through my
website chadandtoddcast.com or through
| | 07:30 | lynda.com and share with me what you create
using these techniques that you learn in this title.
| | Collapse this transcript |
|
|
ConclusionGoodbye| 00:00 | Well, you've reached the end of this title.
| | 00:02 | I hope you had a good time learning
about how to work with audio in Flash CS4.
| | 00:07 | Take a moment to think about all the
things that you've learned in this title.
| | 00:11 | You learned how to load external
audio files, how to work with an XML
| | 00:14 | playlist, how to control volume,
sound progress and even share your
| | 00:19 | application over the web.
| | 00:21 | I'll leave you with this challenge.
| | 00:24 | Take what you've learned in this
title and apply it to making your own
| | 00:27 | unique application.
| | 00:29 | And if you want to, you can feel free
to send me a link, so I can check it out.
| | 00:33 | You can reach me through my website
which is chadandtoddcast.com or of
| | 00:38 | course, at Lynda.com.
| | 00:39 | I'll see you next time.
| | Collapse this transcript |
|
|