Forwarding a video by frame using NetStream in AS3 - actionscript-3

I was looking for a way to go back and forth in my video using the seek function in AS3.
import flash.filesystem.File;
import flash.net.NetStream;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var vid:Video = new Video(MovieClip(root).clip.width, MovieClip(root).clip.height)
MovieClip(root).clip.addChild(vid);
var ns:NetStream = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
vid.attachNetStream(ns);
function asyncErrorHandler(event:AsyncErrorEvent):void
{}
var file: File = File.desktopDirectory;
var myFilter: FileFilter = new FileFilter("MP4;MOV", "*.mp4;*.mov");
file.addEventListener(Event.SELECT, loadImage);
function fn_open(e: MouseEvent): void {
file.browseForOpen("Open", [myFilter]);
}
function loadImage(e: Event): void {
ns.play(file.url);
ns.pause();
}
var seek_value:int = 0
function fn_step(e: MouseEvent): void {
seek_value += 0.5
ns.seek(seek_value)
}
Unfortunately this works, but with seconds... is that possible to do so but with FPS or just a fraction of second? I've already tried entering decimal numbers inside the function, like net_stream.seek(0.5), but no results.
Any ideas?

Related

AS3 NetConnection object must be connected

I'm beginner in AS3 and making a prototype for a game, I tried to add a video in it and came across this problem.
ArgumentError: Error #2126: NetConnection object must be connected.
at flash.net::NetStream/ctor()
at flash.net::NetStream()
at Main()[/Users/admin/Desktop/Prototype 4/Main.as:27]
at runtime::ContentPlayer/loadInitialContent()
at runtime::ContentPlayer/playRawContent()
at runtime::ContentPlayer/playContent()
at runtime::AppRunner/run()
at ADLAppEntry/run()
at global/runtime::ADLEntry()
I googled it but still don't understand the problem.
This is my code.
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.media.*;
import flash.net.*;
import flash.display.MovieClip;
import flashx.textLayout.events.ModelChange;
public class Main extends Sprite
{
public var mc:Sprite = new Sprite();
public var touch:MovieClip = new Touch();
public var yellowbox:MovieClip = new Yellow();
public var purplebox:MovieClip = new Purple();
public var pinkbox:MovieClip = new Pink();
public var Next:MovieClip = new NEXT();
public var myTimer:Timer = new Timer (2000, 1);
public var vid:Video = new Video(700, 360);
public var nc:NetConnection = new NetConnection();
public var ns:NetStream = new NetStream(nc);
public function Main()
{
// constructor code
addChild(mc);
mc.addChild(yellowbox);
yellowbox.addChild(touch);
touch.y = 1000;
touch.x = 50;
vid.y = 300;
vid.x = 10;
yellowbox.addEventListener (MouseEvent.CLICK, onClick);
myTimer.addEventListener(TimerEvent.TIMER, tick);
nc.connect(null);
vid.attachNetStream(ns);
var listener:Object = new Object();
listener.onMetaData = function(evt:Object):void {};
ns.client = listener;
}
public function onClick (e:MouseEvent):void
{
mc.removeChild(yellowbox);
mc.addChild(purplebox);
purplebox.addChild(vid);
ns.play("rick.mp4");
myTimer.start();
}
function tick(e:TimerEvent):void
{
purplebox.addChild(Next);
Next.y = 1000;
Next.x = 330;
}
}
}
Can someone explain to me what's the problem?
Thanks!
Simply, you can not create a NetStream using a NetConnection which is not connected !
To avoid that error, you should connect your NetConnection and then create your NetStream like this :
var nc:NetConnection,
ns:NetStream;
nc = new NetConnection();
trace(nc.connected); // gives : false
nc.connect(null);
trace(nc.connected) // gives : true
ns = new NetStream(nc);
Hope that can help.

Need help making a button play multiple sounds in Adobe Flash

