/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

import flash.external.ExternalInterface;
import System.security;

/**
 * XPC Flash Based Transport
 * Original design by evn@google.com (Eduardo Vela)
 */
class Main {
  private static var SINGLETON:Boolean = false;
  public static function main(swfRoot:MovieClip):Void {
    if (SINGLETON) return;
    SINGLETON = true;

    var origin:String;

    if (_level0.origin == undefined){
      origin = "http://*";
    } else {
      origin = _level0.origin;
    }

    var domain:String = origin.substr(origin.indexOf("//") + 2, origin.length);

    if (origin.substr(0,5)==="http:") {
      security.allowInsecureDomain(domain);
    } else {
      security.allowDomain(domain);
    }

    ExternalInterface.addCallback("setup", { }, function(this_channel:String, role:String) {
      if (this_channel.indexOf(":") > -1) {
        return;
      }

      var other_role:String;

      if (role == "INNER") {
        other_role = "OUTER";
      } else {
        role = "OUTER";
        other_role = "INNER";
      }

      var receiving_lc:LocalConnection = new LocalConnection();
      var sending_lc:LocalConnection = new LocalConnection();
      receiving_lc.receiveMessage = function(to:String, from:String, channel:String, message:String) {
        if ((to === "*" || to === origin) && channel === this_channel) {
          ExternalInterface.call("gadgets.rpctx.flash.receiveMessage", channel, message, from, to);
        }
      }

      ExternalInterface.addCallback("sendMessage_"+this_channel, { }, function(message:String, to:String) {
        if (!to) to = "*";
        sending_lc.send(this_channel + "_" + other_role, "receiveMessage", to, origin, this_channel, message);
      } );
      receiving_lc.connect(this_channel + "_" + role);
    } );
    ExternalInterface.call("ready");
  }

  public function Main() {
  }
}

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

import flash.external.ExternalInterface;
import System.security;

/**
 * XPC Flash Based Transport
 * Original design by evn@google.com (Eduardo Vela)
 */
class Main {
  private static var SINGLETON:Boolean = false;
  public static function main(swfRoot:MovieClip):Void {
    if (SINGLETON) return;
    SINGLETON = true;

    var origin:String;

    if (_level0.origin == undefined){
      origin = "http://*";
    } else {
      origin = _level0.origin;
    }

    var domain:String = origin.substr(origin.indexOf("//") + 2, origin.length);

    if (origin.substr(0,5)==="http:") {
      security.allowInsecureDomain(domain);
    } else {
      security.allowDomain(domain);
    }

    ExternalInterface.addCallback("setup", { }, function(this_channel:String, role:String) {
      if (this_channel.indexOf(":") > -1) {
        return;
      }

      var other_role:String;

      if (role == "INNER") {
        other_role = "OUTER";
      } else {
        role = "OUTER";
        other_role = "INNER";
      }

      var receiving_lc:LocalConnection = new LocalConnection();
      var sending_lc:LocalConnection = new LocalConnection();
      receiving_lc.receiveMessage = function(to:String, from:String, channel:String, message:String) {
        if ((to === "*" || to === origin) && channel === this_channel) {
          ExternalInterface.call("gadgets.rpctx.flash._receiveMessage", channel, message, from, to);
        }
      }

      ExternalInterface.addCallback("sendMessage_"+this_channel, { }, function(message:String, to:String) {
        if (!to) to = "*";
        sending_lc.send(this_channel + "_" + other_role, "receiveMessage", to, origin, this_channel, message);
      } );
      receiving_lc.connect(this_channel + "_" + role);
    } );
    ExternalInterface.call("gadgets.rpctx.flash._ready");
  }

  public function Main() {
  }
}

Rename callback methods for relay SWF. TODO: build this and commit.

git-svn-id: 84334937b86421baa0e582c4ab1a9d358324cbeb@1049774 13f79535-47bb-0310-9956-ffa450edef68


/* Swfdec
 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

/*** GENERAL ***/

ASSetNative = ASnative (4, 0);
ASSetNativeAccessor = ASnative (4, 1);

/*** ASBROADCASTER ***/

function AsBroadcaster () { };

AsBroadcaster.broadcastMessage = ASnative(101, 12);

AsBroadcaster.addListener = function (x) {
  this.removeListener (x);
  this._listeners.push (x);
  return true;
};

AsBroadcaster.removeListener = function (x) {
  var l = this._listeners;
  var i;

  for (var i = 0; i < l.length; i++) {
    if (l[i] == x) {
      l.splice (i, 1);
      return true;
    }
  }
  return false;
};

AsBroadcaster.initialize = function (o) {
  o.broadcastMessage = ASnative(101, 12);
  o.addListener = AsBroadcaster.addListener;
  o.removeListener = AsBroadcaster.removeListener;
  o._listeners = new Array ();
  ASSetPropFlags(o, "broadcastMessage,addListener,removeListener,_listeners", 131);
};
ASSetPropFlags(AsBroadcaster, null, 131);

Key = { ALT: 18, BACKSPACE: 8, CAPSLOCK: 20, CONTROL: 17, DELETEKEY: 46,
    DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37,
    PGDN: 34, PGUP: 33, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38 };
ASSetNative(Key, 800, "getAscii,getCode,isDown");
AsBroadcaster.initialize(Key);
ASSetPropFlags(Key, null, 7);

/*** MOUSE ***/

Mouse = new Object ();
Mouse.show = ASnative (5, 0);
Mouse.hide = ASnative (5, 1);
AsBroadcaster.initialize (Mouse);
ASSetPropFlags(Mouse, null, 7);

/*** STAGE ***/

Stage = new Object ();
AsBroadcaster.initialize (Stage);
ASSetNativeAccessor (Stage, 666, "scaleMode,align,width,height", 1);

/*** LOADVARS ***/

function LoadVars () { };

LoadVars.prototype.contentType = "application/x-www-form-urlencoded";

LoadVars.prototype.load = ASnative (301, 0);
//LoadVars.prototype.send = ASnative (301, 1);
//LoadVars.prototype.sendAndLoad = ASnative (301, 2);
LoadVars.prototype.decode = ASnative (301, 3);

LoadVars.prototype.onLoad = function () {
};

LoadVars.prototype.onData = function (src) {
  this.loaded = true;
  if (src != null) {
    this.decode (src);
    this.onLoad (true);
  } else {
    this.onLoad (false);
  }
};

LoadVars.prototype.toString = function () {
  var str = null;
  for (var x in this) {
    if (str == null) {
      str = escape(x) + "=" + escape(this[x]);
    } else {
      str += "&" + escape(x) + "=" + escape(this[x]);
    }
  }
  return str;
};

LoadVars.prototype.getBytesLoaded = function () {
  return this._bytesLoaded;
};

LoadVars.prototype.getBytesTotal = function () {
  return this._bytesTotal;
};

ASSetPropFlags(LoadVars.prototype, null, 131);

/*** XML ***/

XML.prototype.load = ASnative (301, 0);

/*** System ***/

System = {};
System.capabilities = {};
System.capabilities.Query = ASnative(11, 0);
System.capabilities.Query();
delete System.capabilities.Query;

/*** OH THE HUMANITY ***/

o = null;

/* Swfdec
 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

/*** GENERAL ***/

ASSetNative = ASnative (4, 0);
ASSetNativeAccessor = ASnative (4, 1);

/*** ASBROADCASTER ***/

function AsBroadcaster () { };

AsBroadcaster.broadcastMessage = ASnative(101, 12);

AsBroadcaster.addListener = function (x) {
  this.removeListener (x);
  this._listeners.push (x);
  return true;
};

AsBroadcaster.removeListener = function (x) {
  var l = this._listeners;
  var i;

  for (var i = 0; i < l.length; i++) {
    if (l[i] == x) {
      l.splice (i, 1);
      return true;
    }
  }
  return false;
};

AsBroadcaster.initialize = function (o) {
  o.broadcastMessage = ASnative(101, 12);
  o.addListener = AsBroadcaster.addListener;
  o.removeListener = AsBroadcaster.removeListener;
  o._listeners = new Array ();
  ASSetPropFlags(o, "broadcastMessage,addListener,removeListener,_listeners", 131);
};
ASSetPropFlags(AsBroadcaster, null, 131);

