[Pkg-javascript-commits] [jarisplayer] 55/80: RTMP fixes.

Jonas Smedegaard dr at jones.dk
Tue May 10 08:45:36 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository jarisplayer.

commit 9a2b82b588b7c61645c89d8187698d85509c5a4b
Author: jgmdev <jgmdev at gmail.com>
Date:   Sun Nov 22 02:05:34 2015 -0400

    RTMP fixes.
---
 bin/JarisFLVPlayer.swf     |  Bin 24713 -> 24962 bytes
 changes.txt                |   24 +-
 documentation.txt          |  243 ++--
 src/jaris/Version.hx       |   24 +-
 src/jaris/player/Player.hx | 3477 ++++++++++++++++++++++----------------------
 5 files changed, 1907 insertions(+), 1861 deletions(-)

diff --git a/bin/JarisFLVPlayer.swf b/bin/JarisFLVPlayer.swf
index 29ca65c..493f8bd 100644
Binary files a/bin/JarisFLVPlayer.swf and b/bin/JarisFLVPlayer.swf differ
diff --git a/changes.txt b/changes.txt
index f6fb7c6..6bd35ce 100644
--- a/changes.txt
+++ b/changes.txt
@@ -1,10 +1,16 @@
-Jaris FLV Player v2.0.16 - 11/09/2014
+Jaris FLV Player v2.0.17 - 22/11/2015
+
+    * Disabled second parameter when calling play() on a rtmp source.
+    * Disabled rtmpSourceParser() because it is causing issues.
+    * Added rtmp notes to documentation.txt
+
+Jaris FLV Player v2.0.16 - 11/09/2014
 
     * Fixes in order to compile with new haxe v3 thanks to jonassmedegaard
     * Fix the AsyncErrorEvent exception thrown by player thanks to lcb931023
     * Added loadVideo() JsAPI call, call from JS new video thanks to Spiritdude
     * Added build.hxml
-    
+
 Jaris FLV Player v2.0.15 beta - 27/08/2011
 
     * New player controls
@@ -24,19 +30,19 @@ Jaris FLV Player v2.0.13 beta - 6/03/2011
     * Implemented loop class
     * Added loop functionality by passing loop=true or loop=1 as parameter
     * Fixed reported bug "slider will show wrong position" on pseudostreaming seek (Thanks to Adam)
-    
+
 Jaris FLV Player v2.0.12 beta - 06/11/2010
 
     * Java Script Api to listen for events and control the player.
     * More player events added to use on JSApi.
     * All this changes thanks to Sascha Kluger from http://projekktor.com
-    
+
 Jaris FLV Player v2.0.11 beta - 03/10/2010
 
-    * Removed togglePlay of onFullscreen event since it seems that new flash versions doesnt emits 
+    * Removed togglePlay of onFullscreen event since it seems that new flash versions doesnt emits
       the space keydown anymore that affected playback on fullcreen switching.
     * Added class to store user settings as volume and aspect ratio to load them next time player is load.
-    
+
 Jaris FLV Player v2.0.10 beta - 29/09/2010
 
     * Added flashvar aspectratio option to initially tell on wich aspect ratio to play the video
@@ -85,7 +91,7 @@ Jaris FLV Player v2.0.2 beta - 03/09/2010
     * Some more improvements to controls on short heights
     * Other improvements and code refactoring
     * added id3 info to player events
-    
+
 Jaris FLV Player v2.0.1 beta - 03/08/2010
 
     * Toggle Quality on Context Menu
@@ -95,7 +101,7 @@ Jaris FLV Player v2.0.1 beta - 03/08/2010
     * Controls fixes
     * Other refinements and fixes
     * Duration parameter to indicate how much total time takes input media
-    
+
 Jaris FLV Player v2.0.0 beta - 03/05/2010
 
     * Moved from swishmax 2 to haxe and flashdevelop
@@ -110,7 +116,7 @@ Jaris FLV Player v2.0.0 beta - 03/05/2010
     * Video smoothing enabled by default
     * Added custom context menu
     * Other refinements and fixes
-    
+
 Jaris FLV Player v1.0 - 05/21/2008
 
     * Calculates video aspect ratio on player load.
diff --git a/documentation.txt b/documentation.txt
index dfa8f53..7ae4687 100644
--- a/documentation.txt
+++ b/documentation.txt
@@ -2,7 +2,8 @@
 How To!
 ==================
 
-The above example is one of the ways to embed the player to your html files. Just copy and paste. 
+The above example is one of the ways to embed the player to your html
+files. Just copy and paste.
 
 ---------------------------------------Code------------------------------------------
 <object
@@ -10,36 +11,74 @@ The above example is one of the ways to embed the player to your html files. Jus
   codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,45,2"
   width="640" height="360"
 >
-	<param name="allowFullscreen" value="true">
-	<param name="allowScriptAccess" value="always">
-	<param name="movie" value="JarisFLVPlayer.swf">
-	<param name="bgcolor" value="#000000">
-	<param name="quality" value="high">
-	<param name="scale" value="noscale">
-	<param name="wmode" value="opaque">
-	<param name="flashvars" value="source=jaris-intro.mp4&type=video&streamtype=file&poster=poster.png&autostart=false&logo=logo.png&logoposition=top left&logoalpha=30&logowidth=130&logolink=http://jaris.sourceforge.net&hardwarescaling=false&darkcolor=000000&brightcolor=4c4c4c&controlcolor=FFFFFF&hovercolor=67A8C1">
-	<param name="seamlesstabbing" value="false">
-	<embed
-	  type="application/x-shockwave-flash"
-	  pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"
-	  width="640" height="360"
-	  src="JarisFLVPlayer.swf"
-	  allowfullscreen="true" 
-	  allowscriptaccess="always"
-	  bgcolor="#000000"
-	  quality="high"
-	  scale="noscale"
-	  wmode="opaque"
-	  flashvars="source=jaris-intro.mp4&type=video&streamtype=file&poster=poster.png&autostart=false&logo=logo.png&logoposition=top left&logoalpha=30&logowidth=130&logolink=http://jaris.sourceforge.net&hardwarescaling=false&darkcolor=000000&brightcolor=4c4c4c&controlcolor=FFFFFF&hovercolor=67A8C1"
-	  seamlesstabbing="false"
-	>
-	  <noembed>
-	  </noembed>
-	</embed>
+    <param name="allowFullscreen" value="true">
+    <param name="allowScriptAccess" value="always">
+    <param name="movie" value="JarisFLVPlayer.swf">
+    <param name="bgcolor" value="#000000">
+    <param name="quality" value="high">
+    <param name="scale" value="noscale">
+    <param name="wmode" value="opaque">
+    <param name="flashvars" value="source=jaris-intro.mp4&type=video&streamtype=file&poster=poster.png&autostart=false&logo=logo.png&logoposition=top left&logoalpha=30&logowidth=130&logolink=http://jaris.sourceforge.net&hardwarescaling=false&darkcolor=000000&brightcolor=4c4c4c&controlcolor=FFFFFF&hovercolor=67A8C1">
+    <param name="seamlesstabbing" value="false">
+    <embed
+      type="application/x-shockwave-flash"
+      pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"
+      width="640" height="360"
+      src="JarisFLVPlayer.swf"
+      allowfullscreen="true"
+      allowscriptaccess="always"
+      bgcolor="#000000"
+      quality="high"
+      scale="noscale"
+      wmode="opaque"
+      flashvars="source=jaris-intro.mp4&type=video&streamtype=file&poster=poster.png&autostart=false&logo=logo.png&logoposition=top left&logoalpha=30&logowidth=130&logolink=http://jaris.sourceforge.net&hardwarescaling=false&darkcolor=000000&brightcolor=4c4c4c&controlcolor=FFFFFF&hovercolor=67A8C1"
+      seamlesstabbing="false"
+    >
+      <noembed>
+      </noembed>
+    </embed>
 </object>
 --------------------------------------End-Code---------------------------------------
 
 ==================
+RTMP Playback
+==================
+
+In order to play from RTMP servers set the following parameters
+as follow:
+
+    streamtype=rtmp
+    server=rtmp://server/application/
+    source=streamkey
+
+Some rtmp streaming servers support a source syntax as follows:
+
+    * source=mp4:channel
+    * source=mp3:channel
+
+This is to tell the server in which format to stream the content.
+
+==================
+RTMPD Example
+==================
+
+An example of rtmp streaming using crtmpserver:
+
+1. First, in order to stream from your pc you can use ffmpeg as follows:
+
+    * ffmpeg -i file.avi -vcodec libx264 -f flv -metadata \
+           streamName="test" tcp://127.0.0.1:6666
+
+2. To play this stream on jarisplayer set the flashvars as follow:
+
+    streamtype=rtmp
+    server=rtmp://127.0.0.1/live/
+    source=test
+
+In the example 'live' is an alias of 'flvplayback' and 'test' is
+the streamName.
+
+==================
 Flash Variables
 ==================
 
@@ -47,83 +86,83 @@ Here is the list of variables that you can pass to the player.
 
     * source:
       This is the actual path of the media that is going to be played.
-	  
-	* type:
+
+    * type:
       The type of file to play, allowable values are: audio, video.
-	  
+
     * streamtype:
       The stream type of the file, allowable values are: file, http, rmtp, youtube.
-	  
-	* server:
-	  Used in coordination with rtmp stream servers
-	  
-	* duration:
+
+    * server:
+      Used in coordination with rtmp stream servers
+
+    * duration:
       Total times in seconds for input media or formatted string in the format hh:mm:ss
-    
-	* poster:
+
+    * poster:
       Screenshot of the video that is displayed before playing in png, jpg or gif format.
-    
-	* autostart:
+
+    * autostart:
       A true or false value that indicates to the player if it should auto play the video on load.
-    
-	* logo:
+
+    * logo:
       The path to the image of your logo.
-    
-	* logoposition:
+
+    * logoposition:
       The position of the logo in the player, permitted values are: top left, top right, bottom left and bottom right
-    
-	* logoalpha:
+
+    * logoalpha:
       The transparency percent. values permitted 0 to 100, while more higher the vale less transparency is applied.
-    
-	* logowidth:
+
+    * logowidth:
       The width in pixels of the logo.
-    
-	* logolink:
+
+    * logolink:
       A link to a webpage when the logo is clicked.
-    
-	* hardwarescaling:
+
+    * hardwarescaling:
       Enable or disable hardware scaling on fullscreen mode, values: false or true
-    
-	* logoalpha:
+
+    * logoalpha:
       The transparency percent. values permitted 1 to 100
-	  
-	* controls:
-	  To disable the displaying of controls, values: false to hide otherwise defaults to show
-	  
-	* controltype
-	  Choose which controls to displa. 0 = old controls, 1 = new controls
-	  
-	* controlsize
-	  Changes the height of the new controllers, the default value is 40
-	  
-	* seekcolor
-	  Change the seekbar color (new controls only)
-    
-	* darkcolor:
+
+    * controls:
+      To disable the displaying of controls, values: false to hide otherwise defaults to show
+
+    * controltype
+      Choose which controls to displa. 0 = old controls, 1 = new controls
+
+    * controlsize
+      Changes the height of the new controllers, the default value is 40
+
+    * seekcolor
+      Change the seekbar color (new controls only)
+
+    * darkcolor:
       The darker color of player controls in html hexadecimal format
-    
-	* brightcolor:
+
+    * brightcolor:
       The bright color of player controls in html hexadecimal format
-    
-	* controlcolor:
+
+    * controlcolor:
       The face color of controls in html hexadecimal format
-    
-	* hovercolor:
+
+    * hovercolor:
       On mouse hover color for controls in html hexadecimal format
-	  
-	* aspectratio:
+
+    * aspectratio:
       To override original aspect ratio on first time player load. Allowable values: 1:1, 3:2, 4:3, 5:4, 14:9, 14:10, 16:9, 16:10
-	  
-	* jsapi:
-	  Expose events to javascript functions and enable controlling the player from the outside. Set to any value to enable.
-	  
-	* loop:
-	  As the variable says this keeps looping the video. Set to any value to enable.
-	  
-	* buffertime
-	  To change the default 10 seconds buffer time for local/pseudo streaming
-
-==================	  
+
+    * jsapi:
+      Expose events to javascript functions and enable controlling the player from the outside. Set to any value to enable.
+
+    * loop:
+      As the variable says this keeps looping the video. Set to any value to enable.
+
+    * buffertime
+      To change the default 10 seconds buffer time for local/pseudo streaming
+
+==================
 Keyboard Shortcuts
 ==================
 
@@ -131,27 +170,27 @@ Here is the list of keyboard shortcuts to control Jaris Player.
 
     * SPACE
       Play or pause video.
-	  
+
     * TAB
       Switch between different aspect ratios.
-    
-	* UP
+
+    * UP
       Raise volume
-    
-	* DOWN
+
+    * DOWN
       Lower volume
-    
-	* LEFT
+
+    * LEFT
       Rewind
-    
-	* RIGHT
+
+    * RIGHT
       Forward
-    
-	* M
+
+    * M
       Mute or unmute volume.
-    
-	* F
+
+    * F
       Swtich to fullscreen mode.
-	
-	* X
-      Stops and close current stream
\ No newline at end of file
+
+    * X
+      Stops and close current stream
diff --git a/src/jaris/Version.hx b/src/jaris/Version.hx
index ab14e0b..dc37f66 100644
--- a/src/jaris/Version.hx
+++ b/src/jaris/Version.hx
@@ -1,13 +1,13 @@
-/**    
+/**
  * @author Jefferson González
  * @copyright 2010 Jefferson González
  *
- * @license 
+ * @license
  * This file is part of Jaris FLV Player.
  *
  * Jaris FLV Player is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License or GNU LESSER GENERAL 
- * PUBLIC LICENSE as published by the Free Software Foundation, either version 
+ * it under the terms of the GNU General Public License or GNU LESSER GENERAL
+ * PUBLIC LICENSE as published by the Free Software Foundation, either version
  * 3 of the License, or (at your option) any later version.
  *
  * Jaris FLV Player is distributed in the hope that it will be useful,
@@ -15,8 +15,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License and 
- * GNU LESSER GENERAL PUBLIC LICENSE along with Jaris FLV Player.  If not, 
+ * You should have received a copy of the GNU General Public License and
+ * GNU LESSER GENERAL PUBLIC LICENSE along with Jaris FLV Player.  If not,
  * see <http://www.gnu.org/licenses/>.
  */
 
