I am currently playing an audio file progressively like this:
import flash.media.Sound;
import flash.media.SoundLoaderContext;
import flash.net.URLRequest;
var s:Sound = new Sound();
var context:SoundLoaderContext = new SoundLoaderContext(5000, false);
s.load(new URLRequest('AUDIO URL'), context);
s.play();
which works great, but I want to know when it has enough data (based on the buffer time) and starts playing the file. To clarify, I am not trying to determine when the file has completely downloaded, I know that is done with Event.COMPLETE
How about using the ProgressEvent?
s.addEventListener(ProgressEvent.PROGRESS, progressHandler);
function progressHandler(event:ProgressEvent):void {
trace( event.bytesLoaded );
}
So when the bytesloaded is equal to the buffer amount, you know it.
Edit:
Perhaps you could check for the isBuffering attribute to see if the buffer is filled or not.
Related
So having trouble making sound on keyboard press
I have the imports:
import flash.net.URLRequest;
import flash.media.Sound;
I have the variables
private var soundDownRequest:URLRequest = new URLRequest ("SoundDown.mp3");
private var downSound:Sound = new Sound (soundDownRequest);
and the event listener
private function keyDownHandler(evt:KeyboardEvent):void
{
if (evt.keyCode == 40)//ascii for down arrow
{
downSound.play();
}
}
The sound folder is in the same folder as the .as, its also in the library of the fla, yet it still doesn't work. Any idea why?
Thank you.
Update:
I got the sound to work but not using the external method I was trying to do above.
Had to do it internally.
so you need:
import flash.media.SoundChannel;
-Then you need to make sure your sound file is in your fla library.
once its in the library
-Right click > properties
-Select the Action Script Tab
-Check "export for action script"
-Give the class a name in accordance to the sound
-press ok
add this variable (your will be different):
private var downSound:TheDownSound = new TheDownSound();
downsound is the selected name of the variable, and TheDownSound is the name of the class (the one made earlier for the sound file)
then add this to where you want the sound to play:
var myDownSound:SoundChannel = downSound.play();
Do this if you cant get it working externally like me.
for a better explanation watch this guys youtube video:
https://www.youtube.com/watch?v=SZpwppe7yGs
Your code is working perfectly ok if you put your .mp3 file in the same folder as the output .swf, not near the class .as source file (because its the swf file loading the sound, so the path must be relative to it)
public class ASEntryPoint extends Sprite {
private var soundDownRequest:URLRequest = new URLRequest ("click.mp3");
private var downSound:Sound = new Sound (soundDownRequest);
public function ASEntryPoint() {
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}
private function keyDownHandler(evt:KeyboardEvent):void{
if (evt.keyCode == 40) {
downSound.play();
}
}
}
You need to load the external file, which is asynchronous operation. Then you track the loading event and if it all goes normally you can play your loaded sound.
import flash.events.SecurityErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.media.SoundChannel;
// Keep the sound loader from being garbage collected.
var soundLoader:Sound;
function loadSound(url:String):void
{
var aRequest:URLRequest = new URLRequest(url);
soundLoader = new Sound();
// Handle the normal loading.
soundLoader.addEventListener(Event.COMPLETE, onLoaded);
// Handle the error cases.
soundLoader.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
soundLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError, false, 0, true);
soundLoader.load(aRequest);
}
var audioChannel:SoundChannel;
function onLoaded(e:Event):void
{
// Sound is available here for playback.
audioChannel = soundLoader.play();
}
function onError(e:Event):void
{
trace(e);
}
You can also handle your sound as a streaming audio, but I worked with that years ago in AS2 so I cannot help here. Still, internet suggests a link: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d22.html
I have a WAV music file that I want to loop in Flash Pro. However, I am not sure how to work with this track, which has an opening part and a looping part.
The audio file would be 'divided' in three points: A, B and C. The looping part would be all the audio between points B and C, while the audio between A and B would be the opening part, which would be played only once.
I tried to divide the WAV into two files: A-B would be the intro file, and the B-C the looping file, so that right after the intro sound finishes, the looping sound begins.
Both files are on the library (right now I'm only focusing on local files).
To summarize, here's the AS3 code:
import flash.media.Sound;
import flash.events.Event;
import flash.media.SoundChannel;
var introMusic:Sound = new heroIntro();
var loopingMusic:Sound = new heroLoop();
var musicChannel:SoundChannel = new SoundChannel();
musicChannel = introMusic.play();
musicChannel.addEventListener(Event.SOUND_COMPLETE,continueMusic);
function continueMusic(e:Event):void{
musicChannel.removeEventListener(Event.SOUND_COMPLETE,continueMusic);
musicChannel= introMusic.play();
musicChannel.addEventListener(Event.SOUND_COMPLETE,continueMusic);
}
The loop is completely gapless, but the transition between the intro and the looping parts makes an annoying gap sound. How could I make that transition gapless?
You might be able to avoid the gap sound by playing the 2nd Sound in a different SoundChannel a second or so before the 1st Sound finishes playing. It's not an elegant solution, but it might work. Perhaps something like this:
import flash.media.Sound;
import flash.events.Event;
import flash.media.SoundChannel;
var introMusic:Sound = new heroIntro();
var loopingMusic:Sound = new heroLoop();
var introChannel:SoundChannel = new SoundChannel();
var loopingChannel:SoundChannel = new SoundChannel();
var hasBegunLooping:Boolean = false;
introChannel = introMusic.play();
function update():void{ //called every tick
if(!hasBegunLooping && introChannel.position > introMusic.length - 1000){
loopingChannel = loopingMusic.play(0, int.MAX_VALUE);
hasBegunLooping = true;
}
}
I'm currently working on a project in flashdevelop and I want to include some music. I'm building a game, so multiple files are not an option. Currently all resources are embedded and a simple preloader loads everything (like the flashdevelop default preloader).
I don't want to load the music at the beginning, I'd rather like to stream it when required.
Is it possible to stream embedded sounds?
If not, is it possible to embed these files inside the .swf file and load them later on?
Thanks in advance!
You can do two things. One is to start loading the sounds after the initial loading finishes and save them in a Dictionary maybe. Second is to export a RSL (Runtime Shared Library) from Flash which is a SWF file which you can then load and have access to all the classes defined there.
In the first approach you basically load every sound like this and save them to dictionary:
import flash.media.Sound;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.Dictionary;
var mSounds:Dictionary = new Dictionary();
function loadSound(url:String, soundName:String)
{
var sound:Sound = new Sound();
sound.addEventListener(Event.COMPLETE, onSoundLoadComplete);
sound.load(new URLRequest(url));
function onSoundLoadComplete(e:Event):void
{
sound.removeEventListener(Event.COMPLETE, onSoundLoadComplete);
trace(soundName,"Sound Loaded");
mSounds[soundName] = sound; // save it to dictionary
// then you can load it from dictionary
// using the name you assigned
if(mSounds["crystalised"])
(mSounds["crystalised"] as Sound).play();
}
}
loadSound("C:\\Users\\Gio\\Desktop\\Crystalised.mp3", "crystalised");
In the second approach you have to do more steps, but you load it once. I'll list the steps here:
Make a new Flash Document (FLA)
Import all the sounds you need to the library
In the properties menu of each sound select the Actionscript tab and tick the Export for Runtime Sharing checkbox and fill in the name for output SWF
After you publish this FLA you can load it in your application or game and use it like this:
import flash.display.Loader;
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.events.Event;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.utils.getDefinitionByName;
function loadRSL(url:String):void
{
var loader:Loader = new Loader();
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onRSLLoadComplete);
loader.load(new URLRequest(url), context);
function onRSLLoadComplete(e:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onRSLLoadComplete);
trace("RSL Loaded");
// creating a new instance of the sound which is defined in RSL
var soundClass:Class = getDefinitionByName("Crystalised") as Class;
var sound:Sound = (new soundClass() as Sound);
sound.play();
}
}
loadRSL("SoundLibrary.swf");
This my first time using StackExchange so I apologize if I miss anything.
I am trying to create a AS3 Flash that will record a video using a webcam and RED5 media server; I am stuck (I am not a programmer, more of a computer handyman that does everything).
The example that comes with RED5 works fine (though is in AS2 and I could not, for some reason, make certain things I need to do work), but my code doesnt seem to record the stream as there is not file, the RED5 console only says:
[INFO] [NioProcessor-3] org.red5.server.adapter.ApplicationAdapter - File lecture.flv was deleted
here is the code so far. (updated 09/07/12)
import flash.display.Sprite;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Camera;
import flash.events.MouseEvent;
import flash.media.Microphone;
import flash.events.*;
import flash.media.Video;
var _cam:Camera
var _mic:Microphone
// create basic netConnection object
var _nc:NetConnection = new NetConnection();
_nc.client = this
// connect to the local Red5 server
_nc.connect("rtmp://localhost/myapp");
_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
//Add listeners for buttons
record_btn.addEventListener( MouseEvent.CLICK, recordvid );
stop_btn.addEventListener( MouseEvent.CLICK, stopvideo );
//submit_btn.addEventListener( MouseEvent.CLICK, onSubmit );
//Listeners
function netStatusHandler(event:NetStatusEvent):void{
trace("start netstatus handler");
if (event.info.code == "NetConnection.Connect.Success"){
attachCamera();
}
}
function attachCamera(e:Event = null):void {
trace("attach");
//Attach Camera to field
_cam=Camera.getCamera();
_mic=Microphone.getMicrophone()
vid.attachCamera(_cam);
}
function stopvideo(e:MouseEvent):void {
//_ns.close();
}
function recordvid(e:MouseEvent):void {
var _ns:NetStream = new NetStream(_nc);
trace("publish");
_ns.attachCamera(_cam);
_ns.attachAudio(_mic);
_ns.publish("lecture", "record");
}
You have to connect & wait for the successful status before publishing the stream.
For Example :
var nc:NetConnection = new NetConnection();
nc.connect("rtmp://fms.example.com/lectureseries");
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(event:NetStatusEvent):void{
if (event.info.code == "NetConnection.Connect.Success"){
var ns:NetStream = new NetStream(nc);
ns.publish("lecture", "record");
}
}
Have a look at the Netstream documentation to learn more.
I just found the answer thru extreme googleing, I needed to declare the Netstream variable outside the function; otherwise the "publish" video was "empty" as the garbage collector was destroying my variable at some point.
so outside a function I declare
var _ns:NetStream;
and inside the function I declare:
function recordvid(e:MouseEvent):void {
_ns = new NetStream(_nc);
_ns.attachCamera(_cam);
_ns.attachAudio(_mic);
_ns.publish("lecture", "record");
Awesomely enough, I found the answer right here in stackoverflow
I'm having a lot of trouble getting the total sample length of an mp3.
Also, when I load in the mp3 it does not play all the way through. It plays about half of it's length.
The mp3 I'm testing can be found here, http://bit.ly/GYSOYj.
The code I'm using to play the sound is:
[Embed(source='assets/ffmangun_loop_79393.mp3')]
private var _snd_class:Class;
private var sound:Sound = new _snd_class as Sound;
protected function application1_creationCompleteHandler(event:FlexEvent):void {
sound.length; // 600;
sound.bytesTotal;// 44652
soundChannel = sound.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE, soundComplete);
}
Update:
It was suggested that I load the MP3 instead of embed it. The result is the MP3 plays the full length and the length and the bytes total are now different numbers.
// embedded values
bytes total = 44652
sound length = 600.8163265306122
// load dynamic values
bytes total = 44678
sound length = 1776.3265306122448
Update
This needs to be determined at runtime.
Firstly, "total samples" != sound.bytesLoaded != sound.length. They are all quite different.
In the code below I've included some other Event listeners to try to illustrated the differences. Listening for 'Event.SOUND_COMPLETE' won't tell you much, first off because it'll only fire when the sound has stopped playing, and secondly because it's been proven to be very unreliable. Using Event.OPEN also doesn't tell you much, as the file hasn't started loading yet, and no info can be retrieved or calculated.
You can either use a ProgressEvent or an EnterFrame event to monitor the loading of the Sound and read the length property, but to determine the total samples you'll also need to know what sample rate was used to create the MP3 and whether it's stereo or mono. Once you know these things, you can easily get the sample length of the file by multiplying the length by the sample rate.
Hopefully this usage example helps -
import flash.net.URLRequest;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
var sound:Sound;
var soundChannel:SoundChannel;
var sampleRate:Number = 44.1;
var totalSamples:int;
init();
function init( ):void {
sound = new Sound();
sound.load( new URLRequest( "http://bit.ly/GYSOYj") );
sound.addEventListener( Event.OPEN, soundOpen );
sound.addEventListener( Event.COMPLETE, soundComplete );
soundChannel = sound.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE, scComplete);
}
function soundOpen( e:Event ):void{
trace( "OPEN:", sound.length );
}
function soundComplete( e:Event ):void{
trace( "COMPLETE:", sound.length );
totalSamples = sound.length * sampleRate;
trace( "SAMPLES", totalSamples);
}
function scComplete( e:Event):void{
trace( "sound is complete" );
}
edit: as suggested, one could use as3swf ( bit.ly/HdhVcW ) - but only you can decide if it's worth it or not. Can't imagine what you are trying to build that would require all this..