Key = { ALT: 18, BACKSPACE: 8, CAPSLOCK: 20, CONTROL: 17, DELETEKEY: 46,
    DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37,
    PGDN: 34, PGUP: 33, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38 };
ASSetNative(Key, 800, "getAscii,getCode,isDown");
AsBroadcaster.initialize(Key);
ASSetPropFlags(Key, null, 7);

/*** MOUSE ***/

Mouse = new Object ();
Mouse.show = ASnative (5, 0);
Mouse.hide = ASnative (5, 1);
AsBroadcaster.initialize (Mouse);
ASSetPropFlags(Mouse, null, 7);

/*** STAGE ***/

Stage = new Object ();
AsBroadcaster.initialize (Stage);
ASSetNativeAccessor (Stage, 666, "scaleMode,align,width,height", 1);

/*** LOADVARS ***/

function LoadVars () { };

LoadVars.prototype.contentType = "application/x-www-form-urlencoded";

LoadVars.prototype.load = ASnative (301, 0);
//LoadVars.prototype.send = ASnative (301, 1);
//LoadVars.prototype.sendAndLoad = ASnative (301, 2);
LoadVars.prototype.decode = ASnative (301, 3);

LoadVars.prototype.onLoad = function () {
};

LoadVars.prototype.onData = function (src) {
  this.loaded = true;
  if (src != null) {
    this.decode (src);
    this.onLoad (true);
  } else {
    this.onLoad (false);
  }
};

LoadVars.prototype.toString = function () {
  var str = null;
  for (var x in this) {
    if (str == null) {
      str = escape(x) + "=" + escape(this[x]);
    } else {
      str += "&" + escape(x) + "=" + escape(this[x]);
    }
  }
  return str;
};

LoadVars.prototype.getBytesLoaded = function () {
  return this._bytesLoaded;
};

LoadVars.prototype.getBytesTotal = function () {
  return this._bytesTotal;
};

ASSetPropFlags(LoadVars.prototype, null, 131);

/*** XML ***/

XML.prototype.load = ASnative (301, 0);

/*** System ***/

System = {};
System.capabilities = {};
System.capabilities.Query = ASnative (11, 0);
System.capabilities.Query ();
delete System.capabilities.Query;
$version = System.capabilities.version;

/*** OH THE HUMANITY ***/

o = null;

initialize $version variable

initialize $version variable


