/*****************************************************
*
* Copyright 2009 Adobe Systems Incorporated. All Rights Reserved.
*
*****************************************************
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
*
* The Initial Developer of the Original Code is Adobe Systems Incorporated.
* Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
* Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.elements.compositeClasses
{
import flash.events.Event;
import org.osmf.events.DynamicStreamEvent;
import org.osmf.traits.DynamicStreamTrait;
import org.osmf.traits.MediaTraitBase;
import org.osmf.traits.MediaTraitType;
/**
* @private
*
* The SerialDynamicStreamTrait aggregates DynamicStreamTraits in serial, acting as a single
* trait. This trait will match settings between child traits when switching between children.
*/
internal class SerialDynamicStreamTrait extends DynamicStreamTrait implements IReusable
{
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function SerialDynamicStreamTrait(traitAggregator:TraitAggregator)
{
super();
this.traitAggregator = traitAggregator;
traitAggregationHelper = new TraitAggregationHelper
( traitType
, traitAggregator
, processAggregatedChild
, processUnaggregatedChild
);
}
/**
* @private
*/
override public function getBitrateForIndex(index:int):Number
{
return traitOfCurrentChild.getBitrateForIndex(index);
}
/**
* @private
*/
public function attach():void
{
traitAggregationHelper.attach();
}
/**
* @private
*/
public function detach():void
{
traitAggregationHelper.detach();
}
/**
* @private
*/
override protected function autoSwitchChangeEnd():void
{
// Propagate to the current child.
traitOfCurrentChild.autoSwitch = autoSwitch;
super.autoSwitchChangeEnd();
}
/**
* @private
*/
override protected function switchingChangeEnd(index:int):void
{
if (switching && !preventSwitchingChangePropagate)
{
// Propagate to the current child.
traitOfCurrentChild.switchTo(index);
}
super.switchingChangeEnd(index);
}
/**
* @private
*
* Adds the child as the current listened child. Sets the autoswitch, property to
* carry over from the previous child. If autoswitch is false, attempts to match the bitrate
* for the next media element.
*/
private function processAggregatedChild(child:MediaTraitBase):void
{
if (child == traitOfCurrentChild)
{
var dsTrait:DynamicStreamTrait = child as DynamicStreamTrait;
setNumDynamicStreams(dsTrait.numDynamicStreams);
maxAllowedIndex = dsTrait.maxAllowedIndex;
autoSwitch = dsTrait.autoSwitch;
if (!dsTrait.autoSwitch)
{
for (var i:Number = 0; i <= dsTrait.maxAllowedIndex; i++)
{
if (dsTrait.getBitrateForIndex(i) > getBitrateForIndex(currentIndex))
{
dsTrait.switchTo(Math.max(i-1, 0));
break;
}
else if (dsTrait.getBitrateForIndex(i) == getBitrateForIndex(currentIndex) ||
i == dsTrait.maxAllowedIndex)
{
dsTrait.switchTo(i);
break;
}
}
}
child.addEventListener(DynamicStreamEvent.SWITCHING_CHANGE, onSwitchingChange);
child.addEventListener(DynamicStreamEvent.NUM_DYNAMIC_STREAMS_CHANGE, redispatchEvent);
child.addEventListener(DynamicStreamEvent.AUTO_SWITCH_CHANGE, onAutoSwitchChange);
}
}
private function processUnaggregatedChild(child:MediaTraitBase):void
{
child.removeEventListener(DynamicStreamEvent.SWITCHING_CHANGE, onSwitchingChange);
child.removeEventListener(DynamicStreamEvent.NUM_DYNAMIC_STREAMS_CHANGE, redispatchEvent);
child.removeEventListener(DynamicStreamEvent.AUTO_SWITCH_CHANGE, onAutoSwitchChange);
}
private function redispatchEvent(event:Event):void
{
dispatchEvent(event.clone());
}
private function onAutoSwitchChange(event:DynamicStreamEvent):void
{
// Propagate to composite trait.
autoSwitch = event.autoSwitch;
}
private function onSwitchingChange(event:DynamicStreamEvent):void
{
// Propagate to composite trait.
preventSwitchingChangePropagate = true;
setSwitching(event.switching, traitOfCurrentChild.currentIndex);
preventSwitchingChangePropagate = false;
}
private function get traitOfCurrentChild():DynamicStreamTrait
{
return traitAggregator.listenedChild
? traitAggregator.listenedChild.getTrait(MediaTraitType.DYNAMIC_STREAM) as DynamicStreamTrait
: null;
}
private var traitAggregator:TraitAggregator;
private var traitAggregationHelper:TraitAggregationHelper;
private var preventSwitchingChangePropagate:Boolean;
}
}