package aerys.minko.type.binding
{
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.Signal;
	import aerys.minko.type.enum.DataProviderUsage;

	import flash.utils.Dictionary;

	public final class DataBindings
	{
		private var _owner							: ISceneNode				= null;

		private var _providers						: Vector.<IDataProvider> 	= new <IDataProvider>[];
		private var _bindingNames					: Vector.<String>			= new Vector.<String>();

		private var _bindingNameToValue				: Object					= {};
		private var _bindingNameToChangedSignal		: Object					= {};

		private var _bindingNameToProvider			: Object					= {};
		private var _providerToBindingNames			: Dictionary				= new Dictionary(); // dic[Vector.<String>[]]

		public function get owner() : ISceneNode
		{
			return _owner;
		}

		public function get numProviders() : uint
		{
			return _providers.length;
		}

		public function get numProperties() : uint
		{
			return _bindingNames.length;
		}

		public function DataBindings(owner : ISceneNode)
		{
			_owner = owner;
		}

		public function contains(dataProvider : IDataProvider) : Boolean
		{
			return _providers.indexOf(dataProvider) != -1;
		}

		public function addProvider(provider : IDataProvider) : void
		{
			if (_providerToBindingNames[provider])
				throw new Error('This provider is already bound.');

			var providerBindingNames	: Vector.<String>	= new <String>[];
			var dataDescriptor			: Object			= provider.dataDescriptor;

			provider.changed.add(providerChangedHandler);

			_providerToBindingNames[provider] = providerBindingNames;
			_providers.push(provider);

			for (var attrName : String in dataDescriptor)
			{
				// if this provider attribute is also a dataprovider, let's also bind it
				var bindingName	: String	= dataDescriptor[attrName];
				var attribute	: Object	= provider[attrName];

				if (_bindingNames.indexOf(bindingName) != -1)
					throw new Error(
						'Another data provider is already declaring the \'' + bindingName + '\' property.'
					);

				_bindingNameToProvider[bindingName] = provider;
				_bindingNameToValue[bindingName] = attribute;

				providerBindingNames.push(bindingName);
				_bindingNames.push(bindingName);

				if (_bindingNameToChangedSignal[bindingName])
					_bindingNameToChangedSignal[bindingName].execute(this, bindingName, null, attribute);
			}
		}

		public function removeProvider(provider : IDataProvider) : void
		{
			var providerBindingsNames 	: Vector.<String> 	= _providerToBindingNames[provider];
			var tmpValues				: Object			= {};

			if (providerBindingsNames == null)
				throw new ArgumentError('Unkown provider.');

			var numBindings : uint = _bindingNames.length;
			for (var indexRead : uint = 0, indexWrite : uint = 0; indexRead < numBindings; ++indexRead)
			{
				var bindingName : String = _bindingNames[indexRead];

				if (providerBindingsNames.indexOf(bindingName) != -1)
				{
					tmpValues[bindingName] = _bindingNameToValue[bindingName];

					delete _bindingNameToValue[bindingName];
					delete _bindingNameToProvider[bindingName];
				}
				else
					_bindingNames[indexWrite++] = _bindingNames[indexRead];
			}
			_bindingNames.length = indexWrite;

			provider.changed.remove(providerChangedHandler);

			_providers.splice(_providers.indexOf(provider), 1);

			delete _providerToBindingNames[provider];

			for each (bindingName in providerBindingsNames)
			{
				var changedSignal : Signal = _bindingNameToChangedSignal[bindingName] as Signal;

				if (changedSignal != null)
				{
					changedSignal.execute(
						this, bindingName, tmpValues[bindingName], null
					);
				}
			}
		}

		public function removeAllProviders() : void
		{
			var numProviders : uint = this.numProviders;

			for (var providerId : int = numProviders - 1; providerId >= 0; --providerId)
				removeProvider(getProviderAt(providerId));
		}

		public function hasCallback(bindingName	: String,
									callback	: Function) : Boolean
		{
			var signal : Signal = _bindingNameToChangedSignal[bindingName];

			return signal != null && signal.hasCallback(callback);
		}

		public function addCallback(bindingName : String,
									callback	: Function) : void
		{
			_bindingNameToChangedSignal[bindingName] ||= new Signal(
				'DataBindings.changed[' + bindingName + ']'
			);

			Signal(_bindingNameToChangedSignal[bindingName]).add(callback);
		}

		public function removeCallback(bindingName	: String,
									   callback		: Function) : void
		{
			var signal : Signal = _bindingNameToChangedSignal[bindingName];
			if (!signal)
				throw new ArgumentError('Unkown property \'' + bindingName + '\'.');

			signal.remove(callback);

			if (signal.numCallbacks == 0)
				delete _bindingNameToChangedSignal[bindingName];
		}

		public function getProviderAt(index : uint) : IDataProvider
		{
			return _providers[index];
		}

		public function getProviderByBindingName(bindingName : String) : IDataProvider
		{
			if (_bindingNameToProvider[bindingName] == null)
				throw new ArgumentError('Unkown property \'' + bindingName + '\'.');

			return _bindingNameToProvider[bindingName];
		}

		public function propertyExists(bindingName : String) : Boolean
		{
			return _bindingNameToValue.hasOwnProperty(bindingName);
		}

		public function getProperty(bindingName : String) : *
		{
			return _bindingNameToValue[bindingName];
		}

		public function getPropertyName(bindingIndex : uint) : String
		{
			if (bindingIndex > numProperties)
				throw new ArgumentError('No such binding');

			return _bindingNames[bindingIndex];
		}

		public function copySharedProvidersFrom(source : DataBindings) : void
		{
			var numProviders : uint = source._providers.length;

			for (var providerId : uint = 0; providerId < numProviders; ++providerId)
			{
				var provider : IDataProvider = source._providers[providerId];

				if (provider.usage == DataProviderUsage.SHARED)
					addProvider(provider);
			}
		}

		private function providerChangedHandler(source : IDataProvider, attributeName : String) : void
		{
			if (attributeName == null)
			{
				throw new Error('DataProviders must change one property at a time.');
			}
			else if (attributeName == 'dataDescriptor')
			{
				removeProvider(source);
				addProvider(source);
			}
			else
			{
				var bindingName : String		= source.dataDescriptor[attributeName];
				var oldValue	: Object		= _bindingNameToValue[bindingName];
				var newValue	: Object		= source[attributeName];

				_bindingNameToValue[bindingName] = newValue;

				if (_bindingNameToChangedSignal[bindingName])
					_bindingNameToChangedSignal[bindingName].execute(this, bindingName, oldValue, newValue);
			}
		}
	}
}