@@ -25,11 +25,11 @@ package jaris;
 /**
  * Actual jaris flv player version and date
  */
-class Version 
+class Version
 {
-	public static var NUMBER:String = "2.0.16";
-	public static var STATUS:String = "stable";
-	public static var DATE:String = "11";
-	public static var MONTH:String = "09";
-	public static var YEAR:String = "2014";
+    public static var NUMBER:String = "2.0.17";
+    public static var STATUS:String = "stable";
+    public static var DATE:String = "22";
+    public static var MONTH:String = "11";
+    public static var YEAR:String = "2015";
 }
diff --git a/src/jaris/player/Player.hx b/src/jaris/player/Player.hx
index deff6e0..af35ef7 100644
--- a/src/jaris/player/Player.hx
+++ b/src/jaris/player/Player.hx
@@ -1,13 +1,13 @@
-/**    
+/**
  * @author Jefferson González
  * @copyright 2010 Jefferson González
  *
- * @license 
+ * @license
  * This file is part of Jaris FLV Player.
  *
  * Jaris FLV Player is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License or GNU LESSER GENERAL 
- * PUBLIC LICENSE as published by the Free Software Foundation, either version 
+ * it under the terms of the GNU General Public License or GNU LESSER GENERAL
+ * PUBLIC LICENSE as published by the Free Software Foundation, either version
  * 3 of the License, or (at your option) any later version.
  *
  * Jaris FLV Player is distributed in the hope that it will be useful,
@@ -15,8 +15,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License and 
- * GNU LESSER GENERAL PUBLIC LICENSE along with Jaris FLV Player.  If not, 
+ * You should have received a copy of the GNU General Public License and
+ * GNU LESSER GENERAL PUBLIC LICENSE along with Jaris FLV Player.  If not,
  * see <http://www.gnu.org/licenses/>.
  */
 
