stopping a soundchannel through a movieclip - actionscript-3

my question is as follows. I have a sound triggered by clicking on a movieclip, like this:
var audioPlayer: SoundChannel = new SoundChannel();
var SndJuichen : Sound = new Juichen();
bootje.addEventListener(MouseEvent.CLICK, bootjeClick);
function bootjeClick (e:MouseEvent):void{
audioPlayer = SndJuichen.play();
}
}
and i want to stop this by clicking on another movieclip. for the time being, i have not been able to do this.
so I tried it by clicking on a button. like this:
stop_btn.addEventListener(MouseEvent.CLICK, audioStop);
function audioStop (e:MouseEvent):void{
addEventListener(MouseEvent.MOUSE_DOWN, mousedown);
function mousedown (e:MouseEvent){
audioPlayer.stop();
}
}
At first this worked but, but when i tried it later without changing the code it didn't work anymore.
so my question is how do i get the soundchannel to stop?
I have searched for hours already, if you think you have a link that can easily fix my problem its okay too.
sincerely

Drop the very first line var audioPlayer: SoundChannel = new SoundChannel(); and make sure this code is run in the context of some persistent MovieClip, this way audioPlayer will turn into a property of that MovieClip and be accessible from another frame where you decide to stop the sound.

Related

Controlling Sound on flash video with Play/pause/stop buttons

I have a flash video that is short, has sound, and I've got Play Pause and Stop buttons.
Without sound, it works perfectly. It autoplays, you can hit pause and it pauses, and play resumes where it leaves off. Hitting stop goes to an empty frame if someone wants to turn it off.
I have audio inside my library, and would like connect the audio with the same elements. I've been researching for awhile now, and I've not come up with a solution yet, and having a hard time.
Here is my ActionScript code for my currently working buttons:
StopBtn.addEventListener(MouseEvent.CLICK, stopplaying);
function stopplaying(Event:MouseEvent):void {
stop()
}
PlayBtn.addEventListener(MouseEvent.CLICK, startplaying);
function startplaying(Event:MouseEvent):void {
play()
}
CloseBtn.addEventListener(MouseEvent.CLICK, close);
function close(Event:MouseEvent):void {
gotoAndStop(240)
}
You should use Sound and SoundChannel to do this. And for pause you'll have to save the current play position so that you can continue from there:
var audio:Sound = new audioFromLibrary(); //linkage name
var soundChannel:SoundChannel = new SoundChannel();
var audioPosition:Number = 0;
//PLAY:
soundChannel = audio.play(audioPosition);
//PAUSE:
audioPosition = soundChannel.position;
soundChannel.stop();
//STOP:
soundChannel.stop();

Does adding eventListener with same params null/replace previous eventListeners?

I've inherited a large, legacy Flex project and the deeper I get into the code, the more concerned I am becoming. For example, I am looking at code for a "window" type image viewer within the app. Every time it is displayed, the eventListeners below are added and never removed.
Since these are strong references and never removed, that is one problem but this repeatedly adding eventListeners is giving me pause. The "window" can be displayed and hidden many times in the lifecycle of the app.
My question: does this mean that is has n = (4 * number of times displayed) eventListeners? (...shudder).
This is a huge project revision on a tight budget so I am trying to determine if I fix this sort of thing or just let it go.
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
If they are different eventlisteners, they will be added multiple times. If they all refer to the same function, it will be overridden each time, calling the specific function only once.
try out the following short example to see what i mean:
var s:Sprite = new Sprite(); //some sort of displayobject with EventDispatcher capabilities
s.addEventListener(MouseEvent.CLICK, onClick);
s.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void{
trace("hey");
}
pressing on the Sprite will give you a console output of "hey", not two "hey"s.
Now consider the following:
var s:Sprite = new Sprite();
s.addEventListener(MouseEvent.CLICK, onClick);
s.addEventListener(MouseEvent.CLICK, onClick2);
function onClick(e:MouseEvent):void{
trace("hey");
}
function onClick2(e:MouseEvent):void{
trace("sup");
}
This will give you an output of "hey" and "sup" once you press on the Sprite.
If you are really concerned, you could just give the event listener a weak reference. I don't know how complex the project is you're working on, but implementing something to get rid of all eventlisteners at once (like, waiting for Event.REMOVED_FROM_STAGE and then manually removing the listeners) shouldn't be too time-intensive.

How to Remove a Sound