package org.mangui.chromeless {
    import flash.net.URLStream;

    import org.mangui.HLS.parsing.Level;
    import org.mangui.HLS.*;
    import org.mangui.HLS.utils.*;

    import flash.display.*;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.geom.Rectangle;
    import flash.media.Video;
    import flash.media.SoundTransform;
    import flash.media.StageVideo;
    import flash.media.StageVideoAvailability;
    import flash.utils.setTimeout;

    // import com.sociodox.theminer.*;
    public class ChromelessPlayer extends Sprite {
        /** reference to the framework. **/
        private var _hls : HLS;
        /** Sheet to place on top of the video. **/
        private var _sheet : Sprite;
        /** Reference to the stage video element. **/
        private var _stageVideo : StageVideo = null;
        /** Reference to the video element. **/
        private var _video : Video = null;
        /** Video size **/
        private var _videoWidth : Number = 0;
        private var _videoHeight : Number = 0;
        /** current media position */
        private var _media_position : Number;
        private var _duration : Number;

        /** Initialization. **/
        public function ChromelessPlayer() {
            // Set stage properties
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            stage.addEventListener(Event.RESIZE, _onStageResize);
            // Draw sheet for catching clicks
            _sheet = new Sprite();
            _sheet.graphics.beginFill(0x000000, 0);
            _sheet.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.addEventListener(MouseEvent.CLICK, _clickHandler);
            _sheet.buttonMode = true;
            addChild(_sheet);
            // Connect getters to JS.
            ExternalInterface.addCallback("getLevel", _getLevel);
            ExternalInterface.addCallback("getLevels", _getLevels);
            ExternalInterface.addCallback("getMetrics", _getMetrics);
            ExternalInterface.addCallback("getDuration", _getDuration);
            ExternalInterface.addCallback("getPosition", _getPosition);
            ExternalInterface.addCallback("getPlaybackState", _getPlaybackState);
            ExternalInterface.addCallback("getSeekState", _getSeekState);
            ExternalInterface.addCallback("getType", _getType);
            ExternalInterface.addCallback("getmaxBufferLength", _getmaxBufferLength);
            ExternalInterface.addCallback("getminBufferLength", _getminBufferLength);
            ExternalInterface.addCallback("getlowBufferLength", _getlowBufferLength);
            ExternalInterface.addCallback("getbufferLength", _getbufferLength);
            ExternalInterface.addCallback("getLogDebug", _getLogDebug);
            ExternalInterface.addCallback("getLogDebug2", _getLogDebug2);
            ExternalInterface.addCallback("getCapLeveltoStage", _getCapLeveltoStage);
            ExternalInterface.addCallback("getflushLiveURLCache", _getflushLiveURLCache);
            ExternalInterface.addCallback("getstartFromLowestLevel", _getstartFromLowestLevel);
            ExternalInterface.addCallback("getseekFromLowestLevel", _getseekFromLowestLevel);
            ExternalInterface.addCallback("getJSURLStream", _getJSURLStream);
            ExternalInterface.addCallback("getPlayerVersion", _getPlayerVersion);
            ExternalInterface.addCallback("getAudioTrackList", _getAudioTrackList);
            ExternalInterface.addCallback("getAudioTrackId", _getAudioTrackId);
            // Connect calls to JS.
            ExternalInterface.addCallback("playerLoad", _load);
            ExternalInterface.addCallback("playerPlay", _play);
            ExternalInterface.addCallback("playerPause", _pause);
            ExternalInterface.addCallback("playerResume", _resume);
            ExternalInterface.addCallback("playerSeek", _seek);
            ExternalInterface.addCallback("playerStop", _stop);
            ExternalInterface.addCallback("playerVolume", _volume);
            ExternalInterface.addCallback("playerSetLevel", _setLevel);
            ExternalInterface.addCallback("playerSmoothSetLevel", _smoothSetLevel);
            ExternalInterface.addCallback("playerSetmaxBufferLength", _setmaxBufferLength);
            ExternalInterface.addCallback("playerSetminBufferLength", _setminBufferLength);
            ExternalInterface.addCallback("playerSetlowBufferLength", _setlowBufferLength);
            ExternalInterface.addCallback("playerSetflushLiveURLCache", _setflushLiveURLCache);
            ExternalInterface.addCallback("playerSetstartFromLowestLevel", _setstartFromLowestLevel);
            ExternalInterface.addCallback("playerSetseekFromLowestLevel", _setseekFromLowestLevel);
            ExternalInterface.addCallback("playerSetLogDebug", _setLogDebug);
            ExternalInterface.addCallback("playerSetLogDebug2", _setLogDebug2);
            ExternalInterface.addCallback("playerCapLeveltoStage", _setCapLeveltoStage);
            ExternalInterface.addCallback("playerSetAudioTrack", _setAudioTrack);
            ExternalInterface.addCallback("playerSetJSURLStream", _setJSURLStream);

            setTimeout(_pingJavascript, 50);
        };

        /** Notify javascript the framework is ready. **/
        private function _pingJavascript() : void {
            ExternalInterface.call("onHLSReady", ExternalInterface.objectID);
        };

        /** Forward events from the framework. **/
        private function _completeHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onComplete");
            }
        };

        private function _errorHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                var hlsError : HLSError = event.error;
                ExternalInterface.call("onError", hlsError.code, hlsError.url, hlsError.msg);
            }
        };

        private function _fragmentHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragment", event.metrics.bandwidth, event.metrics.level, stage.stageWidth);
            }
        };

        private function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[0].duration;
            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest", event.levels[0].duration);
            }
        };

        private function _mediaTimeHandler(event : HLSEvent) : void {
            _duration = event.mediatime.duration;
            _media_position = event.mediatime.position;
            if (ExternalInterface.available) {
                ExternalInterface.call("onPosition", event.mediatime.position, event.mediatime.duration, event.mediatime.live_sliding);
            }

            var videoWidth : Number = _video ? _video.videoWidth : _stageVideo.videoWidth;
            var videoHeight : Number = _video ? _video.videoHeight : _stageVideo.videoHeight;

            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    _videoHeight = videoHeight;
                    _videoWidth = videoWidth;
                    _resize();
                    if (ExternalInterface.available) {
                        ExternalInterface.call("onVideoSize", _videoWidth, _videoHeight);
                    }
                }
            }
        };

        private function _stateHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onState", event.state);
            }
        };

        private function _switchHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onSwitch", event.level);
            }
        };

        private function _audioTracksListChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTracksListChange", _getAudioTrackList());
            }
        }

        private function _audioTrackChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTrackChange", event.audioTrack);
            }
        }

        /** Javascript getters. **/
        private function _getLevel() : Number {
            return _hls.level;
        };

        private function _getLevels() : Vector.<Level> {
            return _hls.levels;
        };

        private function _getMetrics() : Object {
            return _hls.metrics;
        };

        private function _getDuration() : Number {
            return _duration;
        };

        private function _getPosition() : Number {
            return _hls.position;
        };

        private function _getPlaybackState() : String {
            return _hls.playbackState;
        };

        private function _getSeekState() : String {
            return _hls.seekState;
        };

        private function _getType() : String {
            return _hls.type;
        };

        private function _getbufferLength() : Number {
            return _hls.bufferLength;
        };

        private function _getmaxBufferLength() : Number {
            return _hls.maxBufferLength;
        };

        private function _getminBufferLength() : Number {
            return _hls.minBufferLength;
        };

        private function _getlowBufferLength() : Number {
            return _hls.lowBufferLength;
        };

        private function _getflushLiveURLCache() : Boolean {
            return _hls.flushLiveURLCache;
        };

        private function _getstartFromLowestLevel() : Boolean {
            return _hls.startFromLowestLevel;
        };

        private function _getseekFromLowestLevel() : Boolean {
            return _hls.seekFromLowestLevel;
        };

        private function _getLogDebug() : Boolean {
            return Log.LOG_DEBUG_ENABLED;
        };

        private function _getLogDebug2() : Boolean {
            return Log.LOG_DEBUG2_ENABLED;
        };

        private function _getCapLeveltoStage() : Boolean {
            return _hls.capLeveltoStage;
        };

        private function _getJSURLStream() : Boolean {
            return (_hls.URLstream is JSURLStream);
        };

        private function _getPlayerVersion() : Number {
            return 2;
        };

        private function _getAudioTrackList() : Array {
            var list : Array = [];
            var vec : Vector.<HLSAudioTrack> = _hls.audioTracks;
            for (var i : Object in vec) {
                list.push(vec[i]);
            }
            return list;
        };

        private function _getAudioTrackId() : Number {
            return _hls.audioTrack;
        };

        /** Javascript calls. **/
        private function _load(url : String) : void {
            _hls.load(url);
        };

        private function _play() : void {
            _hls.stream.play();
        };

        private function _pause() : void {
            _hls.stream.pause();
        };

        private function _resume() : void {
            _hls.stream.resume();
        };

        private function _seek(position : Number) : void {
            _hls.stream.seek(position);
        };

        private function _stop() : void {
            _hls.stream.close();
        };

        private function _volume(percent : Number) : void {
            _hls.stream.soundTransform = new SoundTransform(percent / 100);
        };

        private function _setLevel(level : Number) : void {
            _smoothSetLevel(level);
            if (!isNaN(_media_position) && level != -1) {
                _hls.stream.seek(_media_position);
            }
        };

        private function _smoothSetLevel(level : Number) : void {
            if (level != _hls.level) {
                _hls.level = level;
            }
        };

        private function _setmaxBufferLength(new_len : Number) : void {
            _hls.maxBufferLength = new_len;
        };

        private function _setminBufferLength(new_len : Number) : void {
            _hls.minBufferLength = new_len;
        };

        private function _setlowBufferLength(new_len : Number) : void {
            _hls.lowBufferLength = new_len;
        };

        private function _setflushLiveURLCache(flushLiveURLCache : Boolean) : void {
            _hls.flushLiveURLCache = flushLiveURLCache;
        };

        private function _setstartFromLowestLevel(startFromLowestLevel : Boolean) : void {
            _hls.startFromLowestLevel = startFromLowestLevel;
        };

        private function _setseekFromLowestLevel(seekFromLowestLevel : Boolean) : void {
            _hls.seekFromLowestLevel = seekFromLowestLevel;
        };

        private function _setLogDebug(debug : Boolean) : void {
            Log.LOG_DEBUG_ENABLED = debug;
        };

        private function _setLogDebug2(debug2 : Boolean) : void {
            Log.LOG_DEBUG2_ENABLED = debug2;
        };

        private function _setCapLeveltoStage(value : Boolean) : void {
            _hls.capLeveltoStage = value;
        };

        private function _setJSURLStream(jsURLstream : Boolean) : void {
            if (jsURLstream) {
                _hls.URLstream = JSURLStream as Class;
            } else {
                _hls.URLstream = URLStream as Class;
            }
        };

        private function _setAudioTrack(val : Number) : void {
            if (val == _hls.audioTrack) return;
            _hls.audioTrack = val;
            if (!isNaN(_media_position)) {
                _hls.stream.seek(_media_position);
            }
        };

        /** Mouse click handler. **/
        private function _clickHandler(event : MouseEvent) : void {
            if (stage.displayState == StageDisplayState.FULL_SCREEN_INTERACTIVE || stage.displayState == StageDisplayState.FULL_SCREEN) {
                stage.displayState = StageDisplayState.NORMAL;
            } else {
                stage.displayState = StageDisplayState.FULL_SCREEN;
            }
        };

        /** StageVideo detector. **/
        private function _onStageVideoState(event : StageVideoAvailabilityEvent) : void {
            var available : Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            _hls = new HLS();
            _hls.stage = stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.QUALITY_SWITCH, _switchHandler);
            _hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, _audioTracksListChange);
            _hls.addEventListener(HLSEvent.AUDIO_TRACK_CHANGE, _audioTrackChange);

            if (available && stage.stageVideos.length > 0) {
                _stageVideo = stage.stageVideos[0];
                _stageVideo.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
                _stageVideo.attachNetStream(_hls.stream);
            } else {
                _video = new Video(stage.stageWidth, stage.stageHeight);
                addChild(_video);
                _video.smoothing = true;
                _video.attachNetStream(_hls.stream);
            }
            stage.removeEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            // addChild(new TheMiner());
        };

        private function _onStageResize(event : Event) : void {
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.width = stage.stageWidth;
            _sheet.height = stage.stageHeight;
            _resize();
        };

        private function _resize() : void {
            var rect : Rectangle;
            rect = ScaleVideo.resizeRectangle(_videoWidth, _videoHeight, stage.stageWidth, stage.stageHeight);
            // resize video
            if (_video) {
                _video.width = rect.width;
                _video.height = rect.height;
                _video.x = rect.x;
                _video.y = rect.y;
            } else if (_stageVideo) {
                _stageVideo.viewPort = rect;
            }
        }
    }
}

