Controlling Sound on flash video with Play/pause/stop buttons - actionscript-3

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();

Related

Expand menu (movieclip) and music in music setting error

I have make a menu in Flash that can expand and there music setting inside.
The music plays when the application starts. To stop the music you must expand the menu and click the music icon.
It's working fine after I open the program and stop the music.
And it's working if I want to play again.
But there's problems after that:
I can't stop the music again and the music playing double in background.
This is my FLA file:
https://drive.google.com/file/d/1DpqdH64kDnI8xN6fBAt3pwi_bIRQ52mT/view?usp=drivesdk
Can anyone tell me the fault of my program? Thanks.
About "music playing double" does your (audio) playback function create a new anything? (eg: = new Sound or = new SoundChannel)? If yes...
Create your audio variables once outside of functions, then use your functions only to stop/start audio playback.
Use new Sound only when loading a new track, once loaded then use one SoundChannel to play/stop that Sound object.
You need a Boolean to keep track of whether a Sound is already playing or not. If true then don't send another .play() command (now gives two sounds to output/speakers).
See if the code logic below guides you toward a better setup:
//# declare variables globally (not trapped inside some function)
var snd_Obj :Sound;
var snd_Chann :SoundChannel = new SoundChannel();
var snd_isPlaying :Boolean = false;
//# main app code
loadTrack("someSong.mp3"); //run a function, using "filename" as input parameter
//# supporting functions
function loadTrack (input_filename :String) : void
{
snd_Obj = new Sound();
snd_Obj.addEventListener(Event.COMPLETE, finished_LoadTrack);
snd_Obj.load( input_filename ); //read from function's input parameter
}
function finished_LoadTrack (event:Event) : void
{
snd_Chann = snd_Obj.play(); //# Play returned Speech convert result
snd_Obj.removeEventListener(Event.COMPLETE, onSoundLoaded);
//# now make your Play and Stop buttons active
btn_play.addEventListener(MouseEvent.CLICK, play_Track);
btn_stop.addEventListener(MouseEvent.CLICK, stop_Track);
}
function play_Track (event:Event) : void
{
//# responds to click of Play button
if(snd_isPlaying != true) //# check if NOT TRUE, only then start playback
{
snd_Chann = snd_Obj.play();
snd_isPlaying = true; //# now set TRUE to avoid multiple "Play" commands at once
}
}
function stop_Track (event:Event) : void
{
//# responds to click of Play button
snd_Chann.stop();
snd_isPlaying = false; //# now set FALSE to reset for next Play check
}

Adobe Flash/ Animate muting particular audio

I am in desperate need of help! I have a mute toggle button that I made following a tutorial on youtube in Adobe Animate/Flash using action-script 3.0 and it mutes everything as it is supposed to. However, I now need it to only mute the background music as it is muting my videos as well! How can I alter the code to either make sure only the background sound is muted and not the video?
function setMute(vol)
{
var sTransform:SoundTransform = new SoundTransform(1,0);
sTransform.volume = vol;
SoundMixer.soundTransform = sTransform;
}
var Mute:Boolean = false;
mute_btn.addEventListener(MouseEvent.CLICK,toggleMute_btn);
function toggleMute_btn(event:Event){ if(Mute)
{
Mute = false; setMute(1);
soundLines.gotoAndStop(1);
}
else
{ Mute = true; setMute(0);
soundLines.gotoAndStop(2);
}
}
In Adobe Animate (AS3), a developer can add audio in mainly two ways, timeline audio and external audio loaded by script. There can be even more methods of adding sound to a Flash movie.
In case of timeline audio, which are embedded and plays on movie progress, you may simply stop that movieclip containing that audio causing mute-like effect for that specific audio.
Example:
If your movieclip named BG contains your background music, you can write BG.stop(); for mute and BG.play(); for resuming the audio. This is the easiest method of all.
In case of streaming audio from external source using code,
var bg:Sound = new Sound();
var bgChannel:SoundChannel = new SoundChannel();
bg.load(new URLRequest("test.mp3"));
bgChannel = bg.play();
function vol(v:uint){
var sT:SoundTransform = new SoundTransform();
sT.volume = v;
bgChannel.soundTransform=sT;
}
setTimeout(vol,1000,0);
Similarly, set vol to higher value for unmute.

Switch language (audio and lyric) seamlessly in Adobe Flash

