How to Pause Sound and Resume Where it Left Off

Flash ActionScript 2.0

In recent entries, we examined the Sound constructor and toggling sound globally.  Let’s continue in this vein and take a closer look at how to pause and resume audio.  The Sound class provides two handy methods for this:  Sound.stop() and Sound.start().  Thanks to these, we can wire up a button to pause a Sound instance, and another to restart it, without much effort at all …

var snd:Sound = new Sound();
snd.attachSound("bazooka");

btnHalt.onRelease = function():Void {
  snd.stop();
}
btnResume.onRelease = function():Void {
  snd.start();
}

… but this doesn’t resume the sound:  this starts it again from the beginning.  How can we start the audio from where it left off? 

An answer, short and sweet

Use the optional Sound.start() offset parameter in cahoots with the Sound.position property.  Assuming the above code already in place — in a keyframe of your scripts layer — change the btnResume event handler as follows.

btnResume.onRelease = function():Void {
  snd.start(snd.position / 1000);
}

How it works

Sound.start() accepts two optional parameters:  an offset in seconds and a number of times to loop.  If you want a 5-second Sound instance to start halfway through, supply 2.5 as the first parameter, because 2.5 is half of 5.

snd.start(2.5);

Of course, in this scenario, it’s up to the user when to pause and resume, so a hard coded number won’t do.  The answer rests with the Sound.position property, which tells how far along the audio has played, not unlike like the position of the arm on a record player.  The value returned by this property is a number in milliseconds.  Because Sound.start() expects seconds, divide this value by 1,000.

One final note

Keep in mind, the above snippet, on its own, won‘t do anything to restart an audio file that has run its course.  At the end of a sound clip, the position property will naturally be equal to its duration.  A more intelligent resume button, then, might actually check for this possibility and act accordingly:

btnResume.onRelease = function():Void {
  if (snd.position < snd.duration) {
    snd.start(snd.position / 1000);
  } else {
    snd.start();
  }
}