package aerys.minko.type.binding
{
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.Signal;
	import aerys.minko.type.enum.DataProviderUsage;

	import flash.utils.Dictionary;

	public final class DataBindings
	{
		private var _owner							: ISceneNode				= null;

		private var _providers						: Vector.<IDataProvider> 	= new <IDataProvider>[];
		private var _bindingNames					: Vector.<String>			= new Vector.<String>();

		private var _bindingNameToValue				: Object					= {};
		private var _bindingNameToChangedSignal		: Object					= {};

		private var _bindingNameToProvider			: Object					= {};
		private var _providerToBindingNames			: Dictionary				= new Dictionary(); // dic[Vector.<String>[]]

		public function get owner() : ISceneNode
		{
			return _owner;
		}

		public function get numProviders() : uint
		{
			return _providers.length;
		}

		public function get numProperties() : uint
		{
			return _bindingNames.length;
		}

		public function DataBindings(owner : ISceneNode)
		{
			_owner = owner;
		}

		public function contains(dataProvider : IDataProvider) : Boolean
		{
			return _providers.indexOf(dataProvider) != -1;
		}

		public function addProvider(provider : IDataProvider) : void
		{
			if (_providerToBindingNames[provider])
				throw new Error('This provider is already bound.');

			var providerBindingNames	: Vector.<String>	= new <String>[];
			var dataDescriptor			: Object			= provider.dataDescriptor;

			provider.changed.add(providerChangedHandler);

			_providerToBindingNames[provider] = providerBindingNames;
			_providers.push(provider);

			for (var attrName : String in dataDescriptor)
			{
				// if this provider attribute is also a dataprovider, let's also bind it
				var bindingName	: String	= dataDescriptor[attrName];
				var attribute	: Object	= provider[attrName];

				if (_bindingNames.indexOf(bindingName) != -1)
					throw new Error(
						'Another data provider is already declaring the \'' + bindingName + '\' property.'
					);

				_bindingNameToProvider[bindingName] = provider;
				_bindingNameToValue[bindingName] = attribute;

				providerBindingNames.push(bindingName);
				_bindingNames.push(bindingName);

				if (_bindingNameToChangedSignal[bindingName])
					_bindingNameToChangedSignal[bindingName].execute(this, bindingName, null, attribute);
			}
		}

		public function removeProvider(provider : IDataProvider) : void
		{
			var providerBindingsNames 	: Vector.<String> 	= _providerToBindingNames[provider];
			var tmpValues				: Object			= {};

			if (providerBindingsNames == null)
				throw new ArgumentError('Unkown provider.');

			var numBindings : uint = _bindingNames.length;
			for (var indexRead : uint = 0, indexWrite : uint = 0; indexRead < numBindings; ++indexRead)
			{
				var bindingName : String = _bindingNames[indexRead];

				if (providerBindingsNames.indexOf(bindingName) != -1)
				{
					tmpValues[bindingName] = _bindingNameToValue[bindingName];

					delete _bindingNameToValue[bindingName];
					delete _bindingNameToProvider[bindingName];
				}
				else
					_bindingNames[indexWrite++] = _bindingNames[indexRead];
			}
			_bindingNames.length = indexWrite;

			provider.changed.remove(providerChangedHandler);

			_providers.splice(_providers.indexOf(provider), 1);

			delete _providerToBindingNames[provider];

			for each (bindingName in providerBindingsNames)
			{
				var changedSignal : Signal = _bindingNameToChangedSignal[bindingName] as Signal;

				if (changedSignal != null)
				{
					changedSignal.execute(
						this, bindingName, tmpValues[bindingName], null
					);
				}
			}
		}

		public function removeAllProviders() : void
		{
			var numProviders : uint = this.numProviders;

			for (var providerId : int = numProviders - 1; providerId >= 0; --providerId)
				removeProvider(getProviderAt(providerId));
		}

		public function hasCallback(bindingName	: String,
									callback	: Function) : Boolean
		{
			var signal : Signal = _bindingNameToChangedSignal[bindingName];

			return signal != null && signal.hasCallback(callback);
		}

		public function addCallback(bindingName : String,
									callback	: Function) : void
		{
			_bindingNameToChangedSignal[bindingName] ||= new Signal(
				'DataBindings.changed[' + bindingName + ']'
			);

			Signal(_bindingNameToChangedSignal[bindingName]).add(callback);
		}

		public function removeCallback(bindingName	: String,
									   callback		: Function) : void
		{
			var signal : Signal = _bindingNameToChangedSignal[bindingName];
			if (!signal)
				throw new ArgumentError('Unkown property \'' + bindingName + '\'.');

			signal.remove(callback);

			if (signal.numCallbacks == 0)
				delete _bindingNameToChangedSignal[bindingName];
		}

		public function getProviderAt(index : uint) : IDataProvider
		{
			return _providers[index];
		}

		public function getProviderByBindingName(bindingName : String) : IDataProvider
		{
			if (_bindingNameToProvider[bindingName] == null)
				throw new ArgumentError('Unkown property \'' + bindingName + '\'.');

			return _bindingNameToProvider[bindingName];
		}

		public function propertyExists(bindingName : String) : Boolean
		{
			return _bindingNameToValue.hasOwnProperty(bindingName);
		}

		public function getProperty(bindingName : String) : *
		{
			if (_bindingNames.indexOf(bindingName) < 0)
				throw new Error('The property \'' + bindingName + '\' does not exist.');

			return _bindingNameToValue[bindingName];
		}

		public function getPropertyName(bindingIndex : uint) : String
		{
			if (bindingIndex > numProperties)
				throw new ArgumentError('No such binding');

			return _bindingNames[bindingIndex];
		}

		public function copySharedProvidersFrom(source : DataBindings) : void
		{
			var numProviders : uint = source._providers.length;

			for (var providerId : uint = 0; providerId < numProviders; ++providerId)
			{
				var provider : IDataProvider = source._providers[providerId];

				if (provider.usage == DataProviderUsage.SHARED)
					addProvider(provider);
			}
		}

		private function providerChangedHandler(source : IDataProvider, attributeName : String) : void
		{
			if (attributeName == null)
			{
				throw new Error('DataProviders must change one property at a time.');
			}
			else if (attributeName == 'dataDescriptor')
			{
				removeProvider(source);
				addProvider(source);
			}
			else
			{
				var bindingName : String		= source.dataDescriptor[attributeName];
				var oldValue	: Object		= _bindingNameToValue[bindingName];
				var newValue	: Object		= source[attributeName];

				_bindingNameToValue[bindingName] = newValue;

				if (_bindingNameToChangedSignal[bindingName])
					_bindingNameToChangedSignal[bindingName].execute(this, bindingName, oldValue, newValue);
			}
		}
	}
}

fix DataBindings.getProperty() to throw an error when attempting to read a property that does not exist


/**
 * Copyright (c) 2007 Gabriel Handford
 * See LICENSE.txt for full license information.
 */