I’m creating a multilingual flash game with multilingual narrations. Till now i’ve got one language with an audio stream and lyric to accompany it in it’s own timeline controlled by a button on the main timeline to pause and play. I would like to add 2 more languages with audio and own lyric(karaoke style) for each language in this scene. And eventually have buttons on the main timeline that would switch the language(audio and lyric) and seamlessly continue from where the last language left off. Till now I have this action from the main timeline controlling the audio and lyric. englyr being the movie clip, with audio and lyric in it.
toggleButton.addEventListener(MouseEvent.CLICK, toggleClick3);
toggleButton.buttonState = "off";
function toggleClick3(event:MouseEvent) {
if (toggleButton.buttonState == "on") {
englyr.play();
toggleButton.buttonState = "off";
} else {
toggleButton.buttonState = "on";
englyr.stop();
}
}
I’m assuming I should put the other 2 languages as well as their lyric in englyr so that I can disable/mute languages that are not needed to be heard or seen. One problem is I can’t group the lyric and the narration(2 layers) together as a movie clip in that timeline. Therefore cannot disable the 2 other languages that shouldn’t be heard or seen. Any solutions?
It's probably easier to let them both play from code instead of via the timeline.
The first thing to do is to go to the settings of your audioclips in the library, enable "Export for Actionscript" and set a different class name for both your clips. I have named mine "english" and "french".
The following code manages two sounds and changes the language when you press the button of a language that is currently not playing.
var englishClip:Sound = new english(); //load both sounds.
var frenchClip:Sound = new french();
//create the sound and the sound channel.
var myChannel:SoundChannel = new SoundChannel();
var mySound:Sound = englishClip;
//if you want to have lots of different languages it might be easier to just have different buttons instead of one with a state.
englishButton.addEventListener(MouseEvent.CLICK, SpeakEnglish);
frenchButton.addEventListener(MouseEvent.CLICK, SpeakFrench);
//we'll start with having just the english sound playing.
myChannel = mySound.play();
function SpeakEnglish(event:MouseEvent) {
if (mySound != englishClip) { //if the english sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = englishClip.play(currentPlayPosition); //resume playing from saved position.
}
function SpeakFrench(event:MouseEvent) {
if (mySound != frenchClip) { //if the French sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = frenchClip.play(currentPlayPosition); //resume playing from saved position.
}
This could all be made more compact by having a single function that you pass the appropriate sound to. It would look something like this:
function SpeakEnglish(event:MouseEvent) {
ChangeSound(englishClip);
}
function SpeakFrench(event:MouseEvent) {
ChangeSound(frenchClip);
}
function ChangeSound(newSound:Sound){
if (mySound != newSound) { //if the sound is already playing, do nothing.
var currentPlayPosition:Number = myChannel.position; //save playback position.
myChannel.stop(); //stop playing
mySound = newSound.play(currentPlayPosition); //resume playing from saved
}
And that should solve the problem, i hope that helped :)
Resource: http://www.republicofcode.com/tutorials/flash/as3sound/

Play sound at certain playProgress or videoTime with greensock?

I'm using greensock LoaderMax to load video files and sound files. I've copied as much code as is available to me. A video (s9) is playing and at a certain percentage through the video, I need to play another sound.
if(s9.playProgress > .1) // This is what I can't get to work
{
s12_sound.playSound(); //This sound won't play at .1 playProgress
}
s9.content.visible = true;
s9.playVideo();
stop();
s9.addEventListener(VideoLoader.VIDEO_COMPLETE, play_s9_loop); //This plays a video once s9 is done.
function play_s9_loop(event:Event):void
{
s9.content.visible = false;
s9_loop.content.visible = true;
s9_loop.playVideo();
}
I'm guessing you just can't do an if() on playProgress? Furthermore, I suck at AS3.
You should be able to just listen for the INIT event on the video (which typically means it has loaded enough to determine the duration of the video) and then add an AS cue point.
//...after you create your VideoLoader...
myVideoLoader.addEventListener(LoaderEvent.INIT, initHandler);
myVideoLoader.load();
function initHandler(event:LoaderEvent):void {
myVideoLoader.addASCuePoint( myVideoLoader.duration * 0.1, "myLabel" );
myVideoLoader.addEventListener(VideoLoader.VIDEO_CUE_POINT, cuePointHandler);
}
function cuePointHandler(event:LoaderEvent):void {
trace("Hit the cue point " + event.data.name);
s12_sound.playSound();
}
Also make sure that you preload that s12_sound so that it's ready to play when you need it. Otherwise, you can call playSound() all you want and it ain't gonna happen :)
I haven't used this class before but after reading the docs it looks like you can do something like this:
http://www.greensock.com/as/docs/tween/com/greensock/loading/VideoLoader.html
var mid:Number = s9_loop.duration/2; //get the midpoint using the duration property
s9_loop.addASCuePoint(mid, "middle") //using addASCubePoint to add a cuepoint to the midpoint of the video
s9_loop.addEventListener(VideoLoader.VIDEO_CUE_POINT, handleMidpoint); //listen for the cuepoint
Inside the handler function
protected function handleMidpoint(e:Event):void{
//play your sound
}

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);
}