78 Responses to “How to Pause Sound and Resume Where it Left Off”

  1. mStudios Says:

    As I am not very advanced in Flash, I rely a lot on simple explanations and code I can copy and paste and cook together for my needs. This little gem saved my day after hours of frustrating trial and error and searching on the web. Thank you so very much - now I can finally begin with my flash based storyboard :-)

  2. David Stiller Says:

    mStudios,

    Terrific! Glad to hear it. Best of luck as you continue exploring.

  3. Fezile Mlungu Says:

    David, u the bomb!!!

  4. Fezile Mlungu Says:

    HI David!!!

    How do I create a resume functionality in Flash? I want the user to quit the programme, but when they come back, they should be able to start where they left off.

  5. David Stiller Says:

    Fezile,

    For that, you need a way to store information somewhere other than the user’s memory. Flash provides an AS2 class just for this purpose, the SharedObject class. Check it out! :)

  6. Fezile Mlungu Says:

    DAvid,

    What is the main difference between square1.x = 20 and square1._x = 20 when you are dynamically positioning movieclips on stage? Why would the one with underscore work, whilst the one without underscore doesn’t work. Because the sysytem accepts both of them but will just not work. When and how do you know which one to use to achieve the best result?

  7. bj Says:

    ____ ____ ____ _________ ____ ____ ____ _________ ____
    ||y |||o |||u ||| |||a |||r |||e ||| |||a ||
    ||__|||__|||__|||_______|||__|||__|||__|||_______|||__||
    |/__\|/__\|/__\|/_______\|/__\|/__\|/__\|/_______\|/__\|
    ____ ____ ____ ____ ____ ____ ____
    ||g |||e |||n |||i |||u |||s |||! ||
    ||__|||__|||__|||__|||__|||__|||__||
    |/__\|/__\|/__\|/__\|/__\|/__\|/__\|

  8. David Stiller Says:

    To bj,

    Thanks! But I think that compliment is more than I deserve. ;)

    To Fezile,

    The main difference between _x and x depends on entirely on what class that property belongs to. Between those two, the MovieClip class, which is what you’re describing, only features _x, so x is simply a property that doesn’t exist — unless you create it yourself (the MovieClip class is dynamic, so you can add properties as you like, which in the case of movie clips are effectively variables on their timelines).

    The underscore is a historical throwback. In ActionScript 3.0, the MovieClip class simply goes by x now for horizontal positioning.

    To get the full scoop, I recommend you spend some time in the “MovieClip class” entry of the ActionScript 2.0 Language Reference. It shows you all the properties, methods, and events available to all movie clip instances.

  9. Vinney Says:

    What about if you are streaming a sound dynamically? Does the sound have to be attached using the object.attachSound in order to control playback positioning?

    Thanks,
    Vinney

  10. David Stiller Says:

    Vinney,

    The functionality of the Sound class works across the board. Once the audio is playing, whether it’s attached or loaded, you may monitor its progress with the Sound.position property and control playback positioning by using the optional secondsOffset parameter of the Sound.start() method. Of course, if you’re loading the sound from an external source, you’ll have to make sure it’s fully loaded first.

    If you’re truly streaming the sound — that is, if you’re loading the audio from Flash Media Server — then you’d use the Flash-Media-Server–specific NetStream class. There, too, you would be able to seek to the desired position in the audio stream.

  11. Baz Says:

    Just came across this luckily for me, it has saved me a lot of grief and time writing oodles of bad code trying to get the same effect. Thanks, the short and sweet answer really shows that you know what you are doing, Thanks again.

  12. Emilia Says:

    That was so simple I nearly crapped myself…

    Been playing with the doofus pause button in my project fer days…

    I feel like a dork.

    I mean DAYS! Honestly!!

    Thanks, you’re a Flash God…

  13. David Stiller Says:

    Baz and Emilia,

    Thanks!

  14. Red Rojo Says:

    Couple follow-ups here.

    1. “…truely streaming…”? What do you mean by “truely”? Just because I set the isStreaming argument to “true” doesn’t mean I’m truely streaming?

    2. “Flash Media Server…” Is a Flash Media Server something special? If so, how do I know if the website has one?

    3. What do you mean by the external media is “fully loaded”? I’ve got a 1.25 hour mp3 file on a website that appears to start immediately when called. Is it fully loaded when it’s able to play? Or something else.

    Thanks.

  15. David Stiller Says:

    Red Rojo,

    1. “…truely streaming…”? What do you mean by “truely”? Just because I set the isStreaming argument to “true” doesn’t mean I’m truely streaming?

    That’s right. If you don’t have a streaming server actually sending the file, then you’re only providing a progressive download. In many regards, they amount to the same thing. GIFs and JPGs can progressively download, for example — in good old HTML, I mean — … it’s a useful mechanism that allows the user to begin experiencing the file before it fully loads.

    2. “Flash Media Server…” Is a Flash Media Server something special? If so, how do I know if the website has one?

    Flash Media Server is indeed something special, and it’s expensive.

    3. What do you mean by the external media is “fully loaded”? I’ve got a 1.25 hour mp3 file on a website that appears to start immediately when called. Is it fully loaded when it’s able to play? Or something else.

    Because it’s progressively downloaded (or streaming, depending on your server configuration), that MP3 starts playing when only a few kilobytes have been downloaded.

  16. Red Rojo Says:

    Hmm…. I don’t think I could ever fully load my sound file — it’s 1.25 hours long, 35MB!! So am I right that I can’t use the sound.position or sound.offset parameter if I am loading the sound from an external source? Is there another option?

  17. David Stiller Says:

    Red Rojo,

    While that is an awfully large file, it certainly will load … eventually. I can’t imagine what sort of frustrating experience that might be for dial up users, but QuickTime.com serves up video files that size every day. Even without a streaming server, that file should (in theory) start playing a few a few seconds. But I would probably break it up into a series of smaller files.

  18. Red Rojo Says:

    Sure. I can certainly break up the file — it’s audio only. What’s a workable size? Would I use something like sound.onSoundComplete() to launch the next clip? Should it sound seemless — or might there be delays between clips? Could I then use the sound.position property to pause/resume? Feasible approach?

  19. David Stiller Says:

    Red Rojo,

    Workable size is totally subjective. If you’re sure your visitors have cable, 35MB wouldn’t be out of the question. If you break it up, then yes, the Sound.complete event could trigger each subsequent file. If you used the Sound.load() method to load each piece, there would be a slight delay between each clip. The only way to avoid that would be to preload each clip at least one audio file at a time. The Sound.position would restart from zero for each new file.

  20. Rick Says:

    David-

    Thanks for all the Flash info…It’s helped me alot. However I have an issue that maybe you could explain. I’ve put the action script that you supplied for stopping and resuming sound and it works great only after the second time the user clicks the start button. In other words, the first time the user clicks the play button after sound has been stopped, it goes back to the beginning. The next time they click on the play button after it has been stopped, it resumes from the exact point that it stopped. Any idea what might be going on? Here is what I used as far as the action script:

    var song_sound:Sound = new Sound();
    song_sound.attachSound(”Slide1sound”);
    Stop_Movie_btn.onRelease = function(){
    song_sound.stop();
    }
    Play_Movie_btn.onRelease = function(){
    song_sound.start(song_sound.position / 1000);
    }

    Thanks in advance.

    Rick

  21. David Stiller Says:

    Rick,

    Interesting. Honestly, I can’t imagine why you might encounter what you’ve described, given your code. On its own, the Sound.start() method starts from the beginning — but the optional parameters allow that default behavior to change. It’s possible that something in your song_sound.position / 1000 expression is somehow returning a value of zero, or maybe NaN (Not a Number). You could try using trace() to check …

    Play_Movie_btn.onRelease = function():Void {
      trace(song_sound.position / 1000);
      song_sound.start(song_sound.position / 1000);
    }

    … that’ll let you see what you’re actually feeding in as a parameter.

  22. Rick Says:

    David-

    Thanks for replying so quickly. I did the trace and the first time I clicked on the Play button, it showed a zero in the Output window. Every subsequent time, it showed the appropriate postion where I restarted. I’m authoring this on a Mac. Do you think that it might be a Mac vs PC type of thing?

    Rick

  23. Rick Says:

    David-

    OK, so I think the problem is that you assumed I actually knew what I was doing. I didn’t. Though I had created a sound object and attached the sound, I hadn’t told it to start playing. I had actually put the sound onto the timeline. So when I Stopped the sound and then clicked the Play button, that was actually the first time the attached sound started playing, thus the “0″ in the Output window when I did the Trace. So now, I have gone and put in the Start command in each one of my slides, removed the sound files from the timeline, and everything works perfectly. Sorry to waste your time, David. I really do appreciate your blog, however. It is and awesome resource, as are you. Thanks again!

    Rick

  24. David Stiller Says:

    Rick,

    Ha! No worries. I’m actually really happy for you that you figured it out. :) Good stuff!

  25. Chris C. Says:

    Thank you, thank you. This little script has saved me time, frustration and my sanity. May you live long and prosper.

  26. Gabriel Rodriguez Says:

    Hey David,

    This tutorial helped me a little but it’s not working for my website.

    The following code that I have works well for the stop and play button

    stopMusic.onRelease = function() {
      loops.gotoAndStop(1);
      stopAllSounds();
    }
    startMusic.onRelease = function() {
      loops.gotoAndPlay(2);
    }

    Let me describe what I have here. the “stopMusic” and “startMusic” are my buttons instances and “loops” is the instance for the music clip. However if i want to use this code for pausing the music it won’t work

    pauseMusic.onRelesae = function() {
      if (loops.position < loops.duration) {
        loops.start(loops.position/1000);
      } else {
        loops.start();
      }
    };
  27. David Stiller Says:

    Gabriel,

    In your first set of code, loops must be a movie clip, because you’re invoking a MovieClip method (i.e. gotoAndStop()) on the instance name.

    In the second batch, loops has somehow become a Sound instance — because you’re invoking Sound properties (position, duration) and a method (start()) on it. My hunch is that your problem is spelled out right there. For any of this to work, loops must be an instance of the Sound class. Does that make sense?

  28. Gabriel Rodriguez Says:

    Hey David,

    Thanks for responding. The “loops” instance is a MovieClip. The stop and play function does work but the pause doesn’t.

  29. David Stiller Says:

    Gabriel,

    The stop and play part works because you’re using MovieClip functionality on a movie clip. I’m guessing that you’ve placed audio into frame 2 of the loops clip, and that frame 1 contains no audio. So that makes sense: what you’ve got is an old school way of toggling sound in Flash.

    Because loops is a movie clip symbol, you can’t perform Sound functionality on it. If you want to use the technique discussed in this blog entry, you’ll have to get rid of loops altogether. Use ActionScript to attach or load your audio. That’s when your audio becomes an instance of the Sound class, and that’s when you can invoke methods on it like the ones in the article.

  30. Tejasvita Says:

    Hi,
    I am developing a sound on/off functionality in Actionscript 3.0. I have sound directly on the timeline and the property of the sound is Streaming. I have created a sound object and tried to set the volume = 0. But sound does not stop.

  31. David Stiller Says:

    Tejasvita,

    If you look up the Sound class in the ActionScript 3.0 Language and Components Reference, you’ll find that the new version no longer supports a Sound.stop() method. That explains why comparable ActionScript 2.0 samples won’t work the same way. Where did that stop() method go? It’s now part of a companion class, SoundChannel. In AS3, if you want to further control audio once it plays, you need to associate Sound.play() with a SoundChannel instance.

    var chan:SoundChannel = mySoundInstance.play();
    chan.stop();
  32. Jeff Says:

    Hi David,

    Great tutorial! I definitely was able to absorb the new knowledge and grasp the concepts quite easily.

    I have a general question. I want to achieve the exact same thing (stopping a sound and then resuming it form that exact position), however my sounds are all on the timeline. By using the stop() command to stop the SWF playhead (and stopAllSounds(), to stop the playback of my sounds) I am able to effectively “pause” the playback of my SWF. This is great, until I attempt to resume the playback. Using the play() command resumes the playback of the SWF file, but the sound does not resume playback. It does not even start from the beginning again. Do you know of any way around this, or do I pretty much have to remove the sound from the timeline and use a Sound Object to control the position, as you’ve demonstrated in the tutorial above?

    Many thanks in advance, keep the good advice coming!
    -Jeff

  33. David Stiller Says:

    Jeff,

    What you’re describing is a by-product of using movie clip timelines, rather than Sound instances, to manipulate sound in Flash. If the audio files in your timelines have their Sync property set to Event (see the Property inspector for the audio in a given keyframe) then any sound on that keyframe is loaded all at once into memory. Stopping the timeline under such circumstances is not enough to stop the audio, which is why the additional call to stopAllSounds() is necessary; after all, the sound is already loaded into memory. Restarting the playhead fails to restart the audio in that case because, again, the sound has already loaded and was stopped.

    If the Sync property is set to Stream, then the audio files are locked in-step with the timeline they’re in. In that case, stopping and starting the timeline will synchronize the audio’s stopping and starting. It’s worth a shot, and that’s the only way I can think of to restart audio that is embedded in a timeline. Otherwise, you’d have to send the playhead — even if only momentarily — back to the keyframe into which the audio is first embedded.

  34. Free Loops Says:

    Nice one this is what i need instead of playing from the beginnig. That gets annoying after a few time.

  35. David Stiller Says:

    Free Loops,

    Thanks!

  36. Jeff Says:

    Hi David,

    Thanks for the response. I tried setting my sounds to Stream, and when I pause the timeline, of course the sound pauses as well. But when I resume the timeline, the movie resumes but the sounds do not :( Oh well it was worth the shot.

    Thanks for the advice!

  37. David Stiller Says:

    Jeff,

    If a sound file is embedded in a timeline and set to Stream, that sound will stop and start up again as the timeline does, I promise. :) I just made a test file. New FLA, imported an MP3 and dragged it to frame 1 of Layer 1, set it to Stream, and increased the timeline as long as necessary to play the whole file. Created a quick button, gave it the instance name btn, and used the following event handler:

    var paused = false;
    btn.onRelease = function():Void {
      if (paused) {
        play();
      } else {
        stop();
      }
      paused = !paused;
    }

    That works for me. Granted, it’s not at all the approach illustrated in the original blog entry, but it’s definitely one of the “old school” ways of starting and stopping sound in Flash.

  38. Lee Elliott Says:

    Hi David, In my swf im pausing the audio when another movie clip is loaded and on frame out I need it to resume play. So the only part not explained already is how to detect a frame exit ? I’ve searched for this but people always offer a walk around and never say if its possible and if so could you give an example? Please and Thank you ^^

  39. Amber M Says:

    Thanks! going crazy with that!

    Works great with tell targets to stop(ish) and play a little equalizer animation (moving music bars)!!!

    var mySound:Sound = new Sound();
    mySound.loadSound(”01 Tamacun.mp3″, true);
    mySound.onLoad = function(success) {
    if (success) {
    this.start();
    }
    };
    btnStop.onRelease = function() {
    mySound.stop();
    tellTarget (”_root.equalizer”) {
    gotoAndPlay(20);
    }
    };
    btnPlay.onRelease = function() {
    if (mySound.position

  40. Amber M Says:

    Here’s the rest of that!

    btnPlay.onRelease = function() {
    if (mySound.position

  41. David Stiller Says:

    To Lee …

    Hi David, In my swf im pausing the audio when another movie clip is loaded and on frame out I need it to resume play.

    If you’re using the MovieClipLoader class, you could resume play on the onLoadComplete or onLoadInit event. I’m not sure whose onFrameOut you want to listen for, but for better or worse: a) there is no onFrameOut event in ActionScript and b) what matters seems to be the successful load of your other movie clip.

    So the only part not explained already is how to detect a frame exit ?

    This concept simply isn’t a part of the ActionScript API. Director’s Lingo language can test for frame ins and outs, but ActionScript only looks for frame enters (essentially frame ins).

    If you’re looping in conjunction with a MovieClip.onEnterFrame event, you can use that in conceptually the same way as the idea of a frame out. (I’m not sure if you’re looping in order to determine when the other SWF has loaded.)

    See if “How to Tell When an External SWF has Fully Loaded” helps you out any. MovieClipLoader is likely your easiest solution.

    To Amber …

    Glad you’re having fun with it! :) Woo hoo!

  42. Lee Elliott Says:

    Thanks for the feedback David! The site in question has background music (A). It also has another movie clip that has its own background music(B). When the user selects to play an embedded movie with background music(B) thats when I pause music from (A). Since theres no OnFrameOut (needed for when movie clip is closed or replaced) I put “ins” on every possible selection option so no matter your next move (unless your move is to do nothing) the music(A) will resume when u click a button. Of course using many “ins” to cover one “out” is not efficient and I’m still looking for a better way =/ any ideas? Thanks in advance!

  43. Ean Wilson Says:

    // Initializers and such
    var pauseStatus:Number = 1;
    var themeSound:Sound = new JeopardyTheme();
    var themeSoundChannel:SoundChannel = themeSound.play();
    var themePosition:Number = themeSoundChannel.position;
    trace(”Start: ” + themePosition);

    // Clicked Pause
    function clickedPause(event:MouseEvent):void
    {
    if (pauseStatus == 1)
    {
    themePosition = themeSoundChannel.position;
    trace(”Turn OFF:” + themePosition);
    SoundMixer.stopAll();

    pauseStatus = 0;
    }
    else if (pauseStatus == 0)
    {

    trace(”Turn ON:” + themePosition);
    themeSound.play(themePosition);
    pauseStatus = 1;
    }
    }
    pause_mc.addEventListener(MouseEvent.CLICK, clickedPause);

    First trace: 0

    Okay, first trace is good.

    Click the pause button for the FIRST time (to pause):
    Turn OFF: 3912.134679258

    Okay, so far so good.

    Click the pause button for the SECOND time (to play):
    Turn ON: 3912.134679258

    Okay, again we’re good. Now watch this.

    Click the pause button for the THIRD time (to pause again):
    Turn OFF: 3912.134679258

    Huh? Why didn’t the position advance?

  44. Ean Wilson Says:

    Did some messing around and here’s the answer. :)

    // Sounds
    var themeSound:Sound = new JeopardyTheme();
    var themeSoundChannel:SoundChannel = new SoundChannel();
    themeSoundChannel = themeSound.play();
    var themePosition:Number = themeSoundChannel.position;
    var pauseStatus:Number = 1;

    // Clicked Pause
    function clickedPause(event:MouseEvent):void
    {
    if (pauseStatus == 1)
    {
    themePosition = themeSoundChannel.position;
    themeSoundChannel.stop();
    pauseStatus = 0;
    }
    else if (pauseStatus == 0)
    {
    themeSoundChannel = themeSound.play(themePosition);
    pauseStatus = 1;
    }
    }
    pause_mc.addEventListener(MouseEvent.CLICK, clickedPause);

    Everything works beautiful.

  45. David Stiller Says:

    To Lee …

    Since theres no OnFrameOut (needed for when movie clip is closed or replaced) I put “ins” on every possible selection option …

    I’m afraid I can’t envision what you’re describing. If you’re loading external content — what you’re calling “an embedded movie with background music(B)” — then you’ll obviously be loading that external content by some means (maybe MovieClipLoader, maybe the loadMovie() function, maybe the MovieClip.loadMovie() method …) and whenever you’re doing that loading, that’s when you’ll turn down the volume of the main music. When you then choose to load other external content, that’s when you’ll configure the audio again — either to bring up the volume of the main music again or to leave it as is.

    I’m trying to understand what you mean by “I put ‘ins’ on every possible selection option,” but I’m coming up dry! Maybe these “embedded movies” aren’t external(?). When you describe a movie clip as “closed or replaced,” what ActionScript function/method are you using to do that closing or replacing — and wouldn’t that be the same area of code you’d use to determine the volume of the main audio?

    To Ean …

    Hey, glad you worked out a solution! :) The key, in this case (that is, ActionScript 3.0, which differers from the ActionScript 2.0 in the article), is that you must re-associate the SoundChannel instance with the the Sound.play() method, as you’ve done in your second post:

    themeSoundChannel = themeSound.play(themePosition);

  46. Lee Elliott Says:

    Thanks for your responses again David! When they click to watch this code is run

    on (release) {
    _root.myMusic.stop();
    loadMovie(”mov.swf”, “_root.ani.mov”);
    }

    The “ins” and “outs” were lingo someone else in the blog was using (thought it was u) so i just went with it

    “Closed or Replaced” there is a close button where if they click the movie clip closes and the back ground music comes back on (an example on an “in”) the movie clip is usualy replaced by other buttons which also load swf files into the same movie clip replacing it (another example of an “in”)

    loadMovie(”mov2.swf”, “_root.ani.mov”);

    It would be nice if instead of having to add lines in every button that replaces or closes the movie clip if i could just have a line in the movie clip that said when i get closed or replaced unpause the background music. (an example of an “out”)

    I hope this clears up what I am wanting to know. If you would like I can link the exact page in question.

    Thanks again David.

  47. David Stiller Says:

    Lee,

    You could certainly use ActionScript to programmatically attach a Close button — the same Close button — to each loaded SWF. That way, you would only have to write that button’s code once. I’m not sure if you have a separate button for each external SWF (inside each SWF, say) but if you do, I agree that duplicating so much code would be tedious. By using dot syntax to assign your event handlers (see the “Museum Pieces” article), you would potentially free yourself from some — possibly much — of that duplication.

    It would be nice if instead of having to add lines in every button that replaces or closes the movie clip if i could just have a line in the movie clip that said when i get closed or replaced unpause the background music.

    Have you looked into the MovieClip.onUnload event handler? You could attach an event handler to the movie clip that acts as your container for the incoming content (_root.ani.mov).

  48. Say Em Says:

    You’re a life saver. Watch it go into play @ www.rebbeccacorry.com

  49. Chase Cox Says:

    Alright, I’m using AS 2.0 and trying to get the timeline and sound to stop and start back together. However, a simple stop (); command doesn’t stop the timeline as precisely as my sound stops. I know I’ve butchered the code, but it was all in an attempt to make the two stop together so forgive me. Can you tell me how I can get the two stopping and starting together? Aside from embedding the sound and using streaming audio. Streaming audio just won’t work for this movie because precise timing is required and I can’t have dropped bits of the audio if the load doesn’t work quickly enough.

    Here is the code.

    soundTest = new Sound();
    soundTest.attachSound(”Finalizeaudio”);
    soundTest.start();
    clipLength.text = soundTest.duration/1000+” s”;
    rootTime=_root();
    movieLength.text=rootTime.duration/1000+”s”;
    pauseClip.onPress = function() {
    pausePositionS = soundTest.position/1000;
    soundTest.stop();
    stopRootS=rootTime.position/1000;
    rootTime.stop();
    };
    startClip.onPress = function() {
    if (soundTest.position == soundTest.duration) {
    soundTest.start();
    } else {
    soundTest.start(pausePositionS);
    play();}
    }
    if (rootTime.position==rootTime.duration) {
    rootTime.start();
    }else{
    rootTime.start(stopRootS);
    play();
    };
    startClip.onEnterFrame = function() {
    currentPosition.text = soundTest.position/1000;
    };

    The rootTime=_root is evidently pointless and not doable.

  50. David Stiller Says:

    To Say Em …

    Glad to hear it; thanks!

    To Chase …

    Agreed, the line rootTime=root() doesn’t really do anything, but that doesn’t mean it couldn’t — only that setting a variable to the hypothetical return value of root() is meaningless unless you’ve written a custom root() function to provide the necessary object/data (there isn’t such a function natively).

    The main operative idea behind your code is to invoke MovieClip.stop() and Sound.stop() simultaneously when you desire both entities to stop, then MovieClip.play() and Sound.start() to resume.

    My hunch is that your inconsistent timeline precision is a result of a low overall timeline framerate.

  51. Chase Cox Says:

    The fps was definately a problem. Bumped it up to 24, but I’m still getting some incosistency. Will _root.position/1000 work in conjuction with the _root.play?

  52. Chase Cox Says:

    Oh and MovieClip.play() wouldn’t work for the main timeline.

  53. Chase Cox Says:

    var snd:Sound = new Sound();
    snd.attachSound(”DVDtoVHSsec1″);
    snd.start();
    pauseClip.onPress = function() {
    snd.stop();
    _root.stop();
    };
    startClip.onPress = function() {
    if (snd.position

  54. Faith Tatrow Says:

    Hi David,
    I’m loading external swf files into movieclips on my main Flash timeline. I use this type of code:loadMovie (”myMovie.swf”, “loader1_mc”). The movies load and play great. My problem is that although I am able to pause content on the main timeline of my Flash movie, I cannot pause these external swf files. I have tried giving the movie clips instance names and even referring to these directly in the code of the navigation, but haven’t had any success. Do you have any ideas for me?

  55. David Stiller Says:

    To Chase …

    The fps was definately a problem. Bumped it up to 24, but I’m still getting some incosistency. Will _root.position/1000 work in conjuction with the _root.play?

    This may just be a case of “them’s the brakes,” unfortunately. It sounds like your increased FPS helped a bit, but not enough. As it happens, I develop presentations fairly often in which the main timeline (or any movie clip timeline) needs to be halted in coordination with audio — even external audio — and in my own experience, I haven’t run into deal-breaker inconsistencies … but maybe that’s just luck?

    Your question about _root.position/1000 hinges on what _root means in AS2. Though the reference can change depending on certain factors (outlined here), _root always points to a MovieClip instance. Since the MovieClip class doesn’t define a position property, the expression _root.position has no meaning — not unless you created a numerical variable of your own named position.

    Oh and MovieClip.play() wouldn’t work for the main timeline.

    Actually, you’re already using the MovieClip.play() method: that’s what your _root.play() means. See, everything in ActionScript may be considered an object, and objects are defined by something called classes. When you’re dealing with a dynamic or input text field, you’re dealing with an instance of the TextField class.

    When you’re dealing with a movie clip (even the main timeline, aka _root), you’re dealing with an instance of the MovieClip class. Classes define properties (characteristics), methods (things the object can do), and events (things the object can react to), so when you type _root.play(), you’re invoking a movie clip method (MovieClip.play()) on a MovieClip instance (_root).

    Make sense? The only class names that you reference by class name are static classes such as Math. For example, to round a number you can use Math.round(4.5), because it makes no sense — indeed, is not possible — to create an instance of the Math class.

    Your last bit of sample code got truncated, but it looks like you were on the right track. All you need here is something like this:

    pauseClip.onPress = function():Void {
      snd.stop();
      _root.stop();
    };
    playClip.onPress = function():Void {
      snd.start(snd.position / 1000);
      _root.play();
    };

    … though, out of personal preference, I would probably use onRelease over onPress, and I would only use _root if I knew this SWF wasn’t going to be loaded into another SWF at runtime.

    To Faith …

    How are you trying to pause these loaded SWFs? You said you’ve tried giving them instance names, but when you load a SWF into some container movie clip (e.g. your loader1_mc), that container becomes your reference. In other words, the instance name that sounds is the instance name you’re using as the target in your loadMovie() call.

  56. Chase Cox Says:

    Thanks for the link to the _root page. It helped a lot. What is another object name for the main timeline? I would like to use some other method than _root. Do I just use stop();? and play();?

  57. David Stiller Says:

    Chase,

    As you’ve seen now, _root can indeed be a useful reference to the main timeline, under the circumstances outlined in the other article. In a single-SWF movie, _level0 refers to that same timeline. If you want to “roll your own” reference, you can do something like this:

    var timelineReference:MovieClip = this;

    … in a keyframe script that’s in the main timeline. From that point forward, the arbitrarily named variable timelineReference will point to the main timeline, even if the current SWF is loaded into another SWF.

    But you touched on an idea that leads toward the very best approach: namely, an understanding of scope. Check it out. In this quick snippet …

    pauseClip.onPress = function():Void {
      snd.stop();
      _root.stop();
    };

    … you already know that _root refers to the timeline that contains pauseClip. If you were to drop that prefix altogether …

    pauseClip.onPress = function():Void {
      snd.stop();
      stop();
    };

    … the scope of the MovieClip.stop() method, as shown, belongs to pauseClip because that function is associated with pauseClip’s onPress event. In other words, without _root — or some other object reference — you’re telling pauseClip itself to stop.

    When the function executes, it thinks to itself, “Okay, I’ve got two things to do here: a) invoke Sound.stop() on this snd instance, whatever it is, and b) invoke MovieClip.stop() on … hmmm … well, there’s no reference prefix, so I guess I’ll just apply it to myself. I’m a MovieClip instance, after all. Yup, that makes perfect sense; I can do that. I have no idea what snd is, so I guess I’ll look up the chain. Aha, in the timeline above me, I see a snd object, so I guess that’s the one this function means.”

    Scope causes an object to look inside itself first for any object references. (Note, while ActionScript 3.0 also features this notion of scope, event handlers are scoped differently from how I’m describing here. This answer of mine is strictly geared toward ActionScript 2.0, which is what we’re using.)

    A quick look at the MovieClip class (ActionScript 2.0 Language Reference) shows me that all movie clips feature a _parent property. Bingo! That’s useful. The MovieClip._parent property points to the parent object/timeline of the current movie clip. Therefore, check it out …

    pauseClip.onPress = function():Void {
      snd.stop();
      this._parent.stop();
    };

    That handles it beautifully — assuming pauseClip’s immediate parent is the main timeline.

  58. Rob Says:

    Hey Dave,

    Great website! Thanks for all the helpful info. But I am stuck on a sound issue… I have a website template i’m making thats playing a background sound file from a seperate .SWF file thats being called. It has a play and stop button that uses this code:
    on (release) {
    gotoAndStop(2);
    }
    on (release) {
    _parent.eqq.gotoAndPlay(”pl”);
    _root.soundstatus = “off”;
    }

    I embeded a movie clip onto layer 1 of the website but when I click on “Stop” it stops the sound on the whole site, including the video that I have. How do I change something like this so that it only stops the music track thats playing!!?? Is it because its using _root.soundstatus=”off”;?

  59. David Stiller Says:

    Rob,

    Nah, _root.soundstatus just points to a custom string variable you have in _root. The “trick” to what you’re after depends entirely on how you’re constructing your Sound instance. If you omit the optional parameter in the expression new Sound();, then your Sound instance references the whole movie. On the other hand, if you pass in a reference to a particular movie clip (new Sound(someClip);), you can control the volume of that clip only — which may very well be the clip that contains your loaded content. Choice is yours. :)

    See “Understanding the Sound Constructor (AS2)” and “How to Toggle Sound Globally (AS2)” for details on how this phenomenon plays out in AS2.

    Part of the problem might be your _root reference, too — not because of the name of the soundstatus variable, but simply because _root can be problematic if you don’t understand fully how it works. See if “Is _root Evil?” helps you decide for yourself.

  60. Rob Says:

    Hey Dave thanks for the quick reply. Right now, my music track is a movie clip thats being loaded into level 2 when the site loads like this:

    loadMovieNum(”music1.swf”,2);

    I did look through your global sound blog..so is it possible to set that movie file to a “new sound();” variable and then control the volume of that specifically using my button with something like this:

    on (release) {
    _parent.eqq.gotoAndPlay(”pl”);
    globalVolume.setVolume(0);
    }

    ?? How would you set music1.swf as a new sound when the site initially loads up??

  61. David Stiller Says:

    Rob,

    The loadMovieNum() function loads SWFs into levels, rather than movie clips. Even so, these levels (_level0 [the default], _level1, _level2, etc.) are movie clips. Since the whole of _level2 is your container, you’ll have to use _level2 as the target for your Sound constructor. That should do it, but I’ve never tried it. In that case, you may want to choose to name your variable something else, such as:

    var loadedSWFVolume:Sound = new Sound(_level2);
    
    // Then, later ...
    on (release) {
      _parent.eqq.gotoAndPlay("pl");
      loadedSWFVolume.setVolume(0);
    }

    If, for some reason, that doesn’t work, you could use one of the other approaches for loading a SWF at runtime (the loadMovie() function, the MovieClip.loadMovie() method, or the MovieClipLoader class). Those load content into movie clip containers — that is, an empty (or not) movie clip symbol, with an instance name, on the Stage — so the container clip’s instance name would be your target.

  62. Rob Says:

    Dave,

    Unfortunatley _level2.soundstatus=”off”; did not work…although that would of been sweet!

    I could not get the other method you explained to work either:

    I loaded the music like this:

    var mymusicVolume:Sound = new Sound(_level2);
    loadMovieNum(”music1.swf”, 2);

    Then the play/stop button said:
    on (release) {
    _parent.eqq.gotoAndPlay(”pl”);
    mymusicVolume.setVolume(0);
    }
    But No luck! I guess i’ll have to look into how the other runtime loading methods you gave me work…unless you have another suggestion…but I dont know why the last idea you provided didnt work…hmph..thanks

  63. David Stiller Says:

    Rob,

    Honestly, the soundstatus thing may or may not be related to what you’re after. There is no soundstatus variable in ActionScript out of the box … that’s some sort of custom programming in your file — so it doesn’t surprise me that _level2.soundstatus doesn’t do anything.

    I’m disappointed (for both our sakes!) that new Sound(_level2) doesn’t work. I did some testing just now, and it appears that naming any level as a target for Sound is as good as naming none: it causes the Sound instance to control the whole movie. This happens if you specify the default level (_level0), but I didn’t know that any level would do. Good to know!

    So … for your purposes, you’ll need to load your external content into a movie clip container, rather than a level. I still can’t say what your soundstatus variable is used for, but the following code succeeds as a working template:

    var loadedVolume:Sound = new Sound(container);
    
    var mcl:MovieClipLoader = new MovieClipLoader();
    mcl.loadClip("external.swf", container);
    
    var listener:Object = new Object();
    listener.onLoadInit = function():Void {
      loadedVolume.setVolume(0);
    }
    mcl.addListener(listener);

    The above code assumes a movie clip symbol on the Stage with the instance name container. The Sound instance is associated with that movie clip, then a MovieClipLoader instance uses that same movie clip as the container for the external SWF. The magic happens in the onLoadInit handler, which the MovieClipLoader instance (mcl) listens to. The handler changes the Sound instance’s volume to 0 — and does so after the external SWF has loaded. That’s important. If you set the volume before or while the external content is loading, it doesn’t work.

  64. Rob Says:

    Hey Dave,

    I have to apologize for the constant bother and for sounding dumb but I am pretty new to this and would love to get this thing to work, so I really appriciate all the help you’ve already provided!

    So I used your code from above ‘as is’ to load my music file, but it doesnt play when the page is loaded. “The above code assumes a movie clip symbol on the Stage with the instance name container.” I dont know where to but this new movie clip symbol and to give it an instance. That might be why its not playing…?

    And would I stop the music the same way:

    Getting rid of soundstatus and using:

    on (release) {
    _parent.eqq.gotoAndPlay(”pl”);
    loadedVolume.setVolume(0);
    }

    Thanks again.

  65. David Stiller Says:

    Rob,

    No worries! Your questions aren’t a bother, and you don’t sound dumb at all … just new to ActionScript.

    If you pasted my code literally as is, there are a number of reasons why it wouldn’t work straightaway. First, as you noted, you haven’t yet added a movie clip symbol with the instance name “container,” so let’s start with the very basics. If you start a brand new FLA — literally brand new; there’s nothing in it — and you type the following into it …

    loadMovieNum("music1.swf", 2);

    … then it will load the SWF file “musics1.swf” into level 2 (which is what you originally had). In order for that to work, you’d have to save this new FLA file into the same folder as music1.swf, because there’s not path information in front of that file — it’s assumed to be in the same folder.

    So far, so good. You had ventured so far on your own. I’m proposing a different approach to loading that SWF, because we discovered that levels can’t be used for individualized volume control. That said, consider the MovieClipLoader class. First, you need an instance of that class:

    var mcl:MovieClipLoader = new MovieClipLoader();

    All that does so far is declare an arbitrarily named variable, mcl, and set it to the new MovieClipLoader instance. From this point forward, the variable mcl is one instance — one working object — of the MovieClipLoader class. To see what functionality is available to this class, read up on its entry in the ActionScript 2.0 Language Reference. You’ll see properties (characteristics), methods (things the object can do), and events (things the object can react to). Here’s a quick example of how to load that same music1.swf with your mcl instance, which should entirely replace the existing loadMovieNum() line:

    var mcl:MovieClipLoader = new MovieClipLoader();
    mcl.loadClip("music1.swf", container);

    Not much to it! :) The MovieClipLoader.loadClip() method — one of the things this object can do — is invoked on the mcl instance. This method accepts two parameters, just like your previous loadMovieNum() does. The first parameter is the SWF to load; the second is a movie clip to load it into.

    You should still be in the brand new FLA mentioned above. Your single loadMovieNum() line should be gone, replaced with the two new MovieClipLoader-related lines. Go to Insert > New Symbol and give the new symbol a name (”container” will do). Make it a movie clip and click OK. Now you’ll see that clip in your Library. Drag it to the Stage. Because nothing is in that clip, it will appear a small white circle, which is just a placeholder. Drag that placeholder wherever you like. Wherever you do, that’s going to be where your music1.swf is loaded. If that SWF contains visual elements, their upper left corner will be the position of your container clip. You might want to put it in the upper left corner of the Stage. With this clip selected (by its little white dot), look at the Properties inspector. You’ll see where you can assign your instance name. Because the ActionScript is expected “container,” that’s what you put. (You could have used sparkleStars, but container makes sense in this case, because it describes the function of this movie clip. It doesn’t matter, by the way, that the instance name and the Library name are the same; that’s just coincidence. In reality, the two names are unrelated.)

    Test your movie, and the SWF will load as before. This time, it’s inside that movie clip, and you can change the position of that movie clip, animate it over time, etc., like any other.

    Use that same movie clip’s instance name (container) as the parameter in your Sound instance, and you should be good to go. MovieClipLoader also features events, and the onLoadInit event is handled with the function I showed earlier, which lowers the volume on a particular sound instance, which I arbitrarily named loadedVolume.

    Everything I’ve described stands on its own: you don’t need the soundstatus variable you were using before. The fact that you have a custom soundstatus variable tells me that you have additional custom code in your previous FLA, and while that might be perfectly usable code, I have no idea what it does, so my own suggestions have nothing to do with it — and might even interfere.

  66. bob burock Says:

    Hi David,

    I am trying to find some code that would let the user of my flash presentation resume from where they left off the last time they used the presentation or start from the beginning the next time it is booted. I need a quit function that asks this question.

    I have multiple modules on a desktop format and would like some code similar to what you did for sound / music.

    Do you consult on this for a fee? Please let me know your thoughts.

    PS. The above site is in the works and this is in an unpublished format without audio at this time. Thanks for your help.

    Bob

  67. Kelley Says:

    Hi David

    Hoping this isn’t too confusing and that you can offer some advice: I am loading external SWFs into a master SWF; each external SWF has several MovieClips running in sequential order on the timeline (keypoints with named frames, i.e. seg1, seg2, etc). The MovieClips are named similarly (i.e. MCseg1, MCseg2, etc.). Each MovieClip has embedded sound. I am using an ON/OFF button for the sound, which is placed on the master SWF, and works perfectly: it is a MovieClip with two buttons, (MConOff) an ON button (frame 1) and an OFF button (frame 2), and the code respectively is:

    //ON
    on (release) {
    gotoAndStop(2);
    //moves from ON button to OFF button
    _root.sndPlay.setVolume(0);
    }

    //OFF
    on(release) {
    gotoAndStop(1);
    //moves from OFF button to ON button
    _root.sndPlay.setVolume(100);

    }

    I realize this does not actually stop the sound, it in effect simply adjusts the volume to either (0) or (100). But it works for me…. and the client likes that it keeps the movie moving without sound.

    My problem is not with the sound, however - it is with the MovieClips. My client wants to pause a MovieClip indefinitely (along with it’s sound), and then go back to it without interuption (restart where it left off). I created a separate MovieClip movie control (MCpausePlay) with two buttons: pause (frame 1) and play (frame 2). I coded them like this, respectively:

    //pause
    on (release) {
    gotoAndPlay(2);
    //moves from PAUSE button to PLAY button
    _root.stop();
    stopAllSounds();

    //play
    on (release) {
    gotoAndPlay(1);
    //moves from PLAY button to PAUSE button
    _root.play();
    }

    This does pause the currently running MovieClip, however, the next clip loads. I need to stop the entire timeline, then restart from where I’ve stopped (by ‘timeline’ I mean the sequential MovieClips). So if I am currently running MCseg4, I want to pause it, have it wait for my click, and then start up again. As it is right now, MCseg4 does stop, but MCseg5 starts up. And I cannot get MCseg4 to restart, either.

    Any Ideas?

    My next challenge will be to rewind the currently running MovieClip…. any suggestions on that?

    Kelley

    }

  68. Kelley Says:

    David

    Though I haven’t seen a response to my query, I wanted to update you on my progress:

    I managed to pause and play my MovieClip by placing the pauseBtn and playBtn within the actual MovieClip on the Actions timeline:

    var snd:Sound = new Sound();
    snd.attachSound(”seg1mp3″, true);
    var paused = false

    pauseBtn.onRelease = function():Void {
    stop();
    }

    playBtn.onRelease = function():Void {
    play();
    }

    However, the sound continued playing though the animation stopped. I have a sound file embedded within each MovieClip, so I did this:

    pauseBtn.onRelease = function():Void {
    stop();
    stopAllSounds();
    }

    playBtn.onRelease = function():Void {
    play();
    snd.play();
    }

    The sound does not start again - what am I doing wrong here? How do I get the embedded sound file, “seg1mp3″ to resume play along with the MovieClip?

  69. David Stiller Says:

    To bob …

    Apologies for the late reply! I’m working on two books at the moment, which has eaten into my time more than I had anticipated (and more than I would like to admit!).

    I am trying to find some code that would let the user of my flash presentation resume from where they left off the last time they used the presentation or start from the beginning the next time it is booted.

    For something like this, you’ll want to look into the SharedObject class. SharedObject is essentially the Flash Player version of browser cookies, so you can use a “Flash cookie” to store the user’s placement in the timeline (or in a sound file, or whatever) and retrieve it for later use.

    See if this article gets you started:

    How to Store Persistent Data with the SharedObject Class (AS2)

    … and don’t hesitate to write back if that doesn’t do it for ya. :)

    To Kelley …

    I realize this does not actually stop the sound, it in effect simply adjusts the volume to either (0) or (100). But it works for me…

    That’s a good approach, actually. In fact, it’s the approach I recommend in “How to Toggle Sound Globally (AS2).” Glad to hear that part is working for you. :)

    My problem is not with the sound, however - it is with the MovieClips. […] As it is right now, MCseg4 does stop, but MCseg5 starts up. And I cannot get MCseg4 to restart, either.

    I’m not quite sure I understand yet how your movie clips are laid out in the main timeline. When you say “the next clip loads,” I’m not sure what you jmean by “loads” (e.g. are you referencing external SWF files — that is, loading external content? — or are your movie clips already present in the master SWF? If you’re loading external content at runtime, you’ll have to program your buttons to interrupt the load process in addition to managing the flow of the timeline. If these movie clips are already present, you may have to reference not only the main timeline, but (perhaps) the individual timelines of your movie clips.

    Both the main timeline and movie clip symbols are instances of the MovieClip class, which means you can invoke, for example, the MovieClip.play() method on either. The MovieClip class also provides a stop() method and more &mdash which you’re already using, it looks like — but the difference is that you may also have to use these methods in conjunction with movie clip symbols. To do so, make sure your movie clips have instance names (you can provide one for each with the Property inspector) and precede your calls to play() and stop() (or whatever else) with the relevant instance name. It’s identical in principle to your use of snd.stop(), in which you’re invoking the Sound.stop() method on the snd instance.

    Does that make sense?

    Though I haven’t seen a response to my query, I wanted to update you on my progress

    Thanks for the follow up! :) I’ve been out of state for several days at TODCon 8, so I’m behind in blog replies, but it’s great to hear you’ve continued to work through this endeavor. Good on ya!

    I have a sound file embedded within each MovieClip, so I did this […] The sound does not start again - what am I doing wrong here?

    The stopAllSounds() function doesn’t belong to the Sound class, and it affects all sounds in play at the time it’s called, but stopAllSounds() doesn’t give you as much control as the Sound class.

    I’m not certain, for example, in what way (if at all) the stopAllSounds() function affects the Sound.position property of your snd instance. (It’s easy enough to test, but I don’t have Flash in front of me at the moment.) In contrast, though, invoking Sound.stop() leaves Sound.position with a value you can re-use with the Sound.start() method, as described in the article above.

    I notice you’re trying to invoke a play() method on your snd instance — it’s an easy slip to make! — but the Sound class only features a start() method.

  70. Kelley Says:

    David - thank you!

    To answer you in return: the MovieClips are laid out along the timeline, one after another, within each of the external SWFs. So, for instance, I am working from the index.swf and I click the genInfo button, this loads the external genInfo.swf. This genInfo.swf has an actions layer, a mask layer and a MovieClip layer. Along the MovieClip layer are placed roughly 10 MCs in succession, separated by keyframes. The frame segments (i.e. the space along the timeline separated by keyframes) are also named, as in seg1 for MCseg1, and so on. I did this so that when I need to find a specific MC for changes, I simply scroll through the timeline to find that segment. To the user, there are no breaks in the animation; everything flows along in sync. Because the audio files in whole are quite long (some are 2 mins.) and I need to synchronize animations to the audio files, I broke each original audio file down into segments. Each segment is now 3-10 seconds long, (running at 29fps). That’s why I have so many MCs in my timelines.

    Each MC contains an actions layer, an audio layer and an animations layer.

    I want to be able to control each MC globally (from the index.swf), so that when I am running the genInfo.swf, I can pause and play at will without starting the animation from the very beginning. If I have to build the controls into each external swf, I’d do that - but as it is, I can only control things from the base level of the individual MovieClip. When I attempt something such as, ” _root.stop(); ” on the genInfo.swf file, this does nothing. When I script, ” stop(); ” on the actual MovieClip, however, this stops the MovieClip.

    And the audio file (mp3) continues playing.

    I see now after much research that there is no EASY way to pause a sound file in Flash - for whatever the technical reasoning - one must ‘fool’ the program into first stopping the sound file and recording the track position, then restarting the sound file at that exact track position. Is this correct? Sounds like a lot of scripting that I don’t understand how to do… and I have no idea where I am suppose to script this - in the individual MC, in the external swf housing multiple MCs, or in the index.swf? So far it isn’t working anywhere, so I know I’m doing something wrong because scripting is not one of my strengths; I just don’t seem to grasp the concept of how to find the track position and stop and start.

  71. Kelley Says:

    David,

    I feel like my head is going to spin around soon…. lol…

    Here’s my update:

    I utilized something you have on this page regarding an ‘old school’ method of pausing a sound: (using a button called, “pauseBtn”):

    var paused = false;
    pauseBtn.onRelease = function():Void {
    if (paused) {
    play();
    } else {
    stop();
    }
    paused = !paused;
    }

    OMG - this actually pauses sound!

    HOWEVER……………… there are some problems I’ve noted:

    1) I put it within a MovieClip which has an audio layer and several layers of animation. This actually paused BOTH when clicked! But, the next MovieClip along the timeline started.

    2) Sound quality is terrible! It makes the audio track sound very tinny; this is a narration and the speaker’s voice sounds split in two, as if his voice is made of tin, and it has an echo made of tin. I tried changing the property to “Convert Stereo to Mono” but that made no difference

    Is there a way to utilize this code to pause the currently running MovieClip AND keep the other MovieClips from running,

    AND

    Is there a way to adjust the sound quality once the sound is made to stream?

    I feel that I am so very close to solving this problem, and yet it is still so very far out of reach…

    Kelley

  72. David Stiller Says:

    Kelley,

    Each MC contains an actions layer, an audio layer and an animations layer.

    The organization of your various SWFs, including masks, movie clips, audio layers, etc., sounds fine, complex as it may appear. When I hear “audio layer,” that suggests to me you’re embedding audio directly into your timeline(s), rather than using the Sound class. That’s fine too, but it’s absolutely imperative you understand the difference between using timeline sound and programmed sound.

    Unless you actually instantiate the Sound class and invoke either loadSound() or attachSound(), the only thing you can do with your Sound instance is affect the volume and panning of a particular movie clip. If you leave the Sound constructor empty, that instance affects the main timeline (i.e., the whole SWF), which is the “toggle volume globally” technique described elsewhere on this blog. On the other hand, if you pass a movie clip reference to your Sound instance, you can control the volume/panning of the passed-in movie clip exclusively.

    When I attempt something such as, ” _root.stop(); ” on the genInfo.swf file, this does nothing.

    It does do something — it stops the main timeline of the parent-most movie clip — but if the parent-most movie clip only has one frame and loads everything else dynamically (which is what it sounds like … I think), then stopping the main timeline doesn’t produce any visible results. All movie clips run independently of each other, so to halt the timeline(s) of loaded SWFs and/or movie clips, you’ll have to invoke MovieClip.stop() on each individual SWF/movie clip by way of a MovieClip reference, which is usually an instance name.

    I see now after much research that there is no EASY way to pause a sound file in Flash - for whatever the technical reasoning - one must ‘fool’ the program into first stopping the sound file and recording the track position, then restarting the sound file at that exact track position. Is this correct?

    To be sure, ease vs. difficulty is a subjective judgment, but I believe this endeavor is easier than you realize. If your sound is attached directly to a keyframe, you can use the Property inspector to determine whether the audio’s Sync property is configured as Event or Stream.

    If it’s Event, then the audio in that keyframe gets loaded into memory all at once when the playhead enters that frame. Even if you stop the playhead (MovieClip.stop()), the audio continues to play. (This is when the standalone stopAllSounds() function can come in handy.) To get an Event sound to restart, you have to send the playhead back to the keyframe in which the audio appears, and it will start again from the beginning. In this context, there is no way to start such a sound halfway through.

    If your keyframe sound is set to Stream, it becomes locked in-step with the timeline, which means you don’t need the stopAllSounds() function to halt the audio; a MovieClip.stop() method works just fine. Such audio can be started again simply by way of MovieClip.play(). No need for the Sound.position property, because no Sound instance is necessary. (Again, the only case for a Sound instance with timeline audio is to adjust its volume or panning dynamically.) Stream audio restarts from where it left off by definition, because it’s synchronized with its timeline.

    If you use a Sound instance for more than what I’ve described — that is, to actually load external MP3 files or attach audio assets from your Library — then you’ll use the Sound.stop() and Sound.start() methods (along with the Sound.position property) to resume sound. In this case, audio will not be attached to a timeline frame at all, and you’ll need to use both MovieClip and Sound methods to match up the halting/re-starting of your timeline animation with your audio.

    I utilized something you have on this page regarding an ‘old school’ method of pausing a sound

    That’s another hint that you’re using timeline audio, because the play() and stop() functions correspond to the MovieClip.play() and MovieClip.stop() methods. In other words, your code is only controlling a timeline, and the Sound class doesn’t seem to be involved at all.

    OMG - this actually pauses sound!

    As long as that timeline code is set to Stream, yes. :)

    This actually paused BOTH when clicked! But, the next MovieClip along the timeline started.

    It’s hard for me to pinpoint what’s going on, but it might be that your main timeline (or a parent of the movie clip in question) is still moving forward, which updates the screen toward the following movie clip.

    Sound quality is terrible!

    That’s really one of those “an art and a science” issues. It often takes a bit of fiddling to get your compression right. You’ll see configurations for both Event sounds and Stream sounds in the Publish Settings dialog.

    More importantly, though, you need to fully digest the distinction between timeline audio and programmatic audio (the Sound class).

    In one of your questions/comments, you were wondering where to put all your code. The answer to that, ultimately, depends on what works best for your workflow. It’s generally possible to put all of your code — all of it! — in frame 1 of your parent-most timeline. But wherever code does appear, it simply needs to know what objects to reference (where those objects are, in other words). The easiest way to help Flash help you is to provide instance names for objects, such as movie clips, that are created by hand. This way, your code can reference objects by name and invoke the relevant class methods (or properties, or events) on them.

  73. Kelley Says:

    Thanks for your help, David - it’s a lot for me to digest just now, as I find this all so confusing. I don’t know a sound object from a sound class, if that statement is even correct! :-)

    Each movie clip contains several layers, including actions, audio, and several layers for animations. The audio is actually placed along its own layer, and is currently set to stream in the properties dialog.

    At present I can pause the first movie clip in the timeline along with it’s audio - however, after the apt amount of time elapses (i.e. the first clip is 8.3 seconds at 29fps, 271 frames in length), the next clip plays.

  74. David Stiller Says:

    Kelley,

    These concepts are difficult, for sure, until they sink in. Chin up!

    In ActionScript, everything is considered an object, and objects are defined by their individual blueprints, which are called classes. Your movie clip symbols, for example, are instances of (aka “objects of”) the MovieClip class. As you already know, movie clip symbols have certain characteristics, such as width and height, position on the stage, number of frames, etc. These correspond to properties of the MovieClip class; in AS2, those are _width, _height, _x, _y, _totalframes, and so on. Movie clips can also do things, such as go to a frame and start playing. Such doing-things features are called methods (gotoAndPlay(), loadMovie(), etc.). Movie clips can also respond to things, such as a mouse click. Those features are called events (onPress, onRelease, and so on).

    And it doesn’t stop with movie clips. Everything is an object, and all objects are defined by classes. Text fields are defined by the TextField class, whose properties govern things like width, height, number of characters in the text field, and more; whose methods govern the things a text field can do (setTextFormat(), getFontList(), etc.); whose events govern the things a text field can respond to (onChanged, onSetFocus …).

    Button symbols are defined by the Button class. Arrays are defined by the Array class. Blurs are defined by the BlurFilter class, dates by the Date class, sounds by the Sound class, and on and on. Not all classes feature properties, methods, and events, but those are the main three categories to look for when consulting the ActionScript Language Reference.

    In your case, you’re dealing with audio attached directly to keyframes, which means you’re not using the Sound class, which is fine. Because of that, however, you can’t make use of any of the Sound class members (no properties, methods, or events) — except as those relate to the MovieClip class. Why? Well, the MovieClip class comes into play because your audio is attached to keyframes, and keyframes are stored in a timeline. All timelines, including the main timeline, are instances of (aka objects of) the MovieClip class. This is what allows you to optionally adjust a movie clip’s volume and panning by way of the Sound class (see “Understanding the Sound Constructor (AS2)“), but nothing more.

    At present I can pause the first movie clip in the timeline along with it’s audio - however, after the apt amount of time elapses (i.e. the first clip is 8.3 seconds at 29fps, 271 frames in length), the next clip plays.

    That means something is telling the next clip to play. Perhaps there’s code in the last keyframe of your current movie clip that tells the next one to move?

  75. AndyD Says:

    Hi David

    Quick question re the above. I have a series of .swf movies that load in to a master movie clip. Each child .swf file has a series of mc’s that contain a timeline with embedded audio and animations synced with the audio.

    Your code works great if I place the control panel that pauses/plays the audio within each child .swf. However, I want to be able to send commands to the pause/play buttons that reside within the master timeline but I am really struggling getting it to work once they have been loaded in to the main timeline.

    I have tried targetting the pause/play buttons, but nothing seems to be working. Do you have any ideas why this is happening, or can you not use this method.

    I am basically passing a command from the child timeline to the main timeline, to perform an action in the child timeline. I am just not sure with the attachSound method etc.

    Thanks in advance

  76. Jordan Says:

    This is the first reply in a while, but I just have to reiterate the very first reply to this thread and, no doubt, others after that (I haven’t read them all). I couldn’t agree more mStudios’ sentiments, in regards to the no-bullsh!t approach, to this handy little tutorial. I’ve been searching around, trying to resolve a similar issue and it’s refreshing to finally find somebody who speaks my language!

    Thanks David!

  77. Lele Says:

    Hi David

    Im using AS3 at the moment and building an interactive music video for my assignment … basically we have keyed out video footage of the band and each member is its own MovieClip that is embedded into the main Timeline
    they reside at the very top level of layers. Underneath these layers we have the interactive objects and background scene. I have set up the navigation so that when you arrow key to the left or right it will “switch scenes” - basically going from one background scene on one frame to another scene on another frame ….

    in order to syncronise the lead singers vocals with the song I had to embed the audio file as a layer within the lead singer movieclip - i did try to call the mp3 file to play by code but the audio & video never synced correctly

    my problem is this : i have 5 scenes that you can move around on …. scene1 sits on frame 1, scene 2 on frame 2, etc … when you get to scene 5 the next click event will take you backwards on the timeline to scene 1 … as soon as this happens though the song within the vocals_mc layer seems to restart playing and it creates this layered double-sound effect … if i continue navigating or going backwards, the song layers again and again so that i have this annoying cacophany of copies of the same song playing simultaneously

    what is the quickest, easiest way to avoid this without having to sacrifice the syncronised video/audio?

    many thanks in advance for any help you can provide. This is easily the best explanation of AS2 sound I have seen yet so thank you! :)

  78. David Stiller Says:

    To AndyD …

    Your code works great if I place the control panel that pauses/plays the audio within each child .swf. However, I want to be able to send commands to the pause/play buttons that reside within the master timeline but I am really struggling getting it to work once they have been loaded in to the main timeline.

    Your goal is definitely doable, and it all comes down to finding the right object reference(s), like traversing folders on your hard drive. I should say, your goal is doable if it’s what I think you’re asking — but this part throws me a bit:

    I am basically passing a command from the child timeline to the main timeline, to perform an action in the child timeline. I am just not sure with the attachSound method etc.

    What command are you passing from the child to the parent? Where the the actual pause and play buttons located? It sounds like your pause/play buttons are located in the main SWF (the parent SWF). If so, those buttons can send messages to the loaded (child) SWFs, instructing them to stop and resume their audio. If the attachSound() code resides in the child, your object reference would be whatever object points to the loaded SWF, and then whatever variable name you gave the child’s Sound instance, all separated by dots parent.child.mySound).

    If you can explain the reason for traveling the opposite way — from child to parent — I’ll try to help you figure out the pathing. In principle, though, you should be able to path to the parent by invoking the MovieClip._parent property in the main timeline of the child as the beginning of your object reference.

    To Jordan …

    I’ve been searching around, trying to resolve a similar issue and it’s refreshing to finally find somebody who speaks my language!

    Glad to hear that, man! I appreciate the comment!

    To Lele …

    in order to syncronise the lead singers vocals with the song I had to embed the audio file as a layer within the lead singer movieclip

    There’s nothing wrong with that, but make sure you set the audio’s Sync option to Stream in the Property inspector.

    he vocals_mc layer seems to restart playing and it creates this layered double-sound effect … if i continue navigating or going backwards, the song layers again and again so that i have this annoying cacophany of copies

    That definitely sounds like your audio is set to Event in the keyframe that introduces the audio. Try Stream, which locks your audio in-step with the visuals, and in addition, allows you to stop that timeline with MovieClip.stop() (and restart it again, of course, with MovieClip.play()). That’s the benefit of the Stream setting for Sync. The benefit of the Event setting is that the audio loads fully into memory first, before playing, which allows it to play independently of the timeline. There are pros and cons to everything, and in the case of Event — this is my hunch, mind you — you’re hearing those loops. If you’re using Event, by the way, don’t count on it that the audio will sync to the visuals on everyone’s computer. When you use Stream, you can rely on it.

Leave a Reply