I'm having an issue trying to get my code work for my Adobe Flash project. Basically I'm trying to get a button to play a random sound everytime it's clicked which works but I can't have that same code on the same frame for a different button which is why it gives me this error.
Here is my code:
import flash.utils.Dictionary;
import flash.events.MouseEvent;
var request:URLRequest = new URLRequest("19103_b.mp3");
var ci_diese:Sound = new Sound();
ci_diese.load(request);
var request_two:URLRequest = new URLRequest("19203_b.mp3");
var d_diese:Sound = new Sound();
d_diese.load(request_two);
var request_three:URLRequest = new URLRequest("19204_b.mp3");
var f_diese:Sound = new Sound();
f_diese.load(request_three);
var play_liste = 0;
var dictSounds = new Dictionary ();
dictSounds[1] = d_diese;
dictSounds[2] = ci_diese;
dictSounds[3] = f_diese;
fireweapon_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();
ready_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();}
}
import flash.utils.Dictionary;
import flash.events.MouseEvent;
var request:URLRequest = new URLRequest("Readya.mp3");
var ci_diese2:Sound = new Sound();
ci_diese2.load(request);
var request_two:URLRequest = new URLRequest("Readyb.mp3");
var d_diese2:Sound = new Sound();
d_diese2.load(request_two);
var request_three:URLRequest = new URLRequest("Readyc.mp3");
var f_diese2:Sound = new Sound();
f_diese2.load(request_three);
var play_liste = 0;
var dictSounds = new Dictionary ();
dictSounds[1] = d_diese2;
dictSounds[2] = ci_diese2;
dictSounds[3] = f_diese2;
ready_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();}
}
Any way to rewrite this to accommodate more than one button? The first half works up until it repeats itself at "import flash." I've been searching everywhere for answers so please help!!
You should not name two functions or two variables the same, because the last ones are going to overwrite the first ones.
For example
var request:URLRequest = new URLRequest("19103_b.mp3");
is then overwritten
var request:URLRequest = new URLRequest("Readya.mp3");
The same happens with the button ready_H3AR an the function listener mouseDownHandler
By the way, you don't need to import the classes twice:
import flash.utils.Dictionary;
import flash.events.MouseEvent;
Usually when a task or a block of code is intended to be used many times, it's better to put it in a function to get a simpler and more maintainable code.
So you can do like this :
var sounds:Array = [
['01.mp3', '02.mp3', '03.mp3'], // sounds for the 1st button
['04.mp3', '05.mp3', '06.mp3'] // sounds for the 2nd button
];
var sound:Sound,
sound_channel:SoundChannel = new SoundChannel();
function play_sound(sound_name:String): void
{
var request:URLRequest = new URLRequest('mp3/' + sound_name);
sound = new Sound();
sound.addEventListener(Event.COMPLETE, on_sound_loaded);
sound.load(request);
}
function on_sound_loaded(e:Event): void
{
// if you want, you can stop the current playing sound
// otherwise you don't need the SoundChannel
sound_channel.stop();
sound_channel = Sound(e.target).play();
}
button_01.addEventListener(MouseEvent.MOUSE_DOWN, on_press);
button_02.addEventListener(MouseEvent.MOUSE_DOWN, on_press);
function on_press(e:MouseEvent): void
{
// to get values : 0, 1 or 2
var random:int = int(Math.random () * sounds[0].length);
// if it's the 1st button so pick the sound from the 1st sounds array
if(e.currentTarget.name == 'button_01'){
play_sound(sounds[0][random]);
} else {
play_sound(sounds[1][random]);
}
}
Hope that can help.

Recording Flash Webcam FMS 4.5 to Mp4 results in terrible quality

