[Pkg-javascript-commits] [jarisplayer] 02/80: Jaris Plaver v2.0 now using haxe.

Jonas Smedegaard dr at jones.dk
Tue May 10 08:45:30 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 86a00dbb4fca13aa6dfb679432c634891a6b53a9
Author: jgmylm <jgmylm at edf201c3-a14d-0410-a11e-aa85364efa9f>
Date:   Sat Mar 6 08:46:05 2010 +0000

    Jaris Plaver v2.0 now using haxe.
    
    git-svn-id: https://jaris.svn.sourceforge.net/svnroot/jaris/trunk@2 edf201c3-a14d-0410-a11e-aa85364efa9f
---
 DOCUMENTATION.TXT                     |   11 -
 Jaris FLV Player.hxproj               |   52 ++
 bin/JarisFLVPlayer.swf                |  Bin 0 -> 16949 bytes
 bin/expressInstall.swf                |  Bin 0 -> 773 bytes
 bin/index.html                        |   59 ++
 bin/jaris-intro.mp4                   |  Bin 0 -> 2908604 bytes
 bin/js/swfobject.js                   |    4 +
 logo.png => bin/logo-color.png        |  Bin
 bin/logo.png                          |  Bin 0 -> 34150 bytes
 bin/poster.png                        |  Bin 0 -> 89121 bytes
 jarisplayer.swf                       |  Bin 21276 -> 0 bytes
 jarisplayer.swi                       |  Bin 45389 -> 0 bytes
 LICENSE.TXT => license.txt            |   57 +-
 README.TXT => readme.txt              |    4 +-
 src/jaris/Main.hx                     |   99 ++++
 src/jaris/Version.hx                  |   17 +
 src/jaris/animation/Animation.hx      |   60 ++
 src/jaris/animation/AnimationsBase.hx |  250 ++++++++
 src/jaris/display/Loader.hx           |  139 +++++
 src/jaris/display/Logo.hx             |  168 ++++++
 src/jaris/display/Menu.hx             |  202 +++++++
 src/jaris/display/Poster.hx           |  118 ++++
 src/jaris/events/PlayerEvents.hx      |   56 ++
 src/jaris/player/AspectRatio.hx       |   32 ++
 src/jaris/player/Controls.hx          |  938 ++++++++++++++++++++++++++++++
 src/jaris/player/Player.hx            | 1005 +++++++++++++++++++++++++++++++++
 src/jaris/player/StreamType.hx        |   16 +
 src/jaris/utils/Utils.hx              |  123 ++++
 28 files changed, 3343 insertions(+), 67 deletions(-)

diff --git a/DOCUMENTATION.TXT b/DOCUMENTATION.TXT
deleted file mode 100644
index 53b153e..0000000
--- a/DOCUMENTATION.TXT
+++ /dev/null
@@ -1,11 +0,0 @@
-==================
-Flash Variables
-==================
-
-Here is the list of variables that you can pass to the player.
-
-  * file: This is the actual file that is going to be played.
-  * thumb: Screenshot of the video that is displayed before playing.
-  * logo: An image of your logo that will be displayed on bottom right corner of the player.
-  * alphalogo: A value between 0 and 100 that sets the transparency of your logo.
-  * autostart: A true or false value that indicates to the player if it should auto play the video on load.
\ No newline at end of file
diff --git a/Jaris FLV Player.hxproj b/Jaris FLV Player.hxproj
new file mode 100644
index 0000000..5891723
--- /dev/null
+++ b/Jaris FLV Player.hxproj	
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project>
+  <!-- Output SWF options -->
+  <output>
+    <movie disabled="False" />
+    <movie input="" />
+    <movie path="bin\JarisFLVPlayer.swf" />
+    <movie fps="30" />
+    <movie width="800" />
+    <movie height="600" />
+    <movie version="10" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <class path="src" />
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option mainClass="jaris.Main" />
+    <option override="False" />
+    <option verbose="False" />
+    <option additional="" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <compile path="src\jaris\Main.hx" />
+  </compileTargets>
+  <!-- Assets to embed into the output SWF -->
+  <library>
+    <!-- example: <asset path="..." id="..." update="..." glyphs="..." mode="..." place="..." sharepoint="..." /> -->
+  </library>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <!-- example: <hidden path="..." /> -->
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand />
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="True" />
+    <option testMovie="Default" />
+  </options>
+</project>
\ No newline at end of file
diff --git a/bin/JarisFLVPlayer.swf b/bin/JarisFLVPlayer.swf
new file mode 100644
index 0000000..8bfe04d
Binary files /dev/null and b/bin/JarisFLVPlayer.swf differ
diff --git a/bin/expressInstall.swf b/bin/expressInstall.swf
new file mode 100644
index 0000000..86958bf
Binary files /dev/null and b/bin/expressInstall.swf differ
diff --git a/bin/index.html b/bin/index.html
new file mode 100644
index 0000000..dd62cb1
--- /dev/null
+++ b/bin/index.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+	<title>Jaris FLV Player</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="language" content="en" />
+	<meta name="description" content="" />
+	<meta name="keywords" content="" />
+	
+	<script src="js/swfobject.js" type="text/javascript"></script>
+	<script type="text/javascript">
+		var flashvars = {
+			file: "jaris-intro.mp4",
+			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"
+		};
+		var params = {
+			menu: "false",
+			scale: "noScale",
+			allowFullscreen: "true",
+			allowScriptAccess: "always",
+			bgcolor: "#000000",
+			quality: "high",
+			wmode: "opaque"
+		};
+		var attributes = {
+			id:"JarisFLVPlayer"
+		};
+		swfobject.embedSWF("JarisFLVPlayer.swf", "altContent", "640px", "360px", "10.0.0", "expressInstall.swf", flashvars, params, attributes);
+	</script>
+	<style>
+		html, body { height:100%; }
+		body { margin:0; }
+	</style>
+</head>
+<body>
+<br />
+	<center>
+	<div id="altContent">
+		<h1>Jaris FLV Player</h1>
+		<p>Alternative content</p>
+		<p><a href="http://www.adobe.com/go/getflashplayer"><img 
+			src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" 
+			alt="Get Adobe Flash player" /></a></p>
+	</div>
+	</center>
+</body>
+</html>
\ No newline at end of file
diff --git a/bin/jaris-intro.mp4 b/bin/jaris-intro.mp4
new file mode 100644
index 0000000..8ad9ecb
Binary files /dev/null and b/bin/jaris-intro.mp4 differ
diff --git a/bin/js/swfobject.js b/bin/js/swfobject.js
new file mode 100644
index 0000000..8eafe9d
--- /dev/null
+++ b/bin/js/swfobject.js
@@ -0,0 +1,4 @@
+/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
+	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
+*/
+var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/. [...]
\ No newline at end of file
diff --git a/logo.png b/bin/logo-color.png
similarity index 100%
rename from logo.png
rename to bin/logo-color.png
diff --git a/bin/logo.png b/bin/logo.png
new file mode 100644
index 0000000..da997ab
Binary files /dev/null and b/bin/logo.png differ
diff --git a/bin/poster.png b/bin/poster.png
new file mode 100644
index 0000000..029fd99
Binary files /dev/null and b/bin/poster.png differ
diff --git a/jarisplayer.swf b/jarisplayer.swf
deleted file mode 100644
index 38f1948..0000000
Binary files a/jarisplayer.swf and /dev/null differ
diff --git a/jarisplayer.swi b/jarisplayer.swi
deleted file mode 100644
index d8be98c..0000000
Binary files a/jarisplayer.swi and /dev/null differ
diff --git a/LICENSE.TXT b/license.txt
similarity index 91%
rename from LICENSE.TXT
rename to license.txt
index 946a38d..f55f0f6 100644
--- a/LICENSE.TXT
+++ b/license.txt
@@ -1,4 +1,5 @@
-											GNU GENERAL PUBLIC LICENSE
+					  GNU GENERAL PUBLIC LICENSE
+					  
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@@ -620,60 +621,8 @@ copy of the Program in return for a fee.
 
                      END OF TERMS AND CONDITIONS
 
-            How to Apply These Terms to Your New Programs
 
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    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
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
-									GNU LESSER GENERAL PUBLIC LICENSE
+				  GNU LESSER GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
diff --git a/README.TXT b/readme.txt
similarity index 85%
rename from README.TXT
rename to readme.txt
index c54b43e..234cbcc 100644
--- a/README.TXT
+++ b/readme.txt
@@ -1,8 +1,8 @@
 ==================
 Jaris FLV Player
 ==================
-A flash flv player made on SwishMax 2 that can be embedded into any website for free 
-or commercial use. 
+A flash flv player made using haxe and flash develop that can be embedded into any website
+for free or commercial use. 
 
 Web Page: http://jaris.sourceforge.net/
 Project Page: https://sourceforge.net/projects/jaris/
