[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