I have successfully setup recording webcam to FLV using FMS 4.5 developer edition, so I wanted to attempt recording to an Mp4 next. I am doing a silent save of the video file because the goal here is to be able to have these videos playable outside of Flash/FMS. I set the program up to save the Mp4 file generated by FMS, but the quality is terrible. I am seeing green distortion when movement is captured, and heavy pixelation. Here is my test application code that saves the video file after 5 seconds of recording. Can anyone please point out where I am going wrong? Any help is greatly appreciated.
package com
{
import flash.display.*;
import flash.net.*;
import flash.utils.Timer;
import flash.events.*;
import flash.filesystem.File;
import flash.media.*;
public class Main extends MovieClip
{
private var nc:NetConnection;
private var ns:NetStream;
private var nsPlayer:NetStream;
private var vid:Video;
private var vidPlayer:Video;
private var cam:Camera;
private var mic:Microphone;
private static const LOCAL_VIDEO:String = "myCamera";
private static const VIDEO_FPS:uint = 30;
private static const SAVE_FOLDER_NAME:String = "Saved_Videos";
private static const PATH_TO_FMS:String = "C:/Program Files/Adobe/Flash Media Server 4.5";
private var timer:Timer = new Timer(5000, 1);
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(evt:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.connect("rtmp://localhost/PublishLive/myCamera");
}
function onNetStatus(evt:NetStatusEvent):void
{
if(evt.info.code == "NetConnection.Connect.Success")
{
publishCamera();
displayPublishingVideo();
timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleted);
timer.start();
}
}
private function timerCompleted(evt:TimerEvent)
{
trace("timer completed");
timer.stop();
ns.close();
ns = null;
var saveFile:File = new File(PATH_TO_FMS + "/applications/PublishLive/streams/" + LOCAL_VIDEO + "/" + LOCAL_VIDEO + ".mp4");
var fileName:String = "Video" + ".mp4";
var dir:File = File.documentsDirectory.resolvePath(SAVE_FOLDER_NAME);
dir.createDirectory();
var fileToSave = dir.resolvePath(fileName);
if(fileToSave.exists)
{
fileToSave.deleteFile();
}
saveFile.copyTo(fileToSave, true);
}
private function publishCamera()
{
var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings();
h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_3_1);
cam = Camera.getCamera();
cam.setMode(stage.stageWidth, stage.stageHeight, VIDEO_FPS, true);
cam.setQuality(0, 90);
cam.setKeyFrameInterval(15);
cam.setMotionLevel(100);
mic = Microphone.getMicrophone();
mic.setSilenceLevel(0);
mic.rate = 11;
ns = new NetStream(nc);
ns.videoStreamSettings = h264Settings;
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.publish("mp4:myCamera.mp4", "record");
}
private function displayPublishingVideo():void
{
vid = new Video();
vid.width = stage.stageWidth;
vid.height = stage.stageHeight;
vid.attachCamera(cam);
addChild(vid);
}
}
}
Ok, so I am answering my own question. I found the answer here along with the link to the tool to process: adobe help site
You must convert the files after recording them using a post-processing tool so they can be viewed in other video players.
Edit: VLC can actually play the unprocessed file, so I thought it was a quality issue at first!
You could try to change the quality of the video stream VideoStreamSettings.setQuality(bandwidth:int, quality:int) (link).
You only set one of the bandwidth or quality values and leave the other to 0. I would try to set bandwidth (measured in bytes per second) to 750000 (6 Mbps), which should be plenty for anything less than full HD.
So, in your case, you could try:
h264Settings.setQuality(750000, 0);

Error #2025: The supplied DisplayObject must be a child of the caller - Not sure how to fix