@@ -62,1740 +62,1741 @@ import jaris.player.UserSettings;
  */
 class Player extends EventDispatcher
 {
-	//{Member variables
-	private var _stage:Stage;
-	private var _movieClip:MovieClip;
-	private var _connection:NetConnection;
-	private var _stream:NetStream;
-	private var _fullscreen:Bool;
-	private var _soundMuted:Bool;
-	private var _volume:Float;
-	private var _bufferTime:Float;
-	private var _mouseVisible:Bool;
-	private var _mediaLoaded:Bool;
-	private var _hideMouseTimer:Timer;
-	private var _checkAudioTimer:Timer;
-	private var _mediaSource:String;
-	private var _type:String;
-	private var _streamType:String;
-	private var _server:String; //For future use on rtmp
-	private var _sound:Sound;
-	private var _soundChannel:SoundChannel;
-	private var _id3Info:ID3Info;
-	private var _video:Video;
-	private var _videoWidth:Float;
-	private var _videoHeight:Float;
-	private var _videoMask:Sprite;
-	private var _videoQualityHigh:Bool;
-	private var _mediaDuration:Float;
-	private var _lastTime:Float;	
-	private var _lastProgress:Float;
-	private var _isPlaying:Bool;
-	private var _aspectRatio:Float;
-	private var _currentAspectRatio:String;
-	private var _originalAspectRatio:Float;
-	private var _mediaEndReached:Bool;
-	private var _seekPoints:Array<Float>;
-	private var _downloadCompleted:Bool;
-	private var _startTime:Float;
-	private var _firstLoad:Bool;
-	private var _stopped:Bool;
-	private var _useHardWareScaling:Bool;
-	private var _youtubeLoader:Loader;
-	private var _userSettings:UserSettings;
-	//}
-	
-	
-	//{Constructor
-	public function new() 
-	{
-		super();
-		
-		//{Main Variables Init
-		_stage = Lib.current.stage;
-		_movieClip = Lib.current;
-		_mouseVisible = true;
-		_soundMuted = false;
-		_volume = 1.0;
-		_bufferTime = 10;
-		_fullscreen = false;
-		_mediaLoaded = false;
-		_hideMouseTimer = new Timer(1500);
-		_checkAudioTimer = new Timer(100);
-		_seekPoints = new Array();
-		_downloadCompleted = false;
-		_startTime = 0;
-		_firstLoad = true;
-		_stopped = false;
-		_videoQualityHigh = false;
-		_isPlaying = false;
-		_streamType = StreamType.FILE;
-		_type = InputType.VIDEO;
-		_server = "";
-		_currentAspectRatio = "original";
-		_aspectRatio = 0;
-		_lastTime = 0;
-		_lastProgress = 0;
-		_userSettings = new UserSettings();
-		//}
-		
-		//{Initialize sound object
-		_sound = new Sound();
-		_sound.addEventListener(Event.COMPLETE, onSoundComplete);
+    //{Member variables
+    private var _stage:Stage;
+    private var _movieClip:MovieClip;
+    private var _connection:NetConnection;
+    private var _stream:NetStream;
+    private var _fullscreen:Bool;
+    private var _soundMuted:Bool;
+    private var _volume:Float;
+    private var _bufferTime:Float;
+    private var _mouseVisible:Bool;
+    private var _mediaLoaded:Bool;
+    private var _hideMouseTimer:Timer;
+    private var _checkAudioTimer:Timer;
+    private var _mediaSource:String;
+    private var _type:String;
+    private var _streamType:String;
+    private var _server:String; //For future use on rtmp
+    private var _sound:Sound;
+    private var _soundChannel:SoundChannel;
+    private var _id3Info:ID3Info;
+    private var _video:Video;
+    private var _videoWidth:Float;
+    private var _videoHeight:Float;
+    private var _videoMask:Sprite;
+    private var _videoQualityHigh:Bool;
+    private var _mediaDuration:Float;
+    private var _lastTime:Float;
+    private var _lastProgress:Float;
+    private var _isPlaying:Bool;
+    private var _aspectRatio:Float;
+    private var _currentAspectRatio:String;
+    private var _originalAspectRatio:Float;
+    private var _mediaEndReached:Bool;
+    private var _seekPoints:Array<Float>;
+    private var _downloadCompleted:Bool;
+    private var _startTime:Float;
+    private var _firstLoad:Bool;
+    private var _stopped:Bool;
+    private var _useHardWareScaling:Bool;
+    private var _youtubeLoader:Loader;
+    private var _userSettings:UserSettings;
+    //}
+
+
+    //{Constructor
+    public function new()
+    {
+        super();
+
+        //{Main Variables Init
+        _stage = Lib.current.stage;
+        _movieClip = Lib.current;
+        _mouseVisible = true;
+        _soundMuted = false;
+        _volume = 1.0;
+        _bufferTime = 10;
+        _fullscreen = false;
+        _mediaLoaded = false;
+        _hideMouseTimer = new Timer(1500);
+        _checkAudioTimer = new Timer(100);
+        _seekPoints = new Array();
+        _downloadCompleted = false;
+        _startTime = 0;
+        _firstLoad = true;
+        _stopped = false;
+        _videoQualityHigh = false;
+        _isPlaying = false;
+        _streamType = StreamType.FILE;
+        _type = InputType.VIDEO;
+        _server = "";
+        _currentAspectRatio = "original";
+        _aspectRatio = 0;
+        _lastTime = 0;
+        _lastProgress = 0;
+        _userSettings = new UserSettings();
+        //}
+
+        //{Initialize sound object
+        _sound = new Sound();
+        _sound.addEventListener(Event.COMPLETE, onSoundComplete);
         _sound.addEventListener(Event.ID3, onSoundID3);
         _sound.addEventListener(IOErrorEvent.IO_ERROR, onSoundIOError);
         _sound.addEventListener(ProgressEvent.PROGRESS, onSoundProgress);
 
-		//}
-		
-		//{Initialize video and connection objects
-		_connection = new NetConnection();
-		_connection.client = this;
-		_connection.connect(null);
-		_stream = new NetStream(_connection);
-		
-		_video = new Video(_stage.stageWidth, _stage.stageHeight);
-		
-		_movieClip.addChild(_video);
-		//}
-		
-		//Video mask so that custom menu items work
-		_videoMask = new Sprite();
-		_movieClip.addChild(_videoMask);
-		
-		//Set initial rendering to high quality
-		toggleQuality();
-		
-		//{Initialize system event listeners
-		_movieClip.addEventListener(Event.ENTER_FRAME, onEnterFrame);
-		_stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
-		_stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
-		_stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreen);
-		_stage.addEventListener(Event.RESIZE, onResize);
-		_hideMouseTimer.addEventListener(TimerEvent.TIMER, hideMouseTimer);
-		_checkAudioTimer.addEventListener(TimerEvent.TIMER, checkAudioTimer);
-		_connection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
-		_connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
-		//}
-	}
-	//}
-	
-	
-	//{Timers
-	/**
-	 * Timer that hides the mouse pointer when it is idle and dispatch the PlayerEvents.MOUSE_HIDE
-	 * @param	event
-	 */
-	private function hideMouseTimer(event:TimerEvent):Void
-	{
-		if (_fullscreen)
-		{
-			if (_mouseVisible)
-			{
-				_mouseVisible = false;
-			}
-			else
-			{
-				Mouse.hide();
-				callEvents(PlayerEvents.MOUSE_HIDE);
-				_hideMouseTimer.stop();
-			}
-		}
-	}
-	
-	/**
-	 * To check if the sound finished playing
-	 * @param	event
-	 */
-	private function checkAudioTimer(event:TimerEvent):Void
-	{
-		if (_soundChannel.position + 100 >= _sound.length)
-		{
-			_isPlaying = false;
-			_mediaEndReached = true;
-			callEvents(PlayerEvents.PLAYBACK_FINISHED);
-			
-			_checkAudioTimer.stop();
-		}
-	}
-	//}
-	
-	
-	//{Events
-	/**
-	 * Callback after bandwidth calculation for rtmp streams
-	 */
-	private function onBWDone():Void
-	{
-		//Need to study this more
-	}
-	
-	/**
-	 * Triggers error event on rtmp connections
-	 * @param	event
-	 */
-	private function onAsyncError(event:AsyncErrorEvent):Void
-	{
-		//TODO: Should trigger event for controls to display error message
-		trace(event.error);
-	}
-	
-	/**
-	 * Checks if connection failed or succeed
-	 * @param	event
-	 */
-	private function onNetStatus(event:NetStatusEvent):Void
-	{
-		switch (event.info.code)
-		{
-			case "NetConnection.Connect.Success":
-				if (_streamType == StreamType.RTMP)
-				{
-					_stream = new NetStream(_connection);
-					_stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
-					_stream.bufferTime = 10;
-					_stream.play(Utils.rtmpSourceParser(_mediaSource), true);
-					_stream.client = this;
-					if(_type == InputType.VIDEO) {_video.attachNetStream(_stream); }
-				}
-				callEvents(PlayerEvents.CONNECTION_SUCCESS);
-
-			case "NetStream.Play.StreamNotFound":
-				trace("Stream not found: " + _mediaSource); //Replace with a dispatch for error event
-				callEvents(PlayerEvents.CONNECTION_FAILED);
-				
-			case "NetStream.Play.Stop":
-				if (_streamType != StreamType.RTMP)
-				{
-					if (_isPlaying) { _stream.togglePause(); }
-					_isPlaying = false;
-					_mediaEndReached = true;
-					callEvents(PlayerEvents.PLAYBACK_FINISHED);
-				}
-				
-			case "NetStream.Play.Start":
-				_isPlaying = true;
-				_mediaEndReached = false;
-				if (_stream.bytesLoaded != _stream.bytesTotal || _streamType == StreamType.RTMP)
-				{
-					callEvents(PlayerEvents.BUFFERING);
-				}
-				
-			case "NetStream.Seek.Notify":
-				_mediaEndReached = false;
-				if (_streamType == StreamType.RTMP)
-				{
-					_isPlaying = true;
-					callEvents(PlayerEvents.PLAY_PAUSE);
-					callEvents(PlayerEvents.BUFFERING);
-				}
-				
-			case "NetStream.Buffer.Empty":
-				if (_stream.bytesLoaded != _stream.bytesTotal)
-				{
-					callEvents(PlayerEvents.BUFFERING);
-				}
-				
-			case "NetStream.Buffer.Full":
-				callEvents(PlayerEvents.NOT_BUFFERING);
-				
-			case "NetStream.Buffer.Flush":
-				if (_stream.bytesLoaded == _stream.bytesTotal)
-				{
-					_downloadCompleted = true;
-				}
-		}
-	}
-	
-	/**
-	 * Proccess keyboard shortcuts
-	 * @param	event
-	 */
-	private function onKeyDown(event:KeyboardEvent):Void
-	{
-		var F_KEY:UInt = 70;
-		var M_KEY:UInt = 77;
-		var X_KEY:UInt = 88;
-		
-		if(event.keyCode == Keyboard.TAB)
-		{
-			toggleAspectRatio();
-		}
-		else if(event.keyCode == F_KEY)
-		{
-			toggleFullscreen();
-		}
-		else if(event.keyCode == M_KEY)
-		{
-			toggleMute();
-		}
-		else if(event.keyCode == Keyboard.UP)
-		{
-			volumeUp();
-		}
-		else if(event.keyCode == Keyboard.DOWN)
-		{
-			volumeDown();
-		}
-		else if(event.keyCode == Keyboard.RIGHT)
-		{
-			forward();
-		}
-		else if(event.keyCode == Keyboard.LEFT)
-		{
-			rewind();
-		}
-		else if(event.keyCode == Keyboard.SPACE)
-		{
-			togglePlay();
-		}
-		else if(event.keyCode == X_KEY)
-		{
-			stopAndClose();
-		}
-	}
-	
-	/**
-	 * IF player is full screen shows the mouse when gets hide
-	 * @param	event
-	 */
-	private function onMouseMove(event:MouseEvent):Void
-	{
-		if (_fullscreen && !_mouseVisible)
-		{
-			if (!_hideMouseTimer.running)
-			{
-				_hideMouseTimer.start();
-			}
-			
-			_mouseVisible = true;
-			Mouse.show();
-			
-			callEvents(PlayerEvents.MOUSE_SHOW);
-		}
-	}
-	
-	/**
-	 * Resize video player
-	 * @param	event
-	 */
-	private function onResize(event:Event):Void
-	{
-		resizeAndCenterPlayer();
-	}
-	
-	/**
-	 * Dispath a full screen event to listeners as redraw player an takes care of some other aspects
-	 * @param	event
-	 */
-	private function onFullScreen(event:FullScreenEvent):Void
-	{
-		_fullscreen = event.fullScreen;
-		
-		if (!event.fullScreen)
-		{
-			Mouse.show();
-			callEvents(PlayerEvents.MOUSE_SHOW);
-			_mouseVisible = true;
-		}
-		else
-		{
-			_mouseVisible = true;
-			_hideMouseTimer.start();
-		}
-		
-		resizeAndCenterPlayer();
-		
-		callEvents(PlayerEvents.FULLSCREEN);
-	}
-	
-	/**
-	 * Sits for any cue points available
-	 * @param	data
-	 * @note Planned future implementation
-	 */
-	private function onCuePoint(data:Dynamic):Void
-	{
-		
-	}
-	
-	/**
-	 * After a video is loaded this callback gets the video information at start and stores it on variables
-	 * @param	data
-	 */
-	private function onMetaData(data:Dynamic):Void
-	{
-		if (_firstLoad)
-		{
-			_isPlaying = true;
-			
-			_firstLoad = false;
-			if (data.width)
-			{
-				_videoWidth = data.width;
-				_videoHeight = data.height;
-			}
-			else
-			{
-				_videoWidth = _video.width;
-				_videoHeight = _video.height;
-			}
-			
-			//Store seekpoints times
-			if (data.hasOwnProperty("seekpoints")) //MP4
-			{
-				for (position in Reflect.fields(data.seekpoints))
-				{
-					_seekPoints.push(Reflect.field(data.seekpoints, position).time);
-				}
-			}
-			else if (data.hasOwnProperty("keyframes")) //FLV
-			{
-				for (position in Reflect.fields(data.keyframes.times))
-				{
-					_seekPoints.push(Reflect.field(data.keyframes.times, position));
-				}
-			}
-			
-			_mediaLoaded = true;
-			_mediaDuration = data.duration;
-			_originalAspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
-			
-			if (_aspectRatio <= 0)
-			{
-				_aspectRatio = _originalAspectRatio;
-			}
-			
-			callEvents(PlayerEvents.MEDIA_INITIALIZED);
-			
-			resizeAndCenterPlayer();
-			
-			//Retrieve the volume that user selected last time
-			setVolume(_userSettings.getVolume());
-		}
-	}
-	
-	/**
-	 * Dummy function invoked for pseudostream servers
-	 * @param	data
-	 */
-	private function onLastSecond(data:Dynamic):Void
-	{
-		trace("last second pseudostream");
-	}
-	
-	/**
-	 * Broadcast Timeupdate and Duration	 
-	 */	
-	private function onEnterFrame(event:Event):Void
-	{
-		if (getDuration() > 0 && _lastTime != getCurrentTime()) 
-		{
-			_lastTime = getCurrentTime();
-			callEvents(PlayerEvents.TIME);
-		}
-		
-		if (getBytesLoaded() > 0 && _lastProgress < getBytesLoaded()) 
-		{
-			_lastProgress = getBytesLoaded();
-			callEvents(PlayerEvents.PROGRESS);
-		}
-		
-	}		
-	
-	
-	/**
-	 * Triggers when playbacks end on rtmp streaming server
-	 */
-	private function onPlayStatus(info:Dynamic):Void
-	{
-		_isPlaying = false;
-		_mediaEndReached = true;
-		callEvents(PlayerEvents.PLAYBACK_FINISHED);
-	}
-	
-	/**
-	 * When sound finished downloading
-	 * @param	event
-	 */
-	private function onSoundComplete(event:Event)
-	{
-		_mediaDuration = _sound.length / 1000;
-		_downloadCompleted = true;
-		
-		callEvents(PlayerEvents.MEDIA_INITIALIZED);
-	}
-	
-	/**
-	 * Mimic stream onMetaData
-	 * @param	event
-	 */
-	private function onSoundID3(event:Event)
-	{
-		if (_firstLoad)
-		{
-			_soundChannel = _sound.play();
-			_checkAudioTimer.start();
-
-			_isPlaying = true;
-			
-			_firstLoad = false;
-			
-			_mediaLoaded = true;
-			_mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
-			_aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
-			_originalAspectRatio = _aspectRatio;
-			_id3Info = _sound.id3;
-			
-			callEvents(PlayerEvents.CONNECTION_SUCCESS);
-			callEvents(PlayerEvents.MEDIA_INITIALIZED);
-			
-			resizeAndCenterPlayer();
-			
-			//Retrieve the volume that user selected last time
-			setVolume(_userSettings.getVolume());
-		}
-	}
-	
-	/**
-	 * Dispatch connection failed event on error
-	 * @param	event
-	 */
-	private function onSoundIOError(event:IOErrorEvent)
-	{
-		callEvents(PlayerEvents.CONNECTION_FAILED);
-	}
-	
-	/**
-	 * Monitor sound download progress
-	 * @param	event
-	 */
-	private function onSoundProgress(event:ProgressEvent)
-	{
-		if (_sound.isBuffering)
-		{
-			callEvents(PlayerEvents.BUFFERING);
-		}
-		else
-		{
-			callEvents(PlayerEvents.NOT_BUFFERING);
-		}
-		
-		_mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
-		callEvents(PlayerEvents.MEDIA_INITIALIZED);
-	}
-	
-	/**
-	 * Initializes the youtube loader object
-	 * @param	event
-	 */
-	private function onYouTubeLoaderInit(event:Event):Void
-	{
-		_youtubeLoader.content.addEventListener("onReady", onYoutubeReady);
-		_youtubeLoader.content.addEventListener("onError", onYoutubeError);
-		_youtubeLoader.content.addEventListener("onStateChange", onYoutubeStateChange);
-		_youtubeLoader.content.addEventListener("onPlaybackQualityChange", onYoutubePlaybackQualityChange);
-
-	}
-	
-	/**
-	 * This event is fired when the player is loaded and initialized, meaning it is ready to receive API calls.
-	 */
-	private function onYoutubeReady(event:Event):Void
-	{
-		_movieClip.addChild(_youtubeLoader.content);
-		_movieClip.setChildIndex(_youtubeLoader.content, 0);
-		Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
-		Reflect.field(_youtubeLoader.content, "loadVideoByUrl")(Utils.youtubeSourceParse(_mediaSource));
-		callEvents(PlayerEvents.BUFFERING);
-	}
-
-	/**
-	 * This event is fired whenever the player's state changes. Possible values are unstarted (-1), ended (0), 
-	 * playing (1), paused (2), buffering (3), video cued (5). When the SWF is first loaded it will broadcast 
-	 * an unstarted (-1) event. When the video is cued and ready to play it will broadcast a video cued event (5).
-	 * @param	event
-	 */
-	private function onYoutubeStateChange(event:Event):Void
-	{
-		var status:UInt = Std.parseInt(Reflect.field(event, "data"));
-		
-		switch(status)
-		{
-			case -1:
-				callEvents(PlayerEvents.BUFFERING);
-			
-			case 0:
-				_isPlaying = false;
-				_mediaEndReached = true;
-				callEvents(PlayerEvents.PLAYBACK_FINISHED);
-				
-			case 1:
-				if (_firstLoad)
-				{
-					_isPlaying = true;
-					
-					_videoWidth = _stage.stageWidth;
-					_videoHeight = _stage.stageHeight;
-				
-					_firstLoad = false;
-					
-					_mediaLoaded = true;
-					_mediaDuration = Reflect.field(_youtubeLoader.content, "getDuration")();
-					_aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
-					_originalAspectRatio = _aspectRatio;
-					
-					callEvents(PlayerEvents.CONNECTION_SUCCESS);
-					callEvents(PlayerEvents.MEDIA_INITIALIZED);
-					
-					resizeAndCenterPlayer();
-					
-					//Retrieve the volume that user selected last time
-					setVolume(_userSettings.getVolume());
-				}
-				callEvents(PlayerEvents.NOT_BUFFERING);
-				
-			case 2:
-				callEvents(PlayerEvents.NOT_BUFFERING);
-				
-			case 3:
-				callEvents(PlayerEvents.BUFFERING);
-				
-			case 5:
-				callEvents(PlayerEvents.NOT_BUFFERING);
-		}
-	}
-    
-	/**
-	 * This event is fired whenever the video playback quality changes. For example, if you call the 
-	 * setPlaybackQuality(suggestedQuality) function, this event will fire if the playback quality actually 
-	 * changes. Your code should respond to the event and should not assume that the quality will automatically 
-	 * change when the setPlaybackQuality(suggestedQuality) function is called. Similarly, your code should not 
-	 * assume that playback quality will only change as a result of an explicit call to setPlaybackQuality or any 
-	 * other function that allows you to set a suggested playback quality.
-	 * 
-	 * The value that the event broadcasts is the new playback quality. Possible values are "small", "medium", 
-	 * "large" and "hd720".
-	 * @param	event
-	 */
-	private function onYoutubePlaybackQualityChange(event:Event):Void
-	{
-		//trace(Reflect.field(event, "data"));
-	}
-   
-	/**
-	 * This event is fired when an error in the player occurs. The possible error codes are 100, 101, 
-	 * and 150. The 100 error code is broadcast when the video requested is not found. This occurs when 
-	 * a video has been removed (for any reason), or it has been marked as private. The 101 error code is 
-	 * broadcast when the video requested does not allow playback in the embedded players. The error code 
-	 * 150 is the same as 101, it's just 101 in disguise!
-	 * @param	event
-	 */
-	private function onYoutubeError(event:Event):Void
-	{
-		trace(Reflect.field(event, "data"));
-	}
-	//}
-	
-	
-	//{Private Methods
-	/**
-	 * Function used each time is needed to dispatch an event
-	 * @param	type
-	 */
-	private function callEvents(type:String):Void
-	{
-		var playerEvent:PlayerEvents = new PlayerEvents(type, true);
-		
-		playerEvent.aspectRatio = getAspectRatio();
-		playerEvent.duration = getDuration();
-		playerEvent.fullscreen = isFullscreen();
-		playerEvent.mute = getMute();
-		playerEvent.volume = getVolume();
-		playerEvent.width = _video.width;
-		playerEvent.height = _video.height;
-		playerEvent.stream = getNetStream();
-		playerEvent.sound = getSound();
-		playerEvent.time = getCurrentTime();
-		playerEvent.id3Info = getId3Info();
-		
-		dispatchEvent(playerEvent);
-	}
-	
-	/**
-	 * Reposition and resizes the video player to fit on screen
-	 */
-	private function resizeAndCenterPlayer():Void
-	{
-		if (_streamType != StreamType.YOUTUBE)
-		{
-			_video.height = _stage.stageHeight;
-			_video.width = _video.height * _aspectRatio;
-			
-			_video.x = (_stage.stageWidth / 2) - (_video.width / 2);
-			_video.y = 0;
-			
-			if (_video.width > _stage.stageWidth && _aspectRatio == _originalAspectRatio)
-			{
-				var aspectRatio:Float = _videoHeight / _videoWidth;
-				_video.width = _stage.stageWidth;
-				_video.height = aspectRatio * _video.width;
-				_video.x = 0;
-				_video.y = (_stage.stageHeight / 2) - (_video.height / 2);
-			}
-			
-			_videoMask.graphics.clear();
-			_videoMask.graphics.lineStyle();
-			_videoMask.graphics.beginFill(0x000000, 0);
-			_videoMask.graphics.drawRect(_video.x, _video.y, _video.width, _video.height);
-			_videoMask.graphics.endFill();
-		}
-		else
-		{
-			Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
-			
-			_videoMask.graphics.clear();
-			_videoMask.graphics.lineStyle();
-			_videoMask.graphics.beginFill(0x000000, 0);
-			_videoMask.graphics.drawRect(0, 0, _stage.stageWidth, _stage.stageHeight);
-			_videoMask.graphics.endFill();
-		}
-		
-		callEvents(PlayerEvents.RESIZE);
-	}
-	
-	/**
-	 * Check the best seek point available if the seekpoints array is available
-	 * @param	time time in seconds
-	 * @return best seek point in seconds or given one if no seekpoints array is available
-	 */
-	private function getBestSeekPoint(time:Float):Float
-	{
-		if (_seekPoints.length > 0)
-		{
-			var timeOne:String="0";
-			var timeTwo:String="0";
-			
-			for(prop in Reflect.fields(_seekPoints))
-			{
-				if(Reflect.field(_seekPoints,prop) < time)
-				{
-					timeOne = prop;
-				}
-				else
-				{
-					timeTwo = prop;
-				break;
-				}
-			}
-
-			if(time - _seekPoints[Std.parseInt(timeOne)] < _seekPoints[Std.parseInt(timeTwo)] - time)
-			{
-				return _seekPoints[Std.parseInt(timeOne)];
-			}
-			else
-			{
-				return _seekPoints[Std.parseInt(timeTwo)];
-			}
-		}
-		
-		return time;
-	}
-	
-	/**
-	 * Checks if the given seek time is already buffered
-	 * @param	time time in seconds
-	 * @return true if can seek false if not in buffer
-	 */
-	private function canSeek(time:Float):Bool
-	{
-		if (_type == InputType.VIDEO)
-		{
-			time = getBestSeekPoint(time);
-		}
-		
-		var cacheTotal = Math.floor((getDuration() - _startTime) * (getBytesLoaded() / getBytesTotal())) - 1;
-
-		if(time >= _startTime && time < _startTime + cacheTotal)
-		{
-			return true;
-		}
-		
-		return false;
-	}
-	//}
-	
-	
-	//{Public methods	
-	/**
-	 * Loads a video and starts playing it
-	 * @param	video video url to load
-	 */
-	public function load(source:String, type:String="video", streamType:String="file", server:String=""):Void
-	{
-		stopAndClose();
-		
-		_type = type;
-		_streamType = streamType;
-		_mediaSource = source;
-		_stopped = false;
-		_mediaLoaded = false;
-		_firstLoad = true;
-		_startTime = 0;
-		_downloadCompleted = false;
-		_seekPoints = new Array();
-		_server = server;
-		
-		callEvents(PlayerEvents.BUFFERING);
-		
-		if (_streamType == StreamType.YOUTUBE)
-		{
-			Security.allowDomain("*");
-			Security.allowDomain("www.youtube.com");  
-			Security.allowDomain("youtube.com");  
-			Security.allowDomain("s.ytimg.com");  
-			Security.allowDomain("i.ytimg.com"); 
-		
-			_youtubeLoader = new Loader();
-			_youtubeLoader.contentLoaderInfo.addEventListener(Event.INIT, onYouTubeLoaderInit);
-			_youtubeLoader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
-		}
-		else if (_type == InputType.VIDEO && (_streamType == StreamType.FILE || _streamType == StreamType.PSEUDOSTREAM))
-		{	
-			_connection.connect(null);
-			_stream = new NetStream(_connection);
-			_stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
-			_stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
-			_stream.bufferTime = _bufferTime;
-			_stream.play(source);
-			_stream.client = this;
-			_video.attachNetStream(_stream);
-		}
-		else if (_type == InputType.VIDEO && _streamType == StreamType.RTMP)
-		{
-			_connection.connect(_server);
-		}
-		else if (_type == InputType.AUDIO && _streamType == StreamType.RTMP)
-		{
-			_connection.connect(_server);
-		}
-		else if(_type == InputType.AUDIO && _streamType == StreamType.FILE)
-		{
-			_sound.load(new URLRequest(source));
-		}
-	}
-	
-	private function doAsyncError(e:AsyncErrorEvent) : Void
-	{
-		// Do nothing, to block the exception.
-	}
-	
-	/**
-	 * Closes the connection and makes player available for another video
-	 */
-	public function stopAndClose():Void
-	{
-		if (_mediaLoaded)
-		{
-			_mediaLoaded = false;
-			_isPlaying = false;
-			_stopped = true;
-			_startTime = 0;
-			
-			if (_streamType == StreamType.YOUTUBE)
-			{
-				Reflect.field(_youtubeLoader.content, "destroy")();
-			}
-			else if (_type == InputType.VIDEO)
-			{
-				_stream.close();
-			}
-			else
-			{
-				_soundChannel.stop();
-				_sound.close();
-			}
-		}
-		
-		callEvents(PlayerEvents.STOP_CLOSE);
-	}
-	
-	/**
-	 * Seeks 8 seconds forward from the current position.
-	 * @return current play time after forward
-	 */
-	public function forward():Float
-	{	
-		var seekTime = (getCurrentTime() + 8) + _startTime;
-		
-		if (getDuration() > seekTime)
-		{
-			seekTime = seek(seekTime);
-		}
-		
-		return seekTime;
-	}
-	
-	/**
-	 * Seeks 8 seconds back from the current position.
-	 * @return current play time after rewind
-	 */
-	public function rewind():Float
-	{
-		var seekTime = (getCurrentTime() - 8) + _startTime;
-		
-		if (seekTime >= _startTime)
-		{
-			seekTime = seek(seekTime);
-		}
-		
-		return seekTime;
-	}
-	
-	/**
-	 * Seeks video player to a given time in seconds
-	 * @param	seekTime time in seconds to seek
-	 * @return current play time after seeking
-	 */
-	public function seek(seekTime:Float):Float
-	{
-		if (_startTime <= 1 && _downloadCompleted)
-		{
-			if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-			{
-				_stream.seek(seekTime);
-			}
-			else if (_type == InputType.AUDIO)
-			{
-				_soundChannel.stop();
-				_soundChannel = _sound.play(seekTime * 1000);
-				if (!_isPlaying)
-				{
-					_soundChannel.stop();
-				}
-				
-				setVolume(_userSettings.getVolume());
-			}
-		}
-		else if(_seekPoints.length > 0 && _streamType == StreamType.PSEUDOSTREAM)
-		{
-			seekTime = getBestSeekPoint(seekTime);
-			
-			if (canSeek(seekTime))
-			{
-				_stream.seek(seekTime - _startTime);
-			}
-			else if(seekTime != _startTime)
-			{	
-				_startTime = seekTime;
-				
-				var url:String;
-				if (_mediaSource.indexOf("?") != -1)
-				{
-					url = _mediaSource + "&start=" + seekTime;
-				}
-				else
-				{
-					url = _mediaSource + "?start=" + seekTime;
-				}
-				_stream.play(url);
-			}
-		}
-		else if (_streamType == StreamType.YOUTUBE)
-		{
-			if (!canSeek(seekTime))
-			{
-				_startTime = seekTime;
-				Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
-			}
-			else
-			{
-				Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
-			}
-			
-		}
-		else if (_streamType == StreamType.RTMP)
-		{
-			// seekTime = getBestSeekPoint(seekTime); //Not Needed?
-			_stream.seek(seekTime);
-		}
-		else if(canSeek(seekTime))
-		{
-			if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-			{
-				_stream.seek(seekTime);
-			}
-			else if (_type == InputType.AUDIO)
-			{
-				_soundChannel.stop();
-				_soundChannel = _sound.play(seekTime * 1000);
-				if (!_isPlaying)
-				{
-					_soundChannel.stop();
-				}
-				
-				setVolume(_userSettings.getVolume());
-			}
-		}
-		callEvents(PlayerEvents.SEEK);
-		return seekTime;
-	}
-	
-	/**
-	 * To check wheter the media is playing
-	 * @return true if is playing false otherwise
-	 */
-	public function isPlaying():Bool
-	{
-		return _isPlaying;
-	}
-	
-	/**
-	 * Cycle betewen aspect ratios
-	 * @return new aspect ratio in use
-	 */
-	public function toggleAspectRatio():Float
-	{
-		switch(_currentAspectRatio)
-		{
-			case "original":
-				_aspectRatio = AspectRatio._1_1;
-				_currentAspectRatio = "1:1";
-				
-			case "1:1":
-				_aspectRatio = AspectRatio._3_2;
-				_currentAspectRatio = "3:2";
-				
-			case "3:2":
-				_aspectRatio = AspectRatio._4_3;
-				_currentAspectRatio = "4:3";
-				
-			case "4:3":
-				_aspectRatio = AspectRatio._5_4;
-				_currentAspectRatio = "5:4";
-				
-			case "5:4":
-				_aspectRatio = AspectRatio._14_9;
-				_currentAspectRatio = "14:9";
-				
-			case "14:9":
-				_aspectRatio = AspectRatio._14_10;
-				_currentAspectRatio = "14:10";
-				
-			case "14:10":
-				_aspectRatio = AspectRatio._16_9;
-				_currentAspectRatio = "16:9";
-				
-			case "16:9":
-				_aspectRatio = AspectRatio._16_10;
-				_currentAspectRatio = "16:10";
-				
-			case "16:10":
-				_aspectRatio = _originalAspectRatio;
-				_currentAspectRatio = "original";
-			
-			default:
-				_aspectRatio = _originalAspectRatio;
-				_currentAspectRatio = "original";
-		}
-		
-		resizeAndCenterPlayer();
-		
-		callEvents(PlayerEvents.ASPECT_RATIO);
-		
-		//Store aspect ratio into user settings
-		if (_aspectRatio == _originalAspectRatio)
-		{
-			_userSettings.setAspectRatio(0.0);
-		}
-		else
-		{
-			_userSettings.setAspectRatio(_aspectRatio);
-		}
-		
-		return _aspectRatio;
-	}
-	
-	/**
-	 * Swithces between play and pause
-	 */
-	public function togglePlay():Bool
-	{
-		if (_mediaLoaded)
-		{
-			if (_mediaEndReached)
-			{
-				_mediaEndReached = false;
-				
-				if (_streamType == StreamType.YOUTUBE)
-				{
-					Reflect.field(_youtubeLoader.content, "seekTo")(0);
-					Reflect.field(_youtubeLoader.content, "playVideo")();
-				}
-				else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-				{
-					_stream.seek(0);
-					_stream.togglePause();
-				}
-				else if (_type == InputType.AUDIO)
-				{
-					_checkAudioTimer.start();
-					_soundChannel = _sound.play();
-					setVolume(_userSettings.getVolume());
-				}
-			}
-			else if (_mediaLoaded)
-			{
-				if (_streamType == StreamType.YOUTUBE)
-				{
-					if (_isPlaying)
-					{
-						Reflect.field(_youtubeLoader.content, "pauseVideo")();
-					}
-					else
-					{
-						Reflect.field(_youtubeLoader.content, "playVideo")();
-					}
-				}
-				else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-				{
-					_stream.togglePause();
-				}
-				else if (_type == InputType.AUDIO)
-				{
-					if (_isPlaying)
-					{
-						_soundChannel.stop();
-					}
-					else
-					{
-						//If end of audio reached start from beggining
-						if (_soundChannel.position + 100 >= _sound.length)
-						{
-							_soundChannel = _sound.play();
-						}
-						else 
-						{
-							_soundChannel = _sound.play(_soundChannel.position);
-						}
-						
-						setVolume(_userSettings.getVolume());
-					}
-				}
-			}
-			else if (_stopped)
-			{
-				load(_mediaSource, _type, _streamType, _server);
-			}
-			
-			_isPlaying = !_isPlaying;
-			callEvents(PlayerEvents.PLAY_PAUSE);
-			return _isPlaying;
-		}
-		else if(_mediaSource != "")
-		{
-			load(_mediaSource, _type, _streamType, _server);
-			callEvents(PlayerEvents.BUFFERING);
-			return true;
-		}
-		callEvents(PlayerEvents.PLAY_PAUSE);
-		return false;
-	}
-	
-	/**
-	 * Switches on or off fullscreen
-	 * @return true if fullscreen otherwise false
-	 */
-	public function toggleFullscreen():Bool 
-	{
-		if (_fullscreen)
-		{
-			_stage.displayState = StageDisplayState.NORMAL;
-			_stage.focus = _stage;
-			return false;
-		}
-		else
-		{	
-			if (_useHardWareScaling)
-			{
-				//Match full screen aspec ratio to desktop
-				var aspectRatio = Capabilities.screenResolutionY / Capabilities.screenResolutionX;
-				_stage.fullScreenSourceRect = new Rectangle(0, 0, _videoWidth, _videoWidth * aspectRatio);
-			}
-			else
-			{
-				//Use desktop resolution
-				_stage.fullScreenSourceRect = new Rectangle(0, 0, Capabilities.screenResolutionX ,Capabilities.screenResolutionY);
-			}
-			
-			_stage.displayState = StageDisplayState.FULL_SCREEN;
-			_stage.focus = _stage;
-			return true;
-		}
-	}
-	
-	/**
-	 * Toggles betewen high and low quality image rendering
-	 * @return true if quality high false otherwise
-	 */
-	public function toggleQuality():Bool
-	{
-		if (_videoQualityHigh)
-		{
-			_video.smoothing = false;
-			_video.deblocking = 1;
-		}
-		else
-		{
-			_video.smoothing = true;
-			_video.deblocking = 5;
-		}
-		
-		_videoQualityHigh = _videoQualityHigh?false:true;
-		
-		return _videoQualityHigh;
-	}
-	
-	/**
-	 * Mutes or unmutes the sound
-	 * @return true if muted false if unmuted
-	 */
-	public function toggleMute():Bool
-	{
-		var soundTransform:SoundTransform = new SoundTransform();
-		var isMute:Bool;
-		
-		//unmute sound
-		if (_soundMuted)
-		{
-			_soundMuted = false;
-			
-			if (_volume > 0)
-			{
-				soundTransform.volume = _volume;
-			}
-			else
-			{
-				_volume = 1.0;
-				soundTransform.volume = _volume;
-			}
-			
-			isMute =  false;
-		}
-		
-		//mute sound
-		else
-		{
-			_soundMuted = true;
-			_volume = _stream.soundTransform.volume;
-			soundTransform.volume = 0;
-			_stream.soundTransform = soundTransform;
-			
-			isMute = true;
-		}
-		
-		if (_streamType == StreamType.YOUTUBE)
-		{
-			Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
-		}
-		else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-		{
-			_stream.soundTransform = soundTransform;
-		}
-		else if (_type == InputType.AUDIO)
-		{
-			_soundChannel.soundTransform = soundTransform;
-			setVolume(_userSettings.getVolume());
-		}
-		
-		callEvents(PlayerEvents.MUTE);
-		return isMute;
-	}
-	
-	/**
-	 * Check if player is running on fullscreen mode
-	 * @return true if fullscreen false if not
-	 */
-	public function isFullscreen():Bool
-	{
-		return _stage.displayState == StageDisplayState.FULL_SCREEN;
-	}
-	
-	/**
-	 * Raises the volume
-	 * @return volume value after raising
-	 */
-	public function volumeUp():Float
-	{
-		var soundTransform:SoundTransform = new SoundTransform();
-		
-		if (_soundMuted)
-		{
-			_soundMuted = false;
-		}
-	
-		//raise volume if not already at max
-		if (_volume < 1)
-		{
-			if (_streamType == StreamType.YOUTUBE)
-			{
-				_volume = (Reflect.field(_youtubeLoader.content, "getVolume")() + 10) / 100;
-				Reflect.field(_youtubeLoader.content, "setVolume")(_volume * 100);
-			}
-			else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-			{
-				_volume = _stream.soundTransform.volume + (10/100);
-				soundTransform.volume = _volume;
-				_stream.soundTransform = soundTransform;
-			}
-			else if (_type == InputType.AUDIO)
-			{
-				_volume = _soundChannel.soundTransform.volume + (10/100);
-				soundTransform.volume = _volume;
-				_soundChannel.soundTransform = soundTransform;
-			}
-		}
-		
-		//reset volume to 1.0 if already reached max
-		if (_volume >= 1)
-		{
-			_volume = 1.0;
-		}
-		
-		//Store volume into user settings
-		_userSettings.setVolume(_volume);
-		
-		callEvents(PlayerEvents.VOLUME_UP);
-		return _volume;
-	}
-	
-	/**
-	 * Lower the volume
-	 * @return volume value after lowering
-	 */
-	public function volumeDown():Float
-	{
-		var soundTransform:SoundTransform = new SoundTransform();
-		
-		//lower sound
-		if(!_soundMuted)
-		{	
-			if (_streamType == StreamType.YOUTUBE)
-			{
-				_volume = (Reflect.field(_youtubeLoader.content, "getVolume")() - 10) / 100;
-				Reflect.field(_youtubeLoader.content, "setVolume")(_volume * 100);
-			}
-			else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-			{
-				_volume = _stream.soundTransform.volume - (10/100);
-				soundTransform.volume = _volume;
-				_stream.soundTransform = soundTransform;
-			}
-			else if (_type == InputType.AUDIO)
-			{
-				_volume = _soundChannel.soundTransform.volume - (10/100);
-				soundTransform.volume = _volume;
-				_soundChannel.soundTransform = soundTransform;
-			}
-			
-			//if volume reached min is muted
-			if (_volume <= 0)
-			{
-				_soundMuted = true;
-				_volume = 0;
-			}
-		}
-		
-		//Store volume into user settings
-		_userSettings.setVolume(_volume);
-		
-		callEvents(PlayerEvents.VOLUME_DOWN);
-		return _volume;
-	}
-	//}
-	
-	
-	//{Setters
-	/**
-	 * Set input type
-	 * @param	type Allowable values are audio, video
-	 */
-	public function setType(type:String):Void
-	{
-		_type = type;
-	}
-	
-	/**
-	 * Set streaming type
-	 * @param	streamType Allowable values are file, http, rmtp
-	 */
-	public function setStreamType(streamType:String):Void
-	{
-		_streamType = streamType;
-	}
-	
-	/**
-	 * Sets the server url for rtmp streams
-	 * @param	server
-	 */
-	public function setServer(server:String):Void
-	{
-		_server = server;
-	}
-	
-	/**
-	 * To set the video source in case we dont want to start downloading at first so when use tooglePlay the
-	 * media is loaded automatically
-	 * @param	source
-	 */
-	public function setSource(source):Void
-	{
-		_mediaSource = source;
-	}
-	
-	/**
-	 * Changes the current volume
-	 * @param	volume
-	 */
-	public function setVolume(volume:Float):Void
-	{
-		var soundTransform:SoundTransform = new SoundTransform();
-		
-		if (volume > _volume) {
-			callEvents(PlayerEvents.VOLUME_UP);
-		}
-
-		if (volume < _volume) {
-			callEvents(PlayerEvents.VOLUME_DOWN);
-		}
-
-		if (volume > 0)
-		{
-			_soundMuted = false;
-			_volume = volume;
-		}
-		else
-		{
-			_soundMuted = true;
-			_volume = 1.0;
-		}
-		
-		soundTransform.volume = volume;
-		
-		if (!_firstLoad) //To prevent errors if objects aren't initialized
-		{
-			if (_streamType == StreamType.YOUTUBE)
-			{
-				Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
-			}
-			else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-			{
-				_stream.soundTransform = soundTransform;
-			}
-			else if (_type == InputType.AUDIO)
-			{
-				_soundChannel.soundTransform = soundTransform;
-			}
-		}
-		
-		//Store volume into user settings
-		_userSettings.setVolume(_volume);
-
-		callEvents(PlayerEvents.VOLUME_CHANGE);
-	}
-	
-	/**
-	 * Changes the buffer time for local and pseudo streaming
-	 * @param	time in seconds
-	 */
-	public function setBufferTime(time:Float):Void
-	{
-		if (time > 0)
-		{
-			_bufferTime = time;
-		}
-	}
-	
-	/**
-	 * Changes the aspec ratio of current playing media and resizes video player
-	 * @param	aspectRatio new aspect ratio value
-	 */
-	public function setAspectRatio(aspectRatio:Float):Void
-	{
-		_aspectRatio = aspectRatio;
-		
-		switch(_aspectRatio)
-		{
-			case 0.0:
-				_currentAspectRatio = "original";
-				
-			case AspectRatio._1_1:
-				_currentAspectRatio = "1:1";
-				
-			case AspectRatio._3_2:
-				_currentAspectRatio = "3:2";
-				
-			case AspectRatio._4_3:
-				_currentAspectRatio = "4:3";
-				
-			case AspectRatio._5_4:
-				_currentAspectRatio = "5:4";
-				
-			case AspectRatio._14_9:
-				_currentAspectRatio = "14:9";
-				
-			case AspectRatio._14_10:
-				_currentAspectRatio = "14:10";
-				
-			case AspectRatio._16_9:
-				_currentAspectRatio = "16:9";
-				
-			case AspectRatio._16_10:
-				_currentAspectRatio = "16:10";
-		}
-		
-		resizeAndCenterPlayer();
-		
-		//Store aspect ratio into user settings
-		_userSettings.setAspectRatio(_aspectRatio);
-	}
-	
-	/**
-	 * Enable or disable hardware scaling
-	 * @param	value true to enable false to disable
-	 */
-	public function setHardwareScaling(value:Bool):Void
-	{
-		_useHardWareScaling = value;
-	}
-	//}
-	
-	
-	//{Getters
-	/**
-	 * Gets the volume amount 0.0 to 1.0
-	 * @return 
-	 */
-	public function getVolume():Float
-	{
-		return _volume;
-	}
-	
-	/**
-	 * The current aspect ratio of the loaded Player
-	 * @return
-	 */
-	public function getAspectRatio():Float
-	{
-		return _aspectRatio;
-	}
-	
-	/**
-	 * The current aspect ratio of the loaded Player in string format
-	 * @return
-	 */
-	public function getAspectRatioString():String
-	{
-		return _currentAspectRatio;
-	}
-	
-	/**
-	 * Original aspect ratio of the video
-	 * @return original aspect ratio
-	 */
-	public function getOriginalAspectRatio():Float
-	{
-		return _originalAspectRatio;
-	}
-	
-	/**
-	 * Total duration time of the loaded media
-	 * @return time in seconds
-	 */
-	public function getDuration():Float
-	{
-		return _mediaDuration;
-	}
-	
-	/**
-	 * The time in seconds where the player started downloading
-	 * @return time in seconds
-	 */
-	public function getStartTime():Float
-	{
-		return _startTime;
-	}
-	
-	/**
-	 * The stream associated with the player
-	 * @return netstream object
-	 */
-	public function getNetStream():NetStream
-	{
-		return _stream;
-	}
-	
-	/**
-	 * Video object associated to the player
-	 * @return video object for further manipulation
-	 */
-	public function getVideo():Video
-	{	
-		return _video;
-	}
-	
-	/**
-	 * Sound object associated to the player
-	 * @return sound object for further manipulation
-	 */
-	public function getSound():Sound
-	{
-		return _sound;
-	}
-	
-	/**
-	 * The id3 info of sound object
-	 * @return
-	 */
-	public function getId3Info():ID3Info
-	{
-		return _id3Info;
-	}
-	
-	/**
-	 * The current sound state
-	 * @return true if mute otherwise false
-	 */
-	public function getMute():Bool
-	{
-		return _soundMuted;
-	}
-	
-	/**
-	 * The amount of total bytes
-	 * @return amount of bytes
-	 */
-	public function getBytesTotal():Float
-	{
-		var bytesTotal:Float = 0;
-		
-		if (_streamType == StreamType.YOUTUBE)
-		{
-			if(_youtubeLoader != null && _mediaLoaded)
-			bytesTotal = Reflect.field(_youtubeLoader.content, "getVideoBytesTotal")();
-		}
-		else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-		{
-			bytesTotal = _stream.bytesTotal;
-		}
-		else if (_type == InputType.AUDIO)
-		{
-			bytesTotal = _sound.bytesTotal;
-		}
-		
-		return bytesTotal;
-	}
-	
-	/**
-	 * The amount of bytes loaded
-	 * @return amount of bytes
-	 */
-	public function getBytesLoaded():Float
-	{
-		var bytesLoaded:Float = 0;
-		
-		if (_streamType == StreamType.YOUTUBE)
-		{
-			if(_youtubeLoader != null && _mediaLoaded)
-			bytesLoaded = Reflect.field(_youtubeLoader.content, "getVideoBytesLoaded")();
-		}
-		else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-		{
-			bytesLoaded = _stream.bytesLoaded;
-		}
-		else if (_type == InputType.AUDIO)
-		{
-			bytesLoaded = _sound.bytesLoaded;
-		}
-		
-		return bytesLoaded;
-	}
-	
-	/**
-	 * Current playing file type
-	 * @return audio or video
-	 */
-	public function getType():String
-	{
-		return _type;
-	}
-	
-	/**
-	 * The stream method for the current playing media
-	 * @return
-	 */
-	public function getStreamType():String
-	{
-		return _streamType;
-	}
-	
-	/**
-	 * The server url for current rtmp stream
-	 * @return
-	 */
-	public function getServer():String
-	{
-		return _server;
-	}
-	
-	/**
-	 * To check current quality mode
-	 * @return true if high quality false if low
-	 */
-	public function getQuality():Bool
-	{
-		return _videoQualityHigh;
-	}
-	
-	/**
-	 * The current playing time
-	 * @return current playing time in seconds
-	 */
-	public function getCurrentTime():Float
-	{
-		var time:Float = 0;
-		if (_streamType == StreamType.YOUTUBE)
-		{
-			if(_youtubeLoader != null)
-			{
-				time = Reflect.field(_youtubeLoader.content, "getCurrentTime")();
-			}
-			else
-			{
-				time = 0;
-			}
-		}
-		else if (_streamType == StreamType.PSEUDOSTREAM)
-		{
-			time = getStartTime() + _stream.time;
-		}
-		else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
-		{
-			time = _stream.time;
-		}
-		else if (_type == InputType.AUDIO)
-		{
-			if(_soundChannel != null)
-			{	
-				time = _soundChannel.position / 1000;
-			}
-			else
-			{
-				time = 0;
-			}
-		}
-		
-		return time;
-	}
-	//}
+        //}
+
+        //{Initialize video and connection objects
+        _connection = new NetConnection();
+        _connection.client = this;
+        _connection.connect(null);
+        _stream = new NetStream(_connection);
+
+        _video = new Video(_stage.stageWidth, _stage.stageHeight);
+
+        _movieClip.addChild(_video);
+        //}
+
+        //Video mask so that custom menu items work
+        _videoMask = new Sprite();
+        _movieClip.addChild(_videoMask);
+
+        //Set initial rendering to high quality
+        toggleQuality();
+
+        //{Initialize system event listeners
+        _movieClip.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+        _stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
+        _stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
+        _stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreen);
+        _stage.addEventListener(Event.RESIZE, onResize);
+        _hideMouseTimer.addEventListener(TimerEvent.TIMER, hideMouseTimer);
+        _checkAudioTimer.addEventListener(TimerEvent.TIMER, checkAudioTimer);
+        _connection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
+        _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
+        //}
+    }
+    //}
+
+
+    //{Timers
+    /**
+     * Timer that hides the mouse pointer when it is idle and dispatch the PlayerEvents.MOUSE_HIDE
+     * @param   event
+     */
+    private function hideMouseTimer(event:TimerEvent):Void
+    {
+        if (_fullscreen)
+        {
+            if (_mouseVisible)
+            {
+                _mouseVisible = false;
+            }
+            else
+            {
+                Mouse.hide();
+                callEvents(PlayerEvents.MOUSE_HIDE);
+                _hideMouseTimer.stop();
+            }
+        }
+    }
+
+    /**
+     * To check if the sound finished playing
+     * @param   event
+     */
+    private function checkAudioTimer(event:TimerEvent):Void
+    {
+        if (_soundChannel.position + 100 >= _sound.length)
+        {
+            _isPlaying = false;
+            _mediaEndReached = true;
+            callEvents(PlayerEvents.PLAYBACK_FINISHED);
+
+            _checkAudioTimer.stop();
+        }
+    }
+    //}
+
+
+    //{Events
+    /**
+     * Callback after bandwidth calculation for rtmp streams
+     */
+    private function onBWDone():Void
+    {
+        //Need to study this more
+    }
+
+    /**
+     * Triggers error event on rtmp connections
+     * @param   event
+     */
+    private function onAsyncError(event:AsyncErrorEvent):Void
+    {
+        //TODO: Should trigger event for controls to display error message
+        //trace(event.error);
+    }
+
+    /**
+     * Checks if connection failed or succeed
+     * @param   event
+     */
+    private function onNetStatus(event:NetStatusEvent):Void
+    {
+        switch (event.info.code)
+        {
+            case "NetConnection.Connect.Success":
+                if (_streamType == StreamType.RTMP)
+                {
+                    _stream = new NetStream(_connection);
+                    _stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
+                    _stream.bufferTime = 10;
+                    //_stream.play(Utils.rtmpSourceParser(_mediaSource), true);
+                    _stream.play(_mediaSource);
+                    _stream.client = this;
+                    if(_type == InputType.VIDEO) {_video.attachNetStream(_stream); }
+                }
+                callEvents(PlayerEvents.CONNECTION_SUCCESS);
+
+            case "NetStream.Play.StreamNotFound":
+                trace("Stream not found: " + _mediaSource); //Replace with a dispatch for error event
+                callEvents(PlayerEvents.CONNECTION_FAILED);
+
+            case "NetStream.Play.Stop":
+                if (_streamType != StreamType.RTMP)
+                {
+                    if (_isPlaying) { _stream.togglePause(); }
+                    _isPlaying = false;
+                    _mediaEndReached = true;
+                    callEvents(PlayerEvents.PLAYBACK_FINISHED);
+                }
+
+            case "NetStream.Play.Start":
+                _isPlaying = true;
+                _mediaEndReached = false;
+                if (_stream.bytesLoaded != _stream.bytesTotal || _streamType == StreamType.RTMP)
+                {
+                    callEvents(PlayerEvents.BUFFERING);
+                }
+
+            case "NetStream.Seek.Notify":
+                _mediaEndReached = false;
+                if (_streamType == StreamType.RTMP)
+                {
+                    _isPlaying = true;
+                    callEvents(PlayerEvents.PLAY_PAUSE);
+                    callEvents(PlayerEvents.BUFFERING);
+                }
+
+            case "NetStream.Buffer.Empty":
+                if (_stream.bytesLoaded != _stream.bytesTotal)
+                {
+                    callEvents(PlayerEvents.BUFFERING);
+                }
+
+            case "NetStream.Buffer.Full":
+                callEvents(PlayerEvents.NOT_BUFFERING);
+
+            case "NetStream.Buffer.Flush":
+                if (_stream.bytesLoaded == _stream.bytesTotal)
+                {
+                    _downloadCompleted = true;
+                }
+        }
+    }
+
+    /**
+     * Proccess keyboard shortcuts
+     * @param   event
+     */
+    private function onKeyDown(event:KeyboardEvent):Void
+    {
+        var F_KEY:UInt = 70;
+        var M_KEY:UInt = 77;
+        var X_KEY:UInt = 88;
+
+        if(event.keyCode == Keyboard.TAB)
+        {
+            toggleAspectRatio();
+        }
+        else if(event.keyCode == F_KEY)
+        {
+            toggleFullscreen();
+        }
+        else if(event.keyCode == M_KEY)
+        {
+            toggleMute();
+        }
+        else if(event.keyCode == Keyboard.UP)
+        {
+            volumeUp();
+        }
+        else if(event.keyCode == Keyboard.DOWN)
+        {
+            volumeDown();
+        }
+        else if(event.keyCode == Keyboard.RIGHT)
+        {
+            forward();
+        }
+        else if(event.keyCode == Keyboard.LEFT)
+        {
+            rewind();
+        }
+        else if(event.keyCode == Keyboard.SPACE)
+        {
+            togglePlay();
+        }
+        else if(event.keyCode == X_KEY)
+        {
+            stopAndClose();
+        }
+    }
+
+    /**
+     * IF player is full screen shows the mouse when gets hide
+     * @param   event
+     */
+    private function onMouseMove(event:MouseEvent):Void
+    {
+        if (_fullscreen && !_mouseVisible)
+        {
+            if (!_hideMouseTimer.running)
+            {
+                _hideMouseTimer.start();
+            }
+
+            _mouseVisible = true;
+            Mouse.show();
+
+            callEvents(PlayerEvents.MOUSE_SHOW);
+        }
+    }
+
+    /**
+     * Resize video player
+     * @param   event
+     */
+    private function onResize(event:Event):Void
+    {
+        resizeAndCenterPlayer();
+    }
+
+    /**
+     * Dispath a full screen event to listeners as redraw player an takes care of some other aspects
+     * @param   event
+     */
+    private function onFullScreen(event:FullScreenEvent):Void
+    {
+        _fullscreen = event.fullScreen;
+
+        if (!event.fullScreen)
+        {
+            Mouse.show();
+            callEvents(PlayerEvents.MOUSE_SHOW);
+            _mouseVisible = true;
+        }
+        else
+        {
+            _mouseVisible = true;
+            _hideMouseTimer.start();
+        }
+
+        resizeAndCenterPlayer();
+
+        callEvents(PlayerEvents.FULLSCREEN);
+    }
+
+    /**
+     * Sits for any cue points available
+     * @param   data
+     * @note Planned future implementation
+     */
+    private function onCuePoint(data:Dynamic):Void
+    {
+
+    }
+
+    /**
+     * After a video is loaded this callback gets the video information at start and stores it on variables
+     * @param   data
+     */
+    private function onMetaData(data:Dynamic):Void
+    {
+        if (_firstLoad)
+        {
+            _isPlaying = true;
+
+            _firstLoad = false;
+            if (data.width)
+            {
+                _videoWidth = data.width;
+                _videoHeight = data.height;
+            }
+            else
+            {
+                _videoWidth = _video.width;
+                _videoHeight = _video.height;
+            }
+
+            //Store seekpoints times
+            if (data.hasOwnProperty("seekpoints")) //MP4
+            {
+                for (position in Reflect.fields(data.seekpoints))
+                {
+                    _seekPoints.push(Reflect.field(data.seekpoints, position).time);
+                }
+            }
+            else if (data.hasOwnProperty("keyframes")) //FLV
+            {
+                for (position in Reflect.fields(data.keyframes.times))
+                {
+                    _seekPoints.push(Reflect.field(data.keyframes.times, position));
+                }
+            }
+
+            _mediaLoaded = true;
+            _mediaDuration = data.duration;
+            _originalAspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
+
+            if (_aspectRatio <= 0)
+            {
+                _aspectRatio = _originalAspectRatio;
+            }
+
+            callEvents(PlayerEvents.MEDIA_INITIALIZED);
+
+            resizeAndCenterPlayer();
+
+            //Retrieve the volume that user selected last time
+            setVolume(_userSettings.getVolume());
+        }
+    }
+
+    /**
+     * Dummy function invoked for pseudostream servers
+     * @param   data
+     */
+    private function onLastSecond(data:Dynamic):Void
+    {
+        trace("last second pseudostream");
+    }
+
+    /**
+     * Broadcast Timeupdate and Duration
+     */
+    private function onEnterFrame(event:Event):Void
+    {
+        if (getDuration() > 0 && _lastTime != getCurrentTime())
+        {
+            _lastTime = getCurrentTime();
+            callEvents(PlayerEvents.TIME);
+        }
+
+        if (getBytesLoaded() > 0 && _lastProgress < getBytesLoaded())
+        {
+            _lastProgress = getBytesLoaded();
+            callEvents(PlayerEvents.PROGRESS);
+        }
+
+    }
+
+
+    /**
+     * Triggers when playbacks end on rtmp streaming server
+     */
+    private function onPlayStatus(info:Dynamic):Void
+    {
+        _isPlaying = false;
+        _mediaEndReached = true;
+        callEvents(PlayerEvents.PLAYBACK_FINISHED);
+    }
+
+    /**
+     * When sound finished downloading
+     * @param   event
+     */
+    private function onSoundComplete(event:Event)
+    {
+        _mediaDuration = _sound.length / 1000;
+        _downloadCompleted = true;
+
+        callEvents(PlayerEvents.MEDIA_INITIALIZED);
+    }
+
+    /**
+     * Mimic stream onMetaData
+     * @param   event
+     */
+    private function onSoundID3(event:Event)
+    {
+        if (_firstLoad)
+        {
+            _soundChannel = _sound.play();
+            _checkAudioTimer.start();
+
+            _isPlaying = true;
+
+            _firstLoad = false;
+
+            _mediaLoaded = true;
+            _mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
+            _aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
+            _originalAspectRatio = _aspectRatio;
+            _id3Info = _sound.id3;
+
+            callEvents(PlayerEvents.CONNECTION_SUCCESS);
+            callEvents(PlayerEvents.MEDIA_INITIALIZED);
+
+            resizeAndCenterPlayer();
+
+            //Retrieve the volume that user selected last time
+            setVolume(_userSettings.getVolume());
+        }
+    }
+
+    /**
+     * Dispatch connection failed event on error
+     * @param   event
+     */
+    private function onSoundIOError(event:IOErrorEvent)
+    {
+        callEvents(PlayerEvents.CONNECTION_FAILED);
+    }
+
+    /**
+     * Monitor sound download progress
+     * @param   event
+     */
+    private function onSoundProgress(event:ProgressEvent)
+    {
+        if (_sound.isBuffering)
+        {
+            callEvents(PlayerEvents.BUFFERING);
+        }
+        else
+        {
+            callEvents(PlayerEvents.NOT_BUFFERING);
+        }
+
+        _mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
+        callEvents(PlayerEvents.MEDIA_INITIALIZED);
+    }
+
+    /**
+     * Initializes the youtube loader object
+     * @param   event
+     */
+    private function onYouTubeLoaderInit(event:Event):Void
+    {
+        _youtubeLoader.content.addEventListener("onReady", onYoutubeReady);
+        _youtubeLoader.content.addEventListener("onError", onYoutubeError);
+        _youtubeLoader.content.addEventListener("onStateChange", onYoutubeStateChange);
+        _youtubeLoader.content.addEventListener("onPlaybackQualityChange", onYoutubePlaybackQualityChange);
+
+    }
+
+    /**
+     * This event is fired when the player is loaded and initialized, meaning it is ready to receive API calls.
+     */
+    private function onYoutubeReady(event:Event):Void
+    {
+        _movieClip.addChild(_youtubeLoader.content);
+        _movieClip.setChildIndex(_youtubeLoader.content, 0);
+        Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
+        Reflect.field(_youtubeLoader.content, "loadVideoByUrl")(Utils.youtubeSourceParse(_mediaSource));
+        callEvents(PlayerEvents.BUFFERING);
+    }
+
+    /**
+     * This event is fired whenever the player's state changes. Possible values are unstarted (-1), ended (0),
+     * playing (1), paused (2), buffering (3), video cued (5). When the SWF is first loaded it will broadcast
+     * an unstarted (-1) event. When the video is cued and ready to play it will broadcast a video cued event (5).
+     * @param   event
+     */
+    private function onYoutubeStateChange(event:Event):Void
+    {
+        var status:UInt = Std.parseInt(Reflect.field(event, "data"));
+
+        switch(status)
+        {
+            case -1:
+                callEvents(PlayerEvents.BUFFERING);
+
+            case 0:
+                _isPlaying = false;
+                _mediaEndReached = true;
+                callEvents(PlayerEvents.PLAYBACK_FINISHED);
+
+            case 1:
+                if (_firstLoad)
+                {
+                    _isPlaying = true;
+
+                    _videoWidth = _stage.stageWidth;
+                    _videoHeight = _stage.stageHeight;
+
+                    _firstLoad = false;
+
+                    _mediaLoaded = true;
+                    _mediaDuration = Reflect.field(_youtubeLoader.content, "getDuration")();
+                    _aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
+                    _originalAspectRatio = _aspectRatio;
+
+                    callEvents(PlayerEvents.CONNECTION_SUCCESS);
+                    callEvents(PlayerEvents.MEDIA_INITIALIZED);
+
+                    resizeAndCenterPlayer();
+
+                    //Retrieve the volume that user selected last time
+                    setVolume(_userSettings.getVolume());
+                }
+                callEvents(PlayerEvents.NOT_BUFFERING);
+
+            case 2:
+                callEvents(PlayerEvents.NOT_BUFFERING);
+
+            case 3:
+                callEvents(PlayerEvents.BUFFERING);
+
+            case 5:
+                callEvents(PlayerEvents.NOT_BUFFERING);
+        }
+    }
+
+    /**
+     * This event is fired whenever the video playback quality changes. For example, if you call the
+     * setPlaybackQuality(suggestedQuality) function, this event will fire if the playback quality actually
+     * changes. Your code should respond to the event and should not assume that the quality will automatically
+     * change when the setPlaybackQuality(suggestedQuality) function is called. Similarly, your code should not
+     * assume that playback quality will only change as a result of an explicit call to setPlaybackQuality or any
+     * other function that allows you to set a suggested playback quality.
+     *
+     * The value that the event broadcasts is the new playback quality. Possible values are "small", "medium",
+     * "large" and "hd720".
+     * @param   event
+     */
+    private function onYoutubePlaybackQualityChange(event:Event):Void
+    {
+        //trace(Reflect.field(event, "data"));
+    }
+
+    /**
+     * This event is fired when an error in the player occurs. The possible error codes are 100, 101,
+     * and 150. The 100 error code is broadcast when the video requested is not found. This occurs when
+     * a video has been removed (for any reason), or it has been marked as private. The 101 error code is
+     * broadcast when the video requested does not allow playback in the embedded players. The error code
+     * 150 is the same as 101, it's just 101 in disguise!
+     * @param   event
+     */
+    private function onYoutubeError(event:Event):Void
+    {
+        trace(Reflect.field(event, "data"));
+    }
+    //}
+
+
+    //{Private Methods
+    /**
+     * Function used each time is needed to dispatch an event
+     * @param   type
+     */
+    private function callEvents(type:String):Void
+    {
+        var playerEvent:PlayerEvents = new PlayerEvents(type, true);
+
+        playerEvent.aspectRatio = getAspectRatio();
+        playerEvent.duration = getDuration();
+        playerEvent.fullscreen = isFullscreen();
+        playerEvent.mute = getMute();
+        playerEvent.volume = getVolume();
+        playerEvent.width = _video.width;
+        playerEvent.height = _video.height;
+        playerEvent.stream = getNetStream();
+        playerEvent.sound = getSound();
+        playerEvent.time = getCurrentTime();
+        playerEvent.id3Info = getId3Info();
+
+        dispatchEvent(playerEvent);
+    }
+
+    /**
+     * Reposition and resizes the video player to fit on screen
+     */
+    private function resizeAndCenterPlayer():Void
+    {
+        if (_streamType != StreamType.YOUTUBE)
+        {
+            _video.height = _stage.stageHeight;
+            _video.width = _video.height * _aspectRatio;
+
+            _video.x = (_stage.stageWidth / 2) - (_video.width / 2);
+            _video.y = 0;
+
+            if (_video.width > _stage.stageWidth && _aspectRatio == _originalAspectRatio)
+            {
+                var aspectRatio:Float = _videoHeight / _videoWidth;
+                _video.width = _stage.stageWidth;
+                _video.height = aspectRatio * _video.width;
+                _video.x = 0;
+                _video.y = (_stage.stageHeight / 2) - (_video.height / 2);
+            }
+
+            _videoMask.graphics.clear();
+            _videoMask.graphics.lineStyle();
+            _videoMask.graphics.beginFill(0x000000, 0);
+            _videoMask.graphics.drawRect(_video.x, _video.y, _video.width, _video.height);
+            _videoMask.graphics.endFill();
+        }
+        else
+        {
+            Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
+
+            _videoMask.graphics.clear();
+            _videoMask.graphics.lineStyle();
+            _videoMask.graphics.beginFill(0x000000, 0);
+            _videoMask.graphics.drawRect(0, 0, _stage.stageWidth, _stage.stageHeight);
+            _videoMask.graphics.endFill();
+        }
+
+        callEvents(PlayerEvents.RESIZE);
+    }
+
+    /**
+     * Check the best seek point available if the seekpoints array is available
+     * @param   time time in seconds
+     * @return best seek point in seconds or given one if no seekpoints array is available
+     */
+    private function getBestSeekPoint(time:Float):Float
+    {
+        if (_seekPoints.length > 0)
+        {
+            var timeOne:String="0";
+            var timeTwo:String="0";
+
+            for(prop in Reflect.fields(_seekPoints))
+            {
+                if(Reflect.field(_seekPoints,prop) < time)
+                {
+                    timeOne = prop;
+                }
+                else
+                {
+                    timeTwo = prop;
+                break;
+                }
+            }
+
+            if(time - _seekPoints[Std.parseInt(timeOne)] < _seekPoints[Std.parseInt(timeTwo)] - time)
+            {
+                return _seekPoints[Std.parseInt(timeOne)];
+            }
+            else
+            {
+                return _seekPoints[Std.parseInt(timeTwo)];
+            }
+        }
+
+        return time;
+    }
+
+    /**
+     * Checks if the given seek time is already buffered
+     * @param   time time in seconds
+     * @return true if can seek false if not in buffer
+     */
+    private function canSeek(time:Float):Bool
+    {
+        if (_type == InputType.VIDEO)
+        {
+            time = getBestSeekPoint(time);
+        }
+
+        var cacheTotal = Math.floor((getDuration() - _startTime) * (getBytesLoaded() / getBytesTotal())) - 1;
+
+        if(time >= _startTime && time < _startTime + cacheTotal)
+        {
+            return true;
+        }
+
+        return false;
+    }
+    //}
+
+
+    //{Public methods
+    /**
+     * Loads a video and starts playing it
+     * @param   video video url to load
+     */
+    public function load(source:String, type:String="video", streamType:String="file", server:String=""):Void
+    {
+        stopAndClose();
+
+        _type = type;
+        _streamType = streamType;
+        _mediaSource = source;
+        _stopped = false;
+        _mediaLoaded = false;
+        _firstLoad = true;
+        _startTime = 0;
+        _downloadCompleted = false;
+        _seekPoints = new Array();
+        _server = server;
+
+        callEvents(PlayerEvents.BUFFERING);
+
+        if (_streamType == StreamType.YOUTUBE)
+        {
+            Security.allowDomain("*");
+            Security.allowDomain("www.youtube.com");
+            Security.allowDomain("youtube.com");
+            Security.allowDomain("s.ytimg.com");
+            Security.allowDomain("i.ytimg.com");
+
+            _youtubeLoader = new Loader();
+            _youtubeLoader.contentLoaderInfo.addEventListener(Event.INIT, onYouTubeLoaderInit);
+            _youtubeLoader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
+        }
+        else if (_type == InputType.VIDEO && (_streamType == StreamType.FILE || _streamType == StreamType.PSEUDOSTREAM))
+        {
+            _connection.connect(null);
+            _stream = new NetStream(_connection);
+            _stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
+            _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
+            _stream.bufferTime = _bufferTime;
+            _stream.play(source);
+            _stream.client = this;
+            _video.attachNetStream(_stream);
+        }
+        else if (_type == InputType.VIDEO && _streamType == StreamType.RTMP)
+        {
+            _connection.connect(_server);
+        }
+        else if (_type == InputType.AUDIO && _streamType == StreamType.RTMP)
+        {
+            _connection.connect(_server);
+        }
+        else if(_type == InputType.AUDIO && _streamType == StreamType.FILE)
+        {
+            _sound.load(new URLRequest(source));
+        }
+    }
+
+    private function doAsyncError(e:AsyncErrorEvent) : Void
+    {
+        // Do nothing, to block the exception.
+    }
+
+    /**
+     * Closes the connection and makes player available for another video
+     */
+    public function stopAndClose():Void
+    {
+        if (_mediaLoaded)
+        {
+            _mediaLoaded = false;
+            _isPlaying = false;
+            _stopped = true;
+            _startTime = 0;
+
+            if (_streamType == StreamType.YOUTUBE)
+            {
+                Reflect.field(_youtubeLoader.content, "destroy")();
+            }
+            else if (_type == InputType.VIDEO)
+            {
+                _stream.close();
+            }
+            else
+            {
+                _soundChannel.stop();
+                _sound.close();
+            }
+        }
+
+        callEvents(PlayerEvents.STOP_CLOSE);
+    }
+
+    /**
+     * Seeks 8 seconds forward from the current position.
+     * @return current play time after forward
+     */
+    public function forward():Float
+    {
+        var seekTime = (getCurrentTime() + 8) + _startTime;
+
+        if (getDuration() > seekTime)
+        {
+            seekTime = seek(seekTime);
+        }
+
+        return seekTime;
+    }
+
+    /**
+     * Seeks 8 seconds back from the current position.
+     * @return current play time after rewind
+     */
+    public function rewind():Float
+    {
+        var seekTime = (getCurrentTime() - 8) + _startTime;
+
+        if (seekTime >= _startTime)
+        {
+            seekTime = seek(seekTime);
+        }
+
+        return seekTime;
+    }
+
+    /**
+     * Seeks video player to a given time in seconds
+     * @param   seekTime time in seconds to seek
+     * @return current play time after seeking
+     */
+    public function seek(seekTime:Float):Float
+    {
+        if (_startTime <= 1 && _downloadCompleted)
+        {
+            if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+            {
+                _stream.seek(seekTime);
+            }
+            else if (_type == InputType.AUDIO)
+            {
+                _soundChannel.stop();
+                _soundChannel = _sound.play(seekTime * 1000);
+                if (!_isPlaying)
+                {
+                    _soundChannel.stop();
+                }
+
+                setVolume(_userSettings.getVolume());
+            }
+        }
+        else if(_seekPoints.length > 0 && _streamType == StreamType.PSEUDOSTREAM)
+        {
+            seekTime = getBestSeekPoint(seekTime);
+
+            if (canSeek(seekTime))
+            {
+                _stream.seek(seekTime - _startTime);
+            }
+            else if(seekTime != _startTime)
+            {
+                _startTime = seekTime;
+
+                var url:String;
+                if (_mediaSource.indexOf("?") != -1)
+                {
+                    url = _mediaSource + "&start=" + seekTime;
+                }
+                else
+                {
+                    url = _mediaSource + "?start=" + seekTime;
+                }
+                _stream.play(url);
+            }
+        }
+        else if (_streamType == StreamType.YOUTUBE)
+        {
+            if (!canSeek(seekTime))
+            {
+                _startTime = seekTime;
+                Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
+            }
+            else
+            {
+                Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
+            }
+
+        }
+        else if (_streamType == StreamType.RTMP)
+        {
+            // seekTime = getBestSeekPoint(seekTime); //Not Needed?
+            _stream.seek(seekTime);
+        }
+        else if(canSeek(seekTime))
+        {
+            if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+            {
+                _stream.seek(seekTime);
+            }
+            else if (_type == InputType.AUDIO)
+            {
+                _soundChannel.stop();
+                _soundChannel = _sound.play(seekTime * 1000);
+                if (!_isPlaying)
+                {
+                    _soundChannel.stop();
+                }
+
+                setVolume(_userSettings.getVolume());
+            }
+        }
+        callEvents(PlayerEvents.SEEK);
+        return seekTime;
+    }
+
+    /**
+     * To check wheter the media is playing
+     * @return true if is playing false otherwise
+     */
+    public function isPlaying():Bool
+    {
+        return _isPlaying;
+    }
+
+    /**
+     * Cycle betewen aspect ratios
+     * @return new aspect ratio in use
+     */
+    public function toggleAspectRatio():Float
+    {
+        switch(_currentAspectRatio)
+        {
+            case "original":
+                _aspectRatio = AspectRatio._1_1;
+                _currentAspectRatio = "1:1";
+
+            case "1:1":
+                _aspectRatio = AspectRatio._3_2;
+                _currentAspectRatio = "3:2";
+
+            case "3:2":
+                _aspectRatio = AspectRatio._4_3;
+                _currentAspectRatio = "4:3";
+
+            case "4:3":
+                _aspectRatio = AspectRatio._5_4;
+                _currentAspectRatio = "5:4";
+
+            case "5:4":
+                _aspectRatio = AspectRatio._14_9;
+                _currentAspectRatio = "14:9";
+
+            case "14:9":
+                _aspectRatio = AspectRatio._14_10;
+                _currentAspectRatio = "14:10";
+
+            case "14:10":
+                _aspectRatio = AspectRatio._16_9;
+                _currentAspectRatio = "16:9";
+
+            case "16:9":
+                _aspectRatio = AspectRatio._16_10;
+                _currentAspectRatio = "16:10";
+
+            case "16:10":
+                _aspectRatio = _originalAspectRatio;
+                _currentAspectRatio = "original";
+
+            default:
+                _aspectRatio = _originalAspectRatio;
+                _currentAspectRatio = "original";
+        }
+
+        resizeAndCenterPlayer();
+
+        callEvents(PlayerEvents.ASPECT_RATIO);
+
+        //Store aspect ratio into user settings
+        if (_aspectRatio == _originalAspectRatio)
+        {
+            _userSettings.setAspectRatio(0.0);
+        }
+        else
+        {
+            _userSettings.setAspectRatio(_aspectRatio);
+        }
+
+        return _aspectRatio;
+    }
+
+    /**
+     * Swithces between play and pause
+     */
+    public function togglePlay():Bool
+    {
+        if (_mediaLoaded)
+        {
+            if (_mediaEndReached)
+            {
+                _mediaEndReached = false;
+
+                if (_streamType == StreamType.YOUTUBE)
+                {
+                    Reflect.field(_youtubeLoader.content, "seekTo")(0);
+                    Reflect.field(_youtubeLoader.content, "playVideo")();
+                }
+                else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+                {
+                    _stream.seek(0);
+                    _stream.togglePause();
+                }
+                else if (_type == InputType.AUDIO)
+                {
+                    _checkAudioTimer.start();
+                    _soundChannel = _sound.play();
+                    setVolume(_userSettings.getVolume());
+                }
+            }
+            else if (_mediaLoaded)
+            {
+                if (_streamType == StreamType.YOUTUBE)
+                {
+                    if (_isPlaying)
+                    {
+                        Reflect.field(_youtubeLoader.content, "pauseVideo")();
+                    }
+                    else
+                    {
+                        Reflect.field(_youtubeLoader.content, "playVideo")();
+                    }
+                }
+                else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+                {
+                    _stream.togglePause();
+                }
+                else if (_type == InputType.AUDIO)
+                {
+                    if (_isPlaying)
+                    {
+                        _soundChannel.stop();
+                    }
+                    else
+                    {
+                        //If end of audio reached start from beggining
+                        if (_soundChannel.position + 100 >= _sound.length)
+                        {
+                            _soundChannel = _sound.play();
+                        }
+                        else
+                        {
+                            _soundChannel = _sound.play(_soundChannel.position);
+                        }
+
+                        setVolume(_userSettings.getVolume());
+                    }
+                }
+            }
+            else if (_stopped)
+            {
+                load(_mediaSource, _type, _streamType, _server);
+            }
+
+            _isPlaying = !_isPlaying;
+            callEvents(PlayerEvents.PLAY_PAUSE);
+            return _isPlaying;
+        }
+        else if(_mediaSource != "")
+        {
+            load(_mediaSource, _type, _streamType, _server);
+            callEvents(PlayerEvents.BUFFERING);
+            return true;
+        }
+        callEvents(PlayerEvents.PLAY_PAUSE);
+        return false;
+    }
+
+    /**
+     * Switches on or off fullscreen
+     * @return true if fullscreen otherwise false
+     */
+    public function toggleFullscreen():Bool
+    {
+        if (_fullscreen)
+        {
+            _stage.displayState = StageDisplayState.NORMAL;
+            _stage.focus = _stage;
+            return false;
+        }
+        else
+        {
+            if (_useHardWareScaling)
+            {
+                //Match full screen aspec ratio to desktop
+                var aspectRatio = Capabilities.screenResolutionY / Capabilities.screenResolutionX;
+                _stage.fullScreenSourceRect = new Rectangle(0, 0, _videoWidth, _videoWidth * aspectRatio);
+            }
+            else
+            {
+                //Use desktop resolution
+                _stage.fullScreenSourceRect = new Rectangle(0, 0, Capabilities.screenResolutionX ,Capabilities.screenResolutionY);
+            }
+
+            _stage.displayState = StageDisplayState.FULL_SCREEN;
+            _stage.focus = _stage;
+            return true;
+        }
+    }
+
+    /**
+     * Toggles betewen high and low quality image rendering
+     * @return true if quality high false otherwise
+     */
+    public function toggleQuality():Bool
+    {
+        if (_videoQualityHigh)
+        {
+            _video.smoothing = false;
+            _video.deblocking = 1;
+        }
+        else
+        {
+            _video.smoothing = true;
+            _video.deblocking = 5;
+        }
+
+        _videoQualityHigh = _videoQualityHigh?false:true;
+
+        return _videoQualityHigh;
+    }
+
+    /**
+     * Mutes or unmutes the sound
+     * @return true if muted false if unmuted
+     */
+    public function toggleMute():Bool
+    {
+        var soundTransform:SoundTransform = new SoundTransform();
+        var isMute:Bool;
+
+        //unmute sound
+        if (_soundMuted)
+        {
+            _soundMuted = false;
+
+            if (_volume > 0)
+            {
+                soundTransform.volume = _volume;
+            }
+            else
+            {
+                _volume = 1.0;
+                soundTransform.volume = _volume;
+            }
+
+            isMute =  false;
+        }
+
+        //mute sound
+        else
+        {
+            _soundMuted = true;
+            _volume = _stream.soundTransform.volume;
+            soundTransform.volume = 0;
+            _stream.soundTransform = soundTransform;
+
+            isMute = true;
+        }
+
+        if (_streamType == StreamType.YOUTUBE)
+        {
+            Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
+        }
+        else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+        {
+            _stream.soundTransform = soundTransform;
+        }
+        else if (_type == InputType.AUDIO)
+        {
+            _soundChannel.soundTransform = soundTransform;
+            setVolume(_userSettings.getVolume());
+        }
+
+        callEvents(PlayerEvents.MUTE);
+        return isMute;
+    }
+
+    /**
+     * Check if player is running on fullscreen mode
+     * @return true if fullscreen false if not
+     */
+    public function isFullscreen():Bool
+    {
+        return _stage.displayState == StageDisplayState.FULL_SCREEN;
+    }
+
+    /**
+     * Raises the volume
+     * @return volume value after raising
+     */
+    public function volumeUp():Float
+    {
+        var soundTransform:SoundTransform = new SoundTransform();
+
+        if (_soundMuted)
+        {
+            _soundMuted = false;
+        }
+
+        //raise volume if not already at max
+        if (_volume < 1)
+        {
+            if (_streamType == StreamType.YOUTUBE)
+            {
+                _volume = (Reflect.field(_youtubeLoader.content, "getVolume")() + 10) / 100;
+                Reflect.field(_youtubeLoader.content, "setVolume")(_volume * 100);
+            }
+            else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+            {
+                _volume = _stream.soundTransform.volume + (10/100);
+                soundTransform.volume = _volume;
+                _stream.soundTransform = soundTransform;
+            }
+            else if (_type == InputType.AUDIO)
+            {
+                _volume = _soundChannel.soundTransform.volume + (10/100);
+                soundTransform.volume = _volume;
+                _soundChannel.soundTransform = soundTransform;
+            }
+        }
+
+        //reset volume to 1.0 if already reached max
+        if (_volume >= 1)
+        {
+            _volume = 1.0;
+        }
+
+        //Store volume into user settings
+        _userSettings.setVolume(_volume);
+
+        callEvents(PlayerEvents.VOLUME_UP);
+        return _volume;
+    }
+
+    /**
+     * Lower the volume
+     * @return volume value after lowering
+     */
+    public function volumeDown():Float
+    {
+        var soundTransform:SoundTransform = new SoundTransform();
+
+        //lower sound
+        if(!_soundMuted)
+        {
+            if (_streamType == StreamType.YOUTUBE)
+            {
+                _volume = (Reflect.field(_youtubeLoader.content, "getVolume")() - 10) / 100;
+                Reflect.field(_youtubeLoader.content, "setVolume")(_volume * 100);
+            }
+            else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+            {
+                _volume = _stream.soundTransform.volume - (10/100);
+                soundTransform.volume = _volume;
+                _stream.soundTransform = soundTransform;
+            }
+            else if (_type == InputType.AUDIO)
+            {
+                _volume = _soundChannel.soundTransform.volume - (10/100);
+                soundTransform.volume = _volume;
+                _soundChannel.soundTransform = soundTransform;
+            }
+
+            //if volume reached min is muted
+            if (_volume <= 0)
+            {
+                _soundMuted = true;
+                _volume = 0;
+            }
+        }
+
+        //Store volume into user settings
+        _userSettings.setVolume(_volume);
+
+        callEvents(PlayerEvents.VOLUME_DOWN);
+        return _volume;
+    }
+    //}
+
+
+    //{Setters
+    /**
+     * Set input type
+     * @param   type Allowable values are audio, video
+     */
+    public function setType(type:String):Void
+    {
+        _type = type;
+    }
+
+    /**
+     * Set streaming type
+     * @param   streamType Allowable values are file, http, rmtp
+     */
+    public function setStreamType(streamType:String):Void
+    {
+        _streamType = streamType;
+    }
+
+    /**
+     * Sets the server url for rtmp streams
+     * @param   server
+     */
+    public function setServer(server:String):Void
+    {
+        _server = server;
+    }
+
+    /**
+     * To set the video source in case we dont want to start downloading at first so when use tooglePlay the
+     * media is loaded automatically
+     * @param   source
+     */
+    public function setSource(source):Void
+    {
+        _mediaSource = source;
+    }
+
+    /**
+     * Changes the current volume
+     * @param   volume
+     */
+    public function setVolume(volume:Float):Void
+    {
+        var soundTransform:SoundTransform = new SoundTransform();
+
+        if (volume > _volume) {
+            callEvents(PlayerEvents.VOLUME_UP);
+        }
+
+        if (volume < _volume) {
+            callEvents(PlayerEvents.VOLUME_DOWN);
+        }
+
+        if (volume > 0)
+        {
+            _soundMuted = false;
+            _volume = volume;
+        }
+        else
+        {
+            _soundMuted = true;
+            _volume = 1.0;
+        }
+
+        soundTransform.volume = volume;
+
+        if (!_firstLoad) //To prevent errors if objects aren't initialized
+        {
+            if (_streamType == StreamType.YOUTUBE)
+            {
+                Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
+            }
+            else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+            {
+                _stream.soundTransform = soundTransform;
+            }
+            else if (_type == InputType.AUDIO)
+            {
+                _soundChannel.soundTransform = soundTransform;
+            }
+        }
+
+        //Store volume into user settings
+        _userSettings.setVolume(_volume);
+
+        callEvents(PlayerEvents.VOLUME_CHANGE);
+    }
+
+    /**
+     * Changes the buffer time for local and pseudo streaming
+     * @param   time in seconds
+     */
+    public function setBufferTime(time:Float):Void
+    {
+        if (time > 0)
+        {
+            _bufferTime = time;
+        }
+    }
+
+    /**
+     * Changes the aspec ratio of current playing media and resizes video player
+     * @param   aspectRatio new aspect ratio value
+     */
+    public function setAspectRatio(aspectRatio:Float):Void
+    {
+        _aspectRatio = aspectRatio;
+
+        switch(_aspectRatio)
+        {
+            case 0.0:
+                _currentAspectRatio = "original";
+
+            case AspectRatio._1_1:
+                _currentAspectRatio = "1:1";
+
+            case AspectRatio._3_2:
+                _currentAspectRatio = "3:2";
+
+            case AspectRatio._4_3:
+                _currentAspectRatio = "4:3";
+
+            case AspectRatio._5_4:
+                _currentAspectRatio = "5:4";
+
+            case AspectRatio._14_9:
+                _currentAspectRatio = "14:9";
+
+            case AspectRatio._14_10:
+                _currentAspectRatio = "14:10";
+
+            case AspectRatio._16_9:
+                _currentAspectRatio = "16:9";
+
+            case AspectRatio._16_10:
+                _currentAspectRatio = "16:10";
+        }
+
+        resizeAndCenterPlayer();
+
+        //Store aspect ratio into user settings
+        _userSettings.setAspectRatio(_aspectRatio);
+    }
+
+    /**
+     * Enable or disable hardware scaling
+     * @param   value true to enable false to disable
+     */
+    public function setHardwareScaling(value:Bool):Void
+    {
+        _useHardWareScaling = value;
+    }
+    //}
+
+
+    //{Getters
+    /**
+     * Gets the volume amount 0.0 to 1.0
+     * @return
+     */
+    public function getVolume():Float
+    {
+        return _volume;
+    }
+
+    /**
+     * The current aspect ratio of the loaded Player
+     * @return
+     */
+    public function getAspectRatio():Float
+    {
+        return _aspectRatio;
+    }
+
+    /**
+     * The current aspect ratio of the loaded Player in string format
+     * @return
+     */
+    public function getAspectRatioString():String
+    {
+        return _currentAspectRatio;
+    }
+
+    /**
+     * Original aspect ratio of the video
+     * @return original aspect ratio
+     */
+    public function getOriginalAspectRatio():Float
+    {
+        return _originalAspectRatio;
+    }
+
+    /**
+     * Total duration time of the loaded media
+     * @return time in seconds
+     */
+    public function getDuration():Float
+    {
+        return _mediaDuration;
+    }
+
+    /**
+     * The time in seconds where the player started downloading
+     * @return time in seconds
+     */
+    public function getStartTime():Float
+    {
+        return _startTime;
+    }
+
+    /**
+     * The stream associated with the player
+     * @return netstream object
+     */
+    public function getNetStream():NetStream
+    {
+        return _stream;
+    }
+
+    /**
+     * Video object associated to the player
+     * @return video object for further manipulation
+     */
+    public function getVideo():Video
+    {
+        return _video;
+    }
+
+    /**
+     * Sound object associated to the player
+     * @return sound object for further manipulation
+     */
+    public function getSound():Sound
+    {
+        return _sound;
+    }
+
+    /**
+     * The id3 info of sound object
+     * @return
+     */
+    public function getId3Info():ID3Info
+    {
+        return _id3Info;
+    }
+
+    /**
+     * The current sound state
+     * @return true if mute otherwise false
+     */
+    public function getMute():Bool
+    {
+        return _soundMuted;
+    }
+
+    /**
+     * The amount of total bytes
+     * @return amount of bytes
+     */
+    public function getBytesTotal():Float
+    {
+        var bytesTotal:Float = 0;
+
+        if (_streamType == StreamType.YOUTUBE)
+        {
+            if(_youtubeLoader != null && _mediaLoaded)
+            bytesTotal = Reflect.field(_youtubeLoader.content, "getVideoBytesTotal")();
+        }
+        else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+        {
+            bytesTotal = _stream.bytesTotal;
+        }
+        else if (_type == InputType.AUDIO)
+        {
+            bytesTotal = _sound.bytesTotal;
+        }
+
+        return bytesTotal;
+    }
+
+    /**
+     * The amount of bytes loaded
+     * @return amount of bytes
+     */
+    public function getBytesLoaded():Float
+    {
+        var bytesLoaded:Float = 0;
+
+        if (_streamType == StreamType.YOUTUBE)
+        {
+            if(_youtubeLoader != null && _mediaLoaded)
+            bytesLoaded = Reflect.field(_youtubeLoader.content, "getVideoBytesLoaded")();
+        }
+        else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+        {
+            bytesLoaded = _stream.bytesLoaded;
+        }
+        else if (_type == InputType.AUDIO)
+        {
+            bytesLoaded = _sound.bytesLoaded;
+        }
+
+        return bytesLoaded;
+    }
+
+    /**
+     * Current playing file type
+     * @return audio or video
+     */
+    public function getType():String
+    {
+        return _type;
+    }
+
+    /**
+     * The stream method for the current playing media
+     * @return
+     */
+    public function getStreamType():String
+    {
+        return _streamType;
+    }
+
+    /**
+     * The server url for current rtmp stream
+     * @return
+     */
+    public function getServer():String
+    {
+        return _server;
+    }
+
+    /**
+     * To check current quality mode
+     * @return true if high quality false if low
+     */
+    public function getQuality():Bool
+    {
+        return _videoQualityHigh;
+    }
+
+    /**
+     * The current playing time
+     * @return current playing time in seconds
+     */
+    public function getCurrentTime():Float
+    {
+        var time:Float = 0;
+        if (_streamType == StreamType.YOUTUBE)
+        {
+            if(_youtubeLoader != null)
+            {
+                time = Reflect.field(_youtubeLoader.content, "getCurrentTime")();
+            }
+            else
+            {
+                time = 0;
+            }
+        }
+        else if (_streamType == StreamType.PSEUDOSTREAM)
+        {
+            time = getStartTime() + _stream.time;
+        }
+        else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP)
+        {
+            time = _stream.time;
+        }
+        else if (_type == InputType.AUDIO)
+        {
+            if(_soundChannel != null)
+            {
+                time = _soundChannel.position / 1000;
+            }
+            else
+            {
+                time = 0;
+            }
+        }
+
+        return time;
+    }
+    //}
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/jarisplayer.git



More information about the Pkg-javascript-commits mailing list