package org.httpclient.io {

  import com.adobe.utils.StringUtil;
  import flash.utils.ByteArray;

  import org.httpclient.HttpResponse;
  import org.httpclient.HttpHeader;

  import flash.errors.*;

  /**
   * Bytes from response are placed in this buffer, and parsed according to transfer encoding.
   */
  public class HttpResponseBuffer {

    // Data buffer
    private var _buffer:HttpBuffer = new HttpBuffer();

    // Bytes read of body content
    private var _bodyBytesRead:Number = 0;

    // Response header data parsed from bytes
    private var _headerData:Array = [];

    // The response header, after we parsed it
    private var _responseHeader:HttpResponse;

    // For special transfer encodings (like Chunks); Typically data is streamed directly
    private var _responseBody:HttpBuffer = new HttpBuffer();

    // Notified of response header: function(response:HttpResponse):void { }
    private var _onResponseHeader:Function;

    // Notified of response body data: function(bytes:ByteArray):void { }
    private var _onResponseData:Function;

    // Notified when response is complete: function(bytesRead:Number):void { }
    private var _onResponseComplete:Function

    // If we expect response body
    private var _hasResponseBody:Boolean;

    // If response buffer is done
    private var _isPayloadDone:Boolean = false;

    /**
     * Create response buffer.
     * @param onResponseHeader
     * @param onResponseData
     * @param onResponseComplete
     */
    public function HttpResponseBuffer(hasResponseBody:Boolean, onResponseHeader:Function, onResponseData:Function, onResponseComplete:Function) {
      super();
      _hasResponseBody = hasResponseBody;
      _onResponseHeader = onResponseHeader;
      _onResponseData = onResponseData;
      _onResponseComplete = onResponseComplete;
    }

    /**
     * Write bytes to the buffer.
     * Parse lines for header, or send to onPayload.
     *
     * @param bytes Data
     */
    public function writeBytes(bytes:ByteArray):void {
      if (_isPayloadDone) throw new IllegalOperationError("Response is finished; can't accept more bytes");

      // If we don't have the full header yet
      if (!_responseHeader) {
        _buffer.write(bytes);

        var line:String = _buffer.readLine(true);
        while (line != null) {

          // If empty line, then we reached the end of the header
          if (line == "") {
            _responseHeader = parseHeader(_headerData);
            Log.debug("Response header:\n" + _responseHeader);

            // Notify
            _onResponseHeader(_responseHeader);

            // On information responses, get next response header
            if (_responseHeader.isInformation) {
              _buffer.truncate();
              _responseHeader = null;
              _isPayloadDone = false;
            } else {
              // Pass any extra as payload
              var payload:ByteArray = _buffer.readAvailable();
              Log.debug("Response payload (from parsing header): " + payload.length);
              _isPayloadDone = handlePayload(payload);
              break;
            }

          } else {
            _headerData.push(line);
          }

          line = _buffer.readLine(true);
        }

      } else {
        Log.debug("Response payload: " + bytes.length);
        _isPayloadDone = handlePayload(bytes);
      }

      // Check if complete
      Log.debug("Payload done? " + _isPayloadDone);
      if (!_hasResponseBody) _onResponseComplete(0);
      else if (_isPayloadDone) _onResponseComplete(_responseHeader.contentLength);
    }

    /**
     * Get header, if its been reached.
     */
    public function get header():HttpResponse { return _responseHeader; }

    /**
     * Notify with response data.
     * Check for transfer encodings, otherwise stream it direct.
     * @param bytes The data
     * @return True if we don't expect any more data, false otherwise
     */
    private function handlePayload(bytes:ByteArray):Boolean {
      if (_responseHeader.isChunked) {
        _responseBody.write(bytes);
        _bodyBytesRead += bytes.length;
        return _responseBody.readChunks(_onResponseData);
      } else {
        if (bytes.bytesAvailable > 0) {
          _onResponseData(bytes);
          _bodyBytesRead += bytes.length;
        }
        Log.debug("Bytes read (body): " + _bodyBytesRead + ", content length: " + _responseHeader.contentLength);
        return (_bodyBytesRead >= _responseHeader.contentLength);
      }
    }

    /**
     * Parse HTTP response header.
     * @param lines Lines in header
     * @return The HTTP response so far
     */
    protected function parseHeader(lines:Array):HttpResponse {
      var line:String = lines[0];

      // Regex courtesy of ruby 1.8 Net::HTTP
      // Example, HTTP/1.1 200 OK
      var matches:Array = line.match(/\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/);

      if (!matches)
        throw new Error("Invalid header: " + line + ", matches: " + matches);

      var version:String = matches[1];
      var code:String = matches[2];
      var message:String = matches[3];
      var headers:Array = [];

      for(var i:Number = 1; i < lines.length; i++) {
        line = lines[i];

        var index:int = line.indexOf(":");
        if (index != -1) {
          var name:String = line.substring(0, index);
          var value:String = line.substring(index + 1, line.length);
          headers.push({ name: name, value: value });
        } else {
          Log.warn("Invalid header: " + line);
        }
      }

      return new HttpResponse(version, code, message, new HttpHeader(headers));
    }

  }

}

/**
 * Copyright (c) 2007 Gabriel Handford
 * See LICENSE.txt for full license information.
 */
package org.httpclient.io {

  import com.adobe.utils.StringUtil;
  import flash.utils.ByteArray;

  import org.httpclient.HttpResponse;
  import org.httpclient.HttpHeader;

  import flash.errors.*;

  /**
   * Bytes from response are placed in this buffer, and parsed according to transfer encoding.
   */
  public class HttpResponseBuffer {

    // Data buffer
    private var _buffer:HttpBuffer = new HttpBuffer();

    // Bytes read of body content
    private var _bodyBytesRead:Number = 0;

    // Response header data parsed from bytes
    private var _headerData:Array = [];

    // The response header, after we parsed it
    private var _responseHeader:HttpResponse;

    // For special transfer encodings (like Chunks); Typically data is streamed directly
    private var _responseBody:HttpBuffer = new HttpBuffer();

    // Notified of response header: function(response:HttpResponse):void { }
    private var _onResponseHeader:Function;

    // Notified of response body data: function(bytes:ByteArray):void { }
    private var _onResponseData:Function;

    // Notified when response is complete: function(bytesRead:Number):void { }
    private var _onResponseComplete:Function

    // If we expect response body
    private var _hasResponseBody:Boolean;

    // If response buffer is done
    private var _isPayloadDone:Boolean = false;

    /**
     * Create response buffer.
     * @param onResponseHeader
     * @param onResponseData
     * @param onResponseComplete
     */
    public function HttpResponseBuffer(hasResponseBody:Boolean, onResponseHeader:Function, onResponseData:Function, onResponseComplete:Function) {
      super();
      _hasResponseBody = hasResponseBody;
      _onResponseHeader = onResponseHeader;
      _onResponseData = onResponseData;
      _onResponseComplete = onResponseComplete;
    }

    /**
     * Write bytes to the buffer.
     * Parse lines for header, or send to onPayload.
     *
     * @param bytes Data
     */
    public function writeBytes(bytes:ByteArray):void {
      //if (_isPayloadDone) throw new IllegalOperationError("Response is finished; can't accept more bytes");
      if (_isPayloadDone) return; // TODO: Figure out why on some TLS chunked encoding this happens (oh maybe chunked encoding footer?)

      // If we don't have the full header yet
      if (!_responseHeader) {
        _buffer.write(bytes);

        var line:String = _buffer.readLine(true);
        while (line != null) {

          // If empty line, then we reached the end of the header
          if (line == "") {
            _responseHeader = parseHeader(_headerData);
            Log.debug("Response header:\n" + _responseHeader);

            // Notify
            _onResponseHeader(_responseHeader);

            // On information responses, get next response header
            if (_responseHeader.isInformation) {
              _buffer.truncate();
              _responseHeader = null;
              _isPayloadDone = false;
            } else {
              // Pass any extra as payload
              var payload:ByteArray = _buffer.readAvailable();
              Log.debug("Response payload (from parsing header): " + payload.length);
              _isPayloadDone = handlePayload(payload);
              break;
            }

          } else {
            _headerData.push(line);
          }

          line = _buffer.readLine(true);
        }

      } else {
        Log.debug("Response payload: " + bytes.length);
        _isPayloadDone = handlePayload(bytes);
      }

      // Check if complete
      Log.debug("Payload done? " + _isPayloadDone);
      if (!_hasResponseBody) _onResponseComplete(0);
      else if (_isPayloadDone) _onResponseComplete(_responseHeader.contentLength);
    }

    /**
     * Get header, if its been reached.
     */
    public function get header():HttpResponse { return _responseHeader; }

    /**
     * Notify with response data.
     * Check for transfer encodings, otherwise stream it direct.
     * @param bytes The data
     * @return True if we don't expect any more data, false otherwise
     */
    private function handlePayload(bytes:ByteArray):Boolean {
      if (_responseHeader.isChunked) {
        _responseBody.write(bytes);
        _bodyBytesRead += bytes.length;
        return _responseBody.readChunks(_onResponseData);
      } else {
        if (bytes.bytesAvailable > 0) {
          _onResponseData(bytes);
          _bodyBytesRead += bytes.length;
        }
        Log.debug("Bytes read (body): " + _bodyBytesRead + ", content length: " + _responseHeader.contentLength);
        return (_bodyBytesRead >= _responseHeader.contentLength);
      }
    }

    /**
     * Parse HTTP response header.
     * @param lines Lines in header
     * @return The HTTP response so far
     */
    protected function parseHeader(lines:Array):HttpResponse {
      var line:String = lines[0];

      // Regex courtesy of ruby 1.8 Net::HTTP
      // Example, HTTP/1.1 200 OK
      var matches:Array = line.match(/\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/);

      if (!matches)
        throw new Error("Invalid header: " + line + ", matches: " + matches);

      var version:String = matches[1];
      var code:String = matches[2];
      var message:String = matches[3];
      var headers:Array = [];

      for(var i:Number = 1; i < lines.length; i++) {
        line = lines[i];

        var index:int = line.indexOf(":");
        if (index != -1) {
          var name:String = line.substring(0, index);
          var value:String = line.substring(index + 1, line.length);
          headers.push({ name: name, value: value });
        } else {
          Log.warn("Invalid header: " + line);
        }
      }

      return new HttpResponse(version, code, message, new HttpHeader(headers));
    }

  }

}