So I get an error saying that the supplied DisplayObject must be a child of the caller. What happens is my game works first time around in that clicking the 'Play' button calls the startGame function and removes the menu so that the game is shown, but then at the end of the game when the playAgainBtn is clicked, instead of simply playing the game again / restarting the game, I get this error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
It specifically points to this line:
menuLayer.removeChild(mainMenu);
Here is the code:
package {
import flash.display.MovieClip;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.AntiAliasType;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.LoaderContext;
import flash.display.Sprite;
import flash.net.Socket;
import caurina.transitions.Tweener;
import flash.text.Font;
public class Main extends MovieClip {
public static var backgroundLayer:Sprite = new Sprite;
public static var gameLayer:Sprite = new Sprite;
public static var interfaceLayer:Sprite = new Sprite;
public static var endGameLayer:Sprite = new Sprite;
public static var menuLayer:Sprite = new Sprite;
public static var gameOverLayer:Sprite = new Sprite;
public static var howToLayer:Sprite = new Sprite;
public static var scoresLayer:Sprite = new Sprite;
public static var aboutLayer:Sprite = new Sprite;
public var mainMenu:menuMain = new menuMain;
public var gameEnd:endGame = new endGame;
public var howtoPlay:howToPlay = new howToPlay;
public var gameAbout:aboutGame = new aboutGame;
public var intro:IntroSound = new IntroSound();
public var soundControl:SoundChannel = new SoundChannel();
public var gameTime:int;
public var levelDuration:int;
public var crosshair:crosshair_mc;
static var score:Number;
var enemyShipTimer:Timer;
var enemyShipTimerMed:Timer;
var enemyShipTimerSmall:Timer;
static var scoreHeader:TextField = new TextField();
static var scoreText:TextField = new TextField();
static var timeHeader:TextField = new TextField();
static var timeText:TextField = new TextField();
static var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
public var gameOverscoreFormat = new TextFormat("Arial Rounded MT Bold", 32, 0xFFFFFF);
public function Main()
{
addChild(gameLayer);
addChild(backgroundLayer);
addChild(interfaceLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
interfaceLayer.addChild(gameEnd);
interfaceLayer.addChild(gameAbout);
soundControl = intro.play(0, 100);
addMenuListeners();
}
public function menuReturn(e:Event)
{
addChild(gameLayer);
addChild(backgroundLayer);
addChild(interfaceLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
interfaceLayer.addChild(gameEnd);
interfaceLayer.addChild(gameAbout);
}
public function showAbout(e:Event)
{
menuLayer.removeChild(mainMenu);
interfaceLayer.addChild(gameAbout);
}
public function startGame(e:Event)
{
removeMenuListeners();
soundControl.stop();
interfaceLayer.removeChild(howtoPlay);
interfaceLayer.removeChild(gameAbout);
interfaceLayer.removeChild(gameEnd);
menuLayer.removeChild(mainMenu);
levelDuration = 30;
gameTime = levelDuration;
var gameTimer:Timer = new Timer(1000,levelDuration);
gameTimer.addEventListener(TimerEvent.TIMER, updateTime);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeExpired)
gameTimer.start();
scoreHeader = new TextField();
scoreHeader.text = String("Score: ");
interfaceLayer.addChild(scoreHeader);
scoreHeader.x = 5;
scoreHeader.selectable = false;
scoreHeader.embedFonts = true;
scoreHeader.antiAliasType = AntiAliasType.ADVANCED;
scoreText = new TextField();
scoreText.text = String("0");
interfaceLayer.addChild(scoreText);
scoreText.x = 75;
scoreText.y = 0;
scoreText.selectable = false;
scoreText.embedFonts = true;
scoreText.antiAliasType = AntiAliasType.ADVANCED;
timeHeader = new TextField();
timeHeader.text = String("Time: ");
interfaceLayer.addChild(timeHeader);
timeHeader.x = 500;
timeHeader.y = 0;
timeHeader.selectable = false;
timeHeader.embedFonts = true;
timeHeader.antiAliasType = AntiAliasType.ADVANCED;
timeText = new TextField();
timeText.text = gameTime.toString();
interfaceLayer.addChild(timeText);
timeText.x = 558;
timeText.y = 0;
timeText.selectable = false;
timeText.embedFonts = true;
timeText.antiAliasType = AntiAliasType.ADVANCED;
scoreHeader.setTextFormat(scoreFormat);
scoreText.setTextFormat(scoreFormat);
timeHeader.setTextFormat(scoreFormat);
timeText.setTextFormat(scoreFormat);
var timeScorebg:Sprite = new Sprite();
backgroundLayer.addChild(timeScorebg);
timeScorebg.graphics.beginFill(0x333333);
timeScorebg.graphics.drawRect(0,0,600,30);
timeScorebg.graphics.endFill();
timeScorebg.y = 0;
enemyShipTimer = new Timer(2000);
enemyShipTimer.addEventListener("timer", sendEnemy);
enemyShipTimer.start();
enemyShipTimerMed = new Timer(2500);
enemyShipTimerMed.addEventListener("timer", sendEnemyMed);
enemyShipTimerMed.start();
enemyShipTimerSmall = new Timer(2750);
enemyShipTimerSmall.addEventListener("timer", sendEnemySmall);
enemyShipTimerSmall.start();
crosshair = new crosshair_mc();
gameLayer.addChild(crosshair);
crosshair.mouseEnabled = crosshair.mouseChildren = false;
Mouse.hide();
gameLayer.addEventListener(Event.ENTER_FRAME, moveCursor);
resetScore();
}
function addMenuListeners():void
{
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
}
function removeMenuListeners():void
{
mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
}
public function showInstructions(e:Event)
{
menuLayer.removeChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
}
function sendEnemy(e:Event)
{
var enemy = new EnemyShip();
gameLayer.addChild(enemy);
gameLayer.addChild(crosshair);
}
function sendEnemyMed(e:Event)
{
var enemymed = new EnemyShipMed();
gameLayer.addChild(enemymed);
gameLayer.addChild(crosshair);
}
function sendEnemySmall(e:Event)
{
var enemysmall = new EnemyShipSmall();
gameLayer.addChild(enemysmall);
gameLayer.addChild(crosshair);
}
static function updateScore(points)
{
score += points;
scoreText.text = String(score);
scoreHeader.setTextFormat(scoreFormat);
scoreText.setTextFormat(scoreFormat);
}
static function resetScore()
{
score = 0;
scoreText.text = String(score);
scoreText.setTextFormat(scoreFormat);
}
function updateTime(e:TimerEvent):void
{
gameTime--;
timeText.defaultTextFormat = scoreFormat;
timeText.text = String(gameTime);
}
function timeExpired(e:TimerEvent):void
{
var gameTimer:Timer = e.target as Timer;
gameTimer.removeEventListener(TimerEvent.TIMER, updateTime)
gameTimer.removeEventListener(TimerEvent.TIMER, timeExpired)
interfaceLayer.addChild(gameEnd);
var thisFont:Font = new myFont();
var myFormat:TextFormat = new TextFormat();
myFormat.font = thisFont.fontName;
scoreText = new TextField();
scoreText.defaultTextFormat = myFormat;
scoreText.text = String(score);
interfaceLayer.addChild(scoreText);
scoreText.x = 278;
scoreText.y = 180;
scoreText.selectable = false;
scoreText.embedFonts = true;
scoreText.antiAliasType = AntiAliasType.ADVANCED;
scoreText.setTextFormat(gameOverscoreFormat);
Mouse.show();
removeChild(gameLayer);
addMenuListeners();
}
function moveCursor(event:Event)
{
crosshair.x=mouseX;
crosshair.y=mouseY;
}
}
}
I'm not quite sure how to fix this, so any advice or solution will be welcome. I can't get it to work the way I intended without getting errors.
Thanks.
I believe the problem is calling menuLayer.removeChild(mainMenu); on the second play-through is throwing the error due to the fact that you'd already removed it once already. The quickest solution would be to do a check to ensure menuLayer contains mainMenu before you try and remove it:
if(menuLayer contains mainMenu)
menuLayer.removeChild(mainMenu);
(Note that I don't have access to the IDE right now, but I think this should work)
A more robust solution would be to call a different method when the play button is clicked from the main menu that removes mainMenu from menuLayer, then calls startGame (where as playAgain calls startGame directly).
EDIT
Ok I see what you mean. Perhaps something like this instead:
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, playGame);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, playGameAgain);
...
public function playGame(e:Event)
{
menuLayer.removeChild(mainMenu);
startGame();
}
...
public function playGameAgain(e:Event)
{
startGame();
}
...
public function startGame()
I have no idea why your code is not working, but there is no need to fret, try:
MovieClip(menuLayer.parent).removeChild(menuLayer);
You remove mainMenu in two different locations. My guess is it is being removed once and then again moments later.
if ( mainMenu.parent == menuLayer ) {
menuLayer.removeChild( mainMenu );
}
This will verify that mainMenu is actually a child of menuLayer before removing it. You cannot remove a child from a parent that isn't actually its parent. Imagine the state taking a child away and taking custody of them from a kidnapper. It's not the prettiest comparison, but it gives the right idea.
I cannot verify this without seeing how the game over is handled, but I think potentially the problem is that you are not removing your event listeners each time the game is played. Therefore when you go back to the main menu and add them again, you now have TWO listeners for playAgainBtn.
So when you end a game and click on the playAgainBtn, startGame gets called TWICE. So the first time it removes things just fine, and the second time - there's nothing to remove. This issue will potentially exist with all of your event listeners given your current design.
If this is the case you simply need to remove your event listeners when the menu is removed.
I suggest that whenever you make the menu active you add the listeners, and then remove them whenever you hide it. Maybe have two methods, addMenuListeners and removeMenuListeners
You could create these two functions and use them where appropriate :
function addMenuListeners():void
{
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
}
function removeMenuListeners():void
{
mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
}
If you follow the rule of always removing the event listeners when not in use, you can avoid this issue.
if( mainMenu.parent ){ mainmenu.parent.removeChild( mainMenu );} Or perhaps its already removed / not added at all?
Change this line
menuLayer.removeChild(mainMenu);
to this one..
if (mainMenu.parent != null && mainMenu.parent == menuLayer)
{
menuLayer.removeChild(mainMenu);
}
Hope it will solve.