package org.mangui.chromeless {
    import flash.net.URLStream;

    import org.mangui.HLS.parsing.Level;
    import org.mangui.HLS.*;
    import org.mangui.HLS.utils.*;

    import flash.display.*;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.geom.Rectangle;
    import flash.media.Video;
    import flash.media.SoundTransform;
    import flash.media.StageVideo;
    import flash.media.StageVideoAvailability;
    import flash.utils.setTimeout;

    // import com.sociodox.theminer.*;
    public class ChromelessPlayer extends Sprite {
        /** reference to the framework. **/
        private var _hls : HLS;
        /** Sheet to place on top of the video. **/
        private var _sheet : Sprite;
        /** Reference to the stage video element. **/
        private var _stageVideo : StageVideo = null;
        /** Reference to the video element. **/
        private var _video : Video = null;
        /** Video size **/
        private var _videoWidth : Number = 0;
        private var _videoHeight : Number = 0;
        /** current media position */
        private var _media_position : Number;
        private var _duration : Number;
	/** URL autoload feature */
	private var _autoLoad : Boolean = false;

        /** Initialization. **/
        public function ChromelessPlayer() {
            // Set stage properties
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            stage.addEventListener(Event.RESIZE, _onStageResize);
            // Draw sheet for catching clicks
            _sheet = new Sprite();
            _sheet.graphics.beginFill(0x000000, 0);
            _sheet.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.addEventListener(MouseEvent.CLICK, _clickHandler);
            _sheet.buttonMode = true;
            addChild(_sheet);
            // Connect getters to JS.
            ExternalInterface.addCallback("getLevel", _getLevel);
            ExternalInterface.addCallback("getLevels", _getLevels);
            ExternalInterface.addCallback("getMetrics", _getMetrics);
            ExternalInterface.addCallback("getDuration", _getDuration);
            ExternalInterface.addCallback("getPosition", _getPosition);
            ExternalInterface.addCallback("getPlaybackState", _getPlaybackState);
            ExternalInterface.addCallback("getSeekState", _getSeekState);
            ExternalInterface.addCallback("getType", _getType);
            ExternalInterface.addCallback("getmaxBufferLength", _getmaxBufferLength);
            ExternalInterface.addCallback("getminBufferLength", _getminBufferLength);
            ExternalInterface.addCallback("getlowBufferLength", _getlowBufferLength);
            ExternalInterface.addCallback("getbufferLength", _getbufferLength);
            ExternalInterface.addCallback("getLogDebug", _getLogDebug);
            ExternalInterface.addCallback("getLogDebug2", _getLogDebug2);
            ExternalInterface.addCallback("getCapLeveltoStage", _getCapLeveltoStage);
            ExternalInterface.addCallback("getflushLiveURLCache", _getflushLiveURLCache);
            ExternalInterface.addCallback("getstartFromLowestLevel", _getstartFromLowestLevel);
            ExternalInterface.addCallback("getseekFromLowestLevel", _getseekFromLowestLevel);
            ExternalInterface.addCallback("getJSURLStream", _getJSURLStream);
            ExternalInterface.addCallback("getPlayerVersion", _getPlayerVersion);
            ExternalInterface.addCallback("getAudioTrackList", _getAudioTrackList);
            ExternalInterface.addCallback("getAudioTrackId", _getAudioTrackId);
            // Connect calls to JS.
            ExternalInterface.addCallback("playerLoad", _load);
            ExternalInterface.addCallback("playerPlay", _play);
            ExternalInterface.addCallback("playerPause", _pause);
            ExternalInterface.addCallback("playerResume", _resume);
            ExternalInterface.addCallback("playerSeek", _seek);
            ExternalInterface.addCallback("playerStop", _stop);
            ExternalInterface.addCallback("playerVolume", _volume);
            ExternalInterface.addCallback("playerSetLevel", _setLevel);
            ExternalInterface.addCallback("playerSmoothSetLevel", _smoothSetLevel);
            ExternalInterface.addCallback("playerSetmaxBufferLength", _setmaxBufferLength);
            ExternalInterface.addCallback("playerSetminBufferLength", _setminBufferLength);
            ExternalInterface.addCallback("playerSetlowBufferLength", _setlowBufferLength);
            ExternalInterface.addCallback("playerSetflushLiveURLCache", _setflushLiveURLCache);
            ExternalInterface.addCallback("playerSetstartFromLowestLevel", _setstartFromLowestLevel);
            ExternalInterface.addCallback("playerSetseekFromLowestLevel", _setseekFromLowestLevel);
            ExternalInterface.addCallback("playerSetLogDebug", _setLogDebug);
            ExternalInterface.addCallback("playerSetLogDebug2", _setLogDebug2);
            ExternalInterface.addCallback("playerCapLeveltoStage", _setCapLeveltoStage);
            ExternalInterface.addCallback("playerSetAudioTrack", _setAudioTrack);
            ExternalInterface.addCallback("playerSetJSURLStream", _setJSURLStream);

            setTimeout(_pingJavascript, 50);
        };

        /** Notify javascript the framework is ready. **/
        private function _pingJavascript() : void {
            ExternalInterface.call("onHLSReady", ExternalInterface.objectID);
        };

        /** Forward events from the framework. **/
        private function _completeHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onComplete");
            }
        };

        private function _errorHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                var hlsError : HLSError = event.error;
                ExternalInterface.call("onError", hlsError.code, hlsError.url, hlsError.msg);
            }
        };

        private function _fragmentHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragment", event.metrics.bandwidth, event.metrics.level, stage.stageWidth);
            }
        };

        private function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[0].duration;

            if (_autoLoad) {
                _play();
            }

            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest", event.levels[0].duration);
            }
        };

        private function _mediaTimeHandler(event : HLSEvent) : void {
            _duration = event.mediatime.duration;
            _media_position = event.mediatime.position;
            if (ExternalInterface.available) {
                ExternalInterface.call("onPosition", event.mediatime.position, event.mediatime.duration, event.mediatime.live_sliding);
            }

            var videoWidth : Number = _video ? _video.videoWidth : _stageVideo.videoWidth;
            var videoHeight : Number = _video ? _video.videoHeight : _stageVideo.videoHeight;

            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    _videoHeight = videoHeight;
                    _videoWidth = videoWidth;
                    _resize();
                    if (ExternalInterface.available) {
                        ExternalInterface.call("onVideoSize", _videoWidth, _videoHeight);
                    }
                }
            }
        };

        private function _stateHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onState", event.state);
            }
        };

        private function _switchHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onSwitch", event.level);
            }
        };

        private function _audioTracksListChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTracksListChange", _getAudioTrackList());
            }
        }

        private function _audioTrackChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTrackChange", event.audioTrack);
            }
        }

        /** Javascript getters. **/
        private function _getLevel() : Number {
            return _hls.level;
        };

        private function _getLevels() : Vector.<Level> {
            return _hls.levels;
        };

        private function _getMetrics() : Object {
            return _hls.metrics;
        };

        private function _getDuration() : Number {
            return _duration;
        };

        private function _getPosition() : Number {
            return _hls.position;
        };

        private function _getPlaybackState() : String {
            return _hls.playbackState;
        };

        private function _getSeekState() : String {
            return _hls.seekState;
        };

        private function _getType() : String {
            return _hls.type;
        };

        private function _getbufferLength() : Number {
            return _hls.bufferLength;
        };

        private function _getmaxBufferLength() : Number {
            return _hls.maxBufferLength;
        };

        private function _getminBufferLength() : Number {
            return _hls.minBufferLength;
        };

        private function _getlowBufferLength() : Number {
            return _hls.lowBufferLength;
        };

        private function _getflushLiveURLCache() : Boolean {
            return _hls.flushLiveURLCache;
        };

        private function _getstartFromLowestLevel() : Boolean {
            return _hls.startFromLowestLevel;
        };

        private function _getseekFromLowestLevel() : Boolean {
            return _hls.seekFromLowestLevel;
        };

        private function _getLogDebug() : Boolean {
            return Log.LOG_DEBUG_ENABLED;
        };

        private function _getLogDebug2() : Boolean {
            return Log.LOG_DEBUG2_ENABLED;
        };

        private function _getCapLeveltoStage() : Boolean {
            return _hls.capLeveltoStage;
        };

        private function _getJSURLStream() : Boolean {
            return (_hls.URLstream is JSURLStream);
        };

        private function _getPlayerVersion() : Number {
            return 2;
        };

        private function _getAudioTrackList() : Array {
            var list : Array = [];
            var vec : Vector.<HLSAudioTrack> = _hls.audioTracks;
            for (var i : Object in vec) {
                list.push(vec[i]);
            }
            return list;
        };

        private function _getAudioTrackId() : Number {
            return _hls.audioTrack;
        };

        /** Javascript calls. **/
        private function _load(url : String) : void {
            _hls.load(url);
        };

        private function _play() : void {
            _hls.stream.play();
        };

        private function _pause() : void {
            _hls.stream.pause();
        };

        private function _resume() : void {
            _hls.stream.resume();
        };

        private function _seek(position : Number) : void {
            _hls.stream.seek(position);
        };

        private function _stop() : void {
            _hls.stream.close();
        };

        private function _volume(percent : Number) : void {
            _hls.stream.soundTransform = new SoundTransform(percent / 100);
        };

        private function _setLevel(level : Number) : void {
            _smoothSetLevel(level);
            if (!isNaN(_media_position) && level != -1) {
                _hls.stream.seek(_media_position);
            }
        };

        private function _smoothSetLevel(level : Number) : void {
            if (level != _hls.level) {
                _hls.level = level;
            }
        };

        private function _setmaxBufferLength(new_len : Number) : void {
            _hls.maxBufferLength = new_len;
        };

        private function _setminBufferLength(new_len : Number) : void {
            _hls.minBufferLength = new_len;
        };

        private function _setlowBufferLength(new_len : Number) : void {
            _hls.lowBufferLength = new_len;
        };

        private function _setflushLiveURLCache(flushLiveURLCache : Boolean) : void {
            _hls.flushLiveURLCache = flushLiveURLCache;
        };

        private function _setstartFromLowestLevel(startFromLowestLevel : Boolean) : void {
            _hls.startFromLowestLevel = startFromLowestLevel;
        };

        private function _setseekFromLowestLevel(seekFromLowestLevel : Boolean) : void {
            _hls.seekFromLowestLevel = seekFromLowestLevel;
        };

        private function _setLogDebug(debug : Boolean) : void {
            Log.LOG_DEBUG_ENABLED = debug;
        };

        private function _setLogDebug2(debug2 : Boolean) : void {
            Log.LOG_DEBUG2_ENABLED = debug2;
        };

        private function _setCapLeveltoStage(value : Boolean) : void {
            _hls.capLeveltoStage = value;
        };

        private function _setJSURLStream(jsURLstream : Boolean) : void {
            if (jsURLstream) {
                _hls.URLstream = JSURLStream as Class;
            } else {
                _hls.URLstream = URLStream as Class;
            }
        };

        private function _setAudioTrack(val : Number) : void {
            if (val == _hls.audioTrack) return;
            _hls.audioTrack = val;
            if (!isNaN(_media_position)) {
                _hls.stream.seek(_media_position);
            }
        };

        /** Mouse click handler. **/
        private function _clickHandler(event : MouseEvent) : void {
            if (stage.displayState == StageDisplayState.FULL_SCREEN_INTERACTIVE || stage.displayState == StageDisplayState.FULL_SCREEN) {
                stage.displayState = StageDisplayState.NORMAL;
            } else {
                stage.displayState = StageDisplayState.FULL_SCREEN;
            }
        };

        /** StageVideo detector. **/
        private function _onStageVideoState(event : StageVideoAvailabilityEvent) : void {
            var available : Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            _hls = new HLS();
            _hls.stage = stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.QUALITY_SWITCH, _switchHandler);
            _hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, _audioTracksListChange);
            _hls.addEventListener(HLSEvent.AUDIO_TRACK_CHANGE, _audioTrackChange);

            if (available && stage.stageVideos.length > 0) {
                _stageVideo = stage.stageVideos[0];
                _stageVideo.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
                _stageVideo.attachNetStream(_hls.stream);
            } else {
                _video = new Video(stage.stageWidth, stage.stageHeight);
                addChild(_video);
                _video.smoothing = true;
                _video.attachNetStream(_hls.stream);
            }
            stage.removeEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            // addChild(new TheMiner());

            var autoLoadUrl : String = root.loaderInfo.parameters.url as String;
            if (autoLoadUrl != null) {
                _autoLoad = true;
                _load(autoLoadUrl);
            }
        };

        private function _onStageResize(event : Event) : void {
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.width = stage.stageWidth;
            _sheet.height = stage.stageHeight;
            _resize();
        };

        private function _resize() : void {
            var rect : Rectangle;
            rect = ScaleVideo.resizeRectangle(_videoWidth, _videoHeight, stage.stageWidth, stage.stageHeight);
            // resize video
            if (_video) {
                _video.width = rect.width;
                _video.height = rect.height;
                _video.x = rect.x;
                _video.y = rect.y;
            } else if (_stageVideo) {
                _stageVideo.viewPort = rect;
            }
        }
    }
}

