//**************************************************************************** //Copyright (C) 2004-2005 Macromedia, Inc. All Rights Reserved. //The following is Sample Code and is subject to all restrictions on //such code as contained in the End User License Agreement accompanying //this product. //**************************************************************************** import mx.events.EventDispatcher; import mx.utils.Delegate; import mx.video.*; /** *

Event dispatched when FLVPlayback.BUFFERING state * entered. This state is typically entered immediately after * play() is called or the corresponding control is * clicked, before the playing state is entered. Event Object has * properties state and playheadTime.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* *

"stateChange" event will also be dispatched.

* * @see #BUFFERING * @see #play() * @tiptext buffering event * @helpid ??? */ [Event("buffering")] /** *

Event dispatched when NetConnection is closed, * whether by being timed out or by calling close() * API. Only ever dispatched when streaming from FCS or FVSS. * Event Object has properties state and playheadTime.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @tiptext close event * @helpid 3482 */ [Event("close")] /** *

Event dispatched when playing completes by reaching the end of * the FLV. Is not dispatched if the APIs stop() or * pause() are called or the corresponding controls are * clicked. Event Object has properties state and playheadTime.

* *

When using progressive download and not setting totalTime * explicitly and downloading an FLV with no metadata duration, * the totalTime will be set to an approximate total value, now * that we have played the whole file we can make a guess. That * value is set by the time this event is dispatched.

* *

"stateChange" and "stopped" events will also be dispatched.

* * @tiptext complete event * @helpid 3482 */ [Event("complete")] /** *

Event dispatched when a cue point is reached. Event Object has an * info property that contains the info object received by the * NetStream.onCuePoint callback for FLV cue points or * the object passed into the AS cue point APIs for AS cue points.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @tiptext cuePoint event * @helpid 3483 */ [Event("cuePoint")] /** *

Event dispatched when location of playhead is moved forwards by a call * to seek(). The playheadTime property * will reflect the destination time. Event Object has properties state and * playheadTime.

* *

"seek" will be dispatched. "playheadUpdate" will be * dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #seek() * @tiptext fastForward event * @helpid ??? */ [Event("fastForward")] /** *

Event dispatched the first time the FLV metadata is reached. * Event Object has an info property that contains the info object * received by the NetStream.onMetaData callback.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @tiptext metadataReceived event */ [Event("metadataReceived")] /** *

Event dispatched when pause state entered. This happens when the * pause() API is called or the correpsonding control is * clicked and also happens in some cases when the FLV is loaded if * autoPlay is false (state may go to stopped instead). Event Object has * properties state and playheadTime.

* *

"stateChange" event will also be dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #PAUSED * @see #pause() * @tiptext paused event * @helpid 3489 */ [Event("paused")] /** *

Event dispatched when play state entered. This may not occur * immediately after the play() API is called or * corresponding control is clicked; often the buffering state is * entered first, and then playing. Event Object has properties state and * playheadTime.

* *

"stateChange" event will also be dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #PLAYING * @see #play() * @tiptext playing event * @helpid ??? */ [Event("playing")] /** *

While FLV is playing, this event is dispatched every .25 * seconds. Not dispatched when we are paused or stopped, unless a * seek occurs. Event Object has properties state and playheadTime.

* * @tiptext change event * @helpid 3480 */ [Event("playheadUpdate")] /** *

Indicates progress made in number of bytes downloaded. User can * use this to check bytes loaded or number of bytes in the buffer. * Fires every .25 seconds, starting when load is called and ending * when all bytes are loaded or if there is a network error. Event Object is * of type mx.events.ProgressEvent.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @tiptext progress event * @helpid 3485 */ [Event("progress")] /** *

Event dispatched when FLV is loaded and ready to display. Event * object has properties state and playheadTime.

* *

Fired the first time we enter a responsive state after we * load a new flv with play() or load() API. Only fires once * for each FLV loaded.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

*/ [Event("ready")] /** *

Event dispatched when video is resized. Event Object has * properties x, y, width, height, auto and vp, index number of * VideoPlayer to which this event applies. See activeVideoPlayerIndex and * visibleVideoPlayerIndex.

* *

Auto is true when resize is automatic due to maintainAspectRatio * or autoSize set to true. In this case, the event may be firing for * a VideoPlayer other than the visible VideoPlayer. May be * dispatched even if the dimensions were not actually changed after * an attempt to autoresize occurs.

* *

When auto is false, the event always applies to the visible * VideoPlayer. The vp property still appears, but will always be * equal to visibleVideoPlayerIndex.

* *

Will be triggered (with auto = fals) when setting * visibleVideoPlayerIndex if switching to a player with different * dimensions than the currently visible player.

* * @tiptext resize event * @helpid ???? */ [Event("resize")] /** *

Event dispatched when location of playhead is moved backward by * a call to seek() or when the an autoRewind is * completed. The playheadTime property will reflect the * destination time. Event Object has properties auto, state and * playheadTime. Property auto is true if event was triggered by * autoRewind, false otherwise.

* *

"stateChange" event will be dispatched with a state of * FLVPlayback.REWINDING when the autoRewind is * triggered; this event will not fire until it has completed. * "seek" will be dispatched when there is a seek. "playheadUpdate" * will be dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #REWINDING * @see #autoRewind * @see #seek() * @tiptext rewind event * @helpid ??? */ [Event("rewind")] /** *

Event dispatched when user finishes scrubbing timeline with * seekbar. Event object has properties state and playheadTime.

* *

Event "stateChange" will also be dispatched with new state * (should be PLAYING, PAUSED, STOPPED or BUFFERING). State will * be SEEKING until user finishes scrubbing.

*/ [Event("scrubFinish")] /** *

Event dispatched when user starts scrubbing timeline with * seekbar. Event object has properties state and playheadTime.

* *

Event "stateChange" will also be dispatched with state * SEEKING. State will remain SEEKING * while user is scrubbing.

*/ [Event("scrubStart")] /** *

Event dispatched when location of playhead is changed by a call to * seek() or by using the corresponding control. The * playheadTime property will reflect the destination * time. Event Object has properties state and playheadTime.

* *

"stateChange" event also may be dispatched, but may not. * "rewind" will be dispatched when the seek is backwards and * "fastForward" will be dispatched when the seek is forwards. * "playheadUpdate" will be dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #seek() * @tiptext seek event * @helpid ??? */ [Event("seek")] /** *

Event dispatched when error occurs loading skin swf. Has * message property with error message. If a skin swf is set, * playback will not begin until "ready" event and "skinLoaded" (or * "skinError") event have both fired.

* * @see #skin */ [Event("skinError")] /** *

Event dispatched when skin swf is loaded. No properties (other * than normal target property). If a skin swf is set, playback will * not begin until "ready" event and "skinLoaded" (or "skinError") * event have both fired.

* * @see #skin */ [Event("skinLoaded")] /** *

Event dispatched when playback state changes. Event Object has * properties state and playheadTime.

* *

This event can be used to track when playback enters/leaves * unresponsive states (for example in the middle of connecting, * resizing or rewinding) during which times APIs play(), * pause(), stop() and seek() * will queue the requests to be executed when the player enters * a responsive state.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #state */ [Event("stateChange")] /** *

Event dispatched when FLVPlayback.STOPPED state entered. * This happens when the stop() API is called or the * corresponding control is clicked and also happens in some cases * when the FLV is loaded if autoPlay is false (state may go to paused * instead). The event is also dispatched when the playhead stops * because it has reached the end of the timeline. Event Object has * properties state and playheadTime.

* *

"stateChange" event will also be dispatched.

* *

Event has property vp, index number of VideoPlayer to which this * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.

* * @see #STOPPED * @see #stop() * @tiptext stopped event * @helpid 3487 */ [Event("stopped")] /** *

Event dispatched when volume is changed by changing * volume property (a.k.a. by user). * Event Object has a volume property.

* * @tiptext volumeUpdate event * @helpid 3486 */ [Event("volumeUpdate")] [IconFile("FLVPlayback.png")] [minimumPlayerVersion("8")] [RequiresDataBinding(true)] [LivePreviewVersion("1")] /** *

FLVPlayback extends MovieClip and wraps a VideoPlayer object. * It also "extends" EventDispatcher using mixins.

* * @author copyright 2004-2005 Macromedia, Inc. * @tiptext FLVPlayback * @helpid ??? */ class mx.video.FLVPlayback extends MovieClip { #include "ComponentVersion.as" // // public state constants // /** *

State constant. This is the state when the VideoPlayer is * constructed and when the stream is closed by a call to * close() or timed out on idle.

* *

This is a responsive state.

* * @see #state * @see #stateResponsive * @see #idleTimeout * @see #closeVideoPlayer() */ public static var DISCONNECTED:String = "disconnected"; /** *

State constant. FLV is loaded and play is stopped. This state * is entered when stop() is called and when the * playhead reaches the end of the stream.

* *

This is a responsive state.

* * @see #state * @see #stateResponsive * @see #stopped * @see #stop() */ public static var STOPPED:String = "stopped"; /** *

State constant. FLV is loaded and is playing. * This state is entered when play() * is called.

* *

This is a responsive state.

* * @see #playing * @see #state * @see #stateResponsive * @see #play() */ public static var PLAYING:String = "playing"; /** *

State constant. FLV is loaded, but play is paused. * This state is entered when pause() is * called or when load() is called.

* *

This is a responsive state.

* * @see #paused * @see #state * @see #stateResponsive * @see #pause() * @see #load() */ public static var PAUSED:String = "paused"; /** *

State constant. State entered immediately after * play() or load() is called.

* *

This is a responsive state.

* * @see #buffering * @see #state * @see #stateResponsive */ public static var BUFFERING:String = "buffering"; /** *

State constant. State entered immediately after * play() or load() is called or * after contentPath property is set.

* *

This is a unresponsive state.

* * @see #contentPath * @see #state * @see #stateResponsive * @see #load() * @see #play() */ public static var LOADING:String = "loading"; /** *

State constant. Stream attempted to load was unable to load * for some reason. Could be no connection to server, stream not * found, etc.

* *

This is a unresponsive state.

* * @see #state * @see #stateResponsive */ public static var CONNECTION_ERROR:String = "connectionError"; /** *

State constant. State entered during a autorewind triggered * by a stop. After rewind is complete, the state will be * STOPPED.

* *

This is a unresponsive state.

* * @see #autoRewind * @see #state * @see #stateResponsive */ public static var REWINDING:String = "rewinding"; /** *

State constant. State entered after seek() * is called and also while user is scrubbing with seek bar.

* *

This is a unresponsive state.

* * @see #stateResponsive * @see #state * @see #seek() */ public static var SEEKING:String = "seeking"; /** * Constant passed into findCuePoint or findNearestCuePoint type parameter. */ public static var ALL = "all"; /** * Constant passed into findCuePoint or findNearestCuePoint type parameter. */ public static var EVENT = "event"; /** * Constant passed into findCuePoint or findNearestCuePoint type parameter. */ public static var NAVIGATION = "navigation"; /** * Constant passed into findCuePoint or findNearestCuePoint type parameter. */ public static var FLV = "flv"; /** * Constant passed into findCuePoint or findNearestCuePoint type parameter. */ public static var ACTIONSCRIPT = "actionscript"; // // private instance vars // /** * bounding box movie clip inside of component on stage * * @private */ public var boundingBox_mc:MovieClip; // live preview movie clip private var preview_mc:MovieClip; // the VideoPlayers private var _vp:Array; var _vpState:Array; private var _activeVP:Number; private var _visibleVP:Number; private var _topVP:Number; private static var VP_DEPTH_OFFSET:Number = 100; // the UIManager private var _uiMgr:UIManager; // the CuePointManagers (one for each VideoPlayer) private var _cpMgr:Array; // state private var _preSeekTime:Number; private var _firstStreamReady:Boolean; private var _firstStreamShown:Boolean; // true once we have shown the first stream private var _prevWidth:Number; private var _prevHeight:Number; // properties private var _autoPlay:Boolean; private var _autoRewind:Boolean; private var _autoSize:Boolean; private var _bufferTime:Number; private var _contentPath:String; private var _cuePoints:Array; private var _idleTimeout:Number; private var _isLive:Boolean; private var _aspectRatio:Boolean; private var _playheadUpdateInterval:Number; private var _progressInterval:Number; private var _origWidth:Number; private var _origHeight:Number; private var _scaleX:Number; private var _scaleY:Number; private var _seekToPrevOffset:Number; private var _totalTime:Number; private var _transform:Object; private var _volume:Number; private var __height:Number; private var __width:Number; // cache properties set directly on UIManager private var _backButton:MovieClip; private var _bufferingBar:MovieClip; private var _bufferingBarHides:Boolean; private var _forwardButton:MovieClip; private var _pauseButton:MovieClip; private var _playButton:MovieClip; private var _playPauseButton:MovieClip; private var _seekBar:MovieClip; private var _seekBarInterval:Number; private var _seekBarScrubTolerance:Number; private var _skin:String; private var _skinAutoHide:Boolean; private var _stopButton:MovieClip; private var _muteButton:MovieClip; private var _volumeBar:MovieClip; private var _volumeBarInterval:Number; private var _volumeBarScrubTolerance:Number; // EventDispatcher mixins public var addEventListener:Function; public var removeEventListener:Function; public var dispatchEvent:Function; public var dispatchQueue:Function; // this line forces compilation of the NCManager private var __forceNCMgr:NCManager; //ifdef DEBUG ///** // * @private // */ //var _debuggingOn:Boolean = false; ///** // * @private // */ //var _debugFn:Function = null; //endif // when seekToPrevNavCuePoint compares its time against the // previous cue point, it uses this delta to be sure that if // you are just ahead of a cue point, you can hop over it to // the previous and not get stuck going to the same one over // and over if you are playing. In seconds private static var SEEK_TO_PREV_OFFSET_DEFAULT:Number = 1; // // public methods // /** * constructor */ public function FLVPlayback() { // add EventDispatcher mixins EventDispatcher.initialize(this); // set properties to defaults note that these faults are // in line with the VideoPlayer defaults, so they do not // have to be set on the VideoPlayer object as well. if (_autoPlay == undefined) _autoPlay = true; if (_autoRewind == undefined) _autoRewind = true; if (_autoSize == undefined) _autoSize = false; if (_bufferTime == undefined) _bufferTime = 0.1; if (_contentPath == undefined) _contentPath = ""; if (_cuePoints == undefined) _cuePoints = null; if (_idleTimeout == undefined) _idleTimeout = VideoPlayer.DEFAULT_IDLE_TIMEOUT_INTERVAL; if (_isLive == undefined) _isLive = false; if (_aspectRatio == undefined) _aspectRatio = true; if (_seekToPrevOffset == undefined) _seekToPrevOffset = SEEK_TO_PREV_OFFSET_DEFAULT; if (_playheadUpdateInterval == undefined) _playheadUpdateInterval = VideoPlayer.DEFAULT_UPDATE_PROGRESS_INTERVAL; if (_progressInterval == undefined) _progressInterval = VideoPlayer.DEFAULT_UPDATE_TIME_INTERVAL if (_totalTime == undefined) _totalTime = 0; if (_transform == undefined) _transform = null; if (_volume == undefined) _volume = 100; if (_skinAutoHide == undefined) _skinAutoHide = false; if (_bufferingBarHides == undefined) _bufferingBarHides = false; // have to manage our own height and width and set scale // to 100 otherwise VideoPlayer and skins within component // will be scaled. _origHeight =_prevHeight = __height = this._height; _origWidth = _prevWidth = __width = this._width; _scaleX = 100; _scaleY = 100; this._xscale = 100; this._yscale = 100; // state _preSeekTime = -1; _firstStreamReady = false; _firstStreamShown = false; // create UIManager createUIManager(); // create VideoPlayer and CuePointManager _activeVP = 0; _visibleVP = 0; _topVP = 0; _vp = new Array(); _vpState = new Array(); _cpMgr = new Array(); createVideoPlayer(0); // hide until skin and stream ready _vp[0].visible = false; _vp[0].volume = 0; // remove boundingBox_mc boundingBox_mc._visible = false; boundingBox_mc.unloadMovie(); delete boundingBox_mc; // setup live preview look if (_global.isLivePreview) { createLivePreviewMovieClip(); setSize(__width, __height); } // if cuePoints property set, add and disable now that CuePointManager is created _cpMgr[0].processCuePointsProperty(_cuePoints); delete _cuePoints; _cuePoints = null; } /** *

set width and height simultaneously. Since setting either * one can trigger an autoresize, this can be better than invoking * set width and set height individually.

* *

If autoSize is true then this has no effect, since the player * sets its own dimensions. If maintainAspectRatio is true and * autoSize is false, then changing width or height will trigger * an autoresize.

* * @param width * @param height * @see width * @see height */ public function setSize(w:Number, h:Number):Void { if (_global.isLivePreview) { if (preview_mc == undefined) createLivePreviewMovieClip(); preview_mc.box_mc._width = w; preview_mc.box_mc._height = h; if ( preview_mc.box_mc._width < preview_mc.icon_mc._width || preview_mc.box_mc._height < preview_mc.icon_mc._height ) { preview_mc.icon_mc._visible = false; } else { preview_mc.icon_mc._visible = true; preview_mc.icon_mc._x = (preview_mc.box_mc._width - preview_mc.icon_mc._width) / 2; preview_mc.icon_mc._y = (preview_mc.box_mc._height - preview_mc.icon_mc._height) / 2; } } if (w == width && h == height) return; _prevWidth = __width = w; _prevHeight = __height = h; for (var i:Number = 0; i < _vp.length; i++) { if (_vp[i] != undefined) { _vp[i].setSize(w, h); } } dispatchEvent({type:"resize", x:this.x, y:this.y, width:w, height:h}); } /** *

set scaleX and scaleY simultaneously. Since setting either * one can trigger an autoresize, this can be better than invoking * set width and set height individually.

* *

If autoSize is true then this has no effect, since the player * sets its own dimensions. If maintainAspectRatio is true and * autoSize is false, then changing scaleX or scaleY will trigger an * autoresize.

* * @param scaleX * @param scaleY * @see scaleX * @see scaleY */ public function setScale(xs:Number, ys:Number) { if (xs == scaleX && ys == scaleY) return; _scaleX = xs; _scaleY = ys; for (var i:Number = 0; i < _vp.length; i++) { if (_vp[i] != undefined) { _vp[i].setSize(_origWidth * xs / 100, _origHeight * ys / 100); } } dispatchEvent({type:"resize", x:this.x, y:this.y, width:this.width, height:this.height}); } /** * Sets scaleX and scaleY simultaneously. * * @private */ private function handleEvent(e:Object):Void { var eventState:String = e.state; if (e.state != undefined && e.target._name == _visibleVP && scrubbing) { eventState = SEEKING; } if (e.type == "metadataReceived") { _cpMgr[e.target._name].processFLVCuePoints(e.info.cuePoints); dispatchEvent({type:e.type, info:e.info, vp:e.target._name}); } else if (e.type == "cuePoint") { if (_cpMgr[e.target._name].isFLVCuePointEnabled(e.info)) { dispatchEvent({type:e.type, info:e.info, vp:e.target._name}); } } else if (e.type == "rewind") { dispatchEvent({type:e.type, auto:true, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); _cpMgr[e.target._name].resetASCuePointIndex(e.playheadTime); } else if (e.type == "resize") { dispatchEvent({type:e.type, x:x, y:y, width:width, height:height, auto:true, vp:e.target._name}); _prevWidth = __width; _prevHeight = __height; } else if (e.type == "playheadUpdate") { dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); if (_preSeekTime >= 0 && e.target.state != SEEKING) { var preSeekTime:Number = _preSeekTime; _preSeekTime = -1; _cpMgr[e.target._name].resetASCuePointIndex(e.playheadTime); dispatchEvent({type:"seek", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); if (preSeekTime < e.playheadTime) { dispatchEvent({type:"fastForward", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); } else if (preSeekTime > e.playheadTime) { dispatchEvent({type:"rewind", auto:false, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); } } _cpMgr[e.target._name].dispatchASCuePoints(); } else if (e.type == "stateChange") { var whichVP:Number = e.target._name; // suppress stateChange events while scrubbing if (whichVP == _visibleVP && scrubbing) return; // suppress RESIZING state, just needed for internal // VideoPlayer use anyways, make it LOADING, less confusing // for user, esp when suppressing STOPPED as we do below... if (e.state == VideoPlayer.RESIZING) return; // suppress STOPPED stateChange at beginning when autoPlay // is on and waiting for skin to download to show all at once if (_vpState[whichVP].prevState == LOADING && _vpState[whichVP].autoPlay && e.state == STOPPED) { return; } _vpState[whichVP].prevState = e.state; dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); // check to be sure did not change out from under me before dispatching second event if (_vp[e.target._name].state != eventState) return; switch (eventState) { case BUFFERING: dispatchEvent({type:"buffering", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); break; case PAUSED: dispatchEvent({type:"paused", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); break; case PLAYING: dispatchEvent({type:"playing", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); break; case STOPPED: dispatchEvent({type:"stopped", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); break; } // switch } else if (e.type == "progress") { dispatchEvent({type:e.type, bytesLoaded:e.bytesLoaded, bytesTotal:e.bytesTotal, vp:e.target._name}); } else if(e.type == "ready") { var whichVP:Number = e.target._name; if (!_firstStreamReady) { if (whichVP == _visibleVP) { _firstStreamReady = true; if (_uiMgr.skinReady && !_firstStreamShown) { _uiMgr.visible = true; showFirstStream(); } } } else if (_firstStreamShown && eventState == STOPPED && _vpState[whichVP].autoPlay) { _vp[whichVP].play(); } dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); } else if (e.type == "close" || e.type == "complete") { dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); } } /** *

Shortcut for setting property autoPlay to false * and setting isLive, totalTime and contentPath properties if * given. If totalTime and/or isLive properties are undefined * then they will not be set. If contentPath is undefined, null * or empty string then this function does nothing.

* * @param contentPath * @param totalTime * @param isLive */ public function load(contentPath:String, totalTime:Number, isLive:Boolean):Void { if (_vp[_activeVP] == undefined) return; if (contentPath == undefined || contentPath == null || contentPath == "") { return; } this.autoPlay = false; if (totalTime != undefined) this.totalTime = totalTime; if (isLive != undefined) this.isLive = isLive; this.contentPath = contentPath; } /** *

play. With no args, just takes FLV from paused or stop * state to play state.

* *

With args, acts as a shortcut for setting property * autoPlay to true and setting isLive, totalTime and * contentPath properties if given. If totalTime and/or isLive * properties are undefined then they will not be set.

* * @param contentPath * @param totalTime * @param isLive */ public function play(contentPath:String, totalTime:Number, isLive:Boolean):Void { if (_vp[_activeVP] == undefined) return; if (contentPath == undefined) { _vp[_activeVP].play(); } else { this.autoPlay = true; if (totalTime != undefined) this.totalTime = totalTime; if (isLive != undefined) this.isLive = isLive; this.contentPath = contentPath; } } /** * pause */ public function pause():Void { if (_vp[_activeVP] == undefined) return; _vp[_activeVP].pause(); } /** * stop */ public function stop():Void { if (_vp[_activeVP] == undefined) return; _vp[_activeVP].stop(); } /** *

Seeks to a given time in the file, given in seconds, * decimal precision up to milliseconds.

* * @throws VideoError if time is < 0 * @see VideoPlayer#seek() */ public function seek(time:Number):Void { if (_vp[_activeVP] == undefined) return; _preSeekTime = playheadTime; _vp[_activeVP].seek(time); } /** *

Same as seek()

* * @see #seek() */ public function seekSeconds(time:Number):Void { seek(time); } /** *

Seeks to a percentage of the way through the file. * Takes a number between 0 and 100.

* * @throws VideoError if percent is invalid or if totalTime is * undefined, null or <= 0 * @see #seek() */ public function seekPercent(percent:Number):Void { if (_vp[_activeVP] == undefined) return; if ( percent < 0 || percent > 100 || _vp[_activeVP].totalTime == undefined || _vp[_activeVP].totalTime == null || _vp[_activeVP].totalTime <= 0 ) { throw new VideoError(VideoError.INVALID_SEEK); } seek(_vp[_activeVP].totalTime * percent / 100); } /** *

Gets the percentage played. * Returns a number between 0 and 100.

* */ public function get playheadPercentage():Number { if ( _vp[_activeVP].totalTime == undefined || _vp[_activeVP].totalTime == null || _vp[_activeVP].totalTime <= 0 ) { return undefined; } return _vp[_activeVP].playheadTime / _vp[_activeVP].totalTime * 100; } /** *

Seeks to a percentage of the way through the file. * Takes a number between 0 and 100.

* * @throws VideoError if percent is invalid or if totalTime is * undefined, null or <= 0 * @see #seek() */ public function set playheadPercentage(percent:Number) { seekPercent(percent); } /** *

Seeks to navigation cue point with the given name at or * after given time. Starts search at time 0 if time is * undefined, null or less than 0. If name is undefined or null, * behaves like seekToNextNavCuePoint().

* * @param timeNameOrCuePoint If String, then name of cue point to * search for. Seeks to first enabled navigation cue point with * this name. * *

If Number, time of cue point to seek to. If only time * given, behaves like seekToNextNavCuePoint

* *

If Object, then cuepoint object containing time and/or name * properties for search. Seek to next cue point with this name * at or after the given time. * @throws VideoError if no cue point that matches criteria is found * @see #seek() * @see #seekToPrevNavCuePoint() * @see #seekToNextNavCuePoint() * @see #findCuePoint() * @see #isFLVCuePointEnabled() */ public function seekToNavCuePoint(timeNameOrCuePoint:Object):Void { var cuePoint:Object; switch (typeof timeNameOrCuePoint) { case "string": cuePoint = {name:timeNameOrCuePoint}; break; case "number": cuePoint = {time:timeNameOrCuePoint}; break; case "object": cuePoint = timeNameOrCuePoint; break; } // switch // just seek to next if no name if ( cuePoint.name == null || cuePoint.name == undefined || typeof cuePoint.name != "string" ) { seekToNextNavCuePoint(cuePoint.time); return; } // get next enabled cue point with this name if (isNaN(cuePoint.time)) cuePoint.time = 0; var navCuePoint:Object = findNearestCuePoint(timeNameOrCuePoint, NAVIGATION); while ( navCuePoint != null && ( navCuePoint.time < cuePoint.time || (!isFLVCuePointEnabled(navCuePoint)) ) ) { navCuePoint = findNextCuePointWithName(navCuePoint); } if (navCuePoint == null) throw new VideoError(VideoError.INVALID_SEEK); seek(navCuePoint.time); } /** *

Seeks to next navigation cue point, based on current * playheadTime. Goes to the end if there is no next cue * point. Navigation cue points disabled by ActionScript * will be skipped.

* * @param time starting time from where to look for next * navigation cue point. Default is current playheadTime * @see #cuePoints * @see #seek() * @see #seekToNavCuePoint() * @see #seekToPrevNavCuePoint() * @see #findCuePoint() * @see #isFLVCuePointEnabled() */ public function seekToNextNavCuePoint(time:Number):Void { if (_vp[_activeVP] == undefined) return; if (isNaN(time) || time < 0) { time = _vp[_activeVP].playheadTime + 0.001; } var cuePoint:Object; cuePoint = findNearestCuePoint(time, NAVIGATION); if (cuePoint == null) { //if no cue points could be found, go to the end seek(_vp[_activeVP].totalTime); return; } var index:Number = cuePoint.index; if (cuePoint.time < time) index++; while (index < cuePoint.array.length && !isFLVCuePointEnabled(cuePoint.array[index])) { index++; } if (index >= cuePoint.array.length) { //if no cue points could be found, go to the end var seekTime:Number = _vp[_activeVP].totalTime; // if the last navigation point in the array is past what // we think is the end time, use that instead (even if // disabled). if (cuePoint.array[cuePoint.array.length - 1].time > seekTime) { seekTime = cuePoint.array[cuePoint.array.length - 1]; } seek(seekTime); } else { seek(cuePoint.array[index].time); } } /** *

Seeks to previous navigation cue point, based on current * playheadTime. Goes to beginning if there is no previous * cue point. Navigation cue points disabled by ActionScript * will be skipped.

* * @param time starting time from where to look for next * navigation cue point. Default is current playheadTime * @see #cuePoints * @see #seek() * @see #seekToNavCuePoint() * @see #seekToNextNavCuePoint() * @see #findCuePoint() * @see #isFLVCuePointEnabled() */ public function seekToPrevNavCuePoint(time:Number):Void { if (_vp[_activeVP] == undefined) return; if (isNaN(time) || time < 0) { time = _vp[_activeVP].playheadTime; } var cuePoint:Object = findNearestCuePoint(time, NAVIGATION); if (cuePoint == null) { // if no cue points could be found, go to the beginning seek(0); return; } var index:Number = cuePoint.index; while ( index >= 0 && ( !isFLVCuePointEnabled(cuePoint.array[index]) || cuePoint.array[index].time >= time - _seekToPrevOffset ) ) { index--; } if (index < 0) { seek(0); } else { seek(cuePoint.array[index].time); } } /** *

Add an ActionScript cue point.

* *

Cue point information is wiped out when contentPath property * is set, so to set cue point info for the next FLV to be loaded, * set contentPath first.

* *

It is legal to add multiple AS cue points with the same * name and time. When removeASCuePoint is called with this * name and time, all will be removed.

* * @param timeOrCuePoint If Object, then object describing the cue * point. Must have a name:String and time:Number (in seconds) * property. May have a parameters:Object property that holds * name/value pairs. May have type:String set to "actionscript", * if it is missing or set to something else it will be set * automatically. If the Object does not conform to these * conventions, a VideoError will be thrown. * *

If Number, then time for new cue point to be added * and name parameter must follow.

* @param name Name for cuePoint if timeOrCuePoint parameter * is a Number. * @param parameters Optional parameters for cuePoint if * timeOrCuePoint parameter is a Number. * @returns The cuePoint Object added. Read only: edits to this * Object will effect "cuePoint" event dispatch. * * @throws VideoError if parameters are invalid * @see #findCuePoint() * @see #removeASCuePoint() * @see CuePointManager#addASCuePoint() */ public function addASCuePoint(timeOrCuePoint:Object, name:String, parameters:Object):Number { return _cpMgr[_activeVP].addASCuePoint(timeOrCuePoint, name, parameters); } /** *

Remove an ActionScript cue point from the currently * loaded FLV. Only the name and time properties are used * from the cuePoint parameter to find the cue point to be * removed.

* *

If multiple AS cue points match the search criteria, only * one will be removed. To remove all, call this function * repeatedly in a loop with the same parameters until it returns * null.

* *

Cue point information is wiped out when contentPath property * is set, so to set cue point info for the next FLV to be loaded, * set contentPath first.

* * @param timeNameOrCuePoint If string, name of cue point to * remove; remove first cue point with this name. If number, time * of cue point to remove; remove first cue point at this time. * If Object, then object with name and time properties, remove * cue point with both this name and time. * @returns The cue point that was removed. If there was no * matching cue point then null is returned. * @see #addASCuePoint() * @see #findCuePoint() * @see #removeASCuePoint() */ public function removeASCuePoint(timeNameOrCuePoint:Object):Object { return _cpMgr[_activeVP].removeASCuePoint(timeNameOrCuePoint); } /** *

Find the cue point at the given time and/or with given name. * Which type of cue points searched is determined by optional * type parameter. Default is to search all cue * points. Note that disabled cue points are also included in the * search, use isFLVCuePointEnabled. How the cue points are * searched depends on the type of the first argument.

* * @param timeNameOrCuePoint If String, then name of cue point to * search for. Return the first cue point with this name, or null * if no match. * *

If Number, time of cue point to search for. Only first * three decimal places of time used for search, any more than * that will be rounded. Returns the first cue point with this * time (If there are multiples with same time, which is only * possible with ActionScript cue points, then the one with the * first name alphabetically will be returned.) Returns null if * no match.

* *

If Object, then cuepoint object containing time and/or name * properties for search. If name is undefined or null, then * search behaves same as described above for time only search. * If time is undefined, null or less than 0, then search behaves * same as described above for name only search. If both time * and name are defined and a cue point exists with both that * time and name, then it is returned, otherwise null is returned.

* *

If time is null, undefined or less than 0 and name is null * or undefined, a VideoError is thrown.

* * @param type determines what class of cue points is searched. * possible values are "all", "navigation", "event", "flv", * "actionscript". There are constants defined for each of these. * * @returns null if no match was found, otherwise * copy of cuePoint object with additional properties: * * * @see #ALL * @see #EVENT * @see #NAVIGATION * @see #FLV * @see #ACTIONSCRIPT * @see #cuePoints * @see #addASCuePoint() * @see #removeASCuePoint() * @see #findNearestCuePoint() * @see CuePointManager#getCuePoint() */ public function findCuePoint(timeNameOrCuePoint:Object, type:String):Object { switch (type) { case "event": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].eventCuePoints, false, timeNameOrCuePoint); case "navigation": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].navCuePoints, false, timeNameOrCuePoint); case "flv": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].flvCuePoints, false, timeNameOrCuePoint); case "actionscript": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].asCuePoints, false, timeNameOrCuePoint); case "all": default: return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].allCuePoints, false, timeNameOrCuePoint); } } /** *

Find the cue point at or near the given time and/or with * given name. Which type of cue points searched is determined by * optional type parameter. Default is to search all * cue points. Note that disabled cue points are also included in * the search, use isFLVCuePointEnabled. How the cue points are * searched depends on the type of the first argument.

* * @param timeNameOrCuePoint If String, then name of cue point to * search for. Return the first cue point with this name, or null * if no match. * *

If Number, time of cue point to search for. Only first * three decimal places of time used for search, any more than * that will be rounded. If there is an exact time match, returns * the first cue point with this time (If there are multiples with * same time, which is only possible with ActionScript cue points, * then the one with the first name alphabetically will be * returned.) 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. If there * are no cue points, null is returned.

* *

If Object, then cuepoint object containing time and/or name * properties for search. If name is undefined or null, then * search behaves same as described above for time only search. * If time is undefined, null or less than 0, then search behaves * same as described above for name only search. If both time * and name are defined and a cue point exists with both that * time and name, then it is returned. If there is no exact * match, then the cue point with that exact name and with the * closest time earlier than that is returned. If there is * no cue point with that name earlier than that time, then * the first cue point with that name is returned. If there * are no cue points with that name, null is returned.

* *

If time is null, undefined or less than 0 and name is null * or undefined, a VideoError is thrown.

* * @param type determines what class of cue points is searched. * possible values are "all", "navigation", "event", "flv", * "actionscript". There are constants defined for each of these. * * @returns null if no match was found, otherwise * copy of cuePoint object with additional properties: * * * @see #ALL * @see #EVENT * @see #NAVIGATION * @see #FLV * @see #ACTIONSCRIPT * @see #cuePoints * @see #addASCuePoint() * @see #removeASCuePoint() * @see #findCuePoint() * @see CuePointManager#getCuePoint() */ public function findNearestCuePoint(timeNameOrCuePoint:Object, type:String):Object { switch (type) { case "event": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].eventCuePoints, true, timeNameOrCuePoint); case "navigation": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].navCuePoints, true, timeNameOrCuePoint); case "flv": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].flvCuePoints, true, timeNameOrCuePoint); case "actionscript": return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].asCuePoints, true, timeNameOrCuePoint); case "all": default: return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].allCuePoints, true, timeNameOrCuePoint); } } /** *

Given a cue point object returned from findCuePoint or * findNearestCuePoint (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.

* * @returns null if no match was found, otherwise * copy of cuePoint object with additional properties: * * */ public function findNextCuePointWithName(cuePoint:Object):Object { return _cpMgr[_activeVP].getNextCuePointWithName(cuePoint); } /** *

Enable or disable one or more FLV cue point. Disabled cue * points are disabled for being dispatched as events and * navigating to them with seekToPrevNavCuePoint(), * seekToNextNavCuePoint() and * seekToNavCuePoint().

* *

Cue point information is wiped out when contentPath property * is set, so to set cue point info for the next FLV to be loaded, * set contentPath first.

* *

Changes caused by calls to this function will not be * reflected in results returned from * isFLVCuePointEnabled until * metadataLoaded is true.

* * @param enabled whether to enable or disable FLV cue point * @param timeNameOrCuePoint If string, name of cue point to * enable/disable. If number, time of cue point to * enable/disable. If Object, then object with name and time * properties, enable/disable cue point that matches both name and * time. * @returns If metadataLoaded is true, returns number * of cue points whose enabled state was changed. If * metadataLoaded is false, always returns -1. * @see #cuePoints * @see #isFLVCuePointEnabled() * @see #findCuePoint() * @see #findNearestCuePoint() * @see #findNextCuePointWithName() * @see CuePointManager#setFLVCuePointEnabled() */ public function setFLVCuePointEnabled(enabled:Boolean, timeNameOrCuePoint:Object):Number { return _cpMgr[_activeVP].setFLVCuePointEnabled(enabled, timeNameOrCuePoint); } /** *

Returns false if FLV embedded cue point is disabled by * ActionScript. Cue points are disabled via setting the * cuePoints property or by calling * setFLVCuePointEnabled().

* *

The return value from this function is only meaningful when * metadataLoaded is true (or metadata * property is nonnull, or after "metadataReceived" event). It always * returns true when metadataLoaded is false.

* * @param timeNameOrCuePoint If string, name of cue point to * check; return false only if ALL cue points with this name are * disabled. If number, time of cue point to check. If Object, * then object with name and time properties, check cue point that * matches both name and time. * @returns false if cue point(s) is found and is disabled, true * either if no such cue point exists or if it is not disabled. * If time given is undefined, null or less than 0 then returns * false only if all cue points with this name are disabled. * *

The return value from this function is only meaningful when * metadataLoaded is true. It always returns true when it * is false.

* @see #findCuePoint() * @see #findNearestCuePoint() * @see #findNextCuePointWithName() * @see #setFLVCuePointEnabled() * @see CuePointManager#isFLVCuePointEnabled() */ public function isFLVCuePointEnabled(timeNameOrCuePoint:Object):Boolean { return _cpMgr[_activeVP].isFLVCuePointEnabled(timeNameOrCuePoint); } /** * Override MovieClip functionality to reserve depths less than * 1000 for internal use (used for VideoPlayer and live preview * placeholder. */ public function getNextHighestDepth():Number { var depth:Number = super.getNextHighestDepth(); return (depth < 1000) ? 1000 : depth; } /** * Brings VideoPlayer to the front of the stack of VideoPlayers. * Useful for custom transitions between VideoPlayers. */ public function bringVideoPlayerToFront(index:Number):Void { if (index == _topVP || _vp[index] == undefined) return; _vp[_topVP].swapDepths(_vp[index].getDepth()); _topVP = index; } /** * Get VideoPlayer with given index. When possible, it is * best to access VideoPlayer APIs via FLVPlayback APIs. * Each VideoPlayer._name proprety is its index. */ public function getVideoPlayer(index:Number):VideoPlayer { return _vp[index]; } /** * Close VideoPlayer with given index. Closes NetStream and * deletes VideoPlayer. If the closed video player is the active * or visible VideoPlayer, then active and/or visible VideoPlayer * will be set to the default player (with index 0). You cannot * close the default player, and trying to will throw an error. */ public function closeVideoPlayer(index:Number):VideoPlayer { if (_vp[index] == undefined) return; if (index == 0) throw new VideoError(VideoError.DELETE_DEFAULT_PLAYER); if (_visibleVP == index) visibleVideoPlayerIndex = 0; if (_activeVP == index) activeVideoPlayerIndex = 0; _vp[index].close(); _vp[index].unloadMovie(); delete _vp[index]; _vp[index] = undefined; } // // public properties // /** *

Use activeVideoPlayerIndex to manage multiple FLV streams. Sets * which VideoPlayer instance is affected by most * other APIs. Default is 0. Does not make the * VideoPlayer visible, to do this use * visibleVideoPlayerIndex.

* *

A new VideoPlayer is created the first time * activeVideoPlayerIndex is set to a given number. When * the new VideoPlayer is created, its properties are set to the * value of the default VideoPlayer (activeVideoPlayerIndex == * 0) except for contentPath, totalTime and isLive, which * are always set to the default values (empty string, 0 and * false, respectively), autoPlay which is always false (default * is true for the default VideoPlayer, aka 0), and height and * width which match those of the visibleVideoPlayerIndex. Note that * the cuePoints property will have no effect, just as it would * have no effect on a subsequent load into the default * VideoPlayer.

* *

APIs that control volume, positioning, dimensions, * visibility and UI controls are always global and their behavior * is NOT affected by setting activeVideoPlayerIndex. The * APIs unaffected are: backButton, bufferingBar, * bufferingBarHidesAndDisablesOthers, forwardButton, height, * muteButton, pauseButton, playButton, playPauseButton, scaleX, * scaleY, seekBar, seekBarInterval, seekBarScrubTolerance, * seekToPrevOffset, skin, transform, stopButton, visible, volume, * volumeBar, volumeBarInterval, volumeBarScrubTolerance, width, * x, y, setSize(), setScale()

* *

APIs that control dimensions do interact with * visibleVideoPlayerIndex, however. See that property * for more on that.

* *

APIs that target specific VideoPlayer depending on setting * of activeVideoPlayerIndex: all the rest!

* *

When listening for events, you will get all events for all * VideoPlayers. To distinguish which VideoPlayer the vent is for * use the events vp property, a Number corresponding * to the number set in activeVideoPlayerIndex and * visibleVideoPlayerIndex. All events have this property EXCEPT for * "resize" and "volumeUpdate" which are not specific to a VideoPlayer * but are global for the FLVPlayback instance.

* *

For example, to load a second FLV in the background, set * activeVideoPlayerIndex to 1 and call load(). * When you are ready to show this one and hide the other one, set * visibleVideoPlayerIndex to 1.

* * @see #visibleVideoPlayerIndex */ [Bindable] public function get activeVideoPlayerIndex():Number { return _activeVP; } public function set activeVideoPlayerIndex(i:Number):Void { if (_activeVP == i) return; // if have not done the delay load of first FLV, force it now. if (_vp[_activeVP].onEnterFrame != undefined) { doContentPathConnect(); } _activeVP = i; if (_vp[_activeVP] == undefined) { createVideoPlayer(_activeVP); _vp[_activeVP].visible = false; _vp[_activeVP].volume = 0; } } /** *

Determines whether the FLV is played immediately when * contentPath property is set or if we wait. Even if * autoPlay is false, we do load the content immediately.

* *

If set between loads of new FLVs, has no effect until * next set of contentPath.

* * @see #contentPath * @helpid 0 */ [Inspectable(defaultValue=true)] public function get autoPlay():Boolean { if (_vpState[_activeVP] == undefined) return _autoPlay; return _vpState[_activeVP].autoPlay; } public function set autoPlay(flag:Boolean):Void { if (_activeVP == 0 || _activeVP == undefined) _autoPlay = flag; _vpState[_activeVP].autoPlay = flag; } /** *

Determines whether the FLV is rewound to the first frame * when play stops, either by calling stop() or by * reaching the end of the stream. Meaningless for live streams.

* * @helpid 0 */ [Inspectable(defaultValue=true)] public function get autoRewind():Boolean { if (_vp[_activeVP] == undefined) return _autoRewind; return _vp[_activeVP].autoRewind; } public function set autoRewind(flag:Boolean):Void { if (_activeVP == 0 || _activeVP == undefined) _autoRewind = flag; _vp[_activeVP].autoRewind = flag; } /** *

Determines whether the instance is automatically resized to * the source dimensions. If this is set from false to true after * an FLV has been loaded, an automatic resize will start * immediately.

* * @see #maintainAspectRatio * @see #preferredHeight * @see #preferredWidth * @tiptext Determines whether the display sizes itself according to the preferred size of the media * @helpid 3543 */ [Inspectable(defaultValue=false)] public function get autoSize():Boolean { if (_vp[_activeVP] == undefined) return _autoSize; return _vp[_activeVP].autoSize; } public function set autoSize(flag:Boolean):Void { if (_activeVP == 0 || _activeVP == undefined) _autoSize = flag; _vp[_activeVP].autoSize = flag; } /** *

Get the bandwidth. Numerical Value in bits per second.

* *

When streaming from FCS, can provide SMIL file that * describes how to switch between multiple streams based on * bandwidth. Bandwidth is automatically detected by FCS server * and if this value is set, it will be ignored.

* *

When doing http progressive download, can use the same SMIL * format, but must set the bitrate as there is no automatic * detection.

*/ public function get bitrate():Number { return ncMgr.getBitrate(); } public function set bitrate(b:Number):Void { ncMgr.setBitrate(b); } /** * If state is buffering. Read only. */ public function get buffering():Boolean { if (_vp[_activeVP] == undefined) return false; return (_vp[_activeVP].state == BUFFERING); } /** *

buffering bar control. Displays when in loading or * buffering type state.

*/ public function get bufferingBar():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _bufferingBar = _uiMgr.getControl(UIManager.BUFFERING_BAR); return _bufferingBar; } public function set bufferingBar(s:MovieClip):Void { _bufferingBar = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.BUFFERING_BAR, s); } /** *

If true, we hide and disable certain controls when the * buffering bar is displayed. The seek bar will be hidden, the * play, pause, play/pause, forward and back buttons would be * disabled. Default is false. This only has effect if there * is a buffering bar control.

*/ public function get bufferingBarHidesAndDisablesOthers():Boolean { if (_uiMgr != null && _uiMgr != undefined) { _bufferingBarHides = _uiMgr.bufferingBarHidesAndDisablesOthers; } return _bufferingBarHides; } public function set bufferingBarHidesAndDisablesOthers(b:Boolean):Void { _bufferingBarHides = b; if (_uiMgr != null && _uiMgr != undefined) { _uiMgr.bufferingBarHidesAndDisablesOthers = b; } } /** *

back button control. Clicking calls * seekToPrevNavCuePoint(). * * @see #seekToPrevNavCuePoint()

*/ public function get backButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _backButton = _uiMgr.getControl(UIManager.BACK_BUTTON); return _backButton; } public function set backButton(s:MovieClip):Void { _backButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.BACK_BUTTON, s); } /** *

Sets number of seconds to buffer in memory before playing * back stream. For slow connections streaming over rtmp, it is * important to increase this from the default. Default is * 0.1

*/ [Inspectable(defaultValue=0.1)] public function get bufferTime():Number { if (_vp[_activeVP] == undefined) return _bufferTime; return _vp[_activeVP].bufferTime; } public function set bufferTime(aTime:Number):Void { if (_activeVP == 0 || _activeVP == undefined) _bufferTime = aTime; _vp[_activeVP].bufferTime = aTime; } /** *

property bytesLoaded, read only. Returns -1 when there * is no stream, when the stream is FCS or if the information * is not yet available. Return value only useful for HTTP * download.

* * @tiptext Number of bytes already loaded * @helpid 3455 */ [ChangeEvent("progress")] [Bindable] public function get bytesLoaded():Number { return _vp[_activeVP].bytesLoaded; } /** *

property bytesTotal, read only. Returns -1 when there * is no stream, when the stream is FCS or if the information * is not yet available. Return value only useful for HTTP * download.

* * @tiptext Number of bytes to be loaded * @helpid 3456 */ [ChangeEvent("progress")] [Bindable] public function get bytesTotal():Number { return _vp[_activeVP].bytesTotal; } /** *

URL that determines FLV to stream and how to stream it. * URL can be http URL to an FLV, rtmp URL to a stream or * http URL to an XML file.

* *

If set via component inspector or property inspector, the * loading and/or playing of FLV starts on next "enterFrame" event. * Delay is to allow time to set isLive, autoPlay and cuePoints * properties, among others, which effect loading, as well as to * allow ActionScript on frame one to effect the FLVPlayback * component before it starts playing.

* *

If set via ActionScript, it immediately calls * VideoPlayer.load() if autoPlay is * false or VideoPlayer.play() if * autoPlay is true. Also sends properties * totalTime and isLive into those * VideoPlayer APIs, so be sure to set those BEFORE * setting this property.

* * @see #autoPlay * @see #isLive * @see #totalTime * @see #load() * @see #play() * @see VideoPlayer#load() * @see VideoPlayer#play() */ [Inspectable(type="Video Content Path")] [Bindable] public function get contentPath():String { if (_vp[_activeVP] == undefined || _vp[_activeVP].onEnterFrame != undefined) { return _contentPath; } return _vp[_activeVP].url; } public function set contentPath(url:String):Void { if (_global.isLivePreview) return; if (_vp[_activeVP] == undefined) { // if set by component inspector, before constructor called if (url == _contentPath) return; _contentPath = url; } else { if (_vp[_activeVP].url == url) return; _vpState[_activeVP].minProgressPercent = undefined; if (_vp[_activeVP].onEnterFrame != undefined) { delete _vp[_activeVP].onEnterFrame; _vp[_activeVP].onEnterFrame = undefined; } _cpMgr[_activeVP].reset(); if (_vpState[_activeVP].autoPlay && _firstStreamShown) { _vp[_activeVP].play(url, _vpState[_activeVP].isLive, _vpState[_activeVP].totalTime); } else { _vp[_activeVP].load(url, _vpState[_activeVP].isLive, _vpState[_activeVP].totalTime); } _vpState[_activeVP].isLiveSet = false; _vpState[_activeVP].totalTimeSet = false; } } /** *

Write only Array that describes ActionScript cue points and * disabled embedded FLV cue points. This API is created * specifically to be used by the component inspector and * will not work if set in any other way. Its value only * has an effect on the first FLV loaded, and only if it * is loaded by setting the contentPath property in the * component inspector or property inspector.

* *

To add, remove, enable or disable cue points with * ActionScript, use use addASCuePoint(), * removeASCuePoint(), * setFLVCuePointEnabled().

* * @see #contentPath * @see #addASCuePoint() * @see #removeASCuePoint() * @see #setFLVCuePointEnabled() */ [Inspectable(type="Video Cue Points")] public function set cuePoints(cp:Array):Void { // this can only be set once, and only before the constructor is called if (_cuePoints != undefined) return; _cuePoints = cp; } //ifdef DEBUG ///** // * temporary for development // */ //[Inspectable(defaultValue=false)] //public function get debuggingOn():Boolean { // return _debuggingOn; //} //public function set debuggingOn(d:Boolean):Void { // _debuggingOn = d; //} ///** // * temporary for development. Should be a function that takes // * a String argument. // */ //public function get debuggingOutputFunction():Function { // return _debugFn; //} //public function set debuggingOutputFunction(d:Function):Void { // _debugFn = d; //} //endif /** *

forward button control. Clicking calls * seekToNextNavCuePoint().

* * @see #seekToNextNavCuePoint() */ public function get forwardButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _forwardButton = _uiMgr.getControl(UIManager.FORWARD_BUTTON); return _forwardButton; } public function set forwardButton(s:MovieClip):Void { _forwardButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.FORWARD_BUTTON, s); } /** *

Height of video

* * @see #setSize() * @helpid 0 */ [ChangeEvent("resize")] [Bindable] public function get height():Number { if (_global.isLivePreview) return __height; if (_vp[_visibleVP] != undefined) __height = _vp[_visibleVP].height; return __height; } public function set height(h:Number):Void { setSize(this.width, h); } /** *

Property idleTimeout, which is amount of time in * milliseconds before connection is idle (playing is paused * or stopped) before connection to the FCS server is * terminated. Has no effect to HTTP download of FLV.

* *

If set when stream already idle, restarts idle timeout with * new value.

*/ public function get idleTimeout():Number { if (_vp[_activeVP] == undefined) return _idleTimeout; return _vp[_activeVP].idleTimeout; } public function set idleTimeout(aTime:Number):Void { if (_activeVP == 0 || _activeVP == undefined) _idleTimeout = aTime; _vp[_activeVP].idleTimeout = aTime; } /** * True if stream is RTMP download (streaming from Flash * Communication Server), read only. * * @see VideoPlayer#isRTMP */ public function get isRTMP():Boolean { if (_global.isLivePreview) return true; if (_vp[_activeVP] == undefined) return undefined; return _vp[_activeVP].isRTMP; } /** *

Whether stream is live. This property only matters when * streaming from FVSS or FCS; value is ignored when doing * http download.

* *

If set between loads of new FLVs, has no effect until * next set of contentPath.

* * @see #contentPath * @see VideoPlayer#isLive */ [Inspectable(defaultValue=false)] public function get isLive():Boolean { if (_vp[_activeVP] == undefined) { return _isLive; } else if(_vpState[_activeVP].isLiveSet) { return _vpState[_activeVP].isLive; } else { return _vp[_activeVP].isLive; } } public function set isLive(flag:Boolean):Void { if (_activeVP == 0 || _activeVP == undefined) _isLive = flag; _vpState[_activeVP].isLive = flag; _vpState[_activeVP].isLiveSet = true; } /** *

Determines whether video aspect ratio is maintained. If * this is set from false to true and autoSize is * false after an FLV has been loaded, an automatic resize will * start immediately.

* * @see #autoSize * @see #preferredHeight * @see #preferredWidth * @tiptext Determines whether a Display or Playback instance maintains aspect ratio * @helpid 3451 */ [Inspectable(defaultValue=true)] public function get maintainAspectRatio():Boolean { if (_vp[_activeVP] == undefined) return _aspectRatio; return _vp[_activeVP].maintainAspectRatio; } public function set maintainAspectRatio(flag:Boolean):Void { if (_activeVP == 0 || _activeVP == undefined) _aspectRatio = flag; _vp[_activeVP].maintainAspectRatio = flag; } /** *

Read only. Metadata info packet received in onMetaData * callback, if available. Ready when "metadataReceived" event * dispatched.

* * @see VideoPlayer#metadata */ public function get metadata():Object { if (_vp[_activeVP] == undefined) return null; return _vp[_activeVP].metadata; } /** *

Read only. True if metadata packet has been encountered and * processed OR if it is clear that it will not be. Use this to * check if useful information can be retreived from there various * cue point APIs (findCuePoint, findNearestCuePoint, * findNextCuePointWithName, isFLVCuePointEnabled) for FLV * embedded cue points. * * @see #findCuePoint() * @see #findNearestCuePoint() * @see #findNextCuePointWithName() * @see #isFLVCuePointEnabled() * @see CuePointManager#metadataLoaded */ public function get metadataLoaded():Boolean { if (_vp[_activeVP] == undefined) return false; return _cpMgr[_activeVP].metadataLoaded; } /** *

mute button control.

*/ public function get muteButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _muteButton = _uiMgr.getControl(UIManager.MUTE_BUTTON); return _muteButton; } public function set muteButton(s:MovieClip):Void { _muteButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.MUTE_BUTTON, s); } /** *

Access to instance of the class implementing * INCManager. Read only.

* *

One use case for this is that a custom * INCManager implementation may require custom * initialization.

* * VideoPlayer#ncMgr */ public function get ncMgr():INCManager { if (_vp[_activeVP] == undefined) return null; return _vp[_activeVP].ncMgr; } /** *

pause button control.

*/ public function get pauseButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _pauseButton = _uiMgr.getControl(UIManager.PAUSE_BUTTON); return _pauseButton; } public function set pauseButton(s:MovieClip):Void { _pauseButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PAUSE_BUTTON, s); } /** * If state is paused. Read only. */ [ChangeEvent("stateChange")] [ChangeEvent("paused")] [Bindable] public function get paused():Boolean { if (_vp[_activeVP] == undefined) return false; return (_vp[_activeVP].state == PAUSED); } /** *

play button control.

*/ public function get playButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _playButton = _uiMgr.getControl(UIManager.PLAY_BUTTON); return _playButton; } public function set playButton(s:MovieClip):Void { _playButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PLAY_BUTTON, s); } /** *

The current playhead time in seconds. Setting does a seek * and has all the restrictions of a seek.

* *

The event "playheadUpdate" is dispatched when the playhead * time changes, including every .25 seconds while the FLV is * playing.

* * @return The playhead position, measured in seconds since the start. Will return a fractional value. * @tiptext Current position of the playhead in seconds * @helpid 3463 * @see #seek() * @see VideoPlayer#playheadTime */ [ChangeEvent("playheadUpdate")] [Bindable] public function get playheadTime():Number { if (_vp[_activeVP] == undefined) return 0; return _vp[_activeVP].playheadTime; } public function set playheadTime(position:Number):Void { seek(position); } /** *

Property playheadUpdateInterval, which is amount of time * in milliseconds between each "playheadUpdate" event.

* *

If set when stream is playing, will restart timer.

* * @see VideoPlayer#playheadUpdateInterval */ public function get playheadUpdateInterval():Number { if (_vp[_activeVP] == undefined) return _playheadUpdateInterval; return _vp[_activeVP].playheadUpdateInterval; } public function set playheadUpdateInterval(aTime:Number):Void { if (_activeVP == 0 || _activeVP == undefined) _playheadUpdateInterval = aTime; _cpMgr[_activeVP].playheadUpdateInterval = aTime; _vp[_activeVP].playheadUpdateInterval = aTime; } /** * If state is playing. Read only. */ [ChangeEvent("stateChange")] [ChangeEvent("playing")] [Bindable] public function get playing():Boolean { if (_vp[_activeVP] == undefined) return false; return (_vp[_activeVP].state == PLAYING); } /** *

play/pause button control

*/ public function get playPauseButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _playPauseButton = _uiMgr.getControl(UIManager.PLAY_PAUSE_BUTTON); return _playPauseButton; } public function set playPauseButton(s:MovieClip):Void { _playPauseButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PLAY_PAUSE_BUTTON, s); } /** *

property preferredHeight, get only. Gives the height of the * source FLV. This information is not valid immediately upon * calling play() or load(). It is * ready when the "ready" event fires. * * @return The preferred height of the display. * This is the height of the source FLV. * @see #autoSize * @see #maintainAspectRatio * @tiptext The preferred height of the display * @helpid 3465 */ [ChangeEvent("metadataReceived")] [Bindable] public function get preferredHeight():Number { if (_vp[_activeVP] == undefined) return 0; return _vp[_activeVP].videoHeight; } /** *

property preferredWidth, get only. Gives the width of the * source FLV. This information is not valid immediately upon * calling play() or load(). It is * ready when the "ready" event fires. * * @return The preferred width of the display. * This is the width of the source FLV. * @see #autoSize * @see #maintainAspectRatio * @tiptext The preferred width of the display * @helpid 3466 */ [ChangeEvent("metadataReceived")] [Bindable] public function get preferredWidth():Number { if (_vp[_activeVP] == undefined) return 0; return _vp[_activeVP].videoWidth; } /** *

Property progressInterval, which is amount of time * in milliseconds between each "progress" event.

* *

If set when stream is playing, will restart timer.

* * @see VideoPlayer#progressInterval */ public function get progressInterval():Number { if (_vp[_activeVP] == undefined) return _progressInterval; return _vp[_activeVP].progressInterval; } public function set progressInterval(aTime:Number):Void { if (_activeVP == 0 || _activeVP == undefined) _progressInterval = aTime; _vp[_activeVP].progressInterval = aTime; } /** * 100 is standard scale * * @see #setScale() * @tiptext Specifies the horizontal scale factor * @helpid 3974 */ [ChangeEvent("resize")] [Bindable] function get scaleX():Number { if (_vp[_visibleVP] != undefined) _scaleX = _vp[_visibleVP].width / _origWidth * 100; return this._scaleX; } function set scaleX(xs:Number):Void { setScale(xs, this.scaleY); } /** * 100 is standard scale * * @see #setScale() * @tiptext Specifies the vertical scale factor * @helpid 3975 */ [ChangeEvent("resize")] [Bindable] function get scaleY():Number { if (_vp[_visibleVP] != undefined) _scaleY = _vp[_visibleVP].height / _origHeight * 100; return this._scaleY; } function set scaleY(ys:Number):Void { setScale(this.scaleX, ys); } /** *

True if user is currently scrubbing with the seek bar. read only

*/ public function get scrubbing():Boolean { var seekBar:MovieClip = this.seekBar; if (seekBar == undefined || seekBar.isDragging == undefined) { return false; } return seekBar.isDragging; } /** *

seek bar control

*/ public function get seekBar():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _seekBar = _uiMgr.getControl(UIManager.SEEK_BAR); return _seekBar; } public function set seekBar(s:MovieClip):Void { _seekBar = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.SEEK_BAR, s); } /** * Determines how often check the seek bar handle location when * scubbing, in milliseconds. Default is 250. * * @see UIManager#seekBarInterval * @see UIManager#SEEK_BAR_INTERVAL_DEFAULT */ public function get seekBarInterval():Number { if (_uiMgr != null && _uiMgr != undefined) _seekBarInterval = _uiMgr.seekBarInterval return _seekBarInterval; } public function set seekBarInterval(s:Number) { _seekBarInterval = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.seekBarInterval = _seekBarInterval; } /** *

Determines how far user can move scrub bar before an update * will occur. Specified in percentage from 1 to 100. Set to 0 * to indicate no scrub tolerance--always update position on * seekBarInterval regardless of how far user has moved handle. * Default is 5.

* * @see UIManager#seekBarScrubTolerance * @see UIManager#SEEK_BAR_SCRUB_TOLERANCE_DEFAULT */ public function get seekBarScrubTolerance():Number { if (_uiMgr != null && _uiMgr != undefined) _seekBarScrubTolerance = _uiMgr.seekBarScrubTolerance; return _seekBarScrubTolerance; } public function set seekBarScrubTolerance(s:Number) { _seekBarScrubTolerance = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.seekBarScrubTolerance = _seekBarScrubTolerance; } /** *

when seekToPrevNavCuePoint compares its time against the * previous cue point, it uses this delta to be sure that if you * are just ahead of a cue point, you can hop over it to the * previous and not get stuck going to the same one over and over * if you are playing. In seconds

* */ public function get seekToPrevOffset():Number { return _seekToPrevOffset; } public function set seekToPrevOffset(s:Number):Void { _seekToPrevOffset = s; } /** *

Skin swf

*/ [Inspectable(type="Video Skin")] public function get skin():String { if (_uiMgr != null && _uiMgr != undefined) _skin = _uiMgr.skin; return _skin; } public function set skin(s:String):Void { _skin = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.skin = s; } /** *

Whether to hide the skin when the mouse is not over the video. * Defaults to false.

*/ [Inspectable(defaultValue=false)] public function get skinAutoHide():Boolean { if (_uiMgr != null && _uiMgr != undefined) _skinAutoHide = _uiMgr.skinAutoHide; return _skinAutoHide; } public function set skinAutoHide(b:Boolean):Void { // in live preview always leave to default of false if (_global.isLivePreview) return; _skinAutoHide = b; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.skinAutoHide = b; } /** *

Provides direct access to the * Sound.setTransform() and * Sound.getTransform() APIs. to expose more sound * control. Must set property for changes to take effect, get * property just to get a copy of the current settings to tweak.

* * @see #volume * @see VideoPlayer#transform */ public function get transform():Object { return _transform; } public function set transform(s:Object):Void { _transform = s; if (_vp[_activeVP] != undefined) _vp[_activeVP].transform = _transform; } /** *

Get state. Read only. Set with load(), * play(), stop(), * pause() and seek().

* *

Descriptive constants for values are defined.

* * @see #DISCONNECTED * @see #STOPPED * @see #PLAYING * @see #PAUSED * @see #BUFFERING * @see #LOADING * @see #CONNECTION_ERROR * @see #REWINDING * @see #SEEKING */ [Bindable] [ChangeEvent("stateChange")] public function get state():String { // for live preview, always make state STOPPED if (_global.isLivePreview) { return STOPPED; } // if no VideoPlayer exists (would only happen constructor // called), return DISCONNECTED if (_vp[_activeVP] == undefined) return DISCONNECTED; // force state to SEEKING while scrubbing if (_activeVP == _visibleVP && scrubbing) return SEEKING; var currentState:String = _vp[_activeVP].state; // force state to LOADING if it is RESIZING. RESIZING is just // needed for internal VideoPlayer use anyways, make it // LOADING, less confusing for user, esp when suppressing // STOPPED as we do below... if (currentState == VideoPlayer.RESIZING) return LOADING; // force state to LOADING when STOPPED because autoPlay is // true and waiting for skin to download to show all at once if ( _vpState[_activeVP].prevState == LOADING && _vpState[_activeVP].autoPlay && currentState == STOPPED ) { return LOADING; } return currentState; } /** *

Read only. Gets whether state is responsive, * i.e. whether controls should be enabled in the current * state.

* * @see VideoPlayer#stateResponsive */ public function get stateResponsive():Boolean { if (_vp[_activeVP] == undefined) return false; return _vp[_activeVP].stateResponsive; } /** *

stop button control.

*/ public function get stopButton():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _stopButton = _uiMgr.getControl(UIManager.STOP_BUTTON); return _stopButton; } public function set stopButton(s:MovieClip):Void { _stopButton = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.STOP_BUTTON, s); } /** * If state is stopped. Read only. */ [ChangeEvent("stateChange")] [ChangeEvent("stopped")] [Bindable] public function get stopped():Boolean { if (_vp[_activeVP] == undefined) return false; return (_vp[_activeVP].state == STOPPED); } /** *

property totalTime.

* *

When streaming from FCS and using the default * NCManager, this will be determined * automatically using server side APIs and that value will * override anything set through this property or gathered * from metadata. The property is ready for read when the * STOPPED or PLAYING state is reached after setting the * contentPath property. When live streaming * from FCS, this property is meaningless.

* *

With HTTP download, this property will be determined * automatically if the FLV has metadata embedded, otherwise * it must be set explicitly or it will be 0. If it is set * explicitly than the metadata value in the stream will be * ignored.

* *

When this is set, the setting takes effect for the next * FLV loaded by setting contentPath, it will have no effect * on a flv that has already been loaded. Also, reading this * property will not return the new value passed in until an * flv is loaded.

* *

Playback will still work if this is never set (either * explicitly or automatically), but it may cause problems * with seek controls.

* * @return The total running time of the FLV in seconds * @see #contentPath * @tiptext The total length of the FLV in seconds * @helpid 3467 */ [Inspectable(defaultValue=0)] [ChangeEvent("metadataReceived")] [Bindable] public function get totalTime():Number { if (_global.isLivePreview) return 1; if (_vp[_activeVP] == undefined) { return _totalTime; } else if (_vpState[_activeVP].totalTimeSet) { return _vpState[_activeVP].totalTime; } else { return _vp[_activeVP].totalTime; } } public function set totalTime(aTime:Number):Void { if (_activeVP == 0 || _activeVP == undefined) _totalTime = aTime; _vpState[_activeVP].totalTime = aTime; _vpState[_activeVP].totalTimeSet = true; } public function get visible():Boolean { return this._visible; } public function set visible(v:Boolean) { this._visible = v; } /** *

Use visibleVideoPlayerIndex to manage multiple FLV streams. * qSets which VideoPlayer instance is visible and * audible--only one at a time can be, the rest are hidden and * muted. Default is 0. Does not make the VideoPlayer * targeted by most APIs, for that use activeVideoPlayerIndex

* *

APIs that control dimensions interact with this property. * All that set the dimensions (setScale, setSize, set width, set * height, set scaleX, set scaleY) effect all VideoPlayers. * However, depending on whether autoSize or maintaintAspectRatio * are set on those VideoPlayers, they may have different * dimensions. So APIs that get the dimensions (get width, get * height, get scaleX, get scaleY) get the dimensions of the * visible VideoPlayer only, and while other VideoPlayers may * have the same dimensions, they may not.

* *

To get the dimensions of various VideoPlayers when they are * not visible, listen for the "resize" event and cache the size * value yourself.

* *

Does not have any implications for visibility of the * component as a whole, just which VideoPlayer is visible when * the component is visible. To set visibility for the entire * component, use visible property.

* * @see #activeVideoPlayerIndex * @see #visible */ public function get visibleVideoPlayerIndex():Number { return _visibleVP; } public function set visibleVideoPlayerIndex(i:Number) { if (_visibleVP == i) return; var oldIndex:Number = _visibleVP; if (_vp[i] == undefined) { createVideoPlayer(i); } var needResize:Boolean = (_vp[i].height != _vp[_visibleVP].height || _vp[i].width != _vp[_visibleVP].width); _vp[_visibleVP].visible = false; _vp[_visibleVP].volume = 0; _visibleVP = i; // only show it if stream and skin ready if (_firstStreamShown) { _uiMgr.setupSkinAutoHide(oldIndex); _vp[_visibleVP].visible = true; if (!scrubbing) { _vp[_visibleVP].volume = _volume; } } else if (_vp[_visibleVP].stateResponsive && _vp[_visibleVP].state != DISCONNECTED && _uiMgr.skinReady) { _uiMgr.visible = true; _uiMgr.setupSkinAutoHide(oldIndex); _firstStreamReady = true; showFirstStream(); } if (_vp[oldIndex].height != _vp[_visibleVP].height || _vp[oldIndex].width != _vp[_visibleVP].width) { dispatchEvent({type:"resize", x:this.x, y:this.y, width:this.width, height:this.height, auto:false, vp:_visibleVP}); } // sending extra bogus events to UIManager so UI is updated propertly for new vp _uiMgr.handleEvent({type: "stateChange", state: _vp[_visibleVP].state, vp:_visibleVP}); _uiMgr.handleEvent({type: "playheadUpdate", playheadTime: _vp[_visibleVP].playheadTime, vp:_visibleVP}); if (_vp[_visibleVP].isRTMP) { _uiMgr.handleEvent({type: "ready", vp:_visibleVP}); } else { _uiMgr.handleEvent({type: "progress", bytesLoaded: _vp[_visibleVP].bytesLoaded, bytesTotal: _vp[_visibleVP].bytesTotal, vp:_visibleVP}); } } /** *

Volume control in range from 0 to 100.

* * @return The most recent volume setting * @tiptext The volume setting in value range from 0 to 100. * @helpid 3468 * @see #transform */ [Inspectable(defaultValue=100)] [ChangeEvent("volumeUpdate")] [Bindable] public function get volume():Number { return _volume; } public function set volume(aVol:Number):Void { if (_volume == aVol) return; _volume = aVol; if (!scrubbing) { _vp[_visibleVP].volume = _volume; } dispatchEvent({type:"volumeUpdate", volume:aVol}); } /** *

volume control

*/ public function get volumeBar():MovieClip { if (_uiMgr != null && _uiMgr != undefined) _volumeBar = _uiMgr.getControl(UIManager.VOLUME_BAR); return _volumeBar; } public function set volumeBar(s:MovieClip):Void { _volumeBar = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.VOLUME_BAR, s); } /** * Determines how often check the volume bar handle location * when scubbing, in milliseconds. Default is 250. * * @see UIManager#volumeBarInterval * @see UIManager#VOLUME_BAR_INTERVAL_DEFAULT */ public function get volumeBarInterval():Number { if (_uiMgr != null && _uiMgr != undefined) _volumeBarInterval = _uiMgr.volumeBarInterval return _volumeBarInterval; } public function set volumeBarInterval(s:Number) { _volumeBarInterval = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.volumeBarInterval = _volumeBarInterval; } /** *

Determines how far user can move scrub bar before an update * will occur. Specified in percentage from 1 to 100. Set to 0 * to indicate no scrub tolerance--always update volume on * volumeBarInterval regardless of how far user has moved handle. * Default is 0.

* * @see UIManager#volumeBarScrubTolerance * @see UIManager#VOLUME_BAR_SCRUB_TOLERANCE_DEFAULT */ public function get volumeBarScrubTolerance():Number { if (_uiMgr != null && _uiMgr != undefined) _volumeBarScrubTolerance = _uiMgr.volumeBarScrubTolerance; return _volumeBarScrubTolerance; } public function set volumeBarScrubTolerance(s:Number) { _volumeBarScrubTolerance = s; if (_uiMgr != null && _uiMgr != undefined) _uiMgr.volumeBarScrubTolerance = _volumeBarScrubTolerance; } /** *

Width of video

* * @see #setSize() * @helpid 0 */ [ChangeEvent("resize")] [Bindable] public function get width():Number { if (_global.isLivePreview) return __width; if (_vp[_visibleVP] != undefined) __width = _vp[_visibleVP].width; return __width; } public function set width(w:Number):Void { setSize(w, this.height); } [Bindable] public function get x():Number { return this._x; } public function set x(xpos:Number) { this._x = xpos; } [Bindable] public function get y():Number { return this._y; } public function set y(ypos:Number) { this._y = ypos; } // // private and package internal methods // /** * Creates and configures VideoPlayer movie clip * * @private */ private function createVideoPlayer(index:Number):Void { if (_global.isLivePreview) return; // create var setWidth:Number = this.width; var setHeight:Number = this.height; _vp[index] = VideoPlayer(this.attachMovie("VideoPlayer", String(index), VP_DEPTH_OFFSET + index)); _vp[index].setSize(setWidth, setHeight); _topVP = index; // init _vp[index].autoRewind = _autoRewind; _vp[index].autoSize = _autoSize; _vp[index].bufferTime = _bufferTime; _vp[index].idleTimeout = _idleTimeout; _vp[index].maintainAspectRatio = _aspectRatio; _vp[index].playheadUpdateInterval = _playheadUpdateInterval; _vp[index].progressInterval = _progressInterval; _vp[index].transform = _transform; _vp[index].volume = _volume; // init state object and start onEnterFrame if contentPath set if (index == 0) { _vpState[index] = { id:index, isLive:_isLive, isLiveSet:true, totalTime:_totalTime, totalTimeSet:true, autoPlay:_autoPlay }; if (_contentPath != null && _contentPath != undefined && _contentPath != "") { _vp[index].onEnterFrame = Delegate.create(this, this.doContentPathConnect); } } else { _vpState[index] = { id:index, isLive:false, isLiveSet:true, totalTime:0, totalTimeSet:true, autoPlay:false }; } // listen to events from VideoPlayer _vp[index].addEventListener("resize", this); _vp[index].addEventListener("close", this); _vp[index].addEventListener("complete", this); _vp[index].addEventListener("cuePoint", this); _vp[index].addEventListener("playheadUpdate", this); _vp[index].addEventListener("progress", this); _vp[index].addEventListener("metadataReceived", this); _vp[index].addEventListener("stateChange", this); _vp[index].addEventListener("ready", this); _vp[index].addEventListener("rewind", this); // create CuePointManager to pair with VideoPlayer _cpMgr[index] = new CuePointManager(this, index); _cpMgr[index].playheadUpdateInterval = _playheadUpdateInterval; } /** * Creates UIManager and sets any properties that need setting * * @private */ private function createUIManager():Void { // create UIManager _uiMgr = new UIManager(this); // make skin invisible until "ready" and "skinLoaded" fired _uiMgr.visible = false; // set cached properties if (_backButton != undefined && _backButton != null) { _uiMgr.setControl(UIManager.BACK_BUTTON, _backButton); } if (_bufferingBar != undefined && _bufferingBar != null) { _uiMgr.setControl(UIManager.BUFFERING_BAR, _bufferingBar); } _uiMgr.bufferingBarHidesAndDisablesOthers = _bufferingBarHides; if (_forwardButton != undefined && _forwardButton != null) { _uiMgr.setControl(UIManager.FORWARD_BUTTON, _forwardButton); } if (_pauseButton != undefined && _pauseButton != null) { _uiMgr.setControl(UIManager.PAUSE_BUTTON, _pauseButton); } if (_playButton != undefined && _playButton != null) { _uiMgr.setControl(UIManager.PLAY_BUTTON, _playButton); } if (_playPauseButton != undefined && _playPauseButton != null) { _uiMgr.setControl(UIManager.PLAY_PAUSE_BUTTON, _playPauseButton); } if (_stopButton != undefined && _stopButton != null) { _uiMgr.setControl(UIManager.STOP_BUTTON, _stopButton); } if (_seekBar != undefined && _seekBar != null) { _uiMgr.setControl(UIManager.SEEK_BAR, _seekBar); } if (_seekBarInterval != undefined && _seekBarInterval != null) { _uiMgr.seekBarInterval = _seekBarInterval; } if (_seekBarScrubTolerance != undefined && _seekBarScrubTolerance != null) { _uiMgr.seekBarScrubTolerance = _seekBarScrubTolerance; } if (_skin != undefined && _skin != null) { _uiMgr.skin = _skin; } if (_skinAutoHide != undefined && _skinAutoHide != null) { _uiMgr.skinAutoHide = _skinAutoHide; } if (_muteButton != undefined && _muteButton != null) { _uiMgr.setControl(UIManager.MUTE_BUTTON, _muteButton); } if (_volumeBar != undefined && _volumeBar != null) { _uiMgr.setControl(UIManager.VOLUME_BAR, _volumeBar); } if (_volumeBarInterval != undefined && _volumeBarInterval != null) { _uiMgr.volumeBarInterval = _volumeBarInterval; } if (_volumeBarScrubTolerance != undefined && _volumeBarScrubTolerance != null) { _uiMgr.volumeBarScrubTolerance = _volumeBarScrubTolerance; } } /** * Creates live preview placeholder * * @private */ private function createLivePreviewMovieClip():Void { preview_mc = this.createEmptyMovieClip("preview_mc", 10); preview_mc.createEmptyMovieClip("box_mc", 10); preview_mc.box_mc.beginFill(0x000000); preview_mc.box_mc.moveTo(0, 0); preview_mc.box_mc.lineTo(0, 100); preview_mc.box_mc.lineTo(100, 100); preview_mc.box_mc.lineTo(100, 0); preview_mc.box_mc.lineTo(0, 0); preview_mc.box_mc.endFill(); preview_mc.attachMovie("Icon", "icon_mc", 20); } /** * Called on onEnterFrame to initiate loading the new * contentPath url. We delay to give the user time to set other * vars as well. Only done this way when contentPath set from the * component inspector or property inspector, not when set with AS. * * @see #contentPath * @private */ private function doContentPathConnect():Void { delete _vp[0].onEnterFrame; _vp[0].onEnterFrame = undefined; if (_global.isLivePreview) return; if (_vpState[0].autoPlay && _firstStreamShown) { _vp[0].play(_contentPath, _isLive, _totalTime); } else { _vp[0].load(_contentPath, _isLive, _totalTime); } _vpState[0].isLiveSet = false; _vpState[0].totalTimeSet = false; } private function showFirstStream():Void { _firstStreamShown = true; _vp[_visibleVP].visible = true; if (!scrubbing) { _vp[_visibleVP].volume = _volume; } // play all autoPlay streams loaded into other video players // that have been waiting for (var i:Number = 0; i < _vp.length; i++) { if (_vp[i] != undefined && _vp[i].state == STOPPED && _vpState[i].autoPlay) { _vp[i].play(); } } } /** * Called by UIManager when seekbar scrubbing starts * * @private */ function _scrubStart():Void { var nowTime:Number = playheadTime; _vp[_visibleVP].volume = 0; dispatchEvent({type:"stateChange", state:SEEKING, playheadTime:nowTime, vp:_visibleVP}); dispatchEvent({type:"scrubStart", state:SEEKING, playheadTime:nowTime}); } /** * Called by UIManager when seekbar scrubbing finishes * * @private */ function _scrubFinish():Void { var nowTime:Number = playheadTime; var nowState:String = state; _vp[_visibleVP].volume = _volume; if (nowState != SEEKING) { dispatchEvent({type:"stateChange", state:nowState, playheadTime:nowTime, vp:_visibleVP}); } dispatchEvent({type:"scrubFinish", state:nowState, playheadTime:nowTime}); } /** * Called by UIManager when skin errors * * @private */ function skinError(message:String):Void { if (_firstStreamReady && !_firstStreamShown) { showFirstStream(); } dispatchEvent({type:"skinError", message:message}); } /** * Called by UIManager when skin loads * * @private */ function skinLoaded():Void { if (_firstStreamReady) { _uiMgr.visible = true; if (!_firstStreamShown) { showFirstStream(); } } else if (_contentPath == undefined || _contentPath == null || _contentPath == "") { _uiMgr.visible = true; } dispatchEvent({type:"skinLoaded"}); } //ifdef DEBUG ///** // * @private // */ //function debugTrace(s:String):Void { // if (_debuggingOn) { // if (_debugFn != null && _debugFn != undefined) { // _debugFn.call(null, s); // } else { // trace(s); // } // } //} //endif } // class mx.video.FLVPlayback