How to seamlessly loop Video in Adobe Flash? - html

I import the video to the stage (name it flvControl), set autoPlay to true and then I am trying the following code that is supposed to do the job, but it doesn't work.
function completeHandler(event:fl.video.VideoEvent):void
{
flvControl.play();
}
flvControl.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
When you test movie in Flash, it has half a second white screen flicker in between playbacks, but when you test in a browser (mine is Chrome) not only there is a flicker in between, on subsequent playthroughs video seems to freeze for about 1-2 seconds and then starts to play from about 1-2 seconds down the video. Which essentially makes looping completely unplayable.
Does anyone know how to make video loop seamlessly in Flash? (And to look seamless in browser too?)

The only way I've found to seamlessly loop video is to load the entire clip into memory ByteArray and then use the appendBytes function of a NetStream connected to a Video instance.
Here is a very basic helper class
package
{
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamAppendBytesAction;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.utils.setTimeout;
/**
* #author Michael Archbold (ma#distriqt.com)
*/
public class AppendByteVideoLoop
{
public function AppendByteVideoLoop(video:Video, data:ByteArray):void
{
_video = video;
connect(data);
}
private var _video:Video;
private var _connection:NetConnection;
private var _stream:NetStream;
private var _byteArray:ByteArray;
private var _timer:Timer;
private var _paused : Boolean = false;
public function get paused():Boolean { return _paused; }
public function play():void
{
if (_stream)
_stream.resume();
}
public function pause():void
{
if (_stream)
_stream.pause();
}
public function togglePause():void
{
if (_stream)
_stream.togglePause();
}
private function connect(byteArray:ByteArray):void
{
_byteArray = byteArray;
_connection = new NetConnection();
_connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
_connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
_connection.connect(null);
}
private function addToStream():void
{
_stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
_stream.appendBytes(_byteArray);
}
public function onMetaData(metaData:Object):void
{
// _video.width = metaData.width;
// _video.height = metaData.height;
}
public function onXMPData(xmp:Object):void
{
}
public function onPlayStatus(status:Object):void
{
}
private function connectStream():void
{
_stream = new NetStream(_connection);
_stream.client = this;
_stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
_stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
_video.attachNetStream(_stream);
_stream.play(null);
_stream.appendBytes(_byteArray);
_stream.pause();
}
private function netStatusHandler(event:NetStatusEvent):void
{
trace(event.info.code);
switch (event.info.code)
{
case "NetConnection.Connect.Success":
connectStream();
break;
case "NetStream.Play.StreamNotFound":
trace( "Unable to locate video " );
break;
case "NetStream.Pause.Notify":
_paused = true;
break;
case "NetStream.Unpause.Notify":
_paused = false;
break;
case "NetStream.Buffer.Empty":
addToStream();
break;
case "NetStream.Buffer.Full":
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void
{
trace( "securityErrorHandler: " + event.text );
}
private function asyncErrorHandler(event:AsyncErrorEvent):void
{
trace( "asyncErrorHandler: " + event.error.message );
}
}
}
And then use it something like this:
var video:Video = new Video();
video.smoothing = false;
if (stage)
{
video.width = stage.stageWidth;
video.height = stage.stageHeight;
}
addChild( video );
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener( Event.COMPLETE, loader_completeHandler, false, 0, true );
loader.addEventListener( IOErrorEvent.IO_ERROR, loader_ioErrorHandler, false, 0, true );
loader.load( new URLRequest( "URL_OF_VIDEO" ) );
...
function loader_completeHandler( event:Event ):void
{
var data:ByteArray = ByteArray( loader.data );
var player:AppendByteVideoLoop = new AppendByteVideoLoop( _video, _data );
player.play();
}
Hope that helps.

Related

Object Loading Issue

I am developing an application that consists of several different objects working together. Everything seems to work great, however, when I play this on a web server I notice the graphics and assets that are being loaded in from an external source are taking some time to load I'm not really sure what is going on I was hoping someone might provide some insight. Example, sometimes the graphic assets will not load at all, but audio seems to be loading in ok. Here is an example of my image loading class:
GFXReg.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.display.Sprite;
import flash.text.TextField;
public class GFXReg extends Sprite {
private var mc: MovieClip = new MovieClip();
private var loader: Loader = new Loader();
private var setW: Number;
public var setH: Number;
public var theH: Number;
private var bool: Boolean = false;
public function GFXReg(setSize: Boolean, W: Number, H: Number) {
bool = setSize;
if (bool) {
setW = W;
setH = H;
}
}
private function loadData(e: Event) {
if(loader.contentLoaderInfo.bytesLoaded == loader.contentLoaderInfo.bytesTotal){
addChild(loader);
}else{
var text:TextField = new TextField();
text.text = "Loading..."
addChild(text);
}
if (bool) {
loader.width = setW;
loader.height = setH;
}
}
public function theData(file: String): void {
loader.load(new URLRequest(file));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadData);
}
public function getBytes(str:String):int{
var num:int = 0;
switch(str){
case "loaded":
num = loader.contentLoaderInfo.bytesLoaded;
break;
case "total":
num = loader.contentLoaderInfo.bytesTotal;
break;
}
return num;
}
public function removeData():void{
loader.unloadAndStop(false);
trace("unload?");
}
private function unloadData(e:Event):void{
}
}
}
Main.as Sections(This loads in all the appropriate sections when prompted):
public function Main() {
xmlLoader = new XMLReg("config.xml", processXML);
}
private function processXML(e: Event): void {
theXML = new XML(e.target.data);
dir = theXML.MASTER.#DIRECTORY;
//BACKGROUND
bgGFX.theData(dir + theXML.MAINBG.#IMG);
//INITIALIZE
add(bgGFX,intro);
//INTRO WAS INSTANTIATED IN THE BEGINNING OF THIS CLASS
intro.start();
/*start method adds objects to stage, to test as a solution*/
addChildAt(header, numChildren);
//...
Also in my Main.as class I have a private method transition which loads in the appropriate sections after the previous sections have been completed these assets usually take a few seconds to load in I've noticed when working on a web server.
private function transition(e: Event): void {
//If intro is on the stage instantiate a new QuestionAnswer Object
if (intro.stage) {
header.enableMenu(true);
qa = new QuestAnswer(feedBool,nameCounter,nameVar);
qa.addEventListener("unload", transition);
qa.addEventListener("addFeed", setFeedFalse);
qa.addEventListener("addFeedTrue", setFeedTrue);
qa.addEventListener("enableHelp",enableHelp);
qa.addEventListener("getName",getName);
addChildAt(qa, numChildren-1);
remove(intro);
} else if (qa.stage) {
//If QuestionAnswer is on the Stage instantiate a new Results Object
header.enableMenu(true);
header.enableHelp(false);
results = new Results(qa.resultBundle());
results.addEventListener("unload", transition);
results.addEventListener("addFeed", setFeedFalse);
results.addEventListener("addFeedTrue", setFeedTrue);
results.addEventListener("setName",setName);
addChildAt(results, numChildren-1);
remove(qa);
} else if (results.stage) {
//If Results is on the stage loop back and instantiate a new QuestionAnswer Object
header.enableMenu(true);
header.enableHelp(false);
intro.enableAsset(true);
qa = new QuestAnswer(feedBool,nameCounter,nameVar);
qa.addEventListener("unload", transition);
qa.addEventListener("addFeed", setFeedFalse);
qa.addEventListener("addFeedTrue", setFeedTrue);
addChildAt(qa, numChildren-1);
trackAsset = true;
remove(results);
}
}

Starling not displaying graphic

Hi guys i am new to AS3 and to Starling i am having problem displaying an image in a different class. it does show on my game menu class but i wanted it to show on my play game class.
so i got 3 classes Main that starts the starling that runs GameMenu class.
"GameMenu class"
package {
import starling.display.BlendMode;
import starling.display.Button;
import starling.display.Image;
import starling.display.Sprite;
import starling.events.Event;
public class GameMenu extends Sprite {
private var bg:Image;
private var gameLogo:Image;
private var playBtn:Button;
private var rankBtn:Button;
private var settingBtn:Button;
private var inGame:PlayGame;
public function GameMenu ()
{
super ();
this.addEventListener (Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage (event:Event):void
{
this.removeEventListener (Event.ADDED_TO_STAGE, onAddedToStage);
drawScreen ();
}
private function drawScreen ():void
{
bg = new Image(Assets.getAtlas().getTexture(("Background.png")));
bg.blendMode = BlendMode.NONE;
this.addChild(bg);
gameLogo = new Image(Assets.getAtlas().getTexture(("GameLogo.png")));
gameLogo.x = stage.stageWidth/2 - gameLogo.width/2;
gameLogo.y = 30;
this.addChild(gameLogo);
playBtn = new Button(Assets.getAtlas().getTexture("PlayBtn.png"));
playBtn.x = stage.stageWidth/2 - playBtn.width/2;
playBtn.y = 450;
playBtn.addEventListener(Event.TRIGGERED, onPlayClick);
this.addChild(playBtn);
rankBtn = new Button(Assets.getAtlas().getTexture("RankBtn.png"));
rankBtn.x = rankBtn.bounds.left + 60;
rankBtn.y = 600;
rankBtn.addEventListener(Event.TRIGGERED, onRankClick);
this.addChild(rankBtn);
settingBtn = new Button(Assets.getAtlas().getTexture("SettingBtn.png"));
settingBtn.x = settingBtn.bounds.right + 60;
settingBtn.y = 600;
settingBtn.addEventListener(Event.TRIGGERED, onSettingClick);
this.addChild(settingBtn);
}
private function onRankClick (event:Event):void
{
trace("LEADERBOARD BUTTON HIT")
}
private function onSettingClick (event:Event):void
{
trace("SETTING SCREEN BUTTON HIT")
}
private function onPlayClick (event:Event):void
{
playBtn.removeEventListener(Event.TRIGGERED, onPlayClick);
trace("PLAY BUTTON HIT")
gameLogo.visible = false;
playBtn.visible = false;
rankBtn.visible = false;
settingBtn.visible = false;
//bg.visible = false;
inGame = new PlayGame();
}
}
}
this class works perfectly now.
"PlayGame class"
package {
import starling.display.Image;
import starling.display.Sprite;
import starling.events.Event;
public class PlayGame extends Sprite
{
private var bubble:Image;
public function PlayGame ()
{
trace("PlayGame");
super ();
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage2);
}
private function onAddedToStage2 (event:Event):void
{
trace("OnAddedToStage");
this.removeEventListener (Event.ADDED_TO_STAGE, onAddedToStage2);
drawScreen ();
}
public function drawScreen ():void
{
trace("Bubble");
bubble = new Image(Assets.getAtlas().getTexture(("Bubble.png")));
bubble.x = 100;
bubble.y = 100;
this.addChild(bubble);
}
}
}
the bubble image is now showing and i don't know why?
They are too much parenthesis, but this is not your issue
bubble = new Image(Assets.getAtlas().getTexture(("Bubble.png")));
//is less clean/readable than
bubble = new Image(Assets.getAtlas().getTexture("Bubble.png"));
When facing this kind of issues, if starling/air doesn't report any errors, you should try to be sure the display object are currently rendered.
Try to apply a color instead of the texture.
bubble = new Image( Texture.fromColor(64,64,0xff99ff) );
If this code shows a fancy rectangle of 64 pixel/side, you trouble come from your texture atlas or texture. Be sure to have a valided atlas, validates frames, and names.
If this code doesn't show the facy rectangle, your issue doesn't come from the texture atlas or texture, but more possibly from the display list of starling.
And in your case,
I think you should just need to addChild the Ingame in your GameMenu class :
GameMenu :
private function onPlayClick (event:Event):void
{
//... your stuff
inGame = new PlayGame();
this.parent.addChild(inGame);
}
And it should works.

as3 addEventListner on a function in another class

I have a class calling a function in another class. I want to know
if we can add an Event Listener to know if that function has fired and is finished etc.
Here is the section of the code that is relevant.
myMC = new pictures();
addChild(myMC);
myMC.loadImages("Joyful",1)
// Add Event Listener here to let me know loadImages was called and worked.
As you can see the function is called loadImages() and it is located in a class called pictures.as
Can I add an event listener to this?
Here is a new issue. I am using a similar method and I used your example below and it did not work. Am I missing an import or something? I am only showing the functions that pertain and not my whole script.
Main.class
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import flash.filesystem.*;
import com.greensock.*;
import com.greensock.easing.*;
import flash.system.System;
// Ed's Scripts
import com.*;
import com.views.*;
public class iRosaryMain extends MovieClip
{
/// (Get Main Doc flow) this creates an instace of the main timeline
/// and then I send it
private static var _instance:iRosaryMain;
public static function get instance():iRosaryMain
{
return _instance;
}
/// Declaring Vars
var audio:audioPrayers;
/// Loading Images
//public var theImages:pictures = new pictures();
/// Movie Clips
public var myMary:beautifulMary;
public var myMC:MovieClip;
public var myPic:MovieClip;
public var myFlags:MovieClip;
public static var mt:MovieClip;
var vars:defaultVars = new defaultVars();
public function iRosaryMain()
{
// (Get Main Doc flow) Here I send the an instacne of iRosaryMain to defaultVars.as
_instance = this;
vars.getMainDoc(_instance);
// Sets timeline to mt :) I hope
mt = _instance;
audio = new audioPrayers();
trace("Jesus I trust in you!");// constructor code
audio.sayHailMary();
if (stage)
{
init();
}
}
public function moveLanguages()
{
/// File to languages folder
var checkLanguageFolder:File = File.applicationStorageDirectory.resolvePath("Languages");
///// CHECK LANGUAGES FOLDER - if not in App Storage move it
if (! checkLanguageFolder.exists)
{
var sourceDir:File = File.applicationDirectory.resolvePath("Languages");
var resultDir:File = File.applicationStorageDirectory.resolvePath("Languages");
sourceDir.copyTo(resultDir, true);
trace( "Moved Language!");
}
}
//// MAIN FUNCTIONS IN iRosaryMainClass
function init()
{
//loadFlags();
moveLanguages();
//addChild(theImages);
intro();
}
public function loadFlags()
{
myFlags.addEventListener("MyEvent", eventHandler);
myFlags = new viewLanguages();
addChild(myFlags);
myFlags.x = stage.stageWidth / 2 - myFlags.getBounds(this).width / 2;
function eventHandler()
{
trace("yes loaded");
TweenMax.fromTo(myMary,3, {alpha:1}, {alpha:0, ease:Quint.easeOut, onComplete: closePic} );
}
}
function intro()
{
myMary = new beautifulMary();
addChild(myMary);
loadFlags();
}
public function closePic()
{
removeChild(myMary);
}
public function languageLoaded(lang:String)
{
trace("YES... " + lang);
homeIn();
}
public function homeIn()
{
if (myFlags)
{
TweenMax.fromTo(myFlags,1, {x:myFlags.x}, {x:0-myFlags.width, ease:Quint.easeInOut, onComplete:unloadMyFlags} );
}
function unloadMyFlags()
{
trace("Called Ease out");
if (myFlags is MovieClip)
{
//trace("CURRENT DISPLAY " + currentDisplayScreen);
trace("CURRENT mc " + myFlags);
removeChild(myFlags);
System.gc();
myFlags = null;
trace("CURRENT mc " + myFlags);
}
}
if (! myMC)
{
myMC = new viewHome();
myMC.name = "Home";
myMC.x = stage.stageWidth / 2 - myMC.width / 2;
addChild(myMC);
}
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
public function loadLanguage(Language:String):Function
{
return function(e:MouseEvent):void ;
{
trace("Did it work? " +Language);
vars.loadButtonVars(Language);;
};
//TweenMax.fromTo(EnglishButton,1, {x:EnglishButton.x}, {x:0-EnglishButton.width, ease:Quint.easeOut} );
}
public function loadView(screen:String)
{
trace("Received " + screen);
if (screen=="Home")
{
myMC = new viewHome();
addChild(myMC);
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
if (screen=="PrayTheRosary")
{
myMC = new viewPrayTheRosary();
addChild(myMC);
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
if (screen=="Options")
{
myMC = new viewOptions();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="Downloads")
{
myMC = new viewDownloads();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="beautifulMary")
{
myMC = new beautifulMary();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="Flags")
{
myFlags = new viewLanguages();
addChild(myFlags);
theEaseIn(myFlags);
}
if (screen=="Joyful" || screen=="Sorrowful" || screen=="Glorious" || screen=="Luminous")
{
myPic = new pictures();
addChild(myPic);
myPic.addEventListener( "ImagesLoaded", doTheEaseIn);
myPic.loadImages(""+screen+"",1);
function doTheEaseIn()
{
theEaseIn(myPic);
}
}
}
public function theEaseIn(mc:MovieClip)
{
if (myMC)
{
TweenMax.fromTo(mc,1, {x:stage.stageWidth+mc.width}, {x:stage.stageWidth/2 - mc.width/2, ease:Quint.easeInOut} );
}
}
public function theEaseOut(mc:MovieClip,nextMC:String):Function
{
return function(e:MouseEvent):void ;
{
loadView(nextMC);
/// Tweens out view on screen
TweenMax.fromTo(mc,1, {x:mc.x}, {x:0-mc.width, ease:Quint.easeInOut, onComplete:unloadMC} );
function unloadMC();
{
trace("Called Ease out");
if(mc is MovieClip);
{
//trace("CURRENT DISPLAY " + currentDisplayScreen);
trace("CURRENT mc " + mc);
removeChild(mc);
System.gc();
myMC = null;
trace("CURRENT mc " + mc);
};
};
};/// end return
}
////////////
}/// End iRosaryMain
}// End Package
viewLanguages.as
package com.views
package com.views
{
import flash.display.MovieClip;
import flash.filesystem.File;
import com.roundFlag;
import flash.events.*;
import flash.display.*;
public class viewLanguages extends MovieClip
{
var Flag:MovieClip;
//public static const FLAGS_LOADED:String = "flagsLoaded";
public function viewLanguages()
{
getLang();
}
function numCheck(num:int):Boolean
{
return (num % 2 != 0);
}
/// Get for App Opening
public function getLang()
{
/// When Live
var folderLanguages:File = File.applicationStorageDirectory.resolvePath("Languages");
var availLang = folderLanguages.getDirectoryListing();
var Lang = new Array();
var LangPath = new Array();
var fl:int = 0;
for (var i:uint = 0; i < availLang.length; i++)
{
if (availLang[i].isDirectory)
{
//flag = new Loader();
//flag.load(new URLRequest(File.applicationStorageDirectory.url + "Languages/" + Lang[i] + "/roundFlag.png"));
Lang.push(availLang[i].name);
LangPath.push(availLang[i].nativePath);
Flag = new roundFlag(availLang[i].name);
Flag.name = availLang[i].name;
if (numCheck(i)==false)
{
Flag.y = fl;
Flag.x = 0;
}
else
{
Flag.y = fl;
Flag.x = Flag.width + 33;
fl = fl + Flag.height + 33;
}
Flag.btext.text = availLang[i].name;
addChild(Flag);
trace(availLang[i].nativePath);// gets the name
trace(availLang[i].name);
}
}
trace("Get Lang Called");
dispatchEvent(new Event("MyEvent"));
}
}
}
Yes, you can. Considering you are adding your clip to the display list I assume it extends either Movieclip or Sprite, both of which extend EventDispatcher. In your pictures class you can simply use dispatchEvent(new Event("MyEvent"); to dispatch an event. Then you could add myMC.addEventListener("MyEvent", eventHandler); to react to it.
You should also not use strings for events like I wrote above. It would be better if you declared a public static const IMAGES_LOADED:String = "imagesLoaded"; in your pictures class. Then you should use this constant by dispatching and by listening to it.
EDIT: Here how it would look with the constant:
//your class
package {
import flash.events.Event;
import flash.display.Sprite;
public class Pictures extends Sprite {
public static const IMAGES_LOADED:String = "imagesLoaded";
public function Pictures() {
}
public function onAllImagesLoaded():void {
dispatchEvent(new Event(IMAGES_LOADED));
}
//rest of your methods
}
}
//you would call it like this:
var myMc:Pictures = new Pictures();
myMc.addEventListener(Pictures.IMAGES_LOADED, onImagesLoaded);
myMc.loadImages();
function onImagesLoaded(e:Event):void {
//...etc
}
You have to create custom event class for this to work. Like:
package com.some
{
import flash.events.Event;
public class SomeEvent extends Event
{
// Loading events
public static const MAINDATA_LOADING:String = "onMainDataLoading";
// Other event
public static const SOME_LOADING:String = "onSomeLoading";
public var params:Object;
public function SomeEvent($type:String, $params:Object, $bubbles:Boolean = false, $cancelable:Boolean = false)
{
super($type, $bubbles, $cancelable);
this.params = $params;
}
public override function clone():Event
{
return new SomeEvent(type, this.params, bubbles, cancelable);
}
}
}
Add event dispatch inside wanted class (Pictures) and pass wanted params to event (this or any else)
dispatchEvent(new SomeEvent(SomeEvent.IMAGES_LOADED, this));
Handle event listening:
var myMc:Pictures = new Pictures();
myMc.addEventListener(SomeEvent.IMAGES_LOADED, onImagesLoaded);
myMc.loadImages();
function onImagesLoaded(e:SomeEvent):void {
// handle event.
var picts:Pictures = (e.params as Pictures);
}

Record Sound Using AS3 Worker

Hello I am trying to record the user sound using AS3 Worker everything works well when it comes to communication between the worker and the main scene but I think the record functionnality have and issue here I am using the Record Clash from bytearray.org (http://www.bytearray.org/?p=1858)
and here's is my code am I missing something :
package objects
{
import flash.events.Event;
import flash.system.MessageChannel;
import flash.system.Worker;
import flash.system.WorkerDomain;
import flash.utils.ByteArray;
import starling.display.Button;
import starling.display.Image;
import starling.display.Sprite;
import starling.events.Event;
public class RecordComponent extends Sprite
{
private var audioContainer:Image;
private var recButton:Button;
private var playButton:Button;
private var stopButton:Button;
//background thread for recording
private var worker:Worker;
private var wtm:MessageChannel;
private var mtw:MessageChannel;
private var output:ByteArray;
public function RecordComponent()
{
super();
worker = WorkerDomain.current.createWorker(Workers.RecordWorker);
wtm = worker.createMessageChannel(Worker.current);
mtw = Worker.current.createMessageChannel(worker);
worker.setSharedProperty("wtm",wtm);
worker.setSharedProperty("mtw",mtw);
worker.start();
wtm.addEventListener(flash.events.Event.CHANNEL_MESSAGE,onChannelMessage);
this.addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
}
protected function onChannelMessage(event:flash.events.Event):void
{
output = wtm.receive();
}
protected function onAddedToStage(event:starling.events.Event):void
{
this.removeEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
drawScreen();
}
private function drawScreen():void
{
audioContainer = new Image( Assets.getAtlas().getTexture("audioContainer") );
addChild(audioContainer);
//record button
recButton = new Button( Assets.getAtlas().getTexture("recordButton") );
recButton.x=Math.ceil(194/2 - recButton.width/2);
recButton.y=5;
addChild(recButton);
//stop button
stopButton = new Button( Assets.getAtlas().getTexture("stopButton") );
stopButton.x=recButton.x+10;
stopButton.y=10;
stopButton.visible = false;
addChild(stopButton);
//play button
playButton = new Button( Assets.getAtlas().getTexture("playButton") );
playButton.x=Math.ceil(194 - playButton.width)-25;
playButton.y=10;
playButton.visible = false;
addChild(playButton);
this.addEventListener(starling.events.Event.TRIGGERED, buttons_triggeredHandler);
}
private function buttons_triggeredHandler(event:starling.events.Event):void
{
var currentButton:Button = event.target as Button;
switch(currentButton)
{
case recButton:
startRecording();
break;
case stopButton:
stopRecording();
break;
case playButton:
playRecording();
break;
}
}
private function playRecording():void
{
mtw.send("RECORD_PLAY");
}
private function stopRecording():void
{
stopButton.visible = false;
recButton.x = 25;
playButton.visible = true;
recButton.visible = true;
mtw.send("RECORD_STOP");
//
}
private function startRecording():void
{
recButton.visible = false;
stopButton.visible = true;
playButton.visible = false;
mtw.send("RECORD_START");
}
}
}
RecordWorker
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.media.Microphone;
import flash.system.MessageChannel;
import flash.system.Worker;
import org.as3wavsound.WavSound;
import org.bytearray.micrecorder.MicRecorder;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import org.bytearray.micrecorder.events.RecordingEvent;
public class RecordWorker extends Sprite
{
private var wtm:MessageChannel;
private var mtw:MessageChannel;
// volume in the final WAV file will be downsampled to 50%
private var volume:Number = .75;
// we create the WAV encoder to be used by MicRecorder
private var wavEncoder:WaveEncoder = new WaveEncoder( volume );
// we create the MicRecorder object which does the job
private var recorder:MicRecorder = new MicRecorder( wavEncoder,Microphone.getEnhancedMicrophone() );
public function RecordWorker()
{
wtm = Worker.current.getSharedProperty("wtm");
mtw = Worker.current.getSharedProperty("mtw");
mtw.addEventListener(Event.CHANNEL_MESSAGE,command_Handler);
}
//message received from the main component
protected function command_Handler(event:Event):void
{
switch(mtw.receive())
{
case "RECORD_START":
trace("recording.....");
recorder.record();
recorder.addEventListener(RecordingEvent.RECORDING, onRecording);
recorder.addEventListener(flash.events.Event.COMPLETE, onRecordComplete);
break;
case "RECORD_STOP":
trace("record stopped....");
recorder.stop();
break;
case "RECORD_PLAY":
if(recorder.output.length>0)
{
var player:WavSound = new WavSound(recorder.output);
player.play();
}
break;
}
}
private function onRecording(event:RecordingEvent):void
{
trace ( event.time );
}
private function onRecordComplete(event:flash.events.Event):void
{
}
}
}
anny help will be appriciated
Thanks,
Khaled
Looking at this write-up on Adobe's AS3 reference, it seems that because each created worker is "a virtual instance of the Flash runtime", it has no direct connection to any of the core runtime's input or output channels. The Microphone class is one such cut-off interface, which is why it can't reach the system mic inside a worker.

sound stream stops loading

I have a little sound stream script here, but sometimes if you press play to the next track before the current has done loading the next track doesn't comeplete loading
package player {
import flash.events.Event;
import flash.display.Sprite;
import flash.external.ExternalInterface;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import player.Loader_bar;
public class Stream extends Sprite {
private var _Sound = null;
private var _Channel = null;
private var isLoading = false;
private var _Loader_bar = null;
public var loader_color = null;
public var loader_width = 0;
public var loader_height = 0;
private var i = 0;
public function Stream(){
this._Loader_bar = new Loader_bar();
addChild(this._Loader_bar);
}
public function cnstr(){
this._Loader_bar.color = this.loader_color;
this._Loader_bar.w = this.loader_width;
this._Loader_bar.h = this.loader_height;
this._Loader_bar.cnstr();
}
public function play(url){
this.stop();
this.close();
this._Sound = new Sound();
this.isLoading = true;
this.addEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
this._Sound.addEventListener(Event.COMPLETE, listener_loadedComplete);
this._Sound.load(new URLRequest(url));
this._Channel = this._Sound.play();
}
public function stop(){
if(this._Channel){
this._Channel.stop();
}
}
private function close(){
if(this.isLoading){
this._Sound.close();
}
}
private function listener_loadedComplete(event){
this.close();
this.isLoading = false;
this.removeEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
}
private function listener_bytesLoaded(event){
var float = this._Sound.bytesLoaded / this._Sound.bytesTotal;
this._Loader_bar.progress(float);
var data = {
i : this.i,
float : float,
loaded : this._Sound.bytesLoaded,
total : this._Sound.bytesTotal
};
ExternalInterface.call('swf2js', 'tst_progress', data);
this.i++;
}
}
}
close():void
Closes the stream, causing any download of data to cease.
try this:
create a boolean like hasLoaded, set it to false. When the sound successfully loads set it to true.
Then when you play a sound you can test for hasLoaded in your play() function. If you have called play() before your previous sound has loaded, hasLoaded will be false, in which case you call this._Sound.close() before creating and loading the new sound. The reason for testing instead of just calling close() is so if you have paused the stream you don't have to reload it to play it again.
ADDITION:
Concerning the load not reporting properly, you have your progress logic set up incorrectly. Try this:
1) import flash.events.ProgressEvent
2) For the listener, replace this.addEventListener(Event.ENTER_FRAME, listener_bytesLoaded); in your play() method with this._Sound.addEventListener(ProgressEvent.PROGRESS, listener_bytesLoaded);
3) Change your listener_bytesLoaded() method to the following:
private function listener_bytesLoaded(event:ProgressEvent)
{
var percent = event.bytesLoaded / event.bytesTotal;
this._Loader_bar.progress(percent);
var data = {
i : this.i,
float : percent,
loaded : event.bytesLoaded,
total : event.bytesTotal
};
ExternalInterface.call('swf2js', 'tst_progress', data);
this.i++;
}
4) Change this.removeEventListener(Event.ENTER_FRAME, listener_bytesLoaded);
in your listener_loadedComplete() method to this._Sound.removeEventListener(ProgressEvent.PROGRESS, listener_bytesLoaded); and then move it out of that method and place it inside the conditional in the close() method.
NOTE - I didn't actually compile this but I think its good to go. Hope that helps. :)