Hey guys so I can't figure this out. I want to Remove a single sound from a Class. So I have a start screen and when you press "Play Game" it takes you to the game but the start screen music keeps playing. Ive tried sound mixer remove all sounds which works but it removes every sound in the game even the Main game music. So i just to remove this single sound which is added in its class like so:
public class mcStartGameScreen extends MovieClip
{
private var sndmainSong:Sound;
public var mcStart:MovieClip;
public function mcStartGameScreen()
{
mcStart.buttonMode = true;
mcStart.addEventListener(TouchEvent.TOUCH_TAP, startOnTouch, false, 0, true)
//To completely end game when back button pushed on android
NativeApplication.nativeApplication.addEventListener( KeyboardEvent.KEY_DOWN, handleKeyDown, false, 0, true);
//create sound object from main song in library
sndmainSong = new DST10Class();
sndmainSong.play();
}
Now i want to remove the sound through the mcStart event listener function which is this:
private function startOnTouch(e:TouchEvent):void
{
dispatchEvent(new Event("START_GAME"));
//Tried null but didnt work either
//DST10Class = null;
}
So is their any easy way i can acccomplish this? Any help will be appreciated thank you!
Get a handler of the playing sound, then call stop() when you need to stop it.
var mainChannel:SoundChannel;
sndmainSong = new DST10Class();
mainChannel=sndmainSong.play();
Then, to stop it you call mainChannel.stop() and your sound will stop. To play it again, you need to create another SoundChannel object via sndmainSong.play().

as3 Sound Class Unloading Sound

I have tried this for HOURS. There must be a simple solution to stop the sound and unload it in as3.
This is not all of my code, but in short I am loading random sounds. I need certian vars to be outside of the function so I can reference them with other functions for a progress bar.
How do I unload a sound so I can load a new one using the same names without getting an error the second time its called?
I have two buttons in this test. A play Sound and a Stop Sound Button.
here is my code:
var TheSound:Sound = new Sound();
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, Stopsound);
function PlaySound(e:MouseEvent)
{
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
delete TheSound;
}
HERE IS THE ERROR I GET:
Error: Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
at flash.media::Sound/_load()
at flash.media::Sound/load()
at Untitled_fla::MainTimeline/PlaySound()[Untitled_fla.MainTimeline::frame1:21]
UPDATE.... I TRIED STOPING THE SOUND AND THEN UNLOADING IT AS FOLLOWS
mySoundChannel.stop();
TheSound.close();
BUT NOW I GET THIS ERROR:
Error: Error #2029: This URLStream object does not have a stream opened.
at flash.media::Sound/close()
at Untitled_fla::MainTimeline/shut1()[Untitled_fla.MainTimeline::frame1:35]
I believe I am closer. Thanks so much for your help so far.
In order to stop the sound from playing, you first have to tell the SoundChannel instance to stop like so :
mySoundChannel.stop();
Once you did that, you can close the stream used by the sound instance by invoking the close method like so :
TheSound.close();
Also, the delete keyword is rarely used in as3 and you should not it while some methods are trying to access the variable you are deleting. If you want to dispose of the instance that is currently assigned to your TheSound variable, you should set its value to null. This way, flash will properly garbage collect the old Sound instance that is no longer used when it finds the appropriate time to do so.
You can initialise the variable outside of the function, but define it as a new Sound object each time the function is called. That way it has global scope, and you can load a new URL at any time.
var TheSound:Sound;
var mySoundChannel:SoundChannel = new SoundChannel();
PlayButton.addEventListener(MouseEvent.CLICK, PlaySound);
StopButton.addEventListener(MouseEvent.CLICK, StopSound);
function PlaySound(e:MouseEvent)
{
TheSound = new Sound();
TheSound.load(new URLRequest("http://www.MyWebsite.com/Noel.mp3"));
mySoundChannel = TheSound.play(0);
}
function StopSound(e:MouseEvent)
{
mySoundChannel.stop();
TheSound.close()
}

How do you loop a sound in flash AS3 when it ends?