change from error to ignore.. i think i need to handle chunked footer


package com.kaltura.kdpfl.plugin
{
	import com.akamai.playeranalytics.AnalyticsPluginLoader;
	import com.kaltura.kdpfl.model.ConfigProxy;
	import com.kaltura.kdpfl.model.MediaProxy;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.model.type.StreamerType;
	import com.kaltura.types.KalturaMediaType;
	import com.kaltura.vo.KalturaBaseEntry;
	import com.kaltura.vo.KalturaFlavorAsset;
	import com.kaltura.vo.KalturaMediaEntry;

	import flash.system.Capabilities;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class akamaiMediaAnalyticsMediator extends Mediator
	{
		public static const NAME:String = "akamaiMediaAnalyticsMediator";
		private var _mediaProxy:MediaProxy;

		public function akamaiMediaAnalyticsMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
		}

		override public function onRegister():void
		{
			_mediaProxy = facade.retrieveProxy(MediaProxy.NAME) as MediaProxy;
			super.onRegister();
		}

		override public function listNotificationInterests():Array
		{
			return [NotificationType.MEDIA_READY, NotificationType.MEDIA_ELEMENT_READY];
		}

		override public function handleNotification(notification:INotification):void
		{
			switch (notification.getName())
			{
				case NotificationType.MEDIA_READY:
					//populate analytics metadata
					var configProxy:ConfigProxy = facade.retrieveProxy(ConfigProxy.NAME) as ConfigProxy;
					var entry:KalturaBaseEntry = _mediaProxy.vo.entry;

					AnalyticsPluginLoader.setData("title", entry.name);
					AnalyticsPluginLoader.setData("entryId", entry.id);
					AnalyticsPluginLoader.setData("category", entry.categories);
					AnalyticsPluginLoader.setData("publisherId", configProxy.vo.flashvars.partnerId);

					//find content type
					if (entry is KalturaMediaEntry)
					{
						var mediaEntry:KalturaMediaEntry = entry as KalturaMediaEntry;

						AnalyticsPluginLoader.setData("contentLength", mediaEntry.duration);
						var contentType:String;
						switch (mediaEntry.mediaType)
						{
							case KalturaMediaType.VIDEO:
								contentType = "video";
								break;
							case KalturaMediaType.AUDIO:
								contentType = "audio";
								break;
							case KalturaMediaType.IMAGE:
								contentType = "image";
								break;
							default:
								contentType = "live";
						}
						AnalyticsPluginLoader.setData("contentType", contentType);
					}

					AnalyticsPluginLoader.setData("device", Capabilities.os );
					AnalyticsPluginLoader.setData("playerId", configProxy.vo.flashvars.uiConfId);

					break;

				case NotificationType.MEDIA_ELEMENT_READY:
					//find starting flavor ID
					var flavorAssetId:String;
					var flavorParamsId:String;
					if (_mediaProxy.vo.deliveryType == StreamerType.HTTP)
					{
						flavorAssetId = _mediaProxy.vo.selectedFlavorId;
					}
					else if (_mediaProxy.vo.deliveryType == StreamerType.RTMP)
					{
						flavorAssetId = getFlavorIdByIndex(_mediaProxy.startingIndex);
					}

					for each (var kfa:KalturaFlavorAsset in _mediaProxy.vo.kalturaMediaFlavorArray) {
						if (kfa.id == flavorAssetId) {
							flavorParamsId = kfa.flavorParamsId.toString();
							break;
						}
					}

					if (flavorParamsId)
						AnalyticsPluginLoader.setData("flavorId", flavorParamsId);

					break;
			}
		}

		/**
		 * returns the id of the flavor asset in the given index. null if index is invalid.
		 * @param index
		 * @return
		 *
		 */
		private function getFlavorIdByIndex(index:int):String
		{
			var flavorId:String;

			if (index >= 0 &&
				_mediaProxy.vo.kalturaMediaFlavorArray &&
				index < _mediaProxy.vo.kalturaMediaFlavorArray.length)	{

				flavorId = (_mediaProxy.vo.kalturaMediaFlavorArray[index] as KalturaFlavorAsset).id;
			}

			return flavorId;
		}
	}
}

package com.kaltura.kdpfl.plugin
{
	import com.akamai.playeranalytics.AnalyticsPluginLoader;
	import com.kaltura.kdpfl.model.ConfigProxy;
	import com.kaltura.kdpfl.model.MediaProxy;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.model.type.StreamerType;
	import com.kaltura.types.KalturaMediaType;
	import com.kaltura.vo.KalturaBaseEntry;
	import com.kaltura.vo.KalturaFlavorAsset;
	import com.kaltura.vo.KalturaMediaEntry;

	import flash.system.Capabilities;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class akamaiMediaAnalyticsMediator extends Mediator
	{
		public static const NAME:String = "akamaiMediaAnalyticsMediator";
		private var _mediaProxy:MediaProxy;

		public function akamaiMediaAnalyticsMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
		}

		override public function onRegister():void
		{
			_mediaProxy = facade.retrieveProxy(MediaProxy.NAME) as MediaProxy;
			super.onRegister();
		}

		override public function listNotificationInterests():Array
		{
			return [NotificationType.MEDIA_READY, NotificationType.MEDIA_ELEMENT_READY];
		}

		override public function handleNotification(notification:INotification):void
		{
			switch (notification.getName())
			{
				case NotificationType.MEDIA_READY:
					//populate analytics metadata
					var configProxy:ConfigProxy = facade.retrieveProxy(ConfigProxy.NAME) as ConfigProxy;
					var entry:KalturaBaseEntry = _mediaProxy.vo.entry;

					AnalyticsPluginLoader.setData("title", entry.name);
					AnalyticsPluginLoader.setData("entryId", entry.id);
					AnalyticsPluginLoader.setData("category", entry.categories);
					AnalyticsPluginLoader.setData("publisherId", configProxy.vo.flashvars.partnerId);

					//find content type
					if (entry is KalturaMediaEntry)
					{
						var mediaEntry:KalturaMediaEntry = entry as KalturaMediaEntry;

						AnalyticsPluginLoader.setData("contentLength", mediaEntry.msDuration);
						var contentType:String;
						switch (mediaEntry.mediaType)
						{
							case KalturaMediaType.VIDEO:
								contentType = "video";
								break;
							case KalturaMediaType.AUDIO:
								contentType = "audio";
								break;
							case KalturaMediaType.IMAGE:
								contentType = "image";
								break;
							default:
								contentType = "live";
						}
						AnalyticsPluginLoader.setData("contentType", contentType);
					}

					AnalyticsPluginLoader.setData("device", Capabilities.os );
					AnalyticsPluginLoader.setData("playerId", configProxy.vo.flashvars.uiConfId);

					break;

				case NotificationType.MEDIA_ELEMENT_READY:
					//find starting flavor ID
					var flavorAssetId:String;
					var flavorParamsId:String;
					if (_mediaProxy.vo.deliveryType == StreamerType.HTTP)
					{
						flavorAssetId = _mediaProxy.vo.selectedFlavorId;
					}
					else if (_mediaProxy.vo.deliveryType == StreamerType.RTMP)
					{
						flavorAssetId = getFlavorIdByIndex(_mediaProxy.startingIndex);
					}

					for each (var kfa:KalturaFlavorAsset in _mediaProxy.vo.kalturaMediaFlavorArray) {
						if (kfa.id == flavorAssetId) {
							flavorParamsId = kfa.flavorParamsId.toString();
							break;
						}
					}

					if (flavorParamsId)
						AnalyticsPluginLoader.setData("flavorId", flavorParamsId);

					break;
			}
		}

		/**
		 * returns the id of the flavor asset in the given index. null if index is invalid.
		 * @param index
		 * @return
		 *
		 */
		private function getFlavorIdByIndex(index:int):String
		{
			var flavorId:String;

			if (index >= 0 &&
				_mediaProxy.vo.kalturaMediaFlavorArray &&
				index < _mediaProxy.vo.kalturaMediaFlavorArray.length)	{

				flavorId = (_mediaProxy.vo.kalturaMediaFlavorArray[index] as KalturaFlavorAsset).id;
			}

			return flavorId;
		}
	}
}