Do you know if there's any problem with netstream.appendBytes() for streaming?

I use netstream.appendBytes to get the streaming (flv) from http, but works intermittently (it works, after refresh, doesn't work, then it works and so on...)
What is the problem?, I have not idea
My code is:
import flash.display.*;
import flash.events.*
import flash.net.*;
import flash.utils.ByteArray;
import com.hurlant.util.Hex;
var videoURL:String = "http://url/vivo/flash";
//elemento de conexíon
var conn:NetConnection = new NetConnection();
conn.connect(null);
//stream de red
var stream:NetStream;
//conexión
stream = new NetStream(conn);
//oyente
stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
function Play()
{
var urlStream:URLStream = new URLStream();
//oyentes de URLStream
urlStream.addEventListener(StatusEvent.STATUS, inStatus);
urlStream.addEventListener(Event.COMPLETE, completeHandler);
urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlStream.addEventListener(ProgressEvent.PROGRESS, oyenteProcesoCarga);
//urlStream.addEventListener(ProgressEvent.PROGRESS, describeProcesoCarga);
urlStream.addEventListener(IOErrorEvent.IO_ERROR, ioError);
//Video
var video:Video = new Video(640,480);
video.attachNetStream(stream);
addChild(video);
stream.play(null);
urlStream.load(new URLRequest(videoURL));
}
function ioError(event:IOErrorEvent):void
{
textArea.text += event + "\n";
}
function oyenteProcesoCarga(event:ProgressEvent):void
{
var encr:ByteArray = new ByteArray();
event.target.readBytes(encr);
stream.appendBytes(encr);
}
function describeProcesoCarga(event:ProgressEvent):void
{
if (event.target.bytesAvailable > 0){
var encr:ByteArray = new ByteArray();
event.target.readBytes(encr);
}
}
function securityErrorHandler(event:SecurityErrorEvent):void {
}
function asyncErrorHandler(event:AsyncErrorEvent):void {
// ignore AsyncErrorEvent events.
}
function completeHandler(event:Event):void {
}
function inStatus(event:StatusEvent):void {
}
Play();
Maybe use a stream buffer as HTTP is TCP so not all packets arrive at time.