diff --git a/src/jaris/Main.hx b/src/jaris/Main.hx
new file mode 100644
index 0000000..c46514c
--- /dev/null
+++ b/src/jaris/Main.hx
@@ -0,0 +1,99 @@
+/**
+ * ...
+ * @author Jefferson González
+ * 
+ */
+
+package jaris;
+
+import flash.display.Stage;
+import flash.display.StageAlign;
+import flash.display.StageScaleMode;
+import flash.Lib;
+import flash.system.Capabilities;
+import jaris.display.Loader;
+import jaris.display.Logo;
+import jaris.display.Menu;
+import jaris.display.Poster;
+import jaris.player.Controls;
+import jaris.player.Player;
+import jaris.player.StreamType;
+
+/**
+ * Main jaris player starting point
+ */
+class Main 
+{
+	static function main() 
+	{
+		//Initialize stage and main movie clip
+		var stage = Lib.current.stage;
+		var movieClip = Lib.current;
+		
+		stage.scaleMode = StageScaleMode.NO_SCALE;
+		stage.align = StageAlign.TOP_LEFT;
+		
+		//Reads flash vars
+		var parameters:Dynamic<String> = flash.Lib.current.loaderInfo.parameters;
+		
+		//Draw preview image
+		var poster:String = parameters.poster != null ? parameters.poster : "";
+		var posterImage = new Poster(poster);
+		movieClip.addChild(posterImage);
+		
+		//Initialize and draw player object
+		var player:Player = new Player();
+		if (Capabilities.playerType == "PlugIn" || Capabilities.playerType == "ActiveX")
+		{
+			var autoStart:Bool = parameters.autostart == "true" || parameters.autostart == ""? true: false;
+			var streamType:String = parameters.streamtype != ""? parameters.streamtype : StreamType.FILE;
+			
+			player.setStreamType(streamType);
+			
+			if (autoStart)
+			{
+				player.load(parameters.file);
+			}
+			else
+			{
+				player.setVideoSource(parameters.file);
+			}
+			
+			player.setPoster(posterImage);
+			player.setHardwareScaling(parameters.hardwarescaling=="true"?true:false);
+		}
+		else
+		{
+			//For development purpose
+			player.load("jaris-intro.mp4");
+		}
+		
+		//Modify Context Menu
+		var menu:Menu = new Menu(player);
+		
+		//Draw logo
+		var logoSource:String = parameters.logo != null ? parameters.logo : "logo.png";
+		var logoPosition:String = parameters.logoposition != null ? parameters.logoposition : "top left";
+		var logoAlpha:Float = parameters.logoalpha != null ? Std.parseFloat(parameters.logoalpha) / 100 : 0.3;
+		var logoWidth:Float = parameters.logowidth != null ? Std.parseFloat(parameters.logowidth) : 130;
+		var logoLink:String = parameters.logolink != null ? parameters.logolink : "http://jaris.sourceforge.net";
+		
+		var logo:Logo = new Logo(logoSource, logoPosition, logoAlpha, logoWidth);
+		logo.setLink(logoLink);
+		movieClip.addChild(logo);
+		
+		
+		//Draw Controls
+		var controls:Controls = new Controls(player);
+		
+		var controlColors:Array <String> = ["", "", "", ""];
+		controlColors[0] = parameters.darkcolor != null ? parameters.darkcolor : "";
+		controlColors[1] = parameters.brightcolor != null ? parameters.brightcolor : "";
+		controlColors[2] = parameters.controlcolor != null ? parameters.controlcolor : "";
+		controlColors[3] = parameters.hovercolor != null ? parameters.hovercolor : "";
+		
+		controls.setControlColors(controlColors);
+		
+		movieClip.addChild(controls);
+	}
+}
\ No newline at end of file
diff --git a/src/jaris/Version.hx b/src/jaris/Version.hx
new file mode 100644
index 0000000..75509a4
--- /dev/null
+++ b/src/jaris/Version.hx
@@ -0,0 +1,17 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris;
+
+/**
+ * Actual jaris player version and date
+ */
+class Version 
+{
+	public static var NUMBER:String = "2.0";
+	public static var DATE:String = "05";
+	public static var MONTH:String = "03";
+	public static var YEAR:String = "2010";
+}
\ No newline at end of file
diff --git a/src/jaris/animation/Animation.hx b/src/jaris/animation/Animation.hx
new file mode 100644
index 0000000..d422d56
--- /dev/null
+++ b/src/jaris/animation/Animation.hx
@@ -0,0 +1,60 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.animation;
+
+/**
+ * Gives quick access usage to jaris effects
+ */
+class Animation
+{
+
+	/**
+	 * Quick access to fade in effect
+	 * @param	object
+	 * @param	seconds
+	 */
+	public static function fadeIn(object:Dynamic, seconds:Float)
+	{
+		var animation:AnimationsBase = new AnimationsBase();
+		animation.fadeIn(object, seconds);
+	}
+	
+	/**
+	 * Quick access to fade out effect
+	 * @param	object
+	 * @param	seconds
+	 */
+	public static function fadeOut(object:Dynamic, seconds:Float)
+	{
+		var animation:AnimationsBase = new AnimationsBase();
+		animation.fadeOut(object, seconds);
+	}
+	
+	/**
+	 * Quick access to slide in effect
+	 * @param	object
+	 * @param	position
+	 * @param	seconds
+	 */
+	public static function slideIn(object:Dynamic, position:String, seconds:Float)
+	{
+		var animation:AnimationsBase = new AnimationsBase();
+		animation.slideIn(object, position, seconds);
+	}
+	
+	/**
+	 * Quick access to slide out effect
+	 * @param	object
+	 * @param	position
+	 * @param	seconds
+	 */
+	public static function slideOut(object:Dynamic, position:String, seconds:Float)
+	{
+		var animation:AnimationsBase = new AnimationsBase();
+		animation.slideOut(object, position, seconds);
+	}
+	
+}
\ No newline at end of file
diff --git a/src/jaris/animation/AnimationsBase.hx b/src/jaris/animation/AnimationsBase.hx
new file mode 100644
index 0000000..afe4499
--- /dev/null
+++ b/src/jaris/animation/AnimationsBase.hx
@@ -0,0 +1,250 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.animation;
+
+import flash.display.MovieClip;
+import flash.display.Stage;
+import flash.events.TimerEvent;
+import flash.Lib;
+import flash.utils.Timer;
+
+/**
+ * Jaris main animations
+ */
+class AnimationsBase
+{
+	private var _fadeInTimer:Timer;
+	private var _fadeOutTimer:Timer;
+	
+	private var _slideInTimer:Timer;
+	private var _slideInOrigX:Float;
+	private var _slideInOrigY:Float;
+	private var _slideInPosition:String;
+	private var _slideInIncrements:Float;
+	
+	private var _slideOutTimer:Timer;
+	private var _slideOutOrigX:Float;
+	private var _slideOutOrigY:Float;
+	private var _slideOutPosition:String;
+	private var _slideOutIncrements:Float;
+	
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	
+	
+	private var _currentObject:Dynamic;
+	
+	public function new()
+	{
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+	}
+	
+	private function slideInTimer(event:TimerEvent)
+	{
+		var last:Bool = false;
+		switch(_slideInPosition)
+		{
+			case "top":
+				if (_currentObject.y >= _slideInOrigY) { _slideInTimer.stop(); last = true; }
+				_currentObject.y += _slideInIncrements;
+				
+			case "left":
+				if (_currentObject.x >= _slideInOrigX) { _slideInTimer.stop(); last = true; }
+				_currentObject.x += _slideInIncrements;
+				
+			case "bottom":
+				if (_currentObject.y <= _slideInOrigY) { _slideInTimer.stop(); last = true; }
+				_currentObject.y -= _slideInIncrements;
+				
+			case "right":
+				if (_currentObject.x <= _slideInOrigX) { _slideInTimer.stop(); last = true; }
+				_currentObject.x -= _slideInIncrements;
+		}
+		
+		if (last)
+		{
+			_currentObject.x = _slideInOrigX;
+			_currentObject.y = _slideInOrigY;
+		}
+	}
+	
+	private function slideOutTimer(event:TimerEvent)
+	{
+		if (((_currentObject.x + _currentObject.width)  < 0) || (_currentObject.y + _currentObject.height < 0))
+		{
+			_currentObject.visible = false;
+			_currentObject.x = _slideOutOrigX;
+			_currentObject.y = _slideOutOrigY;
+			
+			_slideOutTimer.stop();
+		}
+		else if (((_currentObject.x)  > _stage.stageWidth) || (_currentObject.y > _stage.stageHeight))
+		{
+			_currentObject.visible = false;
+			_currentObject.x = _slideOutOrigX;
+			_currentObject.y = _slideOutOrigY;
+			
+			_slideOutTimer.stop();
+		}
+		else
+		{
+			switch(_slideOutPosition)
+			{
+				case "top":
+					_currentObject.y -= _slideOutIncrements;
+					
+				case "left":
+					_currentObject.x -= _slideOutIncrements;
+					
+				case "bottom":
+					_currentObject.y += _slideOutIncrements;
+					
+				case "right":
+					_currentObject.x += _slideOutIncrements;
+			}
+		}
+	}
+	
+	private function fadeOutTimer(event:TimerEvent)
+	{
+		if (_currentObject.alpha > 0)
+		{
+			_currentObject.alpha -= 1 / 10;
+		}
+		else
+		{
+			_currentObject.visible = false;
+			_fadeOutTimer.stop();
+		}
+	}
+	
+	private function fadeInTimer(event:TimerEvent)
+	{
+		if (_currentObject.alpha < 1)
+		{
+			_currentObject.alpha += 1 / 10;
+		}
+		else
+		{
+			_fadeInTimer.stop();
+		}
+	}
+	
+	public function slideIn(object:Dynamic, slidePosition:String, speed:Float=1000)
+	{
+		if (object.visible)
+		{
+			object.visible = false;
+		}
+		
+		_slideInOrigX = object.x;
+		_slideInOrigY = object.y;
+		_slideInPosition = slidePosition;
+		
+		var increments:Float = 0;
+		
+		switch(slidePosition)
+		{
+			case "top":
+				object.y = 0 - object.height;
+				increments = object.height + _slideInOrigY;
+				
+			case "left":
+				object.x = 0 - object.width;
+				increments = object.width + _slideInOrigX;
+				
+			case "bottom":
+				object.y = _stage.stageHeight;
+				increments = _stage.stageHeight - _slideInOrigY;
+				
+			case "right":
+				object.x = _stage.stageWidth;
+				increments = _stage.stageWidth - _slideInOrigX;
+		}
+		
+		_slideInIncrements = increments / (speed / 100);
+		
+		_currentObject = object;
+		_currentObject.visible = true;
+		_currentObject.alpha = 1;
+		
+		_slideInTimer = new Timer(speed / 100);
+		_slideInTimer.addEventListener(TimerEvent.TIMER, slideInTimer);
+		_slideInTimer.start();
+	}
+	
+	public function slideOut(object:Dynamic, slidePosition:String, speed:Float=1000)
+	{
+		if (!object.visible)
+		{
+			object.visible = true;
+		}
+		
+		_slideOutOrigX = object.x;
+		_slideOutOrigY = object.y;
+		_slideOutPosition = slidePosition;
+		
+		var increments:Float = 0;
+		
+		switch(slidePosition)
+		{
+			case "top":
+				increments = object.height + _slideOutOrigY;
+				
+			case "left":
+				increments = object.width + _slideOutOrigX;
+				
+			case "bottom":
+				increments = _stage.stageHeight - _slideOutOrigY;
+				
+			case "right":
+				increments = _stage.stageWidth - _slideOutOrigX;
+		}
+		
+		_slideOutIncrements = increments / (speed / 100);
+		
+		_currentObject = object;
+		_currentObject.visible = true;
+		_currentObject.alpha = 1;
+		
+		_slideOutTimer = new Timer(speed / 100);
+		_slideOutTimer.addEventListener(TimerEvent.TIMER, slideOutTimer);
+		_slideOutTimer.start();
+	}
+	
+	public function fadeOut(object:Dynamic, speed:Float=500)
+	{
+		if (!object.visible)
+		{
+			object.visible = true;
+		}
+		
+		object.alpha = 1;
+		_currentObject = object;
+		
+		_fadeOutTimer = new Timer(speed / 10);
+		_fadeOutTimer.addEventListener(TimerEvent.TIMER, fadeOutTimer);
+		_fadeOutTimer.start();
+	}
+	
+	public function fadeIn(object:Dynamic, speed:Float=500)
+	{
+		if (object.visible)
+		{
+			object.visible = false;
+		}
+		
+		object.alpha = 0;
+		_currentObject = object;
+		_currentObject.visible = true;
+		
+		_fadeInTimer = new Timer(speed / 10);
+		_fadeInTimer.addEventListener(TimerEvent.TIMER, fadeInTimer);
+		_fadeInTimer.start();
+	}
+	
+}
\ No newline at end of file
diff --git a/src/jaris/display/Loader.hx b/src/jaris/display/Loader.hx
new file mode 100644
index 0000000..42451f2
--- /dev/null
+++ b/src/jaris/display/Loader.hx
@@ -0,0 +1,139 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.display;
+
+import flash.display.MovieClip;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.Lib;
+
+/**
+ * Control to draw a loading bar
+ */
+class Loader extends Sprite 
+{
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	private var _background:Sprite;
+	private var _loaderTrack:Sprite;
+	private var _loaderThumb:Sprite;
+	
+	private var _brightColor:UInt;
+	private var _controlColor:UInt;
+	
+	private var _forward:Bool;
+
+	public function new() 
+	{
+		super();
+		
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+		
+		_background = new Sprite();
+		addChild(_background);
+		
+		_loaderTrack = new Sprite();
+		addChild(_loaderTrack);
+		
+		_loaderThumb = new Sprite();
+		addChild(_loaderThumb);
+		
+		_brightColor = 0x4c4c4c;
+		_controlColor = 0xFFFFFF;
+		
+		_forward = true;
+		
+		addEventListener(Event.ENTER_FRAME, onEnterFrame);
+		_stage.addEventListener(Event.RESIZE, onResize);
+		
+		drawLoader();
+	}
+	
+	/**
+	 * Animation of a thumb moving on the track
+	 * @param	event
+	 */
+	private function onEnterFrame(event:Event):Void
+	{
+		if (_forward)
+		{
+			if ((_loaderThumb.x + _loaderThumb.width) >= (_loaderTrack.x + _loaderTrack.width))
+			{
+				_forward = false;
+			}
+			else
+			{
+				_loaderThumb.x += 10;
+			}
+		}
+		else
+		{
+			if (_loaderThumb.x  <= _loaderTrack.x)
+			{
+				_forward = true;
+			}
+			else
+			{
+				_loaderThumb.x -= 10;
+			}
+		}
+	}
+	
+	/**
+	 * Redraws the loader to match new stage size
+	 * @param	event
+	 */
+	private function onResize(event:Event):Void
+	{
+		drawLoader();
+	}
+	
+	/**
+	 * Draw loader graphics
+	 */
+	private function drawLoader():Void
+	{
+		//Clear graphics
+		_background.graphics.clear();
+		_loaderTrack.graphics.clear();
+		_loaderThumb.graphics.clear();
+		
+		//Draw background
+		_background.graphics.lineStyle();
+		_background.graphics.beginFill(_brightColor, 0.5);
+		_background.graphics.drawRect(0, 0, _stage.stageWidth, _stage.stageHeight);
+		_background.graphics.endFill();
+		
+		//Draw track
+		var trackWidth:Float = (50 / 100) * _stage.stageWidth;
+		var trackHeight:Float = 15;
+		_loaderTrack.x = (_stage.stageWidth / 2) - (trackWidth / 2);
+		_loaderTrack.y = (_stage.stageHeight / 2) - (trackHeight / 2);
+		_loaderTrack.graphics.lineStyle(2, _controlColor);
+		_loaderTrack.graphics.drawRect(0, 0, trackWidth, trackHeight);
+		
+		//Draw thumb
+		_loaderThumb.x = _loaderTrack.x;
+		_loaderThumb.y = _loaderTrack.y;
+		_loaderThumb.graphics.lineStyle();
+		_loaderThumb.graphics.beginFill(_controlColor, 1);
+		_loaderThumb.graphics.drawRect(0, 0, trackHeight, trackHeight);
+	}
+	
+	/**
+	 * Set loader colors
+	 * @param	colors
+	 */
+	public function setColors(colors:Array<String>):Void
+	{
+		_brightColor = colors[0].length > 0? Std.parseInt("0x" + colors[0]) : 0x4c4c4c;
+		_controlColor = colors[0].length > 0? Std.parseInt("0x" + colors[0]) : 0xFFFFFF;
+		
+		drawLoader();
+	}
+}
\ No newline at end of file
diff --git a/src/jaris/display/Logo.hx b/src/jaris/display/Logo.hx
new file mode 100644
index 0000000..4f7df11
--- /dev/null
+++ b/src/jaris/display/Logo.hx
@@ -0,0 +1,168 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.display;
+
+import flash.display.Loader;
+import flash.display.MovieClip;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.IOErrorEvent;
+import flash.events.MouseEvent;
+import flash.Lib;
+import flash.net.URLRequest;
+
+/**
+ * To display an image in jpg, png or gif format as logo
+ */
+class Logo extends Sprite
+{
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	private var _loader:Loader;
+	private var _position:String;
+	private var _alpha:Float;
+	private var _source:String;
+	private var _width:Float;
+	private var _link:String;
+	private var _loading:Bool;
+	
+	public function new(source:String, position:String, alpha:Float, width:Float=0.0) 
+	{
+		super();
+		
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+		_loader = new Loader();
+		_position = position;
+		_alpha = alpha;
+		_source = source;
+		_width = width;
+		_loading = true;
+		
+		this.tabEnabled = false;
+		
+		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
+		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onNotLoaded);
+        _loader.load(new URLRequest(source));
+	}
+	
+	/**
+	 * Triggers when the logo image could not be loaded
+	 * @param	event
+	 */
+	private function onNotLoaded(event:IOErrorEvent):Void
+	{
+		//Image not loaded
+	}
+	
+	/**
+	 * Triggers when the logo image finished loading.
+	 * @param	event
+	 */
+	private function onLoaderComplete(event:Event)
+	{
+		addChild(_loader);
+		
+		setWidth(_width);
+		setPosition(_position);
+		setAlpha(_alpha);
+		_loading = false;
+		
+		_stage.addEventListener(Event.RESIZE, onStageResize);
+	}
+	
+	/**
+	 * Recalculate logo position on stage resize
+	 * @param	event
+	 */
+	private function onStageResize(event:Event)
+	{
+		setPosition(_position);
+	}
+	
+	/**
+	 * Opens the an url when the logo is clicked
+	 * @param	event
+	 */
+	private function onLogoClick(event:MouseEvent)
+	{
+		Lib.getURL(new URLRequest(_link), "_blank");
+	}
+	
+	/**
+	 * Position where logo will be showing
+	 * @param	position values could be top left, top right, bottom left, bottom right
+	 */
+	public function setPosition(position:String)
+	{
+		switch(position)
+		{
+			case "top left":
+				this.x = 25;
+				this.y = 25;
+			
+			case "top right":
+				this.x = _stage.stageWidth - this._width - 25;
+				this.y = 25;
+			
+			case "bottom left":
+				this.x = 25;
+				this.y = _stage.stageHeight - this.height - 25;
+			
+			case "bottom right":
+				this.x = _stage.stageWidth - this.width - 25;
+				this.y = _stage.stageHeight - this.height - 25;
+				
+			default: 
+				this.x = 25;
+				this.y = 25;
+		}
+	}
+	
+	/**
+	 * To set logo transparency
+	 * @param	alpha
+	 */
+	public function setAlpha(alpha:Float)
+	{
+		this.alpha = alpha;
+	}
+	
+	/**
+	 * Sets logo width and recalculates height keeping aspect ratio
+	 * @param	width
+	 */
+	public function setWidth(width:Float) 
+	{
+		if (width > 0)
+		{
+			this.height = (this.height / this.width) * width;
+			this.width = width;
+		}
+	}
+	
+	/**
+	 * Link that opens when clicked the logo image is clicked
+	 * @param	link
+	 */
+	public function setLink(link:String)
+	{
+		_link = link;
+		this.buttonMode = true;
+		this.useHandCursor = true;
+		this.addEventListener(MouseEvent.CLICK, onLogoClick);
+	}
+	
+	/**
+	 * To check if the logo stills loading
+	 * @return true if loading false otherwise
+	 */
+	public function isLoading():Bool
+	{
+		return _loading;
+	}
+}
\ No newline at end of file
diff --git a/src/jaris/display/Menu.hx b/src/jaris/display/Menu.hx
new file mode 100644
index 0000000..6e63f9e
--- /dev/null
+++ b/src/jaris/display/Menu.hx
@@ -0,0 +1,202 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.display;
+import flash.display.MovieClip;
+import flash.events.ContextMenuEvent;
+import flash.Lib;
+import flash.net.URLRequest;
+import flash.ui.ContextMenu;
+import flash.ui.ContextMenuItem;
+import jaris.player.Player;
+import jaris.player.AspectRatio;
+import jaris.Version;
+
+/**
+ * Modify original context menu
+ */
+class Menu 
+{
+	private var _movieClip:MovieClip;
+	public static var _player:Player;
+	
+	private var _contextMenu:ContextMenu;
+	private var _jarisVersionMenuItem:ContextMenuItem;
+	private var _playMenuItem:ContextMenuItem;
+	private var _fullscreenMenuItem:ContextMenuItem;
+	private var _aspectRatioMenuItem:ContextMenuItem;
+	private var _muteMenuItem:ContextMenuItem;
+	private var _volumeUpMenuItem:ContextMenuItem;
+	private var _volumeDownMenuItem:ContextMenuItem;
+	
+	public function new(player:Player) 
+	{
+		_movieClip = Lib.current;
+		_player = player;
+				
+		_contextMenu = new ContextMenu();
+		_contextMenu.hideBuiltInItems();
+		
+		_contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, onMenuOpen);
+		
+		_jarisVersionMenuItem = new ContextMenuItem("Jaris Player v" + Version.NUMBER, true, true, true);
+		_jarisVersionMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onJarisVersion);
+		
+		_playMenuItem = new ContextMenuItem("Play (SPACE)", true, true, true);
+		_playMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onPlay);
+		
+		_fullscreenMenuItem = new ContextMenuItem("Fullscreen View (F)");
+		_fullscreenMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onFullscreen);
+		
+		_aspectRatioMenuItem = new ContextMenuItem("Aspect Ratio (original) (TAB)");
+		_aspectRatioMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onAspectRatio);
+		
+		_muteMenuItem = new ContextMenuItem("Mute (M)");
+		_muteMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onMute);
+		
+		_volumeUpMenuItem = new ContextMenuItem("Volume + (arrow UP)");
+		_volumeUpMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onVolumeUp);
+		
+		_volumeDownMenuItem = new ContextMenuItem("Volume - (arrow DOWN)");
+		_volumeDownMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onVolumeDown);
+		
+		_contextMenu.customItems.push(_jarisVersionMenuItem);
+		_contextMenu.customItems.push(_playMenuItem);
+		_contextMenu.customItems.push(_fullscreenMenuItem);
+		_contextMenu.customItems.push(_aspectRatioMenuItem);
+		_contextMenu.customItems.push(_muteMenuItem);
+		_contextMenu.customItems.push(_volumeUpMenuItem);
+		_contextMenu.customItems.push(_volumeDownMenuItem);
+		
+		_movieClip.contextMenu = _contextMenu;
+	}
+	
+	/**
+	 * Update context menu item captions depending on player status before showing them
+	 * @param	event
+	 */
+	private function onMenuOpen(event:ContextMenuEvent):Void
+	{
+		if (_player.isPlaying())
+		{
+			_playMenuItem.caption = "Pause (SPACE)";
+		}
+		else
+		{
+			_playMenuItem.caption = "Play (SPACE)";
+		}
+		
+		if (_player.isFullscreen())
+		{
+			_fullscreenMenuItem.caption = "Normal View";
+		}
+		else
+		{
+			_fullscreenMenuItem.caption = "Fullscreen View (F)";
+		}
+		
+		if (_player.getMute())
+		{
+			_muteMenuItem.caption = _player.isFullscreen()?"Unmute":"Unmute (M)";
+		}
+		else
+		{
+			_muteMenuItem.caption = _player.isFullscreen()?"Mute":"Mute (M)";
+		}
+		
+		switch(_player.getAspectRatio())
+		{
+			case _player.getOriginalAspectRatio():
+				_aspectRatioMenuItem.caption = "Aspect Ratio (1:1) (TAB)";
+				
+			case AspectRatio._1_1:
+				_aspectRatioMenuItem.caption ="Aspect Ratio (3:2) (TAB)";
+				
+			case AspectRatio._3_2:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (4:3) (TAB)";
+				
+			case AspectRatio._4_3:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (5:4) (TAB)";
+				
+			case AspectRatio._5_4:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (14:9) (TAB)";
+				
+			case AspectRatio._14_9:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (14:10) (TAB)";
+				
+			case AspectRatio._14_10:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (16:9) (TAB)";
+				
+			case AspectRatio._16_9:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (16:10) (TAB)";
+				
+			case AspectRatio._16_10:
+				_aspectRatioMenuItem.caption = "Aspect Ratio (original) (TAB)";
+		}
+	}
+	
+	/**
+	 * Open jaris player website
+	 * @param	event
+	 */
+	private function onJarisVersion(event:ContextMenuEvent)
+	{
+		Lib.getURL(new URLRequest("http://jaris.sourceforge.net"), "_blank");
+	}
+	
+	/**
+	 * Toggles playback
+	 * @param	event
+	 */
+	private function onPlay(event:ContextMenuEvent)
+	{
+		_player.togglePlay();
+	}
+	
+	/**
+	 * Toggles fullscreen
+	 * @param	event
+	 */
+	private function onFullscreen(event:ContextMenuEvent)
+	{
+		_player.toggleFullscreen();
+	}
+	
+	/**
+	 * Toggles aspect ratio
+	 * @param	event
+	 */
+	private function onAspectRatio(event:ContextMenuEvent)
+	{
+		_player.toggleAspectRatio();
+	}
+	
+	/**
+	 * Toggles mute
+	 * @param	event
+	 */
+	private function onMute(event:ContextMenuEvent)
+	{
+		_player.toggleMute();
+	}
+	
+	/**
+	 * Raise volume
+	 * @param	event
+	 */
+	private function onVolumeUp(event:ContextMenuEvent)
+	{
+		_player.volumeUp();
+	}
+	
+	/**
+	 * Lower volume
+	 * @param	event
+	 */
+	private function onVolumeDown(event:ContextMenuEvent)
+	{
+		_player.volumeDown();
+	}
+}
\ No newline at end of file
diff --git a/src/jaris/display/Poster.hx b/src/jaris/display/Poster.hx
new file mode 100644
index 0000000..de8056a
--- /dev/null
+++ b/src/jaris/display/Poster.hx
@@ -0,0 +1,118 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.display;
+
+import flash.display.DisplayObject;
+import flash.display.Loader;
+import flash.display.MovieClip;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.IOErrorEvent;
+import flash.Lib;
+import flash.net.URLRequest;
+
+/**
+ * To display an png, jpg or gif as preview of video content
+ */
+class Poster extends Sprite
+{
+
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	private var _loader:Loader;
+	private var _source:String;
+	private var _width:Float;
+	private var _height:Float;
+	private var _loading:Bool;
+	private var _loaderStatus:jaris.display.Loader;
+	
+	public function new(source:String):Void
+	{
+		super();
+		
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+		_loader = new Loader();
+		_source = source;
+		_loading = true;
+		
+		//Reads flash vars
+		var parameters:Dynamic<String> = flash.Lib.current.loaderInfo.parameters;
+		
+		//Draw Loader status
+		var loaderColors:Array <String> = ["", "", "", ""];
+		loaderColors[0] = parameters.brightcolor != null ? parameters.brightcolor : "";
+		loaderColors[1] = parameters.controlcolor != null ? parameters.controlcolor : "";
+		
+		_loaderStatus = new jaris.display.Loader();
+		_loaderStatus.setColors(loaderColors);
+		addChild(_loaderStatus);
+		
+		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
+		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onNotLoaded);
+        _loader.load(new URLRequest(source));
+	}
+	
+	/**
+	 * Triggers when the poster image could not be loaded
+	 * @param	event
+	 */
+	private function onNotLoaded(event:IOErrorEvent):Void
+	{
+		//Image not loaded
+	}
+	
+	/**
+	 * Triggers when the poster image finalized loading
+	 * @param	event
+	 */
+	private function onLoaderComplete(event:Event):Void
+	{
+		_loaderStatus.visible = false;
+		removeChild(_loaderStatus);
+		
+		addChild(_loader);
+		
+		_width = this.width;
+		_height = this.height;
+		_loading = false;
+		
+		_stage.addEventListener(Event.RESIZE, onStageResize);
+		
+		resizeImage();
+	}
+	
+	/**
+	 * Triggers when the stage is resized to resize the poster image
+	 * @param	event
+	 */
+	private function onStageResize(event:Event):Void
+	{
+		resizeImage();
+	}
+	
+	/**
+	 * Resizes the poster image to take all the stage
+	 */
+	private function resizeImage():Void
+	{
+		this.height = _stage.stageHeight;
+		this.width = ((_stage.stageWidth / _stage.stageHeight) * this.height);
+		
+		this.x = (_stage.stageWidth / 2) - (this.width / 2);
+	}
+	
+	/**
+	 * To check if the poster image stills loading
+	 * @return true if stills loading false if loaded
+	 */
+	public function isLoading():Bool
+	{
+		return _loading;
+	}
+	
+}
\ No newline at end of file
diff --git a/src/jaris/events/PlayerEvents.hx b/src/jaris/events/PlayerEvents.hx
new file mode 100644
index 0000000..f50b3ba
--- /dev/null
+++ b/src/jaris/events/PlayerEvents.hx
@@ -0,0 +1,56 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.events;
+
+import flash.net.NetStream;
+
+/**
+ * Stores constants of the player events
+ */
+class PlayerEvents 
+{
+	public static var ASPECT_RATIO = "onAspectRatio";
+	public static var MOUSE_SHOW = "onMouseShow";
+	public static var MOUSE_HIDE = "onMouseHide";
+	public static var FULLSCREEN = "onFullscreen";
+	public static var VOLUME_UP = "onVolumeUp";
+	public static var VOLUME_DOWN = "onVolumeDown";
+	public static var MUTE = "onMute";
+	public static var FORWARD = "onForward";
+	public static var REWIND = "onRewind";
+	public static var PLAY_PAUSE = "onPlayPause";
+	public static var BUFFERING = "onBuffering";
+	public static var NOT_BUFFERING = "onNotBuffering";
+	public static var CONNECTION_FAILED = "onConnectionFailed";
+	public static var CONNECTION_SUCCESS = "onConnectionSuccess";
+	public static var META_RECIEVED = "onMetaDataReceived";
+	public static var PLAYBACK_FINISHED = "onPlaybackFinished";
+	public static var STOP_CLOSE = "onStopAndClose";
+	public static var RESIZE = "onResize";
+	
+	public var aspectRatio:Float;
+	public var fullscreen:Bool;
+	public var mute:Bool;
+	public var volume:Float;
+	public var duration:Float;
+	public var width:Float;
+	public var height:Float;
+	public var stream:NetStream;
+	public var time:Float;
+	
+	
+	public function new() 
+	{
+		fullscreen = false;
+		mute = false;
+		volume = 1.0;
+		duration = 0;
+		width = 0;
+		height = 0;
+		time = 0;
+	}
+	
+}
\ No newline at end of file
diff --git a/src/jaris/player/AspectRatio.hx b/src/jaris/player/AspectRatio.hx
new file mode 100644
index 0000000..350b26d
--- /dev/null
+++ b/src/jaris/player/AspectRatio.hx
@@ -0,0 +1,32 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.player;
+
+/**
+ * Stores the player used constants
+ */
+class AspectRatio 
+{
+	public static var _1_1:Float = 1 / 1;	
+	public static var _3_2:Float = 3 / 2;	
+	public static var _4_3:Float = 4 / 3;
+	public static var _5_4:Float = 5 / 4;
+	public static var _14_9:Float = 14 / 9;
+	public static var _14_10:Float = 14 / 10;
+	public static var _16_9:Float = 16 / 9;
+	public static var _16_10:Float = 16 / 10;
+	
+	/**
+	 * Calculates the ratio for a given width and height
+	 * @param	width
+	 * @param	height
+	 * @return aspect ratio
+	 */
+	public static function getAspectRatio(width:Float, height:Float):Float
+	{
+		return width / height;
+	}
+}
\ No newline at end of file
diff --git a/src/jaris/player/Controls.hx b/src/jaris/player/Controls.hx
new file mode 100644
index 0000000..7c2e9ef
--- /dev/null
+++ b/src/jaris/player/Controls.hx
@@ -0,0 +1,938 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.player;
+
+//{Libraries
+import flash.display.GradientType;
+import flash.events.Event;
+import flash.events.TimerEvent;
+import flash.geom.Matrix;
+import flash.Lib;
+import flash.events.MouseEvent;
+import flash.display.MovieClip;
+import flash.net.NetStream;
+import flash.geom.Rectangle;
+import flash.text.TextField;
+import flash.text.TextFieldAutoSize;
+import flash.utils.Timer;
+import jaris.animation.Animation;
+import jaris.display.Loader;
+import jaris.events.PlayerEvents;
+import jaris.player.Player;
+import flash.display.Sprite;
+import flash.display.Stage;
+import jaris.utils.Utils;
+//}
+
+/**
+ * Default controls for jaris player
+ */
+class Controls extends MovieClip {
+	
+	//{Member Variables
+	private var _thumb:Sprite;
+	private var _track:Sprite;
+	private var _trackDownloaded:Sprite;
+	private var _trackBar:Sprite;
+	private var _scrubbing:Bool;
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	private var _player:Player;
+	private var _darkColor:UInt;
+	private var _brightColor:UInt;
+	private var _controlColor:UInt;
+	private var _hoverColor:UInt;
+	private var _hideControlsTimer:Timer;
+	private var _currentPlayTimeLabel:TextField;
+	private var _totalPlayTimeLabel:TextField;
+	private var _seekPlayTimeLabel:TextField;
+	private var _percentLoaded:Float;
+	private var _controlsVisible:Bool;
+	private var _seekBar:Sprite;
+	private var _controlsBar:Sprite;
+	private var _playControl:Sprite;
+	private var _pauseControl:Sprite;
+	private var _aspectRatioControl:Sprite;
+	private var _fullscreenControl:Sprite;
+	private var _volumeIcon:Sprite;
+	private var _volumeTrack:Sprite;
+	private var _volumeSlider:Sprite;
+	private var _loader:Loader;
+	//}
+	
+	
+	//{Constructor
+	public function new(player:Player)
+	{
+		super();
+		
+		//{Main variables
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+		_player = player;
+		_darkColor = 0x000000;
+		_brightColor = 0x4c4c4c;
+		_controlColor = 0xFFFFFF;
+		_hoverColor = 0x67A8C1;
+		_percentLoaded = 0.0;
+		_hideControlsTimer = new Timer(500);
+		_controlsVisible = false;
+		//}
+		
+		//{Seeking Controls initialization
+		_seekBar = new Sprite();
+		addChild(_seekBar);
+		
+		_trackBar = new Sprite(  );
+		_trackBar.tabEnabled = false;
+		_seekBar.addChild(_trackBar);
+		
+		_trackDownloaded = new Sprite(  );
+		_trackDownloaded.tabEnabled = false;
+		_seekBar.addChild(_trackDownloaded);
+		
+		_track = new Sprite(  );
+		_track.tabEnabled = false;
+		_track.buttonMode = true;
+		_track.useHandCursor = true;
+		_seekBar.addChild(_track);
+		
+		
+		_thumb = new Sprite(  );
+		_thumb.buttonMode = true;
+		_thumb.useHandCursor = true;
+		_thumb.tabEnabled = false;
+		_seekBar.addChild(_thumb);
+		
+		_currentPlayTimeLabel = new TextField();
+		_currentPlayTimeLabel.autoSize = TextFieldAutoSize.LEFT;
+		_currentPlayTimeLabel.text = "00:00:00";
+		_currentPlayTimeLabel.tabEnabled = false;
+		_seekBar.addChild(_currentPlayTimeLabel);
+		
+		_totalPlayTimeLabel = new TextField();
+		_totalPlayTimeLabel.autoSize = TextFieldAutoSize.LEFT;
+		_totalPlayTimeLabel.text = "00:00:00";
+		_totalPlayTimeLabel.tabEnabled = false;
+		_seekBar.addChild(_totalPlayTimeLabel);
+		
+		_seekPlayTimeLabel = new TextField();
+		_seekPlayTimeLabel.visible = false;
+		_seekPlayTimeLabel.autoSize = TextFieldAutoSize.LEFT;
+		_seekPlayTimeLabel.text = "00:00:00";
+		_seekPlayTimeLabel.tabEnabled = false;
+		addChild(_seekPlayTimeLabel);
+		
+		drawSeekControls();
+		//}
+		
+		//{Playing controls initialization
+		_controlsBar = new Sprite();
+		_controlsBar.visible = true;
+		addChild(_controlsBar);
+		
+		_playControl = new Sprite();
+		_playControl.buttonMode = true;
+		_playControl.useHandCursor = true;
+		_playControl.tabEnabled = false;
+		_controlsBar.addChild(_playControl);
+		
+		_pauseControl = new Sprite();
+		_pauseControl.visible = false;
+		_pauseControl.buttonMode = true;
+		_pauseControl.useHandCursor = true;
+		_pauseControl.tabEnabled = false;
+		_controlsBar.addChild(_pauseControl);
+		
+		_aspectRatioControl = new Sprite();
+		_aspectRatioControl.buttonMode = true;
+		_aspectRatioControl.useHandCursor = true;
+		_aspectRatioControl.tabEnabled = false;
+		_controlsBar.addChild(_aspectRatioControl);
+		
+		_fullscreenControl = new Sprite();
+		_fullscreenControl.buttonMode = true;
+		_fullscreenControl.useHandCursor = true;
+		_fullscreenControl.tabEnabled = false;
+		_controlsBar.addChild(_fullscreenControl);
+		
+		_volumeIcon = new Sprite();
+		_volumeIcon.buttonMode = true;
+		_volumeIcon.useHandCursor = true;
+		_volumeIcon.tabEnabled = false;
+		_controlsBar.addChild(_volumeIcon);
+		
+		_volumeSlider = new Sprite();
+		_controlsBar.addChild(_volumeSlider);
+		
+		_volumeTrack = new Sprite();
+		_volumeTrack.buttonMode = true;
+		_volumeTrack.useHandCursor = true;
+		_volumeTrack.tabEnabled = false;
+		_controlsBar.addChild(_volumeTrack); 
+		//}
+		
+		//{Loader bar
+		_loader = new Loader();
+		_loader.visible = false;
+		
+		var loaderColors:Array <String> = ["", "", "", ""];
+		loaderColors[0] = Std.string(_brightColor);
+		loaderColors[1] = Std.string(_controlColor);
+		
+		_loader.setColors(loaderColors);
+		
+		addChild(_loader);
+		//}
+		
+		//{event Listeners
+		_movieClip.addEventListener(Event.ENTER_FRAME, onEnterFrame);
+		_thumb.addEventListener(MouseEvent.MOUSE_DOWN, onThumbMouseDown);
+		_thumb.addEventListener(MouseEvent.MOUSE_UP, onThumbMouseUp);
+		_thumb.addEventListener(MouseEvent.MOUSE_OVER, onThumbHover);
+		_thumb.addEventListener(MouseEvent.MOUSE_OUT, onThumbMouseOut);
+		_thumb.addEventListener(MouseEvent.MOUSE_MOVE, onTrackMouseMove);
+		_thumb.addEventListener(MouseEvent.MOUSE_OUT, onTrackMouseOut);
+		_track.addEventListener(MouseEvent.CLICK, onTrackClick);
+		_track.addEventListener(MouseEvent.MOUSE_MOVE, onTrackMouseMove);
+		_track.addEventListener(MouseEvent.MOUSE_OUT, onTrackMouseOut);
+		_trackBar.addEventListener(MouseEvent.MOUSE_OUT, onThumbMouseUp);
+		_controlsBar.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
+		_controlsBar.addEventListener(MouseEvent.MOUSE_OVER, onMouseMove);
+		_playControl.addEventListener(MouseEvent.CLICK, onPlayClick);
+		_playControl.addEventListener(MouseEvent.MOUSE_OVER, onPlayButtonHover);
+		_playControl.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutRedrawControlBar);
+		_pauseControl.addEventListener(MouseEvent.CLICK, onPauseClick);
+		_pauseControl.addEventListener(MouseEvent.MOUSE_OVER, onPauseButtonHover);
+		_pauseControl.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutRedrawControlBar);
+		_aspectRatioControl.addEventListener(MouseEvent.CLICK, onAspectRatioClick);
+		_aspectRatioControl.addEventListener(MouseEvent.MOUSE_OVER, onAspectRatioButtonHover);
+		_aspectRatioControl.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutRedrawControlBar);
+		_fullscreenControl.addEventListener(MouseEvent.CLICK, onFullscreenClick);
+		_fullscreenControl.addEventListener(MouseEvent.MOUSE_OVER, onFullscreenButtonHover);
+		_fullscreenControl.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutRedrawControlBar);
+		_volumeIcon.addEventListener(MouseEvent.CLICK, onVolumeIconClick);
+		_volumeIcon.addEventListener(MouseEvent.MOUSE_OVER, onVolumeIconButtonHover);
+		_volumeIcon.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutRedrawControlBar);
+		_volumeTrack.addEventListener(MouseEvent.CLICK, onVolumeTrackClick);
+		
+		_player.addEventListener(PlayerEvents.FULLSCREEN, onPlayerFullScreen);
+		_player.addEventListener(PlayerEvents.MOUSE_HIDE, onPlayerMouseHide);
+		_player.addEventListener(PlayerEvents.MOUSE_SHOW, onPlayerMouseShow);
+		_player.addEventListener(PlayerEvents.META_RECIEVED, onPlayerMetaData);
+		_player.addEventListener(PlayerEvents.BUFFERING, onPlayerBuffering);
+		_player.addEventListener(PlayerEvents.NOT_BUFFERING, onPlayerNotBuffering);
+		_player.addEventListener(PlayerEvents.RESIZE, onPlayerResize);
+		_player.addEventListener(PlayerEvents.PLAY_PAUSE, onPlayerPlayPause);
+		_player.addEventListener(PlayerEvents.PLAYBACK_FINISHED, onPlayerPlaybackFinished);
+		_player.addEventListener(PlayerEvents.CONNECTION_FAILED, onPlayerStreamNotFound);
+		
+		_stage.addEventListener(MouseEvent.MOUSE_UP, onThumbMouseUp);
+		_stage.addEventListener(MouseEvent.MOUSE_OUT, onThumbMouseUp);
+		_stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
+		
+		_hideControlsTimer.addEventListener(TimerEvent.TIMER, hideControlsTimer);
+		
+		_hideControlsTimer.start();
+		//}
+	}
+	//}
+
+	
+	//{Timers
+	/**
+	 * Hides the playing controls when not moving mouse.
+	 * @param	event The timer event associated
+	 */
+	private function hideControlsTimer(event:TimerEvent):Void
+	{
+		if (_player.isPlaying())
+		{
+			if (_controlsVisible)
+			{
+				if (_stage.mouseX < _controlsBar.x)
+				{
+					_controlsVisible = false;
+				}
+			}
+			else
+			{
+				hideControls();
+				_hideControlsTimer.stop();
+			}
+		}
+	}
+	//}
+	
+	
+	//{Events
+	/**
+	 * Keeps syncronized various elements of the controls like the thumb and download track bar
+	 * @param	event
+	 */
+	private function onEnterFrame(event:Event)
+	{
+		if(_player.getDuration() > 0) {
+			if(_scrubbing) {
+				_player.seek(_player.getDuration() * (_thumb.x / _track.width));
+			}
+			else {
+				_currentPlayTimeLabel.text = Utils.formatTime(_player.getTime());
+				_thumb.x = (_player.getTime()+_player.getStartTime()) / _player.getDuration() * (_track.width-_thumb.width);
+			}
+		}
+		
+		_volumeSlider.height = _volumeTrack.height * (_player.getVolume() / 1.0);
+		_volumeSlider.y = (_volumeTrack.y + _volumeTrack.height) - _volumeSlider.height;
+		
+		drawDownloadProgress();
+	}
+	
+	/**
+	 * Show playing controls on mouse movement.
+	 * @param	event
+	 */
+	private function onMouseMove(event:MouseEvent):Void
+	{
+		if (_stage.mouseX >= _controlsBar.x)
+		{
+			if (!_hideControlsTimer.running)
+			{
+				_hideControlsTimer.start();
+			}
+			
+			_controlsVisible = true;
+			showControls();
+		}
+	}
+	
+	/**
+	 * Used for various controls to redraw controbar after mouse out to clear hover effect
+	 * @param	event
+	 */
+	private function onMouseOutRedrawControlBar(event:MouseEvent)
+	{
+		drawPlayingControls();
+	}
+	
+	/**
+	 * Toggles pause or play
+	 * @param	event
+	 */
+	private function onPlayClick(event:MouseEvent):Void
+	{
+		_player.togglePlay();
+		_playControl.visible = !_player.isPlaying();
+		_pauseControl.visible = _player.isPlaying();
+	}
+	
+	/**
+	 * Changes play control color to hover color
+	 * @param	event
+	 */
+	private function onPlayButtonHover(event:MouseEvent):Void
+	{
+		var triangleRatio = ((80 / 100) * (_controlsBar.width - 20));
+		_playControl.graphics.clear();
+		_playControl.graphics.lineStyle();
+		_playControl.graphics.beginFill(_hoverColor);
+		Utils.drawTriangle(_playControl, 0, 0, triangleRatio, 0);
+		_playControl.graphics.endFill();
+	}
+	
+	/**
+	 * Toggles pause or play
+	 * @param	event
+	 */
+	private function onPauseClick(event:MouseEvent):Void
+	{
+		_player.togglePlay();
+		_playControl.visible = !_player.isPlaying();
+		_pauseControl.visible = _player.isPlaying();
+	}
+	
+	/**
+	 * Changes pause button color to hover color
+	 * @param	event
+	 */
+	private function onPauseButtonHover(event:MouseEvent):Void
+	{
+		_pauseControl.graphics.lineStyle();
+		_pauseControl.graphics.beginFill(_hoverColor);
+		_pauseControl.graphics.drawRoundRect(0, 0, (33 / 100) * _playControl.width, _playControl.height, 6, 6);
+		_pauseControl.graphics.drawRoundRect(_playControl.width - ((33 / 100) * _playControl.width), 0, (33 / 100) * _playControl.width, _playControl.height, 6, 6);
+		_pauseControl.graphics.endFill();
+		
+		_pauseControl.graphics.lineStyle();
+		_pauseControl.graphics.beginFill(0x000000, 0);
+		_pauseControl.graphics.drawRect(0, 0, _pauseControl.width, _playControl.height);
+		_pauseControl.graphics.endFill();
+	}
+	
+	/**
+	 * Toggles betewen aspect ratios
+	 * @param	event
+	 */
+	private function onAspectRatioClick(event:MouseEvent):Void
+	{
+		_player.toggleAspectRatio();
+	}
+	
+	/**
+	 * Changes aspect ratio icon color to hover one
+	 * @param	event
+	 */
+	private function onAspectRatioButtonHover(event:MouseEvent):Void
+	{
+		_aspectRatioControl.graphics.clear();
+		
+		_aspectRatioControl.graphics.lineStyle(2, _hoverColor);
+		_aspectRatioControl.graphics.drawRect(0, 0, _playControl.width, _playControl.height);
+		
+		_aspectRatioControl.graphics.lineStyle();
+		_aspectRatioControl.graphics.beginFill(_hoverColor, 1);
+		_aspectRatioControl.graphics.drawRect(5, 5, _aspectRatioControl.width - 12, _aspectRatioControl.height - 12);
+		_aspectRatioControl.graphics.endFill();
+		
+		_aspectRatioControl.graphics.lineStyle();
+		_aspectRatioControl.graphics.beginFill(0x000000, 0);
+		_aspectRatioControl.graphics.drawRect(0, 0, _aspectRatioControl.width, _aspectRatioControl.height);
+		_aspectRatioControl.graphics.endFill();
+	}
+	
+	/**
+	 * Toggles between window and fullscreen mode
+	 * @param	event
+	 */
+	private function onFullscreenClick(event:MouseEvent)
+	{
+		_player.toggleFullscreen();
+	}
+	
+	/**
+	 * Changes fullscreen icon color to hover one
+	 * @param	event
+	 */
+	private function onFullscreenButtonHover(event:MouseEvent):Void
+	{
+		_fullscreenControl.graphics.lineStyle(2, _hoverColor);
+		_fullscreenControl.graphics.beginFill(0x000000, 0);
+		_fullscreenControl.graphics.drawRoundRect(0, 0, _playControl.width, _playControl.height, 6, 6);
+		_fullscreenControl.graphics.endFill();
+		
+		_fullscreenControl.graphics.lineStyle();
+		_fullscreenControl.graphics.beginFill(_hoverColor, 1);
+		_fullscreenControl.graphics.drawRoundRect(3, 3, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(_fullscreenControl.width - 9, 3, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(3, _fullscreenControl.height - 9, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(_fullscreenControl.width - 9, _fullscreenControl.height - 9, 4, 4, 2, 2);
+		_fullscreenControl.graphics.endFill();
+	}
+	
+	/**
+	 * Toggles between mute and unmute
+	 * @param	event
+	 */
+	public function onVolumeIconClick(event: MouseEvent)
+	{
+		_player.toggleMute();
+	}
+	
+	/**
+	 * Changes volume icon color to hover one
+	 * @param	event
+	 */
+	public function onVolumeIconButtonHover(event: MouseEvent)
+	{
+		_volumeIcon.graphics.lineStyle();
+		_volumeIcon.graphics.beginFill(_hoverColor, 1);
+		_volumeIcon.graphics.drawRect(0, ((50 / 100) * _playControl.height) / 2, _playControl.width / 2, ((50 / 100) * _playControl.height));
+		_volumeIcon.graphics.moveTo(_playControl.width / 2, ((50 / 100) * _playControl.height)/2);
+		_volumeIcon.graphics.lineTo(_playControl.width, 0);
+		_volumeIcon.graphics.lineTo(_playControl.width, _playControl.height);
+		_volumeIcon.graphics.lineTo(_playControl.width / 2, ((50 / 100) * _playControl.height) + (((50 / 100) * _playControl.height) / 2));
+		_volumeIcon.graphics.endFill();
+	}
+	
+	/**
+	 * Detect user click on volume track control and change volume according
+	 * @param	event
+	 */
+	private function onVolumeTrackClick(event:MouseEvent)
+	{
+		var percent:Float = _volumeTrack.height - _volumeTrack.mouseY;
+		var volume:Float = 1.0 * (percent / _volumeTrack.height);
+		
+		_player.setVolume(volume);
+	}
+	
+	/**
+	 * Display not found message
+	 * @param	event
+	 */
+	private function onPlayerStreamNotFound(event:PlayerEvents):Void
+	{
+		//todo: to work on this
+	}	
+	
+	/**
+	 * Shows the loader bar when buffering
+	 * @param	event
+	 */
+	private function onPlayerBuffering(event:PlayerEvents):Void
+	{
+		_loader.visible = true;
+	}
+	
+	/**
+	 * Hides loader bar when not buffering
+	 * @param	event
+	 */
+	private function onPlayerNotBuffering(event:PlayerEvents):Void
+	{
+		_loader.visible = false;
+	}
+		
+	/**
+	 * Monitors playbeack when finishes tu update controls
+	 * @param	event
+	 */
+	private function onPlayerPlaybackFinished(event:PlayerEvents):Void
+	{
+		_playControl.visible = !_player.isPlaying();
+		_pauseControl.visible = _player.isPlaying();
+		showControls();
+	}
+	
+	/**
+	 * Monitors keyboard play pause actions to update icons
+	 * @param	event
+	 */
+	private function onPlayerPlayPause(event:PlayerEvents)
+	{
+		_playControl.visible = !_player.isPlaying();
+		_pauseControl.visible = _player.isPlaying();
+	}
+	
+	/**
+	 * Function fired by the player FULLSCREEN event that redraws the player controls
+	 * @param	event
+	 */
+	private function onPlayerFullScreen(event:PlayerEvents)
+	{
+		redrawControls();
+		
+		//Need to check when hardware scaling enabled
+		//Limit check to 3 in case of hanging (infinite loop)
+		var count:UInt = 1;
+		while (_seekBar.width != _stage.stageWidth && count <= 3)
+		{
+			redrawControls();
+			hideControls();
+			count++;
+		}
+	}
+	
+	/**
+	 * Resizes the video player on windowed mode substracting the seekbar height
+	 * @param	event
+	 */
+	private function onPlayerResize(event:PlayerEvents)
+	{
+		if (!_player.isFullscreen())
+		{
+			_player.getVideo().height = _stage.stageHeight - _trackBar.height;
+			_player.getVideo().width = _player.getVideo().height * _player.getAspectRatio();
+			
+			_player.getVideo().x = (_stage.stageWidth / 2) - (_player.getVideo().width / 2);
+		}
+	}
+	
+	/**
+	 * Updates media total time duration.
+	 * @param	event
+	 */
+	private function onPlayerMetaData(event:PlayerEvents):Void
+	{
+		_totalPlayTimeLabel.text = Utils.formatTime(event.duration);
+		_playControl.visible = !_player.isPlaying();
+		_pauseControl.visible = _player.isPlaying();
+	}
+	
+	/**
+	 * Hides seekbar if on fullscreen.
+	 * @param	event
+	 */
+	private function onPlayerMouseHide(event:PlayerEvents)
+	{
+		if (_seekBar.visible && _player.isFullscreen())
+		{
+			Animation.slideOut(_seekBar, "bottom", 1000);
+		}
+	}
+	
+	/**
+	 * Shows seekbar
+	 * @param	event
+	 */
+	private function onPlayerMouseShow(event:PlayerEvents)
+	{
+		//Only use slidein effect on fullscreen since switching to windowed mode on
+		//hardware scaling causes a bug by a slow response on stage height changes
+		if (_player.isFullscreen() && !_seekBar.visible)
+		{
+			Animation.slideIn(_seekBar, "bottom",1000);
+		}
+		else
+		{
+			_seekBar.visible = true;
+		}
+	}
+	
+	/**
+	 * Translates a user click in to time and seeks to it
+	 * @param	event
+	 */
+	private function onTrackClick(event:MouseEvent)
+	{
+		var clickPosition:Float = _track.mouseX - _currentPlayTimeLabel.width;
+		_player.seek(_player.getDuration() * (clickPosition / _track.width));
+	}
+	
+	/**
+	 * Shows a small tooltip showing the time calculated by mouse position
+	 * @param	event
+	 */
+	private function onTrackMouseMove(event:MouseEvent):Void
+	{
+		var clickPosition:Float = _track.mouseX - _currentPlayTimeLabel.width;
+		_seekPlayTimeLabel.text = Utils.formatTime(_player.getDuration() * (clickPosition / _track.width));
+		
+		_seekPlayTimeLabel.y = _stage.stageHeight - _trackBar.height - _seekPlayTimeLabel.height - 1;
+		_seekPlayTimeLabel.x = clickPosition + (_seekPlayTimeLabel.width / 2);
+		
+		_seekPlayTimeLabel.backgroundColor = _brightColor;
+		_seekPlayTimeLabel.background = true;
+		_seekPlayTimeLabel.textColor = _controlColor;
+		_seekPlayTimeLabel.borderColor = _darkColor;
+		_seekPlayTimeLabel.border = true;
+		
+		if (!_seekPlayTimeLabel.visible)
+		{
+			Animation.fadeIn(_seekPlayTimeLabel, 300);
+		}
+	}
+	
+	/**
+	 * Hides the tooltip that shows the time calculated by mouse position
+	 * @param	event
+	 */
+	private function onTrackMouseOut(event:MouseEvent):Void
+	{
+		Animation.fadeOut(_seekPlayTimeLabel, 300);
+	}
+	
+	/**
+	 * Enables dragging of thumb for seeking media
+	 * @param	event
+	 */
+	private function onThumbMouseDown(event:MouseEvent)
+	{
+		_scrubbing = true;
+		var rectangle:Rectangle = new Rectangle(_track.x, _track.y, _track.width-_thumb.width, 0);
+		_thumb.startDrag(false, rectangle);
+	}
+	
+	/**
+	 * Changes thumb seek control to hover color
+	 * @param	event
+	 */
+	private function onThumbHover(event:MouseEvent)
+	{
+		_thumb.graphics.lineStyle();
+		_thumb.graphics.beginFill(_hoverColor);
+		_thumb.graphics.drawRect(_currentPlayTimeLabel.width, (_seekBar.height/2)-(10/2), 10, 10);
+		_thumb.graphics.endFill();
+	}
+	
+	/**
+	 * Changes thumb seek control to control color
+	 * @param	event
+	 */
+	private function onThumbMouseOut(event:MouseEvent)
+	{
+		_thumb.graphics.lineStyle();
+		_thumb.graphics.beginFill(_controlColor);
+		_thumb.graphics.drawRect(_currentPlayTimeLabel.width, (_seekBar.height/2)-(10/2), 10, 10);
+		_thumb.graphics.endFill();
+	}
+	
+	/**
+	 * Disables dragging of thumb
+	 * @param	event
+	 */
+	private function onThumbMouseUp(event:MouseEvent) 
+	{
+		_scrubbing = false;
+		_thumb.stopDrag(  );
+	}
+	//}
+	
+	
+	//{Drawing functions
+	/**
+	 * Clears all current graphics a draw new ones
+	 */
+	private function redrawControls():Void
+	{
+		_seekBar.graphics.clear();
+		_trackBar.graphics.clear();
+		_track.graphics.clear();
+		_thumb.graphics.clear();
+		
+		drawSeekControls();
+		drawPlayingControls();
+	}
+	
+	/**
+	 * Draws the download progress track bar
+	 */
+	private function drawDownloadProgress():Void
+	{
+		if (_player.getNetStream().bytesTotal > 0)
+		{
+			var bytesLoaded:Float = _player.getNetStream().bytesLoaded;
+			var bytesTotal:Float = _player.getNetStream().bytesTotal;
+			
+			_percentLoaded = bytesLoaded / bytesTotal;
+		}
+		
+		var position:Float = _player.getStartTime() / _player.getDuration();
+		
+		_trackDownloaded.graphics.clear();
+		
+		_trackDownloaded.graphics.lineStyle();
+		_trackDownloaded.graphics.beginFill(_brightColor, 0xFFFFFF);
+		_trackDownloaded.graphics.drawRect(_currentPlayTimeLabel.width + (position * _track.width), (_seekBar.height / 2) - (10 / 2), _track.width * _percentLoaded, 10);
+		_trackDownloaded.graphics.endFill();
+	}
+	
+	/**
+	 * Draws all seekbar controls
+	 */
+	private function drawSeekControls()
+	{
+		_seekBar.x = 0;
+		_seekBar.y = _stage.stageHeight - 25;
+		_seekBar.graphics.lineStyle();
+		_seekBar.graphics.beginFill(0x000000, 0);
+		_seekBar.graphics.drawRect(0, 0, _stage.stageWidth, 25);
+		_seekBar.graphics.endFill();
+		_seekBar.width = _stage.stageWidth;	
+		_seekBar.height = 25;
+		
+		var matrix:Matrix = new Matrix(  );
+		matrix.createGradientBox(_seekBar.width, 25, Utils.degreesToRadians(90), 0, _seekBar.height-25);
+		var colors:Array<UInt> = [_brightColor, _darkColor];
+		var alphas:Array<UInt> = [1, 1];
+		var ratios:Array<UInt> = [0, 255];
+		_trackBar.graphics.lineStyle();
+		_trackBar.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
+		_trackBar.graphics.drawRect(0, 0, _seekBar.width, _seekBar.height);
+		_trackBar.graphics.endFill(  );
+		
+		_currentPlayTimeLabel.textColor = _controlColor;
+		_currentPlayTimeLabel.y = _seekBar.height - (_trackBar.height/2)-(_currentPlayTimeLabel.height/2);
+		
+		_totalPlayTimeLabel.textColor = _controlColor;
+		_totalPlayTimeLabel.x = _seekBar.width - _totalPlayTimeLabel.width;
+		_totalPlayTimeLabel.y = _seekBar.height - (_trackBar.height / 2) - (_totalPlayTimeLabel.height / 2);
+		
+		drawDownloadProgress();
+		
+		_track.graphics.lineStyle(1, _controlColor);
+		_track.graphics.beginFill(_darkColor, 0);
+		_track.graphics.drawRect(_currentPlayTimeLabel.width, (_seekBar.height / 2) - (10 / 2), _seekBar.width - _currentPlayTimeLabel.width - _totalPlayTimeLabel.width, 10);
+		_track.graphics.endFill();
+		
+		_thumb.graphics.lineStyle();
+		_thumb.graphics.beginFill(_controlColor);
+		_thumb.graphics.drawRect(_currentPlayTimeLabel.width, (_seekBar.height/2)-(10/2), 10, 10);
+		_thumb.graphics.endFill();
+	}
+	
+	/**
+	 * Draws control bar player controls
+	 */
+	private function drawPlayingControls():Void
+	{
+		//Reset sprites for redraw
+		_controlsBar.graphics.clear();
+		_playControl.graphics.clear();
+		_pauseControl.graphics.clear();
+		_aspectRatioControl.graphics.clear();
+		_fullscreenControl.graphics.clear();
+		_volumeTrack.graphics.clear();
+		_volumeIcon.graphics.clear();
+		_volumeSlider.graphics.clear();
+		
+		//Draw controls bar
+		var barWidth = 60;
+		_controlsBar.x = (_stage.stageWidth - barWidth) + 20;
+		_controlsBar.y = 25;
+		
+		var matrix:Matrix = new Matrix(  );
+		matrix.createGradientBox(barWidth, _stage.stageHeight - 75, Utils.degreesToRadians(0), 0, _stage.stageHeight-75);
+		var colors:Array<UInt> = [_brightColor, _darkColor];
+		var alphas:Array<Float> = [0.75, 0.75];
+		var ratios:Array<UInt> = [0, 255];
+		_controlsBar.graphics.lineStyle();
+		_controlsBar.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
+		_controlsBar.graphics.drawRoundRect(0, 0, barWidth, _stage.stageHeight-75, 20, 20);
+		_controlsBar.graphics.endFill();
+		_controlsBar.width = barWidth;	
+		_controlsBar.height = _stage.stageHeight - 75;
+		
+		var topMargin = 10;
+		var barCenter:Float = (_controlsBar.width - 20) / 2;
+		
+		//Draw playbutton
+		var triangleRatio = ((80 / 100) * (_controlsBar.width - 20));
+		_playControl.x = barCenter - (triangleRatio/2);
+		_playControl.y = topMargin;
+		_playControl.graphics.lineStyle();
+		_playControl.graphics.beginFill(_controlColor);
+		Utils.drawTriangle(_playControl, 0, 0, triangleRatio, 0);
+		_playControl.graphics.endFill();
+		
+		//Draw pausebutton
+		_pauseControl.x = _playControl.x;
+		_pauseControl.y = _playControl.y;
+		_pauseControl.graphics.lineStyle();
+		_pauseControl.graphics.beginFill(_controlColor);
+		_pauseControl.graphics.drawRoundRect(0, 0, (33 / 100) * _playControl.width, _playControl.height, 6, 6);
+		_pauseControl.graphics.drawRoundRect(_playControl.width - ((33 / 100) * _playControl.width), 0, (33 / 100) * _playControl.width, _playControl.height, 6, 6);
+		_pauseControl.graphics.endFill();
+		
+		_pauseControl.graphics.lineStyle();
+		_pauseControl.graphics.beginFill(_controlColor, 0);
+		_pauseControl.graphics.drawRect(0, 0, _pauseControl.width, _playControl.height);
+		_pauseControl.graphics.endFill();
+		
+		//Draw aspec ratio button
+		_aspectRatioControl.x = _playControl.x;
+		_aspectRatioControl.y = _playControl.y + _playControl.height + topMargin;
+		_aspectRatioControl.graphics.lineStyle(2, _controlColor);
+		_aspectRatioControl.graphics.drawRect(0, 0, _playControl.width, _playControl.height);
+		
+		_aspectRatioControl.graphics.lineStyle();
+		_aspectRatioControl.graphics.beginFill(_controlColor, 1);
+		_aspectRatioControl.graphics.drawRect(5, 5, _aspectRatioControl.width - 12, _aspectRatioControl.height - 12);
+		_aspectRatioControl.graphics.endFill();
+		
+		_aspectRatioControl.graphics.lineStyle();
+		_aspectRatioControl.graphics.beginFill(0x000000, 0);
+		_aspectRatioControl.graphics.drawRect(0, 0, _aspectRatioControl.width, _aspectRatioControl.height);
+		_aspectRatioControl.graphics.endFill();
+		
+		//Draw fullscreen button
+		_fullscreenControl.x = _playControl.x;
+		_fullscreenControl.y = _aspectRatioControl.y + _aspectRatioControl.height + topMargin;
+		_fullscreenControl.graphics.lineStyle(2, _controlColor);
+		_fullscreenControl.graphics.beginFill(0x000000, 0);
+		_fullscreenControl.graphics.drawRoundRect(0, 0, _playControl.width, _playControl.height, 6, 6);
+		_fullscreenControl.graphics.endFill();
+		
+		_fullscreenControl.graphics.lineStyle();
+		_fullscreenControl.graphics.beginFill(_controlColor, 1);
+		_fullscreenControl.graphics.drawRoundRect(3, 3, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(_fullscreenControl.width - 9, 3, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(3, _fullscreenControl.height - 9, 4, 4, 2, 2);
+		_fullscreenControl.graphics.drawRoundRect(_fullscreenControl.width - 9, _fullscreenControl.height - 9, 4, 4, 2, 2);
+		_fullscreenControl.graphics.endFill();
+		
+		//Draw volume icon
+		_volumeIcon.x = _playControl.x;
+		_volumeIcon.y = _controlsBar.height - _playControl.height - 10;
+		_volumeIcon.graphics.lineStyle();
+		_volumeIcon.graphics.beginFill(_controlColor, 1);
+		_volumeIcon.graphics.drawRect(0, ((50 / 100) * _playControl.height) / 2, _playControl.width / 2, ((50 / 100) * _playControl.height));
+		_volumeIcon.graphics.moveTo(_playControl.width / 2, ((50 / 100) * _playControl.height)/2);
+		_volumeIcon.graphics.lineTo(_playControl.width, 0);
+		_volumeIcon.graphics.lineTo(_playControl.width, _playControl.height);
+		_volumeIcon.graphics.lineTo(_playControl.width / 2, ((50 / 100) * _playControl.height) + (((50 / 100) * _playControl.height) / 2));
+		_volumeIcon.graphics.endFill();
+		
+		//Draw volume track
+		_volumeTrack.x = _playControl.x;
+		_volumeTrack.y = (_fullscreenControl.y + _fullscreenControl.height) + 10;
+		_volumeTrack.graphics.lineStyle(1, _controlColor);
+		_volumeTrack.graphics.beginFill(0x000000, 0);
+		_volumeTrack.graphics.drawRect(0, 0, _playControl.width / 2, _volumeIcon.y - (_fullscreenControl.y + _fullscreenControl.height) - 20);
+		_volumeTrack.graphics.endFill();
+		_volumeTrack.x = barCenter - (_volumeTrack.width / 2);
+		
+		//Draw volume slider
+		_volumeSlider.x = _volumeTrack.x;
+		_volumeSlider.y = _volumeTrack.y;
+		_volumeSlider.graphics.lineStyle();
+		_volumeSlider.graphics.beginFill(_controlColor, 1);
+		_volumeSlider.graphics.drawRect(0, 0, _volumeTrack.width, _volumeTrack.height);
+		_volumeSlider.graphics.endFill();
+		
+	}
+	//}
+	
+	
+	//{Private Methods
+	/**
+	 * Hide de play controls bar
+	 */
+	private function hideControls():Void
+	{
+		if(_controlsBar.visible)
+		{
+			drawPlayingControls();	
+			Animation.slideOut(_controlsBar, "right", 1500);
+		}
+	}
+	
+	/**
+	 * Shows play controls bar
+	 */
+	private function showControls():Void
+	{
+		if(!_controlsBar.visible)
+		{
+			drawPlayingControls();	
+			Animation.slideIn(_controlsBar, "right", 1500);
+		}
+	}
+	//}
+	
+	
+	//{Setters
+	/**
+	 * Sets the player colors and redraw them
+	 * @param	colors Array of colors in the following order: darkColor, brightColor, controlColor, hoverColor
+	 */
+	public function setControlColors(colors:Array<String>):Void
+	{
+		_darkColor = colors[0].length > 0? Std.parseInt("0x" + colors[0]) : 0x000000;
+		_brightColor = colors[1].length > 0? Std.parseInt("0x" + colors[1]) : 0x4c4c4c;
+		_controlColor = colors[2].length > 0? Std.parseInt("0x" + colors[2]) : 0xFFFFFF;
+		_hoverColor = colors[3].length > 0? Std.parseInt("0x" + colors[3]) : 0x67A8C1;
+		
+		var loaderColors:Array <String> = ["", "", "", ""];
+		loaderColors[0] = colors[1];
+		loaderColors[1] = colors[2];
+		_loader.setColors(loaderColors);
+		
+		redrawControls();
+	}
+	//}
+	
+}
\ No newline at end of file
diff --git a/src/jaris/player/Player.hx b/src/jaris/player/Player.hx
new file mode 100644
index 0000000..570a5ca
--- /dev/null
+++ b/src/jaris/player/Player.hx
@@ -0,0 +1,1005 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.player;
+
+import flash.display.MovieClip;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.display.StageDisplayState;
+import flash.events.Event;
+import flash.events.FullScreenEvent;
+import flash.events.KeyboardEvent;
+import flash.events.MouseEvent;
+import flash.events.NetStatusEvent;
+import flash.events.TimerEvent;
+import flash.geom.Rectangle;
+import flash.Lib;
+import flash.media.SoundTransform;
+import flash.media.Video;
+import flash.net.NetConnection;
+import flash.net.NetStream;
+import flash.system.Capabilities;
+import flash.ui.Keyboard;
+import flash.ui.Mouse;
+import flash.utils.Timer;
+import jaris.display.Poster;
+import jaris.events.PlayerEvents;
+
+/**
+ * Jaris main video player
+ */
+class Player 
+{
+	//{Member variables
+	private var _stage:Stage;
+	private var _movieClip:MovieClip;
+	private var _connection:NetConnection;
+	private var _stream:NetStream;
+	private var _video:Video;
+	private var _fullscreen:Bool;
+	private var _soundMuted:Bool;
+	private var _volume:Float;
+	private var _mouseVisible:Bool;
+	private var _videoLoaded:Bool;
+	private var _hideMouseTimer:Timer;
+	private var _videoSource:String;
+	private var _streamType:String;
+	private var _videoServer:String; //For future use on rtmp
+	private var _videoWidth:Float;
+	private var _videoHeight:Float;
+	private var _videoDuration:Float;
+	private var _videoMask:Sprite;
+	private var _isPlaying:Bool;
+	private var _eventListeners:Dynamic;
+	private var _eventCount:UInt;
+	private var _playerEvent:PlayerEvents;
+	private var _aspectRatio:Float;
+	private var _originalAspectRatio:Float;
+	private var _videoEndReached:Bool;
+	private var _seekPoints:Array<Float>;
+	private var _downloadCompleted:Bool;
+	private var _startTime:Float;
+	private var _firstLoad:Bool;
+	private var _stopped:Bool;
+	private var _videoQualityHigh:Bool;
+	private var _useHardWareScaling:Bool;
+	private var _poster:Poster;
+	//}
+	
+	
+	//{Constructor
+	public function new() 
+	{
+		//{Main Variables Init
+		_stage = Lib.current.stage;
+		_movieClip = Lib.current;
+		_mouseVisible = true;
+		_soundMuted = false;
+		_volume = 1.0;
+		_fullscreen = false;
+		_videoLoaded = false;
+		_hideMouseTimer = new Timer(1500);
+		_eventListeners = new Array();
+		_eventCount = 0;
+		_playerEvent = new PlayerEvents();
+		_seekPoints = new Array();
+		_downloadCompleted = false;
+		_startTime = 0;
+		_firstLoad = true;
+		_stopped = false;
+		_videoQualityHigh = false;
+		_isPlaying = false;
+		_streamType = StreamType.FILE;
+		//}
+		
+		//{Initialize video and connection objets
+		_connection = new NetConnection();
+		_connection.connect(null);
+		_stream = new NetStream(_connection);
+		
+		_video = new Video(_stage.stageWidth, _stage.stageHeight);
+		_video.attachNetStream(_stream);
+		
+		_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
+		_stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
+		_stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
+		_stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreen);
+		_hideMouseTimer.addEventListener(TimerEvent.TIMER, hideMouseTimer);
+		_stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
+		//}
+	}
+	//}
+	
+	
+	//{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();
+			}
+		}
+	}
+	//}
+	
+	
+	//{Events
+	/**
+	 * Checks if connection failed or succeed
+	 * @param	event
+	 */
+	private function onNetStatus(event:NetStatusEvent):Void
+	{
+		switch (event.info.code)
+		{
+			case "NetConnection.Connect.Success":
+				callEvents(PlayerEvents.CONNECTION_SUCCESS);
+
+			case "NetStream.Play.StreamNotFound":
+				trace("Stream not found: " + _videoSource);
+				callEvents(PlayerEvents.CONNECTION_FAILED);
+				
+			case "NetStream.Play.Stop":
+				if (_isPlaying) { _stream.togglePause(); }
+				_isPlaying = false;
+				_videoEndReached = true;
+				callEvents(PlayerEvents.PLAYBACK_FINISHED);
+				
+			case "NetStream.Play.Start":
+				_isPlaying = true;
+				_videoEndReached = false;
+				if (_stream.bytesLoaded != _stream.bytesTotal)
+				{
+					callEvents(PlayerEvents.BUFFERING);
+				}
+				
+			case "NetStream.Seek.Notify":
+				_videoEndReached = false;
+				
+			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;
+		
+		switch(event.keyCode)
+		{
+			case Keyboard.TAB:
+				_playerEvent.aspectRatio = toggleAspectRatio();
+				callEvents(PlayerEvents.ASPECT_RATIO);
+			
+			case F_KEY:
+				toggleFullscreen();
+				
+			case M_KEY:
+				_playerEvent.mute = toggleMute();
+				callEvents(PlayerEvents.MUTE);
+				
+			case Keyboard.UP:
+				_playerEvent.volume = volumeUp();
+				callEvents(PlayerEvents.VOLUME_UP);
+				
+			case Keyboard.DOWN:
+				_playerEvent.volume = volumeDown();
+				callEvents(PlayerEvents.VOLUME_DOWN);
+				
+			case Keyboard.RIGHT:
+				_playerEvent.time = forward();
+				callEvents(PlayerEvents.FORWARD);
+				
+			case Keyboard.LEFT:
+				_playerEvent.time = rewind();
+				callEvents(PlayerEvents.REWIND);
+				
+			case Keyboard.SPACE:
+				togglePlay();
+				callEvents(PlayerEvents.PLAY_PAUSE);
+				
+			case X_KEY:
+				stopAndClose();
+				callEvents(PlayerEvents.STOP_CLOSE);
+		}
+	}
+	
+	/**
+	 * 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);
+		}
+	}
+	
+	/**
+	 * 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();
+			
+			//If browser player resume playing
+			if ((Capabilities.playerType == "ActiveX" || Capabilities.playerType == "PlugIn") && isPlaying())
+			{
+				togglePlay();
+			}
+		}
+		
+		resizeAndCenterPlayer();
+		
+		_playerEvent.fullscreen = _fullscreen;
+		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;
+			
+			if (_poster != null)
+			{
+				_poster.visible = false;
+			}
+			
+			_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));
+				}
+			}
+			
+			_videoLoaded = true;
+			_videoDuration = data.duration;
+			_aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
+			_originalAspectRatio = _aspectRatio;
+			
+			_playerEvent.duration = _videoDuration;
+			_playerEvent.width = _videoWidth;
+			_playerEvent.height = _videoHeight;
+			_playerEvent.aspectRatio = _aspectRatio;
+			
+			callEvents(PlayerEvents.META_RECIEVED);
+			
+			resizeAndCenterPlayer();
+		}
+	}
+	
+	/**
+	 * Dummy function invoked for pseudostream servers
+	 * @param	data
+	 */
+	private function onLastSecond(data:Dynamic):Void
+	{
+		
+	}
+	//}
+	
+	
+	//{Private Methods
+	/**
+	 * Function used each time is needed to dispatch an event
+	 * @param	type
+	 */
+	private function callEvents(type:String):Void
+	{
+		for (index in Reflect.fields(_eventListeners))
+		{
+			if (Reflect.field(_eventListeners, index)[0] == type)
+			{
+				Reflect.field(_eventListeners, index)[1](_playerEvent);
+			}
+		}
+	}
+	
+	/**
+	 * Reposition and resizes the video player to fit on screen
+	 */
+	private function resizeAndCenterPlayer():Void
+	{
+		_video.height = _stage.stageHeight;
+		_video.width = _video.height * _aspectRatio;
+		
+		_video.x = (_stage.stageWidth / 2) - (_video.width / 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();
+		
+		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
+	{
+		time = getBestSeekPoint(time);
+		
+		var cacheTotal = Math.floor((getDuration() - _startTime) * (_stream.bytesLoaded / _stream.bytesTotal)) - 1;
+
+		if(time >= _startTime && time < _startTime + cacheTotal)
+		{
+			return true;
+		}
+		
+		return false;
+	}
+	//}
+	
+	
+	//{Public methods	
+	/**
+	 * Adds a listener for player event calls
+	 * @param	type a type from PlayerEvents class
+	 * @param	listener a function
+	 */
+	public function addEventListener(type:String, listener:Dynamic):Void
+	{
+		_eventListeners[_eventCount] = [type, listener];
+		
+		_eventCount++;
+	}
+	
+	/**
+	 * Loads a video and starts playing it
+	 * @param	video video url to load
+	 */
+	public function load(video:String, server:String=""):Void
+	{
+		_stopped = false;
+		_videoSource = video;
+		_videoLoaded = false;
+		_firstLoad = true;
+		_startTime = 0;
+		_downloadCompleted = false;
+		_seekPoints = new Array();
+		
+		callEvents(PlayerEvents.BUFFERING);
+		
+		_stream.bufferTime = 10;
+		_stream.play(video);
+		_stream.client = this;
+	}
+	
+	/**
+	 * Closes the connection and makes player available for another video
+	 */
+	public function stopAndClose():Void
+	{
+		_videoLoaded = false;
+		_isPlaying = false;
+		_stopped = true;
+		_startTime = 0;
+		_poster.visible = true;
+		_stream.close();
+	}
+	
+	/**
+	 * Seeks 8 seconds forward from the current position.
+	 * @return current play time after forward
+	 */
+	public function forward():Float
+	{	
+		var seekTime = (getTime() + 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 = (getTime() - 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)
+		{
+			_stream.seek(seekTime);
+		}
+		else if(_seekPoints.length > 0 && _streamType == StreamType.PSEUDOSTREAM)
+		{
+			seekTime = getBestSeekPoint(seekTime);
+			
+			if (canSeek(seekTime))
+			{
+				_stream.seek(seekTime);
+			}
+			else if(seekTime != _startTime)
+			{	
+				var url:String;
+				if (_videoSource.indexOf("?") != -1)
+				{
+					url = _videoSource + "&start=" + seekTime;
+				}
+				else
+				{
+					url = _videoSource + "?start=" + seekTime;
+				}
+				
+				_startTime = seekTime;
+				_stream.play(url);
+			}
+		}
+		else if(canSeek(seekTime))
+		{
+			seekTime = getBestSeekPoint(seekTime);
+			_stream.seek(seekTime);
+		}
+		
+		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 rations
+	 * @return new aspect ratio in use
+	 */
+	public function toggleAspectRatio():Float
+	{
+		switch(_aspectRatio)
+		{
+			case _originalAspectRatio:
+				_aspectRatio = AspectRatio._1_1;
+				
+			case AspectRatio._1_1:
+				_aspectRatio = AspectRatio._3_2;
+				
+			case AspectRatio._3_2:
+				_aspectRatio = AspectRatio._4_3;
+				
+			case AspectRatio._4_3:
+				_aspectRatio = AspectRatio._5_4;
+				
+			case AspectRatio._5_4:
+				_aspectRatio = AspectRatio._14_9;
+				
+			case AspectRatio._14_9:
+				_aspectRatio = AspectRatio._14_10;
+				
+			case AspectRatio._14_10:
+				_aspectRatio = AspectRatio._16_9;
+				
+			case AspectRatio._16_9:
+				_aspectRatio = AspectRatio._16_10;
+				
+			case AspectRatio._16_10:
+				_aspectRatio = _originalAspectRatio;
+			
+			default:
+				_aspectRatio = _originalAspectRatio;
+		}
+		
+		resizeAndCenterPlayer();
+		
+		return _aspectRatio;
+	}
+	
+	/**
+	 * Swithces between play and pause
+	 */
+	public function togglePlay():Bool
+	{
+		if (_videoLoaded)
+		{
+			if (_videoEndReached)
+			{
+				_videoEndReached = false;
+				_stream.seek(0);
+				_stream.togglePause();
+			}
+			else if (_videoLoaded)
+			{
+				_stream.togglePause();
+			}
+			else if (_stopped)
+			{
+				load(_videoSource);
+			}
+			
+			_isPlaying = !_isPlaying;
+			
+			return _isPlaying;
+		}
+		else if(_videoSource != "")
+		{
+			load(_videoSource);
+			
+			return true;
+		}
+		
+		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();
+		
+		//unmute sound
+		if (_soundMuted)
+		{
+			_soundMuted = false;
+			
+			if (_volume > 0)
+			{
+				soundTransform.volume = _volume;
+			}
+			else
+			{
+				_volume = 1.0;
+				soundTransform.volume = _volume;
+			}
+			
+			_stream.soundTransform = soundTransform;
+			
+			return false;
+		}
+		
+		//mute sound
+		else
+		{
+			_soundMuted = true;
+			_volume = _stream.soundTransform.volume;
+			soundTransform.volume = 0;
+			_stream.soundTransform = soundTransform;
+			
+			return true;
+		}
+	}
+	
+	/**
+	 * 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)
+		{
+			_volume = _stream.soundTransform.volume + (10/100);
+			soundTransform.volume = _volume;
+			_stream.soundTransform = soundTransform;
+		}
+		
+		//reset volume to 1.0 if already reached max
+		if (_volume >= 1)
+		{
+			_volume = 1.0;
+		}
+		
+		return _volume;
+	}
+	
+	/**
+	 * Lower the volume
+	 * @return volume value after lowering
+	 */
+	public function volumeDown():Float
+	{
+		var soundTransform:SoundTransform = new SoundTransform();
+		
+		//lower sound
+		if(!_soundMuted)
+		{
+			_volume = _stream.soundTransform.volume - (10/100);
+			soundTransform.volume = _volume;
+			_stream.soundTransform = soundTransform;
+			
+			//if volume reached min is muted
+			if (_volume <= 0)
+			{
+				_soundMuted = true;
+				_volume = 0;
+			}
+		}
+		
+		return _volume;
+	}
+	//}
+	
+	
+	//{Setters
+	/**
+	 * Set streaming type
+	 * @param	streamType Allowable values are file, http, rmtp
+	 */
+	public function setStreamType(streamType:String):Void
+	{
+		_streamType = streamType;
+	}
+	 
+	/**
+	 * To set a reference to a poster image that should be disabled when media is loaded and ready to play
+	 * @param	poster
+	 */
+	public function setPoster(poster:Poster)
+	{
+		_poster = poster;
+	}
+	
+	/**
+	 * 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 setVideoSource(source):Void
+	{
+		_videoSource = source;
+	}
+	
+	/**
+	 * Changes the current volume
+	 * @param	volume
+	 */
+	public function setVolume(volume:Float):Void
+	{
+		var soundTransform:SoundTransform = new SoundTransform();
+		
+		if (volume > 0)
+		{
+			_soundMuted = false;
+			_volume = volume;
+		}
+		else
+		{
+			_soundMuted = true;
+			_volume = 1.0;
+		}
+		
+		soundTransform.volume = volume;
+		_stream.soundTransform = soundTransform;
+	}
+	
+	/**
+	 * 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;
+		
+		resizeAndCenterPlayer();
+	}
+	
+	/**
+	 * Enable or disable hardware scaling
+	 * @param	value true to enable false to disable
+	 */
+	public function setHardwareScaling(value:Bool):Void
+	{
+		_useHardWareScaling = value;
+	}
+	//}
+	
+	
+	//{Getters
+	/**
+	 * Current playtime of the loaded video
+	 * @return
+	 */
+	public function getTime():Float
+	{
+		return _stream.time;
+	}
+	
+	/**
+	 * 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;
+	}
+	
+	/**
+	 * Original aspect ratio of the video
+	 * @return original aspect ratio
+	 */
+	public function getOriginalAspectRatio():Float
+	{
+		return _originalAspectRatio;
+	}
+	
+	/**
+	 * The stream associated with the player
+	 * @return netstream object
+	 */
+	public function getNetStream():NetStream
+	{
+		return _stream;
+	}
+	
+	/**
+	 * Total duration time of the loaded media
+	 * @return time in seconds
+	 */
+	public function getDuration():Float
+	{
+		return _videoDuration;
+	}
+	
+	/**
+	 * The time in seconds where the player started downloading
+	 * @return time in seconds
+	 */
+	public function getStartTime():Float
+	{
+		return _startTime;
+	}
+	
+	/**
+	 * Video object associated to the player
+	 * @return video object for further manipulation
+	 */
+	public function getVideo():Video
+	{
+		return _video;
+	}
+	
+	/**
+	 * The current sound state
+	 * @return true if mute otherwise false
+	 */
+	public function getMute():Bool
+	{
+		return _soundMuted;
+	}
+	//}
+}
\ No newline at end of file
diff --git a/src/jaris/player/StreamType.hx b/src/jaris/player/StreamType.hx
new file mode 100644
index 0000000..1c98b70
--- /dev/null
+++ b/src/jaris/player/StreamType.hx
@@ -0,0 +1,16 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.player;
+
+/**
+ * Some constants for the stream type
+ */
+class StreamType 
+{
+	public static var FILE:String = "file";
+	public static var PSEUDOSTREAM:String = "http";
+	public static var RTMP:String = "rtmp";
+}
\ No newline at end of file
diff --git a/src/jaris/utils/Utils.hx b/src/jaris/utils/Utils.hx
new file mode 100644
index 0000000..9e17d32
--- /dev/null
+++ b/src/jaris/utils/Utils.hx
@@ -0,0 +1,123 @@
+/**
+ * ...
+ * @author Jefferson González
+ */
+
+package jaris.utils;
+
+/**
+ * Some utility functions
+ */
+class Utils 
+{
+
+	/**
+	 * Converts degrees to radians for easy rotation where applicable
+	 * @param	value A radian value to convert
+	 * @return conversion of degree to radian
+	 */
+	public static function degreesToRadians(value:Float):Float
+	{
+		return (Math.PI / 180) * value;
+	}
+	
+	/**
+	 * Converts a float value representing seconds to a readale string
+	 * @param	time A given time in seconds
+	 * @return A string in the format 00:00:00
+	 */
+	public static function formatTime(time:Float):String
+	{
+		var seconds:String = "";
+		var minutes:String = "";
+		var hours:String = "";
+		var timeString:String = "";
+		
+		if (((time / 60) / 60) >= 1)
+		{
+			if (Math.floor((time / 60)) / 60 < 10)
+			{
+				hours = "0" + Math.floor(time / 60) + ":";
+			}
+			else
+			{
+				hours = Math.floor(time / 60) + ":";
+			}
+			
+			if (Math.floor((time / 60) % 60) < 10)
+			{
+				minutes = "0" + Math.floor((time / 60) % 60) + ":";
+			}
+			else
+			{
+				minutes = Math.floor((time / 60) % 60) + ":";
+			}
+			
+			if (Math.floor(time % 60) < 10)
+			{
+				seconds = "0" + Math.floor(time % 60);
+			}
+			else
+			{
+				seconds = Std.string(Math.floor(time % 60));
+			}
+		}
+		else if((time / 60) >= 1)
+		{
+			hours = "00:";
+			
+			if (Math.floor(time / 60) < 10)
+			{
+				minutes = "0" + Math.floor(time / 60) + ":";
+			}
+			else
+			{
+				minutes = Math.floor(time / 60) + ":";
+			}
+			
+			if (Math.floor(time % 60) < 10)
+			{
+				seconds = "0" + Math.floor(time % 60);
+			}
+			else
+			{
+				seconds = Std.string(Math.floor(time % 60));
+			}
+		}
+		else
+		{
+			hours = "00:";
+			
+			minutes = "00:";
+			
+			if (Math.floor(time) < 10)
+			{
+				seconds = "0" + Math.floor(time);
+			}
+			else
+			{
+				seconds = Std.string(Math.floor(time));
+			}
+		}
+		
+		timeString += hours + minutes + seconds;
+		
+		return timeString;
+	}
+	
+	/**
+	 * Draws a triangle. Im not so good on mathematics so this is incomplete only for play button xD
+	 * @param	object
+	 * @param	x
+	 * @param	y
+	 * @param	ratio
+	 * @param	rotation
+	 */
+	public static function drawTriangle(object:Dynamic, x:Float, y:Float, ratio:Float, rotation:Float=0):Void
+	{	
+		object.graphics.moveTo(x, y);
+		object.graphics.lineTo(x, y + ratio);
+		object.graphics.lineTo(x + ratio, y + (ratio / 2 ));
+		object.graphics.lineTo(x, y);
+	}
+}
\ No newline at end of file

-- 
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