What AS3 code is used to loop a sound using AS3?
This won't give you perfect, gapless playback but it will cause the sound to loop.
var sound:Sound = new Sound();
var soundChannel:SoundChannel;
sound.addEventListener(Event.COMPLETE, onSoundLoadComplete);
sound.load("yourmp3.mp3");
// we wait until the sound finishes loading and then play it, storing the
// soundchannel so that we can hear when it "completes".
function onSoundLoadComplete(e:Event):void{
sound.removeEventListener(Event.COMPLETE, onSoundLoadComplete);
soundChannel = sound.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundChannelSoundComplete);
}
// this is called when the sound channel completes.
function onSoundChannelSoundComplete(e:Event):void{
e.currentTarget.removeEventListener(Event.SOUND_COMPLETE, onSoundChannelSoundComplete);
soundChannel = sound.play();
}
If you want the sound to loop many times with a flawless, gapless playback, you can call
sound.play(0, 9999); // 9999 means to loop 9999 times
But you still would need to set up a soundcomplete listener if you want infinite playback after the 9999th play. The problem with this way of doing things is if you have to pause/restart the sound. This will create a soundChannel whose duration is 9999 times longer than the actual sound file's duration, and calling play(duration) when duration is longer than the sound's length causes a horrible crash.
var sound:Sound = whateverSoundYouNeedToPlay;
function playSound():void
{
var channel:SoundChannel = sound.play();
channel.addEventListener(Event.SOUND_COMPLETE, onComplete);
}
function onComplete(event:Event):void
{
SoundChannel(event.target).removeEventListener(event.type, onComplete);
playSound();
}
import flash.media.Sound;
import flash.media.SoundChannel;
var mySound:Sound = new Bgm(); //Bgm() is the class of the internal sound which can be done in the library panel.
playSound();
function playSound():void
{
var channel:SoundChannel = mySound.play();
channel.addEventListener(Event.SOUND_COMPLETE, onComplete);
}
function onComplete(event:Event):void
{
SoundChannel(event.target).removeEventListener(event.type, onComplete);
playSound();
}
This works perfectly.
To expand on #scriptocalypse's gapless playback a bit:
The problem of not having proper gapless playback comes from mp3 including information about the file in either the head or the tail of the file (id3 tags etc), hence the small pause when you try to loop it. There are a few things you can do depending on your situation.
Ignore it, just play as normal, with a small pause at the end of every file. You can also try and mask it with another sound (a beat drop yo), or fade out and fade in.
If your sounds are embedded, and not streaming, then create a fla file, drag your mp3 in there, and set them to export (the same way you'd add a linkage name for a MovieClip etc). It seems that when you export sounds like this, Flash takes the delay into account, or strips it out when it creates the Sound object. Either way, you can just do a simple play() passing the loops that you want for a gapless playback (I've found using a loops parameter is better than waiting on the SOUND_COMPLETE event and playing it again).
You can try some of the ogg libraries to use .ogg files instead of .mp3. A simple google search for "as3 ogg lib" will turn up what you need. Personally, I found them a bit awkward to use, and I couldn't afford the overhead added (as opposed to mp3 decoding, which is done in the player).
If your mp3 files are streaming, then the only way to get gapless playback is to layer them. Determine the gap (depending on what you used to encode them, it'll be different - my files has a gap of about 330ms), and when you reach it, start playing the overlay. It's a proper pain if you're doing fading, but when it works, it works quite nicely. Worst case scenario, you end up with situation (1)
I guess this what you looking for in case the voice/music file is in the library:
var mysound:my_sound = new my_sound();
mysound.play(0,2); // this will repeat the sound 2 times.
This appears to have worked for me:
var nowTime:Number = (new Date()).time;
var timeElapsed:Number = nowTime - _lastTime;
_lastTime = nowTime;
_musicTimeElapsed+=timeElapsed;
if(_musicTimeElapsed >= _musicA.length - GAP_LENGTH)
{
_musicTimeElapsed = 0;
_musicA.play(0);
}
The other answers are great, however if you do not want to use code (for whatever reason), you can put the sound in a movieclip, set the sound property to "Stream", and then add as many frames as you like to the movie clip to ensure it plays fully.
This, of course, is a less preferred way, but for animators I'm sure it may be preferable in some situations (for example when synced with mouth animations that the animator wants looped).
this work for me :
import flash.media.Sound;
import flash.media.SoundChannel;
var soundUrl:String ="music.mp3";
var soundChannel:SoundChannel = new SoundChannel();
var sound:Sound = new Sound();
sound.load(new URLRequest(soundUrl));
soundChannel = sound.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE,onComplete);
function onComplete(e:Event):void{
sound = new Sound();
sound.load(new URLRequest(soundUrl));
soundChannel = sound.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE,onComplete);
}