Add URL auto-loading support to the chromeless player

The "url" flashvar now allows the chromeless player to automatically load and play the specified URL.
This allows the player to be used without any JavaScript.


//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2012 Freshplanet (http://freshplanet.com | opensource@freshplanet.com)
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//////////////////////////////////////////////////////////////////////////////////////

package com.freshplanet.ane.AirBackgroundFetch
{
	import flash.events.EventDispatcher;
	import flash.events.StatusEvent;
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

	public class AirBackgroundFetch extends EventDispatcher
	{
		// --------------------------------------------------------------------------------------//
		//																						 //
		// 									   PUBLIC API										 //
		// 																						 //
		// --------------------------------------------------------------------------------------//

		/** AirBackgroundFetch is supported on iOS and Android devices. */
		public static function get isSupported() : Boolean
		{
			var isIOS:Boolean = (Capabilities.manufacturer.indexOf("iOS") != -1);
			var isAndroid:Boolean = (Capabilities.manufacturer.indexOf("Android") != -1)
			return isIOS || isAndroid;
		}

		public function AirBackgroundFetch()
		{
			if (!_instance)
			{
				_context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
				if (!_context)
				{
					log("ERROR - Extension context is null. Please check if extension.xml is setup correctly.");
					return;
				}
				_context.addEventListener(StatusEvent.STATUS, onStatus);

				_instance = this;
			}
			else
			{
				throw Error("This is a singleton, use getInstance(), do not call the constructor directly.");
			}
		}

		public static function getInstance() : AirBackgroundFetch
		{
			return _instance ? _instance : new AirBackgroundFetch();
		}

		public var logEnabled : Boolean = true;

		// --------------------------------------------------------------------------------------//
		//																						 //
		// 									 	PRIVATE API										 //
		// 																						 //
		// --------------------------------------------------------------------------------------//

		private static const EXTENSION_ID : String = "com.freshplanet.AirBackgroundFetch";

		private static var _instance : AirBackgroundFetch;

		private var _context : ExtensionContext;

		private function onStatus( event : StatusEvent ) : void
		{
			if (event.code == "LOGGING") // Simple log message
			{
				log(event.level);
			}
		}

		private function log( message : String ) : void
		{
			if (logEnabled) trace("[AirBackgroundFetch] " + message);
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2012 Freshplanet (http://freshplanet.com | opensource@freshplanet.com)
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//////////////////////////////////////////////////////////////////////////////////////

package com.freshplanet.ane.AirBackgroundFetch
{
	import flash.events.EventDispatcher;
	import flash.events.StatusEvent;
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

	public class AirBackgroundFetch extends EventDispatcher
	{
		// --------------------------------------------------------------------------------------//
		//																						 //
		// 									   PUBLIC API										 //
		// 																						 //
		// --------------------------------------------------------------------------------------//

		/** AirBackgroundFetch is supported on iOS and Android devices. */
		public static function get isSupported() : Boolean
		{
			var isIOS:Boolean = (Capabilities.manufacturer.indexOf("iOS") != -1);
			var isAndroid:Boolean = (Capabilities.manufacturer.indexOf("Android") != -1)
			return isIOS || isAndroid;
		}

		public function AirBackgroundFetch()
		{
			if (!_instance)
			{
				_context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
				if (!_context)
				{
					log("ERROR - Extension context is null. Please check if extension.xml is setup correctly.");
					return;
				}
				_context.addEventListener(StatusEvent.STATUS, onStatus);

				_instance = this;
			}
			else
			{
				throw Error("This is a singleton, use getInstance(), do not call the constructor directly.");
			}
		}

		public static function getInstance() : AirBackgroundFetch
		{
			return _instance ? _instance : new AirBackgroundFetch();
		}

		public var logEnabled : Boolean = true;

		// --------------------------------------------------------------------------------------//
		//																						 //
		// 									 	FUNCTIONS										 //
		// 																						 //
		// --------------------------------------------------------------------------------------//

		/**
        * Load a music stream url
        * @param url:String
        */
        public function loadUrl(url:String, data:String):void
        {
            _context.call("loadUrl", url, data);
        }

		// --------------------------------------------------------------------------------------//
		//																						 //
		// 									 	PRIVATE API										 //
		// 																						 //
		// --------------------------------------------------------------------------------------//

		private static const EXTENSION_ID : String = "com.freshplanet.AirBackgroundFetch";

		private static var _instance : AirBackgroundFetch;

		private var _context : ExtensionContext;

		private function onStatus( event : StatusEvent ) : void
		{
			if (event.code == "LOGGING") // Simple log message
			{
				log(event.level);
			}
		}

		private function log( message : String ) : void
		{
			if (logEnabled) trace("[AirBackgroundFetch] " + message);
		}
	}
}

Add loadUrl method

Add loadUrl method


#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

function hasOwnProperty_inner (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = ASnative (101, 5);
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}

function hasOwnProperty (o, prop)
{
  var result = hasOwnProperty_inner (o, prop);
#if __SWF_VERSION__ != 6
  if (result == false) {
    ASSetPropFlags (o, prop, 0, 256);
    result = hasOwnProperty_inner (o, prop);
    if (result)
      ASSetPropFlags (o, prop, 256);
  }
#endif
  return result;
}

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

#if __SWF_VERSION__ != 6
  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    if (!hasOwnProperty_inner(o, prop) && hasOwnProperty(o, prop))
    {
      set_info (info, prop, "not6", true);
    }
    else
    {
      set_info (info, prop, "not6", false);
    }
  }
#endif

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (get_info (info, prop, "not6") == true) {
      flags += "6";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (!o.hasOwnProperty ("mySecretId")) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

function hasOwnProperty_inner (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = ASnative (101, 5);
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}

function hasOwnProperty (o, prop)
{
  var result = hasOwnProperty_inner (o, prop);
#if __SWF_VERSION__ != 6
  if (result == false) {
    ASSetPropFlags (o, prop, 0, 256);
    result = hasOwnProperty_inner (o, prop);
    if (result)
      ASSetPropFlags (o, prop, 256);
  }
#endif
  return result;
}

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

#if __SWF_VERSION__ != 6
  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    if (!hasOwnProperty_inner(o, prop) && hasOwnProperty(o, prop))
    {
      set_info (info, prop, "not6", true);
    }
    else
    {
      set_info (info, prop, "not6", false);
    }
  }
#endif

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    if (typeof (o[prop]) == "undefined") {
      ASSetPropFlags (o, prop, 0, 5248);
      if (typeof (o[prop]) != "undefined") {
	set_info (info, prop, "newer", true);
	// don't set the flags back
      } else {
	set_info (info, prop, "newer", false);
      }
    } else {
      set_info (info, prop, "newer", false);
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (get_info (info, prop, "not6") == true) {
      flags += "6";
    }
    if (get_info (info, prop, "newer") == true) {
      flags += "n";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var newer = false;
    var prop = all[i];

    if (typeof (o[prop]) == "undefined") {
      ASSetPropFlags (o, prop, 0, 5248);
      if (typeof (o[prop]) != "undefined")
	newer = true;
    }

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }

    if (newer == true)
      ASSetPropFlags (o, prop, 5248);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      var newer = false;

      if (typeof (o[prop]) == "undefined") {
	ASSetPropFlags (o, prop, 0, 5248);
	if (typeof (o[prop]) != "undefined")
	  newer = true;
      }

      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);

      if (newer == true)
	ASSetPropFlags (o, prop, 5248);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (!o.hasOwnProperty ("mySecretId")) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

Make trace_properties.as detect and display props that are hidden with flags


package goplayer
{
  import flash.display.BlendMode
  import flash.display.DisplayObject
  import flash.events.TimerEvent
  import flash.utils.Timer
  import flash.utils.getTimer

  public class Fader
  {
    private const timer : Timer = new Timer(0)

    private var object : DisplayObject
    private var speed : Duration

    private var _targetAlpha : Number = NaN
    private var startAlpha : Number
    private var startTime : uint

    public function Fader(object : DisplayObject, speed : Duration)
    {
      this.object = object
      this.speed = speed

      timer.addEventListener(TimerEvent.TIMER, handleTimer)

      object.blendMode = BlendMode.LAYER
    }

    private function handleTimer(event : TimerEvent) : void
    {
      update()

      if (ended)
        timer.stop()
    }

    private function get ended() : Boolean
    { return phase == 1 }

    public function get targetAlpha() : Number
    { return _targetAlpha }

    public function set targetAlpha(value : Number) : void
    {
      // First time around, set the alpha immediately.
      if (isNaN(targetAlpha))
        object.alpha = value

      if (value != targetAlpha)
        $targetAlpha = value
    }

    private function set $targetAlpha(value : Number) : void
    {
      _targetAlpha = value

      if (targetAlpha != object.alpha)
        startFading()
    }

    private function startFading() : void
    {
      startAlpha = object.alpha
      startTime = getTimer()

      timer.start()
    }

    private function update() : void
    { object.alpha = startAlpha + deltaAlpha * phase }

    private function get deltaAlpha() : Number
    { return targetAlpha - startAlpha }

    private function get phase() : Number
    { return clamp(elapsedTime.dividedBy(duration), 0, 1) }

    private function get elapsedTime() : Duration
    { return Duration.milliseconds(getTimer() - startTime) }

    private function get duration() : Duration
    { return speed.scaledBy(Math.abs(targetAlpha - startAlpha)) }
  }
}

package goplayer
{
  import flash.display.BlendMode
  import flash.display.DisplayObject
  import flash.events.TimerEvent
  import flash.utils.Timer
  import flash.utils.getTimer

  public class Fader
  {
    private const timer : Timer = new Timer(0)

    private var object : DisplayObject
    private var speed : Duration

    private var _targetAlpha : Number = NaN
    private var startAlpha : Number
    private var startTime : uint

    public function Fader(object : DisplayObject, speed : Duration)
    {
      this.object = object
      this.speed = speed

      timer.addEventListener(TimerEvent.TIMER, handleTimer)

      object.blendMode = BlendMode.LAYER
    }

    private function handleTimer(event : TimerEvent) : void
    {
      update()

      if (ended)
        timer.stop()
    }

    private function get ended() : Boolean
    { return phase === 1 }

    public function get targetAlpha() : Number
    { return _targetAlpha }

    public function set targetAlpha(value : Number) : void
    {
      // First time around, set the alpha immediately.
      if (isNaN(targetAlpha))
        alpha = value

      if (value !== targetAlpha)
        $targetAlpha = value
    }

    private function set alpha(value : Number) : void
    {
      object.alpha = value
      object.visible = value > 0
    }

    private function set $targetAlpha(value : Number) : void
    {
      _targetAlpha = value

      if (targetAlpha !== object.alpha)
        startFading()
    }

    private function startFading() : void
    {
      startAlpha = object.alpha
      startTime = getTimer()

      timer.start()
    }

    private function update() : void
    { alpha = startAlpha + deltaAlpha * phase }

    private function get deltaAlpha() : Number
    { return targetAlpha - startAlpha }

    private function get phase() : Number
    { return clamp(elapsedTime.dividedBy(duration), 0, 1) }

    private function get elapsedTime() : Duration
    { return Duration.milliseconds(getTimer() - startTime) }

    private function get duration() : Duration
    { return speed.scaledBy(Math.abs(targetAlpha - startAlpha)) }
  }
}

Make Fader set visible to false when alpha is 0.


package aerys.minko.scene.controller.animation
{
	import flash.utils.getTimer;

	import aerys.minko.ns.minko_animation;
	import aerys.minko.scene.controller.EnterFrameController;
	import aerys.minko.type.Signal;

	use namespace minko_animation;

	public class AbstractAnimationController extends EnterFrameController implements IAnimationController
	{

		protected var _isPlaying  				: Boolean;

		protected var _updateOneTime			: Boolean;

		protected var _loopBeginTime			: int;
		protected var _loopEndTime				: int;
		protected var _looping					: Boolean;
		protected var _currentTime				: int;
		protected var _previousTime				: int;
		protected var _totalTime				: int;

		protected var _timeFunction				: Function;

		protected var _lastTime					: int;

		protected var _labelNames				: Vector.<String>;
		protected var _labelTimes				: Vector.<Number>;

		protected var _looped					: Signal;
		protected var _started					: Signal;
		protected var _stopped					: Signal;
		protected var _labelHit					: Signal;

		private var _nextLabelIds				: Array;

		public function get numLabels() : uint
		{
			return _labelNames.length;
		}

		public function get timeFunction() : Function
		{
			return _timeFunction;
		}

		public function set timeFunction(value : Function) : void
		{
			_timeFunction = value;
		}

		public function get started() : Signal
		{
			return _started;
		}

		public function get stopped() : Signal
		{
			return _stopped;
		}

		public function get looped() : Signal
		{
			return _looped;
		}

		public function get labelHit():Signal
		{
			return _labelHit;
		}

		public function get totalTime() : int
		{
			return _totalTime;
		}

		public function get looping() : Boolean
		{
			return _looping;
		}
		public function set looping(value : Boolean) : void
		{
			_looping = value;
		}

		public function get isPlaying() : Boolean
		{
			return _isPlaying;
		}
		public function set isPlaying(value : Boolean) : void
		{
			_isPlaying = value;
		}

		public function get currentTime() : int
		{
			return _currentTime;
		}

		minko_animation function setCurrentTime(v : int) : void
		{
			_currentTime = v;
		}

		public function AbstractAnimationController(loop : Boolean = true)
		{
			super();

			_looping = true;

			_labelNames = new <String>[];
			_labelTimes = new <Number>[];

			_looped	= new Signal('AnimationController.looped');
			_started = new Signal('AnimationController.started');
			_stopped = new Signal('AnimationController.stopped');
			_labelHit = new Signal('AnimationController.labelHit');
		}

		public function seek(time : Object) : IAnimationController
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error(
					'Time value is outside of playback window. '
					+'To reset playback window, call resetPlaybackWindow.'
				);

			_currentTime = timeValue;

			updateNextLabel();
			checkLabelHit(_currentTime, _currentTime);

			return this;
		}

		protected function updateNextLabel(currentTime : int = -1) : void
		{
			_nextLabelIds = [];

			if (!_labelTimes.length)
				return;

			if (currentTime == -1)
				currentTime = _currentTime;

			var min : int = int.MAX_VALUE;

			for(var i : int = 0; i < _labelTimes.length; ++i)
			{
				var time : int = _labelTimes[i];

				if (time < _loopBeginTime || time > _loopEndTime)
					continue;

				if (time >= currentTime)
				{
					if (time < min)
					{
						min = time;
						_nextLabelIds = [i];
					}
					else if (time == min)
					{
						_nextLabelIds.push(i);
					}
				}
			}

			if (!_nextLabelIds.length)
			{
				updateNextLabel(_loopBeginTime);
			}
			else if (min == _loopEndTime)
			{
				for(i = 0; i < _labelTimes.length; ++i)
				{
					if (_labelTimes[i] == _loopBeginTime && _nextLabelIds.indexOf(i) == -1)
						_nextLabelIds.push(i);
				}
			}
		}

		public function play() : IAnimationController
		{
			_isPlaying = true;
			_lastTime = _timeFunction != null ? _timeFunction(getTimer()) : getTimer();
			_started.execute(this);

			return this;
		}

		public function stop() : IAnimationController
		{
			_isPlaying = false;
			_updateOneTime 	= true;
			_lastTime = _timeFunction != null ? _timeFunction(getTimer()) : getTimer();
			_stopped.execute(this);

			return this;
		}

		public function setPlaybackWindow(beginTime	: Object = null,
										  endTime	: Object = null) : IAnimationController
		{
			_loopBeginTime	= beginTime != null ? getAnimationTime(beginTime) : 0;
			_loopEndTime	= endTime != null ? getAnimationTime(endTime) : _totalTime;

			if (_currentTime < _loopBeginTime || _currentTime > _loopEndTime)
				_currentTime = _loopBeginTime;

			updateNextLabel();
			checkLabelHit(_currentTime, _currentTime);

			return this;
		}

		public function resetPlaybackWindow() : IAnimationController
		{
			setPlaybackWindow();

			return this;
		}

		protected function getAnimationTime(time : Object) : uint
		{
			var timeValue : uint;

			if (time is uint || time is int || time is Number)
			{
				timeValue = uint(time);
			}
			else if (time is String)
			{
				var labelCount : uint = _labelNames.length;

				for (var labelId : uint = 0; labelId < labelCount; ++labelId)
					if (_labelNames[labelId] == time)
						timeValue = _labelTimes[labelId];
			}
			else
			{
				throw new Error('Invalid argument type: time must be Number or String');
			}

			return timeValue;
		}

		protected function updateOnTime(time : Number) : Boolean
		{
			if (_isPlaying || _updateOneTime)
			{
				_previousTime = _currentTime;
				if (_timeFunction != null)
					time = _timeFunction(time);

				var deltaT 			: Number = time - _lastTime;
				var lastCurrentTime : Number = _currentTime;

				if (_isPlaying)
				{
					_currentTime = _loopBeginTime
						+ (_currentTime + deltaT - _loopBeginTime)
						% (_loopEndTime - _loopBeginTime);
				}

				if ((deltaT > 0 && lastCurrentTime > _currentTime)
					|| (deltaT < 0 && (lastCurrentTime < _currentTime
						|| _currentTime * lastCurrentTime < 0)))
				{
					if (_looping)
						_looped.execute(this);
					else
					{
						_currentTime = deltaT > 0 ? _totalTime : 0;
						stop();

						return true;
					}
				}
			}

			_lastTime = time;

			return _isPlaying || _updateOneTime;
		}

		public function addLabel(name : String, time : Number) : IAnimationController
		{
			if (_labelNames.indexOf(name) >= 0)
				throw new Error('A label with the same name already exists.');

			_labelNames.push(name);
			_labelTimes.push(time);

			updateNextLabel();

			return this;
		}

		protected function checkLabelHit(previousTime : int, newTime : int) : void
		{
			if (!_isPlaying || !_nextLabelIds || !_nextLabelIds.length) || !_labelHit.numCallbacks)
				return;

			var nextLabelTime	: Number	= _labelTimes[_nextLabelIds[0]];
			var trigger			: Boolean	= false;

			if (newTime < previousTime)
			{
				if (previousTime < nextLabelTime && nextLabelTime <= _loopEndTime)
					trigger = true;
				else if (_loopBeginTime <= nextLabelTime && nextLabelTime <= newTime)
					trigger = true;
			}
			else
			{
				if ((previousTime < nextLabelTime && nextLabelTime <= newTime) || newTime == nextLabelTime)
					trigger = true;
			}
			if (trigger)
			{
				for each(var i : int in _nextLabelIds)
					triggerLabelHit(_labelNames[i], _labelTimes[i]);

				updateNextLabel((newTime + 1) % _loopEndTime);
			}
		}

		public function changeLabel(oldName : String, newName : String) : IAnimationController
		{
			var index : int = _labelNames.indexOf(oldName);

			if (index < 0)
				throw new Error('The time label named \'' + oldName + '\' does not exist.');

			_labelNames[index] = newName;

			return this;
		}

		public function setTimeForLabel(name : String, newTime : Number) : IAnimationController
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			_labelTimes[index] = newTime;

			updateNextLabel();

			return this;
		}

		public function hasLabel(name : String) : Boolean
		{
			return _labelNames.indexOf(name) >= 0;
		}

		public function removeLabel(name : String) : IAnimationController
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			var numLabels : uint = _labelNames.length - 1;

			_labelNames[index] = _labelNames[numLabels];
			_labelNames.length = numLabels;

			_labelTimes[index] = _labelTimes[numLabels];
			_labelTimes.length = numLabels;

			return this;
		}

		public function getLabelName(index : uint) : String
		{
			return _labelNames[index];
		}

		public function getLabelTime(index : uint) : Number
		{
			return _labelTimes[index];
		}

		public function getLabelTimeByName(name : String) : Number
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			return _labelTimes[index];
		}

		minko_animation function triggerLabelHit(labelName : String, labelTime : int) : void
		{
			if (_labelHit.numCallbacks)
				_labelHit.execute(this, labelName, labelTime);
		}
	}
}

