Mouse_Move Error

Hello,
I have a Document Class that creates a video player and I’m having problems toggling on/off the playback controls (by playback controls I mean “play/pause/volume/full screen”).
The playback controls are a separate movieclip in my main .fla file which I have set “export for actionscript” to with the value of “Controls”.
I’m using the Mouse_Move event to toggle the playback controls on/off and it works fine except for when I move my mouse vigorously about.
The error I’m getting is:


ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
 at flash.display::DisplayObjectContainer/removeChild()
 at VPlayer/turnOnControls()
 at flash.utils::Timer/_timerDispatch()
 at flash.utils::Timer/tick()

I’ve provided my full code below.
Any help greatly appreciated as I’m a bit confused on how to resolve the error. I tried adding error handling to mask the error but I’m not sure where to apply the event listener code or which event to listen for to handle this particular area (you’ll notice on line 178 of the Document Class I’ve added error handling which doesn’t appear to work).
Thanks in advance!
Kind regards,
M.


package
{
    // Import all the required classes
 import flash.text.TextField;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.events.NetStatusEvent;
    import flash.text.TextFieldAutoSize;
 import flash.text.TextFormat;
    import flash.display.Sprite;
    import flash.display.MovieClip;
 import flash.display.StageDisplayState;
    import flash.events.Event;
 import flash.events.TimerEvent;
    import flash.events.MouseEvent;
    import flash.events.NetStatusEvent;
 import flash.events.SecurityErrorEvent;
 import flash.events.AsyncErrorEvent;
 import flash.events.IOErrorEvent;
 import flash.media.SoundTransform;
 import flash.geom.Rectangle;
 import flash.utils.Timer;
    
 // Define the video player Class
    public class VPlayer extends MovieClip 
    {
        private var _stream:NetStream;
  private var _play:MovieClip;
  private var _controls:MovieClip;
        private var _video:Video;
  private var _toolbar:Sprite;
  private var _thumb:Sprite;
  private var _track:Sprite;
  private var _scrubbing:Boolean;
        private var _playbackTime:TextField;
        private var _duration:uint;
  private var _TotalDuration;
  private var _SoundTransform:SoundTransform = new SoundTransform();
        private var _TextFormat:TextFormat = new TextFormat();
  private var _position;
  private var _backposition:int = 0;
  private var _mouseArea:Sprite;
  private var _timer:Timer;
  
  // Define the Class constructor
  public function VPlayer() 
        {
   // Specify the video to play (this is now controlled via the main .fla file instead)
   //init("Video.flv");
   
   // This Sprite will act as the toggle for the playback controls
   _mouseArea = new Sprite;
   _mouseArea.graphics.lineStyle();
   _mouseArea.graphics.beginFill(0xCC00FF);
   _mouseArea.graphics.drawRect(0, 0, stage.stageWidth, 240);
   _mouseArea.graphics.endFill();
   _mouseArea.alpha = 0;
   
   // Preset the timer variable
   _timer = new Timer(3000, 1);
   _timer.addEventListener("timer", turnOnControls);
        }
  
  private function init(url):void
  {
   // Create the control component
   _controls = new Controls();
   
   // Create the "cover screen" that is shown before the video plays
   _play = new Play();
   _play.buttonMode = true;
   
   // Create a new video object
   _video = new Video(419, 235);
   
   // Create the playback text field and hide off stage initially
            _playbackTime = new TextField();
   _playbackTime.x = 155;
   _playbackTime.y = 217;
   _playbackTime.autoSize = TextFieldAutoSize.LEFT;
   _playbackTime.y = 1000;
   
   // Set the video duration to zero
            _duration = 0;   
   
   // Create a new NetConnection and apply to the NetStream
   var connection:NetConnection = new NetConnection();
            connection.connect(null);
            _stream = new NetStream(connection);
            
   // Create a MetaData object to check the video duration
            var client:Object = new Object();
            client.onMetaData = oMetaData;
   
   // Specify the object on which callback methods are invoked
            _stream.client = client;
   
   // Specify the initial buffer time (10 seconds)
   _stream.bufferTime = 10;
   
   // Specify the video stream to be displayed within the boundaries of the Video object
            _video.attachNetStream(_stream);
   
   // Create a invisible track for the scrubber to be dragged along
   _track = new Sprite();
            _track.graphics.lineStyle();
            _track.graphics.drawRect(0, -2.5, 100, 5);
   
   // Create the scrubber button
   _thumb = new Sprite();
            _thumb.graphics.lineStyle();
            _thumb.graphics.beginFill(0xCC0000);
            _thumb.graphics.drawRect(36, 221, 11, 11);
            _thumb.graphics.endFill();
   
   // Add the video object and cover screen to the display list
            addChild(_video);
   addChild(_play);   
   
   _play.addEventListener(MouseEvent.CLICK, function(){ 
                    // Play the video                 
                 _stream.play(url);
                 
                 // Remove the initial Storm Media cover screen
                 removeChild(_play);
                 
                 // Add the controls/scrubber/time controls/mouseArea
                 addChild(_controls);                 
                 addChild(_thumb);   
                 addChild(_track);
                          addChild(_playbackTime);
                 addChild(_mouseArea);
                 
                 // Setup the 'full screen' control
                 _controls.bFullScreen.addEventListener(MouseEvent.CLICK, toggleFullScreen);
                 _controls.bFullScreen.addEventListener(MouseEvent.MOUSE_OVER, oMouseOver);
                 _controls.bFullScreen.addEventListener(MouseEvent.MOUSE_OUT, oMouseOut);                 
                 
                 // Setup the 'mute sound' control
                 _controls.bMuteSound.addEventListener(MouseEvent.CLICK, toggleSound);
                 _controls.bMuteSound.addEventListener(MouseEvent.MOUSE_OVER, oMouseOver);
                 _controls.bMuteSound.addEventListener(MouseEvent.MOUSE_OUT, oMouseOut);
                 
                 // Setup the 'play/pause' control
                 _controls.bPlayPause.addEventListener(MouseEvent.CLICK, togglePlayback);
                 _controls.bPlayPause.addEventListener(MouseEvent.MOUSE_OVER, oMouseOver);
                 _controls.bPlayPause.addEventListener(MouseEvent.MOUSE_OUT, oMouseOut);
                 _controls.bPlayPause.buttonMode = true;
                 
                 // Create the scrubber button
                 _thumb.addEventListener(MouseEvent.MOUSE_DOWN, oMouseDown);
                          _thumb.addEventListener(MouseEvent.MOUSE_UP, oMouseUp);
                 _thumb.addEventListener(MouseEvent.MOUSE_OVER, oMouseOver);
                 _thumb.addEventListener(MouseEvent.MOUSE_OUT, oMouseOut);
                 _thumb.buttonMode = true;
                 _thumb.alpha = 0;
                 
                 // Add listener for the mouse area (roll over and show controls, roll out and hide controls)
                 _mouseArea.addEventListener(MouseEvent.MOUSE_MOVE, function(){ 
                                  if(_controls.currentFrame > 1)
                                 {
                                  // If the controls haven't finished rolling out 
                                  // then pause for a few seconds before rolling back in again
                                  _timer.start();
                                 }
                                 else
                                 {
                                  // Remove the mouse area so that the playback controls aren't triggered prematurely
                                  removeChild(_mouseArea); 
                                  
                                  // Start the playback controls animation
                                  _controls.gotoAndPlay(2);
                                 }
                                 });
                 
                 // Error handler for mouse move event
                 _mouseArea.addEventListener(IOErrorEvent.IO_ERROR, function(){ trace("an error occurred"); });
                  })
   
   // Listener for playback text and video scrubbing
            addEventListener(Event.ENTER_FRAME, oEnterFrame);
   
   // Handlers for net status/security errors/asynchronous errors
            _stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
   _stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
   _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
  }
  
  // Function to turn on the playback controls
  private function turnOnControls(e:TimerEvent):void
  {
   // Turn off the timer event listener
   _timer.removeEventListener("timer", turnOnControls);
   
   // Remove the mouse area so that the playback controls aren't triggered prematurely
   removeChild(_mouseArea); 
   
   // Start the playback controls animation
    _controls.gotoAndPlay(2);
  }
  
  // Function to toggle full screen playback on/off
  private function toggleFullScreen(e:MouseEvent):void
  {
   stage.displayState = StageDisplayState.FULL_SCREEN;
  }
  
  // Function to toggle sound on/off
  private function toggleSound(e:MouseEvent):void
  {
   switch(_SoundTransform.volume)
   {
    case 0:
     _controls.bMuteSound.alpha = 1;
     _SoundTransform.volume = 1;
     break;
     
    case 1:
     _controls.bMuteSound.alpha = 0.3;
     _SoundTransform.volume = 0;
     break;
   }
   
   _stream.soundTransform = _SoundTransform;
  }
  
  // Function to toggle playback on/off
  private function togglePlayback(e:MouseEvent):void
  {
   switch(_controls.bPlayPause.currentFrame)
   {
    case 1:
     _controls.bPlayPause.gotoAndStop(2);
     break;
     
    case 2:
     _controls.bPlayPause.gotoAndStop(1);
     break;
   }
   
   _stream.togglePause();
  }
        // Function to display video duration
  private function oMetaData(data:Object):void 
        {
            _duration = data.duration;   
   
   // GET THE HOURS
   var Hours = Math.floor(_duration / 3600);
   
   // GET THE MINUTES
   var Minutes = Math.floor((_duration - 3600 * Hours) / 60);
   
   // GET THE SECONDS
   var Seconds = (_duration - 3600 * Hours - 60 * Minutes);
   var prefix = Math.floor(Seconds % 60) < 10 ? "0" : "";
   
   _TotalDuration = /*String(Hours) + ":" +*/ String(Minutes) + ":" + prefix + String(Seconds);
        }
        
        // Function for playback display and scrubbing facility
  private function oEnterFrame(event:Event):void 
        {
   if(_duration > 0 && _stream.time > 0) 
            {
    _playbackTime.defaultTextFormat = _TextFormat;
    _TextFormat.color = 0xCC0000;
    _TextFormat.font = "Arial";
    _TextFormat.bold = true;
    _playbackTime.setTextFormat(_TextFormat);
    _playbackTime.text = generateTime(_stream.time) + " / " + _TotalDuration;
            }
   
   // Handle the scrubbing through the video playback
   if(_duration > 0) 
   {
                if(_scrubbing) 
    {
     _stream.seek(_duration * _thumb.x / _track.width);
    }
    else 
    {
     // Use this variable to keep track of current
     _position = _stream.time;
     if(_position > 10)
     {
      _backposition = (_position-5);
     }
     _thumb.x = _stream.time / _duration * _track.width;
    }
            }
        }
  
  // Function to return current time
  function generateTime(nCurrentTime:Number):String
  {
   var nMinutes:String = (Math.floor(nCurrentTime / 60) < 10 ? "0" : "") + Math.floor(nCurrentTime / 60);
   var nSeconds:String = (Math.floor(nCurrentTime % 60) < 10 ? "0" : "") + Math.floor(nCurrentTime % 60);
   
   //Set Result 
   var sResult:String = nMinutes + ":" + nSeconds;
   
   //Return value
   return sResult;
  }
  
  // Function for handling scrubber mouse down event
  private function oMouseDown(e:MouseEvent):void 
  {
   _scrubbing = true;
            var rectangle:Rectangle = new Rectangle(0, 0, _track.width, 0);
            _thumb.startDrag(false, rectangle);
        }
        
        // Function for handling scrubber mouse up event
  private function oMouseUp(e:MouseEvent):void 
  {
            _scrubbing = false;
            _thumb.stopDrag();
        }
  
  // Function for handling scrubber mouse over event
  private function oMouseOver(e:MouseEvent):void
  {
   // If the control movieclip is on frame 10 already then the Timer to hide the controls will need to be cancelled
            if(_controls.currentFrame == 10)
   {
    _controls.oTimer.stop();
   }
  }
  
  // Function for handling scrubber mouse over event
  private function oMouseOut(e:MouseEvent):void
  {
   // If the control movieclip is on frame 10 already then the Timer to hide the controls will need to be cancelled
            if(_controls.currentFrame == 10)
   {
    _controls.oTimer.start();
   }
  }
  
  // Function for handling net status events
  public function netStatusHandler(e:NetStatusEvent):void 
  {
   var error = new TextField();
   
   switch (e.info.code) 
   {
                case "NetStream.Seek.InvalidTime":
     // Move scrubber position back 5 seconds as current position is not available
     _stream.seek(_backposition);
     break;
     
                case "NetStream.Play.StreamNotFound":
     // Define error settings
     error.x = 85;
     error.y = 110;
     error.autoSize = TextFieldAutoSize.LEFT;
     error.defaultTextFormat = _TextFormat;
     
     // Define the text formatting
     _TextFormat.color = 0xFF0000;
     _TextFormat.font = "Arial";
     _TextFormat.bold = true;
     
     // Set the error message
     error.text = "Sorry, we are currently updating this video";
     addChild(error);
     
     // Apply the formatting to the text field
     error.setTextFormat(_TextFormat);
                    break;
            }
        }
  
  // Function for handling security errors
  private function securityErrorHandler(e:SecurityErrorEvent):void 
  {
            trace("securityErrorHandler: " + e);
        }
        
        // Function for handling asynchronous errors
  private function asyncErrorHandler(e:AsyncErrorEvent):void 
  {
            trace("asyncErrorHandler; " + e);
        }
  
  // Function for adding the mouseArea sprite (which triggers the controls to be displayed)
  public function bringBackMouseArea():void
  {
   addChild(_mouseArea);
  }
  
  // Function for toggling the scrubber button on/off
  public function toggleScrubber(o):void
  {
   _thumb.alpha = o;
  }
  
  // Function for toggling the playback time on/off
  public function toggleTime(o):void
  {
   // Can't apply alpha to dynamic text field so have to reposition instead
   _playbackTime.y = o;
  }
    }
}