change duration to milliseconds

qnd: change duration to milliseconds

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@91935 6b8eccd3-e8c5-4e7d-8186-e12b5326b719


//////////////////////////////////////////////////////////////////////////////////////
//
//  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.AirMediaPlayer
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.StatusEvent;
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

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

		/** AirMediaPlayer 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 AirMediaPlayer()
		{
			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():AirMediaPlayer
		{
			return _instance ? _instance:new AirMediaPlayer();
		}

		public var logEnabled:Boolean = true;

		/**
		*
		*/
		public function loadUrl(url:String):void
		{
			_context.call("loadUrl", url);
		}

		/**
		*
		*/
		public function play(startTime:int=0):void
		{
			_context.call("play", startTime);
		}

		/**
		*
		*/
		public function pause():void
		{
			_context.call("pause");
		}

		/**
		*
		*/
		public function close():void
		{
			_context.call("close");
		}

		/**
		* Length in milliseconds
		*/
		public function get length():int
		{
			return _context.call("getLength") as int;
		}

		/**
		* Progress in milliseconds
		*/
		public function get progress():int
		{
			return _context.call("getProgress") as int;
		}

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

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

		private static var _instance:AirMediaPlayer;

		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("[AirMediaPlayer] " + 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.AirMediaPlayer
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.StatusEvent;
	import flash.external.ExtensionContext;
	import flash.system.Capabilities;

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

		/** AirMediaPlayer 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 AirMediaPlayer()
		{
			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():AirMediaPlayer
		{
			return _instance ? _instance:new AirMediaPlayer();
		}

		public var logEnabled:Boolean = true;

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

		/**
		* Start playing the stream.
        * If the playback has been paused before, it will continue from this point.
        * @param startTime:int the start time in milliseconds
		*/
		public function play(startTime:int=0):void
		{
			_context.call("play", startTime);
		}

		/**
		* Pause the playback
		*/
		public function pause():void
		{
			_context.call("pause");
		}

		/**
		* Close the stream and release.
        * Note that loadUrl() has to be called again before replaying if close has been called.
		*/
		public function close():void
		{
			_context.call("close");
		}

		/**
		* Length in milliseconds
		*/
		public function get length():int
		{
			return _context.call("getLength") as int;
		}

		/**
		* Progress in milliseconds
		*/
		public function get progress():int
		{
			return _context.call("getProgress") as int;
		}

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

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

		private static var _instance:AirMediaPlayer;

		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("[AirMediaPlayer] " + message);
		}
	}
}

Add documentation

Add documentation


package org.mangui.chromeless {

    import org.mangui.HLS.parsing.Level;
    import org.mangui.HLS.*;
    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;

    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 video element. **/
        private var _video:StageVideo;
        /** current media position */
        private var _media_position:Number;

        /** Initialization. **/
        public function ChromelessPlayer():void {
            // 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);
            // 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("getPosition",_getPosition);
            ExternalInterface.addCallback("getState",_getState);
            ExternalInterface.addCallback("getType",_getType);
            ExternalInterface.addCallback("getmaxBufferLength",_getmaxBufferLength);
            ExternalInterface.addCallback("getbufferLength",_getbufferLength);
            // 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("playerSetmaxBufferLength",_setmaxBufferLength);
            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) {
                ExternalInterface.call("onError",event.message);
            }
        };

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

        private function _manifestHandler(event:HLSEvent):void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest",event.levels[0].duration);
            }
        };
        private function _mediaTimeHandler(event:HLSEvent):void {
            if (ExternalInterface.available) {
                _media_position = event.mediatime.position;
                ExternalInterface.call("onPosition",event.mediatime.position,event.mediatime.duration);
            }
        };
        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);
            }
        };

        /** Javascript getters. **/
        private function _getLevel():Number { return _hls.getLevel(); };
        private function _getLevels():Vector.<Level> { return _hls.getLevels(); };
        private function _getMetrics():Object { return _hls.getMetrics(); };
        private function _getPosition():Number { return _hls.getPosition(); };
        private function _getState():String { return _hls.getState(); };
        private function _getType():String { return _hls.getType(); };
        private function _getbufferLength():Number { return _hls.getBufferLength(); };
        private function _getmaxBufferLength():Number { return _hls.maxBufferLength; };

        /** 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 { _hls.setPlaybackQuality(level); if (!isNaN(_media_position)) {_hls.stream.seek(_media_position);}};
        private function _setmaxBufferLength(new_len:Number):void { _hls.maxBufferLength = new_len;};

        /** 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;
            }
            _hls.setWidth(stage.stageWidth);
        };

        /** StageVideo detector. **/
        private function _onStageVideoState(event:StageVideoAvailabilityEvent):void {
            var available:Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            if (available && stage.stageVideos.length > 0) {
              _video = stage.stageVideos[0];
              _video.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
              _hls = new HLS();
              _video.attachNetStream(_hls.stream);
            } else {
              var video:Video = new Video(stage.stageWidth, stage.stageHeight);
              addChild(video);
              _hls = new HLS();
              video.smoothing = true;
              video.attachNetStream(_hls.stream);
            }
            _hls.setWidth(stage.stageWidth);
            _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.STATE,_stateHandler);
            _hls.addEventListener(HLSEvent.QUALITY_SWITCH,_switchHandler);
        };

    }

}

package org.mangui.chromeless {

    import org.mangui.HLS.parsing.Level;
    import org.mangui.HLS.*;
    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;

    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 video element. **/
        private var _video:StageVideo;
        /** current media position */
        private var _media_position:Number;

        /** Initialization. **/
        public function ChromelessPlayer():void {
            // 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);
            // 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("getPosition",_getPosition);
            ExternalInterface.addCallback("getState",_getState);
            ExternalInterface.addCallback("getType",_getType);
            ExternalInterface.addCallback("getmaxBufferLength",_getmaxBufferLength);
            ExternalInterface.addCallback("getbufferLength",_getbufferLength);
            ExternalInterface.addCallback("getPlayerVersion",_getPlayerVersion);
            // 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("playerSetmaxBufferLength",_setmaxBufferLength);
            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) {
                ExternalInterface.call("onError",event.message);
            }
        };

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

        private function _manifestHandler(event:HLSEvent):void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest",event.levels[0].duration);
            }
        };
        private function _mediaTimeHandler(event:HLSEvent):void {
            if (ExternalInterface.available) {
                _media_position = event.mediatime.position;
                ExternalInterface.call("onPosition",event.mediatime.position,event.mediatime.duration);
            }
        };
        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);
            }
        };

        /** Javascript getters. **/
        private function _getLevel():Number { return _hls.getLevel(); };
        private function _getLevels():Vector.<Level> { return _hls.getLevels(); };
        private function _getMetrics():Object { return _hls.getMetrics(); };
        private function _getPosition():Number { return _hls.getPosition(); };
        private function _getState():String { return _hls.getState(); };
        private function _getType():String { return _hls.getType(); };
        private function _getbufferLength():Number { return _hls.getBufferLength(); };
        private function _getmaxBufferLength():Number { return _hls.maxBufferLength; };
        private function _getPlayerVersion():Number { return 2; };

        /** 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 { _hls.setPlaybackQuality(level); if (!isNaN(_media_position)) {_hls.stream.seek(_media_position);}};
        private function _setmaxBufferLength(new_len:Number):void { _hls.maxBufferLength = new_len;};

        /** 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;
            }
            _hls.setWidth(stage.stageWidth);
        };

        /** StageVideo detector. **/
        private function _onStageVideoState(event:StageVideoAvailabilityEvent):void {
            var available:Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            if (available && stage.stageVideos.length > 0) {
              _video = stage.stageVideos[0];
              _video.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
              _hls = new HLS();
              _video.attachNetStream(_hls.stream);
            } else {
              var video:Video = new Video(stage.stageWidth, stage.stageHeight);
              addChild(video);
              _hls = new HLS();
              video.smoothing = true;
              video.attachNetStream(_hls.stream);
            }
            _hls.setWidth(stage.stageWidth);
            _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.STATE,_stateHandler);
            _hls.addEventListener(HLSEvent.QUALITY_SWITCH,_switchHandler);
        };

    }

}

