| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.controls.videoClasses |
| { |
| |
| import flash.events.Event; |
| import mx.controls.VideoDisplay; |
| import mx.core.mx_internal; |
| import mx.events.MetadataEvent; |
| import mx.managers.ISystemManager; |
| import mx.managers.SystemManager; |
| import mx.resources.IResourceManager; |
| import mx.resources.ResourceManager; |
| |
| use namespace mx_internal; |
| |
| [ResourceBundle("controls")] |
| |
| /** |
| * The CuePointManager class lets you use ActionScript code to |
| * manage the cue points associated with the VideoDisplay control. |
| * |
| * @see mx.controls.VideoDisplay |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public class CuePointManager |
| { |
| include "../../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _owner:VideoPlayer; |
| |
| private var _metadataLoaded:Boolean; |
| private var _disabledCuePoints:Array; |
| private var _disabledCuePointsByNameOnly:Object; |
| private var _cuePointIndex:uint; |
| private var _cuePointTolerance:Number; |
| private var _linearSearchTolerance:Number; |
| |
| private static var DEFAULT_LINEAR_SEARCH_TOLERANCE:Number = 50; |
| |
| private var cuePoints:Array; |
| |
| /** |
| * @private |
| * Reference to VideoDisplay object associated with this CuePointManager |
| * instance. |
| */ |
| mx_internal var videoDisplay:VideoDisplay; |
| |
| /** |
| * @private |
| * Used for accessing localized Error messages. |
| */ |
| private var resourceManager:IResourceManager = |
| ResourceManager.getInstance(); |
| |
| // |
| // public APIs |
| // |
| |
| /** |
| * Constructor. |
| * |
| * @param owner The VideoPlayer instance that is the parent of this CuePointManager. |
| * @param id This parameter is ignored; it is provided only for backwards compatibility. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function CuePointManager(owner:VideoPlayer, id:uint = 0) |
| { |
| // take in id just to be back-wards compatible |
| super(); |
| |
| _owner = owner; |
| reset(); |
| _cuePointTolerance = _owner.playheadUpdateInterval / 2000; |
| _linearSearchTolerance = DEFAULT_LINEAR_SEARCH_TOLERANCE; |
| } |
| |
| /** |
| * @private |
| * Reset cue point lists |
| */ |
| private function reset():void |
| { |
| _metadataLoaded = false; |
| cuePoints = null; |
| _disabledCuePoints = null; |
| _cuePointIndex = 0; |
| } |
| |
| /** |
| * @private |
| * read only, has metadata been loaded |
| */ |
| private function get metadataLoaded():Boolean |
| { |
| return _metadataLoaded; |
| } |
| |
| /** |
| * @private |
| * <p>Set by FLVPlayback to update _cuePointTolerance</p> |
| * Should be exposed in VideoDisplay/ here in Flex 2.0. |
| */ |
| private function set playheadUpdateInterval(aTime:Number):void |
| { |
| _cuePointTolerance = aTime / 2000; |
| } |
| |
| /** |
| * Adds a cue point. |
| * |
| * <p>You can add multiple cue points with the same |
| * name and time. When you call the <code>removeCuePoint()</code> method |
| * with the name and time, it removes the first matching cue point. |
| * To remove all matching cue points, you have to make additional calls to |
| * the <code>removeCuePoint()</code> method.</p> |
| * |
| * @param cuePoint The Object describes the cue |
| * point. It must contain the properties <code>name:String</code> |
| * and <code>time:Number</code> (in seconds). |
| * If the Object does not conform to these |
| * conventions, it throws a <code>VideoError</code> error. |
| * |
| * @return A copy of the cue point Object added. The copy has the |
| * following additional properties: |
| * |
| * <ul> |
| * <li><code>array</code> - the Array of all cue points. Treat |
| * this Array as read only because adding, removing or editing objects |
| * within it can cause cue points to malfunction.</li> |
| * |
| * <li><code>index</code> - the index into the Array for the |
| * returned cue point.</li> |
| * </ul> |
| * |
| * @throws mx.controls.videoClasses.VideoError If the arguments are invalid. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function addCuePoint(cuePoint:Object):Object |
| { |
| var message:String; |
| |
| // make sense of param |
| var copy:Object = deepCopyObject(cuePoint); |
| |
| // sanity check |
| var timeUndefined:Boolean = (isNaN(copy.time) || copy.time < 0); |
| if (timeUndefined) |
| { |
| message = resourceManager.getString( |
| "controls", "wrongTime"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| if (!copy.name) |
| { |
| message = resourceManager.getString( |
| "controls", "wrongName"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| |
| // add cue point to cue point array |
| var index:Number; |
| copy.type = "actionscript"; |
| if (cuePoints == null || cuePoints.length < 1) |
| { |
| index = 0; |
| cuePoints = []; |
| cuePoints.push(copy); |
| } |
| else |
| { |
| index = getCuePointIndex(cuePoints, true, copy.time, null, 0, 0); |
| index = (cuePoints[index].time > copy.time) ? 0 : index + 1; |
| cuePoints.splice(index, 0, copy); |
| } |
| |
| // adjust _cuePointIndex |
| var now:Number = _owner.playheadTime; |
| if (now > 0) |
| { |
| if (_cuePointIndex == index) |
| { |
| if (now > cuePoints[index].time) |
| { |
| _cuePointIndex++; |
| } |
| } |
| else if (_cuePointIndex > index) |
| { |
| _cuePointIndex++; |
| } |
| } |
| else |
| { |
| _cuePointIndex = 0; |
| } |
| |
| // return the cue point |
| var returnObject:Object = deepCopyObject(cuePoints[index]); |
| returnObject.array = cuePoints; |
| returnObject.index = index; |
| videoDisplay.dispatchEvent(new Event("cuePointsChanged")); |
| return returnObject; |
| } |
| |
| /** |
| * Removes a cue point from the currently |
| * loaded FLV file. Only the <code>name</code> and <code>time</code> |
| * properties are used from the <code>cuePoint</code> argument to |
| * determine the cue point to be removed. |
| * |
| * <p>If multiple cue points match the search criteria, only |
| * one will be removed. To remove all cue points, call this function |
| * repeatedly in a loop with the same arguments until it returns |
| * <code>null</code>.</p> |
| * |
| * @param cuePoint The Object must contain at least one of |
| * <code>name:String</code> and <code>time:Number</code> properties, and |
| * removes the cue point that matches the specified properties. |
| * |
| * @return An object representing the cue point removed. If there was no |
| * matching cue point, then it returns <code>null</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function removeCuePoint(cuePoint:Object):Object |
| { |
| // bail if no cue points |
| if (cuePoints == null || cuePoints.length < 1) |
| return null; |
| |
| // remove cue point from cue point array |
| var index:Number = getCuePointIndex(cuePoints, false, cuePoint.time, cuePoint.name, 0, 0); |
| if (index < 0) |
| return null; |
| |
| cuePoint = cuePoints[index]; |
| cuePoints.splice(index, 1); |
| |
| // adjust _cuePointIndex |
| if (_owner.playheadTime > 0) |
| { |
| if (_cuePointIndex > index) |
| { |
| _cuePointIndex--; |
| } |
| } |
| else |
| { |
| _cuePointIndex = 0; |
| } |
| |
| videoDisplay.dispatchEvent(new Event("cuePointsChanged")); |
| // return the cue point |
| return cuePoint; |
| } |
| |
| /** |
| * @private |
| * removes enabled cue points from _disabledCuePoints |
| */ |
| private function removeCuePoints(cuePointArray:Array, cuePoint:Object):Number |
| { |
| var matchIndex:Number; |
| var matchCuePoint:Object; |
| var numChanged:Number = 0; |
| for (matchIndex = getCuePointIndex(cuePointArray, true, -1, cuePoint.name, 0, 0); matchIndex >= 0; |
| matchIndex = getNextCuePointIndexWithName(matchCuePoint.name, cuePointArray, matchIndex)) |
| { |
| // remove match |
| matchCuePoint = cuePointArray[matchIndex]; |
| cuePointArray.splice(matchIndex, 1); |
| matchIndex--; |
| numChanged++; |
| } |
| return numChanged; |
| } |
| |
| /** |
| * @private |
| * inserts cue points into array |
| */ |
| private function insertCuePoint(insertIndex:Number, cuePointArray:Array, cuePoint:Object):Array |
| { |
| if (insertIndex < 0) |
| { |
| cuePointArray = []; |
| cuePointArray.push(cuePoint); |
| } |
| else |
| { |
| // find insertion point |
| if (cuePointArray[insertIndex].time > cuePoint.time) |
| { |
| insertIndex = 0; |
| } |
| else |
| { |
| insertIndex++; |
| } |
| // insert into sorted cuePointArray |
| cuePointArray.splice(insertIndex, 0, cuePoint); |
| } |
| return cuePointArray; |
| } |
| |
| // |
| // package internal methods, called by FLVPlayback |
| // |
| |
| /** |
| * @private |
| * <p>Called by FLVPlayback on "playheadUpdate" event |
| * to throw "cuePoint" events when appropriate.</p> |
| */ |
| mx_internal function dispatchCuePoints():void |
| { |
| var now:Number = _owner.playheadTime; |
| if (_owner.stateResponsive && cuePoints != null) |
| { |
| while (_cuePointIndex < cuePoints.length && |
| cuePoints[_cuePointIndex].time <= now + _cuePointTolerance) |
| { |
| var metadataEvent:MetadataEvent = |
| new MetadataEvent(MetadataEvent.CUE_POINT); |
| metadataEvent.info = deepCopyObject(cuePoints[_cuePointIndex++]); |
| _owner.dispatchEvent(metadataEvent); |
| } |
| } |
| } |
| |
| /** |
| * @private |
| * When our place in the stream is changed, this is called |
| * to reset our index into actionscript cue point array. |
| * Another method is used when cue points are added |
| * are removed. |
| */ |
| mx_internal function resetCuePointIndex(time:Number):void |
| { |
| if (time <= 0 || cuePoints == null) |
| { |
| _cuePointIndex = 0; |
| return; |
| } |
| var index:Number = getCuePointIndex(cuePoints, true, time, null, 0, 0); |
| _cuePointIndex = (cuePoints[index].time < time) ? index + 1 : index; |
| } |
| |
| /** |
| * @private |
| * Search for a cue point in an array sorted by time. See |
| * closeIsOK parameter for search rules. |
| * |
| * @param cuePointArray array to search |
| * @param closeIsOK If true, the behavior differs depending on the |
| * parameters passed in: |
| * |
| * <ul> |
| * |
| * <li>If name is null or undefined, then if the specific time is |
| * not found then the closest time earlier than that is returned. |
| * If there is no cue point earlier than time, the first cue point |
| * is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 then the first |
| * cue point with the given name is returned.</li> |
| * |
| * <li>If time and name are both defined then the closest cue |
| * point, then if the specific time and name is not found then the |
| * closest time earlier than that with that name is returned. If |
| * there is no cue point with that name and with an earlier time, |
| * then the first cue point with that name is returned. If there |
| * is no cue point with that name, null is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 and name is null |
| * or undefined, a VideoError is thrown.</li> |
| * |
| * </ul> |
| * |
| * <p>If closeIsOK is false the behavior is:</p> |
| * |
| * <ul> |
| * |
| * <li>If name is null or undefined and there is a cue point with |
| * exactly that time, it is returned. Otherwise null is |
| * returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 then the first |
| * cue point with the given name is returned.</li> |
| * |
| * <li>If time and name are both defined and there is a cue point |
| * with exactly that time and name, it is returned. Otherwise null |
| * is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 and name is null |
| * or undefined, a VideoError is thrown.</li> |
| * |
| * </ul> |
| * @param time search criteria |
| * @param name search criteria |
| * @param start index of first item to be searched, used for |
| * recursive implementation, defaults to 0 if undefined |
| * @param len length of array to search, used for recursive |
| * implementation, defaults to cuePointArray.length if undefined |
| * @returns index for cue point in given array or -1 if no match found |
| * @throws VideoError if time and/or name parameters are bad |
| * @see #cuePointCompare() |
| */ |
| private function getCuePointIndex(cuePointArray:Array, closeIsOK:Boolean, |
| time:Number, name:String, |
| start:Number, len:Number):Number |
| { |
| // sanity checks |
| if (cuePointArray == null || cuePointArray.length < 1) |
| return -1; |
| |
| var timeUndefined:Boolean = (isNaN(time) || time < 0); |
| if (timeUndefined && !name) |
| { |
| var message:String = resourceManager.getString( |
| "controls", "wrongTimeName"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| |
| if (len == 0) len = cuePointArray.length; |
| |
| // name is passed in and time is undefined or closeIsOK is |
| // true, search for first name starting at either start |
| // parameter index or index at or after passed in time, respectively |
| if (name && (closeIsOK || timeUndefined)) |
| { |
| var firstIndex:Number; |
| var index:Number; |
| if (timeUndefined) |
| firstIndex = start; |
| else |
| firstIndex = getCuePointIndex(cuePointArray, closeIsOK, time, null, 0, 0); |
| for (index = firstIndex; index >= start; index--) |
| if (cuePointArray[index].name == name) |
| break; |
| if (index >= start) |
| return index; |
| for (index = firstIndex + 1; index < len; index++) |
| if (cuePointArray[index].name == name) |
| break; |
| if (index < len) |
| return index; |
| return -1; |
| } |
| |
| var result:Number; |
| |
| // iteratively check if short length |
| if (len <= _linearSearchTolerance) |
| { |
| var max:Number = start + len; |
| for (var i:uint = start; i < max; i++) |
| { |
| result = cuePointCompare(time, name, cuePointArray[i]); |
| if (result == 0) |
| return i; |
| if (result < 0) break; |
| } |
| if (closeIsOK) |
| { |
| if (i > 0) |
| return i - 1; |
| return 0; |
| } |
| return -1; |
| } |
| |
| // split list and recurse |
| var halfLen:Number = Math.floor(len / 2); |
| var checkIndex:Number = start + halfLen; |
| result = cuePointCompare(time, name, cuePointArray[checkIndex]); |
| if (result < 0) |
| return getCuePointIndex(cuePointArray, closeIsOK, time, name, |
| start, halfLen); |
| if (result > 0) |
| return getCuePointIndex(cuePointArray, closeIsOK, time, name, |
| checkIndex + 1, halfLen - 1 + (len % 2)); |
| return checkIndex; |
| } |
| |
| /** |
| * @private |
| * <p>Given a name, array and index, returns the next cue point in |
| * that array after given index with the same name. Returns null |
| * if no cue point after that one with that name. Throws |
| * VideoError if argument is invalid.</p> |
| * |
| * @returns index for cue point in given array or -1 if no match found |
| */ |
| private function getNextCuePointIndexWithName(name:String, array:Array, index:Number):Number |
| { |
| var message:String; |
| |
| // sanity checks |
| if (!name) |
| { |
| message = resourceManager.getString( |
| "controls", "wrongName"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| if (!array) |
| { |
| message = resourceManager.getString( |
| "controls", "undefinedArray"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| if (isNaN(index) || index < -1 || index >= array.length) |
| { |
| message = resourceManager.getString( |
| "controls", "wrongIndex"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| |
| // find it |
| var i:int; |
| for (i = index + 1; i < array.length; i++) |
| if (array[i].name == name) |
| break; |
| if (i < array.length) |
| return i; |
| return -1; |
| } |
| |
| /** |
| * @private |
| * Takes two cue point Objects and returns -1 if first sorts |
| * before second, 1 if second sorts before first and 0 if they are |
| * equal. First compares times with millisecond precision. If |
| * they match, compares name if name parameter is not null or undefined. |
| */ |
| private static function cuePointCompare(time:Number, name:String, cuePoint:Object):Number |
| { |
| var compTime1:Number = Math.round(time * 1000); |
| var compTime2:Number = Math.round(cuePoint.time * 1000); |
| if (compTime1 < compTime2) return -1; |
| if (compTime1 > compTime2) return 1; |
| if (name != null) |
| { |
| if (name == cuePoint.name) return 0; |
| if (name < cuePoint.name) return -1; |
| return 1; |
| } |
| return 0; |
| } |
| |
| /** |
| * @private |
| * |
| * <p>Search for a cue point in the given array at the given time |
| * and/or with given name.</p> |
| * |
| * @param closeIsOK If true, the behavior differs depending on the |
| * parameters passed in: |
| * |
| * <ul> |
| * |
| * <li>If name is null or undefined, then if the specific time is |
| * not found then the closest time earlier than that is returned. |
| * If there is no cue point earlier than time, the first cue point |
| * is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 then the first |
| * cue point with the given name is returned.</li> |
| * |
| * <li>If time and name are both defined then the closest cue |
| * point, then if the specific time and name is not found then the |
| * closest time earlier than that with that name is returned. If |
| * there is no cue point with that name and with an earlier time, |
| * then the first cue point with that name is returned. If there |
| * is no cue point with that name, null is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 and name is null |
| * or undefined, a VideoError is thrown.</li> |
| * |
| * </ul> |
| * |
| * <p>If closeIsOK is false the behavior is:</p> |
| * |
| * <ul> |
| * |
| * <li>If name is null or undefined and there is a cue point with |
| * exactly that time, it is returned. Otherwise null is |
| * returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 then the first |
| * cue point with the given name is returned.</li> |
| * |
| * <li>If time and name are both defined and there is a cue point |
| * with exactly that time and name, it is returned. Otherwise null |
| * is returned.</li> |
| * |
| * <li>If time is null, undefined or less than 0 and name is null |
| * or undefined, a VideoError is thrown.</li> |
| * |
| * </ul> |
| * @param timeOrCuePoint If String, then name for search. If |
| * Number, then time for search. If Object, then cuepoint object |
| * containing time and/or name parameters for search. |
| * @returns <code>null</code> if no match was found, otherwise |
| * copy of cuePoint object with additional properties: |
| * |
| * <ul> |
| * |
| * <li><code>array</code> - the array that was searched. Treat |
| * this array as read only as adding, removing or editing objects |
| * within it can cause cue points to malfunction.</li> |
| * |
| * <li><code>index</code> - the index into the array for the |
| * returned cuepoint.</li> |
| * |
| * </ul> |
| * @see #getCuePointIndex() |
| */ |
| private function getCuePoint(cuePointArray:Array, closeIsOK:Boolean, |
| timeNameOrCuePoint:Object = null):Object |
| { |
| var cuePoint:Object; |
| switch (typeof(timeNameOrCuePoint)) |
| { |
| case "string": |
| cuePoint = {name:timeNameOrCuePoint}; |
| break; |
| case "number": |
| cuePoint = {time:timeNameOrCuePoint}; |
| break; |
| case "object": |
| cuePoint = timeNameOrCuePoint; |
| break; |
| } // switch |
| var index:Number = getCuePointIndex(cuePointArray, closeIsOK, cuePoint.time, cuePoint.name, 0, 0); |
| if (index < 0) return null; |
| cuePoint = deepCopyObject(cuePointArray[index]); |
| cuePoint.array = cuePointArray; |
| cuePoint.index = index; |
| return cuePoint; |
| } |
| |
| /** |
| * @private |
| * <p>Given a cue point object returned from getCuePoint (needs |
| * the index and array properties added to those cue points), |
| * returns the next cue point in that array after that one with |
| * the same name. Returns null if no cue point after that one |
| * with that name. Throws VideoError if argument is invalid.</p> |
| * |
| * @returns <code>null</code> if no match was found, otherwise |
| * copy of cuePoint object with additional properties: |
| * |
| * <ul> |
| * |
| * <li><code>array</code> - the array that was searched. Treat |
| * this array as read only as adding, removing or editing objects |
| * within it can cause cue points to malfunction.</li> |
| * |
| * <li><code>index</code> - the index into the array for the |
| * returned cuepoint.</li> |
| * |
| * </ul> |
| */ |
| private function getNextCuePointWithName(cuePoint:Object):Object |
| { |
| var message:String; |
| |
| // sanity checks |
| if (!cuePoint) |
| { |
| message = resourceManager.getString( |
| "controls", "undefinedParameter"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| if (isNaN(cuePoint.time) || cuePoint.time < 0) |
| { |
| message = resourceManager.getString( |
| "controls", "wrongTime"); |
| throw new VideoError(VideoError.ILLEGAL_CUE_POINT, message); |
| } |
| |
| // get index |
| var index:Number = getNextCuePointIndexWithName(cuePoint.name, cuePoint.array, cuePoint.index); |
| if (index < 0) |
| return null; |
| |
| // return copy |
| var returnCuePoint:Object = deepCopyObject(cuePoint.array[index]); |
| returnCuePoint.array = cuePoint.array; |
| returnCuePoint.index = index; |
| return returnCuePoint; |
| } |
| |
| /** |
| * Search for a cue point with specified name. |
| * |
| * @param name The name of the cue point. |
| * |
| * @return <code>null</code> if no match was found, or |
| * a copy of the matching cue point Object with additional properties: |
| * |
| * <ul> |
| * <li><code>array</code> - the Array of cue points searched. Treat |
| * this array as read only because adding, removing or editing objects |
| * within it can cause cue points to malfunction.</li> |
| * |
| * <li><code>index</code> - the index into the Array for the |
| * returned cue point.</li> |
| * </ul> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getCuePointByName(name:String):Object |
| { |
| return getCuePoint(cuePoints, false, name); |
| } |
| |
| /** |
| * Returns an Array of all cue points. |
| * |
| * @return An Array of cue point objects. |
| * Each cue point object describes the cue |
| * point, and contains the properties <code>name:String</code> |
| * and <code>time:Number</code> (in seconds). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getCuePoints():Array |
| { |
| return cuePoints; |
| } |
| |
| /** |
| * Removes all cue points. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function removeAllCuePoints():void |
| { |
| cuePoints = null; |
| videoDisplay.dispatchEvent(new Event("cuePointsChanged")); |
| } |
| |
| /** |
| * Set the array of cue points. |
| * |
| * <p>You can add multiple cue points with the same |
| * name and time. When you call the <code>removeCuePoint()</code> method |
| * with this name, only the first one is removed.</p> |
| * |
| * @param cuePointArray An Array of cue point objects. |
| * Each cue point object describes the cue |
| * point. It must contain the properties <code>name:String</code> |
| * and <code>time:Number</code> (in seconds). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setCuePoints(cuePointArray:Array):void |
| { |
| // sanity checks |
| if (cuePointArray == null) |
| return; |
| for (var index:uint = 0; index < cuePointArray.length; index++) |
| { |
| addCuePoint(cuePointArray[index]); |
| } |
| } |
| |
| /** |
| * @private |
| * Used to make copies of cue point objects. |
| */ |
| private static function deepCopyObject(obj:Object, recurseLevel:Number = 0):Object |
| { |
| if (obj == null || typeof(obj) != "object") return obj; |
| if (isNaN(recurseLevel)) recurseLevel = 0; |
| var newObj:Object = {}; |
| for (var i:Object in obj) |
| { |
| if (recurseLevel == 0 && (i == "array" || i == "index")) |
| { |
| // skip it |
| } |
| else if (typeof(obj[i]) == "object") |
| { |
| newObj[i] = deepCopyObject(obj[i], recurseLevel+1); |
| } |
| else |
| { |
| newObj[i] = obj[i]; |
| } |
| } |
| return newObj; |
| } |
| |
| } // class mx.controls.videoClasses.CuePointManager |
| |
| } |