package aerys.minko.scene.controller.animation
{
	import flash.utils.getTimer;

	import aerys.minko.ns.minko_animation;
	import aerys.minko.scene.controller.EnterFrameController;
	import aerys.minko.type.Signal;

	use namespace minko_animation;

	public class AbstractAnimationController extends EnterFrameController implements IAnimationController
	{

		protected var _isPlaying  				: Boolean;

		protected var _updateOneTime			: Boolean;

		protected var _loopBeginTime			: int;
		protected var _loopEndTime				: int;
		protected var _looping					: Boolean;
		protected var _currentTime				: int;
		protected var _previousTime				: int;
		protected var _totalTime				: int;

		protected var _timeFunction				: Function;

		protected var _lastTime					: int;

		protected var _labelNames				: Vector.<String>;
		protected var _labelTimes				: Vector.<Number>;

		protected var _looped					: Signal;
		protected var _started					: Signal;
		protected var _stopped					: Signal;
		protected var _labelHit					: Signal;

		private var _nextLabelIds				: Array;

		public function get numLabels() : uint
		{
			return _labelNames.length;
		}

		public function get timeFunction() : Function
		{
			return _timeFunction;
		}

		public function set timeFunction(value : Function) : void
		{
			_timeFunction = value;
		}

		public function get started() : Signal
		{
			return _started;
		}

		public function get stopped() : Signal
		{
			return _stopped;
		}

		public function get looped() : Signal
		{
			return _looped;
		}

		public function get labelHit():Signal
		{
			return _labelHit;
		}

		public function get totalTime() : int
		{
			return _totalTime;
		}

		public function get looping() : Boolean
		{
			return _looping;
		}
		public function set looping(value : Boolean) : void
		{
			_looping = value;
		}

		public function get isPlaying() : Boolean
		{
			return _isPlaying;
		}
		public function set isPlaying(value : Boolean) : void
		{
			_isPlaying = value;
		}

		public function get currentTime() : int
		{
			return _currentTime;
		}

		minko_animation function setCurrentTime(v : int) : void
		{
			_currentTime = v;
		}

		public function AbstractAnimationController(loop : Boolean = true)
		{
			super();

			_looping = true;

			_labelNames = new <String>[];
			_labelTimes = new <Number>[];

			_looped	= new Signal('AnimationController.looped');
			_started = new Signal('AnimationController.started');
			_stopped = new Signal('AnimationController.stopped');
			_labelHit = new Signal('AnimationController.labelHit');
		}

		public function seek(time : Object) : IAnimationController
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error(
					'Time value is outside of playback window. '
					+'To reset playback window, call resetPlaybackWindow.'
				);

			_currentTime = timeValue;

			updateNextLabel();
			checkLabelHit(_currentTime, _currentTime);

			return this;
		}

		protected function updateNextLabel(currentTime : int = -1) : void
		{
			_nextLabelIds = [];

			if (!_labelTimes.length)
				return;

			if (currentTime == -1)
				currentTime = _currentTime;

			var min : int = int.MAX_VALUE;

			for(var i : int = 0; i < _labelTimes.length; ++i)
			{
				var time : int = _labelTimes[i];

				if (time < _loopBeginTime || time > _loopEndTime)
					continue;

				if (time >= currentTime)
				{
					if (time < min)
					{
						min = time;
						_nextLabelIds = [i];
					}
					else if (time == min)
					{
						_nextLabelIds.push(i);
					}
				}
			}

			if (!_nextLabelIds.length)
			{
				updateNextLabel(_loopBeginTime);
			}
			else if (min == _loopEndTime)
			{
				for(i = 0; i < _labelTimes.length; ++i)
				{
					if (_labelTimes[i] == _loopBeginTime && _nextLabelIds.indexOf(i) == -1)
						_nextLabelIds.push(i);
				}
			}
		}

		public function play() : IAnimationController
		{
			_isPlaying = true;
			_lastTime = _timeFunction != null ? _timeFunction(getTimer()) : getTimer();
			_started.execute(this);

			return this;
		}

		public function stop() : IAnimationController
		{
			_isPlaying = false;
			_updateOneTime 	= true;
			_lastTime = _timeFunction != null ? _timeFunction(getTimer()) : getTimer();
			_stopped.execute(this);

			return this;
		}

		public function setPlaybackWindow(beginTime	: Object = null,
										  endTime	: Object = null) : IAnimationController
		{
			_loopBeginTime	= beginTime != null ? getAnimationTime(beginTime) : 0;
			_loopEndTime	= endTime != null ? getAnimationTime(endTime) : _totalTime;

			if (_currentTime < _loopBeginTime || _currentTime > _loopEndTime)
				_currentTime = _loopBeginTime;

			updateNextLabel();
			checkLabelHit(_currentTime, _currentTime);

			return this;
		}

		public function resetPlaybackWindow() : IAnimationController
		{
			setPlaybackWindow();

			return this;
		}

		protected function getAnimationTime(time : Object) : uint
		{
			var timeValue : uint;

			if (time is uint || time is int || time is Number)
			{
				timeValue = uint(time);
			}
			else if (time is String)
			{
				var labelCount : uint = _labelNames.length;

				for (var labelId : uint = 0; labelId < labelCount; ++labelId)
					if (_labelNames[labelId] == time)
						timeValue = _labelTimes[labelId];
			}
			else
			{
				throw new Error('Invalid argument type: time must be Number or String');
			}

			return timeValue;
		}

		protected function updateOnTime(time : Number) : Boolean
		{
			if (_isPlaying || _updateOneTime)
			{
				_previousTime = _currentTime;
				if (_timeFunction != null)
					time = _timeFunction(time);

				var deltaT 			: Number = time - _lastTime;
				var lastCurrentTime : Number = _currentTime;

				if (_isPlaying)
				{
					_currentTime = _loopBeginTime
						+ (_currentTime + deltaT - _loopBeginTime)
						% (_loopEndTime - _loopBeginTime);
				}

				if ((deltaT > 0 && lastCurrentTime > _currentTime)
					|| (deltaT < 0 && (lastCurrentTime < _currentTime
						|| _currentTime * lastCurrentTime < 0)))
				{
					if (_looping)
						_looped.execute(this);
					else
					{
						_currentTime = deltaT > 0 ? _totalTime : 0;
						stop();

						return true;
					}
				}
			}

			_lastTime = time;

			return _isPlaying || _updateOneTime;
		}

		public function addLabel(name : String, time : Number) : IAnimationController
		{
			if (_labelNames.indexOf(name) >= 0)
				throw new Error('A label with the same name already exists.');

			_labelNames.push(name);
			_labelTimes.push(time);

			updateNextLabel();

			return this;
		}

		protected function checkLabelHit(previousTime : int, newTime : int) : void
		{
			if (!_isPlaying || !_nextLabelIds || !_nextLabelIds.length || !_labelHit.numCallbacks)
				return;

			var nextLabelTime	: Number	= _labelTimes[_nextLabelIds[0]];
			var trigger			: Boolean	= false;

			if (newTime < previousTime)
			{
				if (previousTime < nextLabelTime && nextLabelTime <= _loopEndTime)
					trigger = true;
				else if (_loopBeginTime <= nextLabelTime && nextLabelTime <= newTime)
					trigger = true;
			}
			else
			{
				if ((previousTime < nextLabelTime && nextLabelTime <= newTime) || newTime == nextLabelTime)
					trigger = true;
			}
			if (trigger)
			{
				for each(var i : int in _nextLabelIds)
					triggerLabelHit(_labelNames[i], _labelTimes[i]);

				updateNextLabel((newTime + 1) % _loopEndTime);
			}
		}

		public function changeLabel(oldName : String, newName : String) : IAnimationController
		{
			var index : int = _labelNames.indexOf(oldName);

			if (index < 0)
				throw new Error('The time label named \'' + oldName + '\' does not exist.');

			_labelNames[index] = newName;

			return this;
		}

		public function setTimeForLabel(name : String, newTime : Number) : IAnimationController
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			_labelTimes[index] = newTime;

			updateNextLabel();

			return this;
		}

		public function hasLabel(name : String) : Boolean
		{
			return _labelNames.indexOf(name) >= 0;
		}

		public function removeLabel(name : String) : IAnimationController
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			var numLabels : uint = _labelNames.length - 1;

			_labelNames[index] = _labelNames[numLabels];
			_labelNames.length = numLabels;

			_labelTimes[index] = _labelTimes[numLabels];
			_labelTimes.length = numLabels;

			return this;
		}

		public function getLabelName(index : uint) : String
		{
			return _labelNames[index];
		}

		public function getLabelTime(index : uint) : Number
		{
			return _labelTimes[index];
		}

		public function getLabelTimeByName(name : String) : Number
		{
			var index : int = _labelNames.indexOf(name);

			if (index < 0)
				throw new Error('The time label named \'' + name + '\' does not exist.');

			return _labelTimes[index];
		}

		minko_animation function triggerLabelHit(labelName : String, labelTime : int) : void
		{
			if (_labelHit.numCallbacks)
				_labelHit.execute(this, labelName, labelTime);
		}
	}
}

Fix compilation.

Fix compilation.