add a getPlayerVersion method.

add a getPlayerVersion method.


package aerys.minko.type.loader
{
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.type.Signal;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.getQualifiedClassName;

	public class TextureLoader implements ILoader
	{
		private var _progress			: Signal;
		private var _error				: Signal;
		private var _complete			: Signal;

		private var _isComplete			: Boolean;

		private var _mipmap				: Boolean;

		protected var _textureResource	: TextureResource;

		public function get progress() : Signal
		{
			return _progress;
		}

		public function get error() : Signal
		{
			return _error;
		}

		public function get complete() : Signal
		{
			return _complete;
		}

		public function get isComplete() : Boolean
		{
			return _isComplete;
		}

		public function get textureResource() : TextureResource
		{
			return _textureResource;
		}

		public function TextureLoader(enableMipmapping : Boolean = true)
		{
			_mipmap				= enableMipmapping;

			_textureResource 	= new TextureResource();
			_isComplete 		= false;
			_error				= new Signal('TextureLoader.error');
			_progress			= new Signal('TextureLoader.progress');
			_complete			= new Signal('TextureLoader.complete');
		}

		public function load(request : URLRequest) : void
		{
			var loader : URLLoader = new URLLoader();

			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
			loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR, loadIoErrorHandler);
			loader.load(request);
		}

		private function loadIoErrorHandler(e : IOErrorEvent) : void
		{
			_textureResource = null;
			_error.execute(this, e.errorID, e.text);
		}

		private function loadProgressHandler(e : ProgressEvent) : void
		{
			_progress.execute(this, e.bytesLoaded, e.bytesTotal);
		}

		private function loadCompleteHandler(e : Event) : void
		{
			loadBytes(URLLoader(e.currentTarget).data);
		}

		public function loadClass(classObject : Class) : void
		{
			var assetObject : Object		= new classObject();

			if (assetObject is Bitmap || assetObject is BitmapData)
			{
				var bitmapData : BitmapData = assetObject as BitmapData;
				if (bitmapData == null)
					bitmapData = Bitmap(assetObject).bitmapData;

				_textureResource.setContentFromBitmapData(bitmapData, _mipmap);
				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else if (assetObject is ByteArray)
			{
				loadBytes(ByteArray(assetObject));
			}
			else
			{
				var className : String = getQualifiedClassName(classObject);
				className = className.substr(className.lastIndexOf(':') + 1);

				_isComplete = true;

				throw new Error('No texture can be created from an object of type \'' + className + '\'');
			}
		}

		public function loadBytes(bytes : ByteArray) : void
		{
			bytes.position = 0;

			if (bytes.readByte() == 'A'.charCodeAt(0) &&
				bytes.readByte() == 'T'.charCodeAt(0) &&
				bytes.readByte() == 'F'.charCodeAt(0))
			{
				bytes.position = 0;
				_textureResource.setContentFromATF(bytes);
				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else
			{
				bytes.position = 0;

				var loader : Loader = new Loader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBytesCompleteHandler);
				loader.loadBytes(bytes);
			}
		}

		private function loadBytesCompleteHandler(e : Event) : void
		{
			var displayObject : DisplayObject = LoaderInfo(e.currentTarget).content;

			if (displayObject is Bitmap)
			{
				_textureResource.setContentFromBitmapData(Bitmap(displayObject).bitmapData, _mipmap);
				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else
			{
				var className : String = getQualifiedClassName(displayObject);

				className = className.substr(className.lastIndexOf(':') + 1);
				_isComplete = true;
				throw new Error('No texture can be created from an object of type \'' + className + '\'');
			}
		}

		public static function loadClass(classObject 		: Class,
										 enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.loadClass(classObject);

			return textureLoader.textureResource;
		}

		public static function load(request				: URLRequest,
									enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.load(request);

			return textureLoader.textureResource;
		}

		public static function loadBytes(bytes				: ByteArray,
										 enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.loadBytes(bytes);

			return textureLoader.textureResource;
		}
	}
}

package aerys.minko.type.loader
{
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.type.Signal;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.getQualifiedClassName;

	public class TextureLoader implements ILoader
	{
		private var _progress			: Signal;
		private var _error				: Signal;
		private var _complete			: Signal;

		private var _isComplete			: Boolean;

		private var _mipmap				: Boolean;

		protected var _textureResource	: TextureResource;

		public function get progress() : Signal
		{
			return _progress;
		}

		public function get error() : Signal
		{
			return _error;
		}

		public function get complete() : Signal
		{
			return _complete;
		}

		public function get isComplete() : Boolean
		{
			return _isComplete;
		}

		public function get textureResource() : TextureResource
		{
			return _textureResource;
		}

		public function TextureLoader(enableMipmapping : Boolean = true)
		{
			_mipmap				= enableMipmapping;

			_textureResource 	= new TextureResource();
			_isComplete 		= false;
			_error				= new Signal('TextureLoader.error');
			_progress			= new Signal('TextureLoader.progress');
			_complete			= new Signal('TextureLoader.complete');
		}

		public function load(request : URLRequest) : void
		{
			var loader : URLLoader = new URLLoader();

			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
			loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR, loadIoErrorHandler);
			loader.load(request);
		}

		private function loadIoErrorHandler(e : IOErrorEvent) : void
		{
			_textureResource = null;
			_error.execute(this, e.errorID, e.text);
		}

		private function loadProgressHandler(e : ProgressEvent) : void
		{
			_progress.execute(this, e.bytesLoaded, e.bytesTotal);
		}

		private function loadCompleteHandler(e : Event) : void
		{
			loadBytes(URLLoader(e.currentTarget).data);
		}

		public function loadClass(classObject : Class) : void
		{
			var assetObject : Object		= new classObject();

			if (assetObject is Bitmap || assetObject is BitmapData)
			{
				var bitmapData : BitmapData = assetObject as BitmapData;

				if (bitmapData == null)
					bitmapData = Bitmap(assetObject).bitmapData;

				_textureResource.setContentFromBitmapData(bitmapData, _mipmap);
				bitmapData.dispose();

				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else if (assetObject is ByteArray)
			{
				loadBytes(ByteArray(assetObject));
			}
			else
			{
				var className : String = getQualifiedClassName(classObject);
				className = className.substr(className.lastIndexOf(':') + 1);

				_isComplete = true;

				throw new Error('No texture can be created from an object of type \'' + className + '\'');
			}
		}

		public function loadBytes(bytes : ByteArray) : void
		{
			bytes.position = 0;

			if (bytes.readByte() == 'A'.charCodeAt(0) &&
				bytes.readByte() == 'T'.charCodeAt(0) &&
				bytes.readByte() == 'F'.charCodeAt(0))
			{
				bytes.position = 0;
				_textureResource.setContentFromATF(bytes);
				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else
			{
				bytes.position = 0;

				var loader : Loader = new Loader();

				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBytesCompleteHandler);
				loader.loadBytes(bytes);
			}
		}

		private function loadBytesCompleteHandler(e : Event) : void
		{
			var displayObject : DisplayObject = LoaderInfo(e.currentTarget).content;

			if (displayObject is Bitmap)
			{
				var bitmapData : BitmapData = Bitmap(displayObject).bitmapData;

				_textureResource.setContentFromBitmapData(bitmapData, _mipmap);
				bitmapData.dispose();

				_isComplete = true;
				_complete.execute(this, _textureResource);
			}
			else
			{
				var className : String = getQualifiedClassName(displayObject);

				className = className.substr(className.lastIndexOf(':') + 1);
				_isComplete = true;

				throw new Error(
					'No texture can be created from an object of type \'' + className + '\''
				);
			}
		}

		public static function loadClass(classObject 		: Class,
										 enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.loadClass(classObject);

			return textureLoader.textureResource;
		}

		public static function load(request				: URLRequest,
									enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.load(request);

			return textureLoader.textureResource;
		}

		public static function loadBytes(bytes				: ByteArray,
										 enableMipMapping 	: Boolean = true) : TextureResource
		{
			var textureLoader : TextureLoader = new TextureLoader(enableMipMapping);

			textureLoader.loadBytes(bytes);

			return textureLoader.textureResource;
		}
	}
}

call BitmapData.dispose() to dispose each temporary bitmap data object when TextureResource.setContentFromBitmapData() has been called to free the memory as soon as possible


/**
  * LzSoundMC.as
  *
  * @copyright Copyright 2001-2008 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic AS2
  */

/**
  * Wraps the streaming MP3 loader in a movieclip-like API.
  * Used for proxyless mp3 audio loading.
  *
  * @access private
  */
var SoundMC = function (mc) {
    this.init(mc);
}

SoundMC.prototype = new MovieClip();

// the attached flash Sound object
SoundMC.prototype._sound = null;
// flag required for loader
SoundMC.prototype.isaudio = true;
// tracks the loading progress
SoundMC.prototype.loadstate = 0;
// next frame to be played
SoundMC.prototype._nextframe = -1;

SoundMC.prototype.addProperty("_totalframes", function () {
    return Math.floor(this._sound.duration * .001 * canvas.framerate) || 0;
}, null);

SoundMC.prototype.addProperty("_currentframe", function () {
    if (this._nextframe != -1) {
        return this._nextframe;
    } else {
        return Math.floor(this._sound.position * .001 * canvas.framerate) || 0;
    }
}, null);

SoundMC.prototype.addProperty("_framesloaded", function () {
    return Math.floor((this._sound.getBytesLoaded() / this._sound.getBytesTotal()) * this._totalframes) || 0;
}, null);

/**
  * @access private
  */
SoundMC.prototype.play = function (direct=false) {
    // if we're not seeking to a specific frame and we're at the end already, start at the beginning
    if (direct != true && this._currentframe == this._totalframes) {
        var t = 0;
    } else {
        var t = this._currentframe / canvas.framerate;
        if (t < 0) t = 0;
    }
    this._nextframe = -1;
    this._sound.stop();
    this._sound.start(t);
}

/**
  * @access private
  */
SoundMC.prototype.gotoAndPlay = function (f) {
    this._nextframe = f;
    this.play(true);
}

/**
  * @access private
  */
SoundMC.prototype.stop = function () {
    this._sound.stop();
}

/**
  * @access private
  */
SoundMC.prototype.gotoAndStop = function (f) {
    this.stop();
    this._nextframe = f;
}

/**
  * @access private
  */
SoundMC.prototype.loadMovie = function (reqstr) {
    this.init();
    this._sound.loadSound(reqstr, true);
    this.loadstate = 1;
}

/**
  * @access private
  */
SoundMC.prototype.getBytesLoaded = function () {
    return this._sound.getBytesLoaded();
}

/**
  * @access private
  */
SoundMC.prototype.getBytesTotal = function () {
    return this._sound.getBytesTotal();
}

/**
  * @access private
  */
SoundMC.prototype.unload = function () {
    this.stop();
    delete this._sound;
    this.loadstate = 0;
}

/**
  * @access private
  */
SoundMC.prototype.setPan = function (p) {
    this._sound.setPan(p);
}

/**
  * @access private
  */
SoundMC.prototype.setVolume = function (v) {
    this._sound.setVolume(v);
}

/**
  * @access private
  */
SoundMC.prototype.getPan = function () {
    return this._sound.getPan();
}

/**
  * @access private
  */
SoundMC.prototype.getVolume = function () {
    return this._sound.getVolume();
}

/**
  * @access private
  */
SoundMC.prototype.loadDone = function (success) {
    if (success != true) {
        // LzLoader -> LzSprite -> LzView
        this.loader.owner.owner.resourceloaderror();
        if ($debug) {
            Debug.warn("failed to load %w", this.reqobj.url);
        }
    } else {
        this.loadstate = 2;
    }
}

/**
  * @access private
  */
SoundMC.prototype.init = function (mc) {
    this._sound.stop();
    delete this._sound;
    if (mc != null) {
        this._sound = new Sound(mc);
    } else {
        this._sound = new Sound();
    }
    this._sound.checkPolicyFile = true;
    this._sound.mc = this;
/** @access private */
    this._sound.onLoad = function (success) {
        this.mc.loadDone(success);
    }
/** @access private */
    this._sound.onSoundComplete = function () {
    }

    this.loadstate = 0;
}

/**
  * @access private
  */
SoundMC.prototype.getTotalTime = function () {
    return this._sound.duration * .001;
}

/**
  * @access private
  */
SoundMC.prototype.getCurrentTime = function () {
    // use _nextframe if the sound was stopped at a specific frame, cf. gotoAndStop
    if (this._nextframe != -1) {
        return this._nextframe / canvas.framerate;
    } else {
        return this._sound.position * .001;
    }
}

/**
  * @access private
  */
SoundMC.prototype.seek = function (secs, playing) {
    this._sound.stop();
    this._sound.start(this.getCurrentTime() + secs);
    if (playing != true) {
        this._sound.stop();
        // LzLoader -> LzSprite
        this.loader.owner.updatePlayStatus();
    }
}

/**
  * @access private
  */
SoundMC.prototype.getID3 = function () {
    return this._sound.id3;
}

/**
  * LzSoundMC.as
  *
  * @copyright Copyright 2001-2009 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic AS2
  */

/**
  * Wraps the streaming MP3 loader in a movieclip-like API.
  * Used for proxyless mp3 audio loading.
  *
  * @access private
  */
var SoundMC = function (mc) {
    this.init(mc);
}

SoundMC.prototype = new MovieClip();

// the attached flash Sound object
SoundMC.prototype._sound = null;
// flag required for loader
SoundMC.prototype.isaudio = true;
// tracks the loading progress
SoundMC.prototype.loadstate = 0;
// next frame to be played
SoundMC.prototype._nextframe = -1;

SoundMC.prototype.addProperty("_totalframes", function () {
    return Math.floor(this._sound.duration * .001 * canvas.framerate) || 0;
}, null);

SoundMC.prototype.addProperty("_currentframe", function () {
    if (this._nextframe != -1) {
        return this._nextframe;
    } else {
        return Math.floor(this._sound.position * .001 * canvas.framerate) || 0;
    }
}, null);

SoundMC.prototype.addProperty("_framesloaded", function () {
    return Math.floor((this._sound.getBytesLoaded() / this._sound.getBytesTotal()) * this._totalframes) || 0;
}, null);

/**
  * @access private
  */
SoundMC.prototype.play = function (direct=false) {
    // if we're not seeking to a specific frame and we're at the end already, start at the beginning
    if (direct != true && this._currentframe == this._totalframes) {
        var t = 0;
    } else {
        var t = this._currentframe / canvas.framerate;
        if (t < 0) t = 0;
    }
    this._nextframe = -1;
    this._sound.stop();
    this._sound.start(t);
}

/**
  * @access private
  */
SoundMC.prototype.gotoAndPlay = function (f) {
    this._nextframe = f;
    this.play(true);
}

/**
  * @access private
  */
SoundMC.prototype.stop = function () {
    this._sound.stop();
}

/**
  * @access private
  */
SoundMC.prototype.gotoAndStop = function (f) {
    this.stop();
    this._nextframe = f;
}

/**
  * @access private
  */
SoundMC.prototype.loadMovie = function (reqstr) {
    this.init();
    this._sound.loadSound(reqstr, true);
    this.loadstate = 1;
}

/**
  * @access private
  */
SoundMC.prototype.getBytesLoaded = function () {
    return this._sound.getBytesLoaded();
}

/**
  * @access private
  */
SoundMC.prototype.getBytesTotal = function () {
    return this._sound.getBytesTotal();
}

/**
  * @access private
  */
SoundMC.prototype.unload = function () {
    this.stop();
    delete this._sound;
    this.loadstate = 0;
}

/**
  * @access private
  */
SoundMC.prototype.setPan = function (p) {
    this._sound.setPan(p);
}

/**
  * @access private
  */
SoundMC.prototype.setVolume = function (v) {
    this._sound.setVolume(v);
}

/**
  * @access private
  */
SoundMC.prototype.getPan = function () {
    return this._sound.getPan();
}

/**
  * @access private
  */
SoundMC.prototype.getVolume = function () {
    return this._sound.getVolume();
}

/**
  * @access private
  */
SoundMC.prototype.loadDone = function (success) {
    // @devnote Loading invalid files still results in a successful load,
    // therefore check duration to identify valid mp3-files (LPP-7880)
    if (success != true || this._sound.duration == 0) {
        this.loader.doError(this.loader.mc);
        if ($debug) {
            Debug.warn("failed to load %w", this.reqobj.url);
        }
    } else {
        this.loadstate = 2;
    }
}

/**
  * @access private
  */
SoundMC.prototype.init = function (mc) {
    this._sound.stop();
    delete this._sound;
    if (mc != null) {
        this._sound = new Sound(mc);
    } else {
        this._sound = new Sound();
    }
    this._sound.checkPolicyFile = true;
    this._sound.mc = this;
/** @access private */
    this._sound.onLoad = function (success) {
        this.mc.loadDone(success);
    }
/** @access private */
    this._sound.onSoundComplete = function () {
    }

    this.loadstate = 0;
}

/**
  * @access private
  */
SoundMC.prototype.getTotalTime = function () {
    return this._sound.duration * .001;
}

/**
  * @access private
  */
SoundMC.prototype.getCurrentTime = function () {
    // use _nextframe if the sound was stopped at a specific frame, cf. gotoAndStop
    if (this._nextframe != -1) {
        return this._nextframe / canvas.framerate;
    } else {
        return this._sound.position * .001;
    }
}

/**
  * @access private
  */
SoundMC.prototype.seek = function (secs, playing) {
    this._sound.stop();
    this._sound.start(this.getCurrentTime() + secs);
    if (playing != true) {
        this._sound.stop();
        // LzLoader -> LzSprite
        this.loader.owner.updatePlayStatus();
    }
}

/**
  * @access private
  */
SoundMC.prototype.getID3 = function () {
    return this._sound.id3;
}

Change 20090309-bargull-tGm by bargull@dell--p4--2-53 on 2009-03-09 02:14:09
    in /home/Admin/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: handle invalid files in SoundMC

New Features:

Bugs Fixed: LPP-7880 (SWF8: mp3 loading responds with error-swf / onerror not dispatched) (partial)

Technical Reviewer: hminsky
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
Invalid files still send onLoad(true), so check Sound.duration as a simple means to identify valid mp3-files.
Also call LzLoader#doError() instead of LzView#resourceloaderror() in order to remove requests properly from load-queue.

Tests:
testcase at bugreport
examples/music/music.lzx

git-svn-id: d62bde4b5aa582fdf07c8d403e53e0399a7ed285@13220 fa20e4f9-1d0a-0410-b5f3-dc9c16b8b17c


package aerys.minko.type.animation
{
	import aerys.minko.scene.node.IScene;
	import aerys.minko.scene.node.ITransformable;
	import aerys.minko.scene.node.group.Group;
	import aerys.minko.type.animation.timeline.ITimeline;

	import flash.utils.getTimer;

	import org.osmf.elements.DurationElement;

	public class Animation
	{
		private var _id				: String;

		private var _beginTime		: uint;
		private var _lastTime		: uint;

		private var _playingOn		: IScene;
		private var _timelines		: Vector.<ITimeline>;
		private var _duration		: uint;

		public function get id() : String { return _id; }

		public function Animation(id		: String,
								  timelines : Vector.<ITimeline>)
		{
			_id			= id;
			_timelines	= timelines;
			_lastTime	= 0;

			_duration	= 0;
			for each (var timeline : ITimeline in timelines)
				if (_duration < timeline.duration)
					_duration = timeline.duration;
		}

		public function tick() : void
		{
			var time : uint = (getTimer() - _beginTime) % _duration;
			transformNodes(time);
		}

		public function step(deltaTime : uint = 80) : void
		{
			var time : uint = (_lastTime + deltaTime) % _duration;
			transformNodes(time);
		}

		public function stepReverse(deltaTime : uint = 80) : void
		{
			var time : int = (_lastTime - deltaTime) % _duration;
			if (time < 0)
				time = time + _duration;

			transformNodes(time);
		}

		private function transformNodes(time : uint) : void
		{
			_lastTime = time;

			var timelinesCount : uint = _timelines.length;
			for (var i : uint = 0; i < timelinesCount; ++i)
			{
				var timeline		: ITimeline	= _timelines[i];
				var timelineTarget	: String	= timeline.target;

				var target			: ITransformable;
				if (_playingOn.name == timelineTarget)
					target = ITransformable(_playingOn);
				else if (_playingOn is Group)
					target = ITransformable(Group(_playingOn).getDescendantByName(timelineTarget));

				if (!target)
					continue;

				timeline.updateAt(time, target);
			}
		}

		public function playOn(node : IScene) : void
		{
			_beginTime	= getTimer();
			_playingOn	= node;
			_lastTime	= 0;
		}

		public function stop() : void
		{
			_playingOn = null;
		}

	}
}

package aerys.minko.type.animation
{
	import aerys.minko.scene.node.IScene;
	import aerys.minko.scene.node.ITransformable;
	import aerys.minko.scene.node.group.Group;
	import aerys.minko.type.animation.timeline.ITimeline;

	import flash.utils.getTimer;

	public class Animation
	{
		private var _id				: String;

		private var _beginTime		: uint;
		private var _lastTime		: uint;

		private var _playingOn		: IScene;
		private var _timelines		: Vector.<ITimeline>;
		private var _duration		: uint;

		public function get id() : String { return _id; }

		public function Animation(id		: String,
								  timelines : Vector.<ITimeline>)
		{
			_id			= id;
			_timelines	= timelines;
			_lastTime	= 0;

			_duration	= 0;
			for each (var timeline : ITimeline in timelines)
				if (_duration < timeline.duration)
					_duration = timeline.duration;
		}

		public function tick() : void
		{
			var time : uint = (getTimer() - _beginTime) % _duration;
			transformNodes(time);
		}

		public function step(deltaTime : uint = 80) : void
		{
			var time : uint = (_lastTime + deltaTime) % _duration;
			transformNodes(time);
		}

		public function stepReverse(deltaTime : uint = 80) : void
		{
			var time : int = (_lastTime - deltaTime) % _duration;
			if (time < 0)
				time = time + _duration;

			transformNodes(time);
		}

		private function transformNodes(time : uint) : void
		{
			_lastTime = time;

			var timelinesCount : uint = _timelines.length;
			for (var i : uint = 0; i < timelinesCount; ++i)
			{
				var timeline		: ITimeline	= _timelines[i];
				var timelineTarget	: String	= timeline.target;

				var target			: ITransformable;
				if (_playingOn.name == timelineTarget)
					target = ITransformable(_playingOn);
				else if (_playingOn is Group)
					target = ITransformable(Group(_playingOn).getDescendantByName(timelineTarget));

				if (!target)
					continue;

				timeline.updateAt(time, target);
			}
		}

		public function playOn(node : IScene) : void
		{
			_beginTime	= getTimer();
			_playingOn	= node;
			_lastTime	= 0;
		}

		public function stop() : void
		{
			_playingOn = null;
		}

	}
}

Remove usused import

Remove usused import