Parent Directory | Revision Log
Revision 1.1 - (view) (download)
1 : | thiswind | 1.1 | //**************************************************************************** |
2 : | //Copyright (C) 2004-2005 Macromedia, Inc. All Rights Reserved. | ||
3 : | //The following is Sample Code and is subject to all restrictions on | ||
4 : | //such code as contained in the End User License Agreement accompanying | ||
5 : | //this product. | ||
6 : | //**************************************************************************** | ||
7 : | |||
8 : | import mx.events.EventDispatcher; | ||
9 : | import mx.utils.Delegate; | ||
10 : | import mx.video.*; | ||
11 : | |||
12 : | /** | ||
13 : | * <p>Event dispatched when <code>FLVPlayback.BUFFERING</code> state | ||
14 : | * entered. This state is typically entered immediately after | ||
15 : | * <code>play()</code> is called or the corresponding control is | ||
16 : | * clicked, before the playing state is entered. Event Object has | ||
17 : | * properties state and playheadTime.</p> | ||
18 : | * | ||
19 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
20 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
21 : | * | ||
22 : | * <p>"stateChange" event will also be dispatched.</p> | ||
23 : | * | ||
24 : | * @see #BUFFERING | ||
25 : | * @see #play() | ||
26 : | * @tiptext buffering event | ||
27 : | * @helpid ??? | ||
28 : | */ | ||
29 : | [Event("buffering")] | ||
30 : | |||
31 : | /** | ||
32 : | * <p>Event dispatched when <code>NetConnection</code> is closed, | ||
33 : | * whether by being timed out or by calling <code>close()</code> | ||
34 : | * API. Only ever dispatched when streaming from FCS or FVSS. | ||
35 : | * Event Object has properties state and playheadTime.</p> | ||
36 : | * | ||
37 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
38 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
39 : | * | ||
40 : | * @tiptext close event | ||
41 : | * @helpid 3482 | ||
42 : | */ | ||
43 : | [Event("close")] | ||
44 : | |||
45 : | /** | ||
46 : | * <p>Event dispatched when playing completes by reaching the end of | ||
47 : | * the FLV. Is not dispatched if the APIs <code>stop()</code> or | ||
48 : | * <code>pause()</code> are called or the corresponding controls are | ||
49 : | * clicked. Event Object has properties state and playheadTime.</p> | ||
50 : | * | ||
51 : | * <p>When using progressive download and not setting totalTime | ||
52 : | * explicitly and downloading an FLV with no metadata duration, | ||
53 : | * the totalTime will be set to an approximate total value, now | ||
54 : | * that we have played the whole file we can make a guess. That | ||
55 : | * value is set by the time this event is dispatched.</p> | ||
56 : | * | ||
57 : | * <p>"stateChange" and "stopped" events will also be dispatched.</p> | ||
58 : | * | ||
59 : | * @tiptext complete event | ||
60 : | * @helpid 3482 | ||
61 : | */ | ||
62 : | [Event("complete")] | ||
63 : | |||
64 : | /** | ||
65 : | * <p>Event dispatched when a cue point is reached. Event Object has an | ||
66 : | * info property that contains the info object received by the | ||
67 : | * <code>NetStream.onCuePoint</code> callback for FLV cue points or | ||
68 : | * the object passed into the AS cue point APIs for AS cue points.</p> | ||
69 : | * | ||
70 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
71 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
72 : | * | ||
73 : | * @tiptext cuePoint event | ||
74 : | * @helpid 3483 | ||
75 : | */ | ||
76 : | [Event("cuePoint")] | ||
77 : | |||
78 : | /** | ||
79 : | * <p>Event dispatched when location of playhead is moved forwards by a call | ||
80 : | * to <code>seek()</code>. The <code>playheadTime</code> property | ||
81 : | * will reflect the destination time. Event Object has properties state and | ||
82 : | * playheadTime.</p> | ||
83 : | * | ||
84 : | * <p>"seek" will be dispatched. "playheadUpdate" will be | ||
85 : | * dispatched.</p> | ||
86 : | * | ||
87 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
88 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
89 : | * | ||
90 : | * @see #seek() | ||
91 : | * @tiptext fastForward event | ||
92 : | * @helpid ??? | ||
93 : | */ | ||
94 : | [Event("fastForward")] | ||
95 : | |||
96 : | /** | ||
97 : | * <p>Event dispatched the first time the FLV metadata is reached. | ||
98 : | * Event Object has an info property that contains the info object | ||
99 : | * received by the <code>NetStream.onMetaData</code> callback.</p> | ||
100 : | * | ||
101 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
102 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
103 : | * | ||
104 : | * @tiptext metadataReceived event | ||
105 : | */ | ||
106 : | [Event("metadataReceived")] | ||
107 : | |||
108 : | /** | ||
109 : | * <p>Event dispatched when pause state entered. This happens when the | ||
110 : | * <code>pause()</code> API is called or the correpsonding control is | ||
111 : | * clicked and also happens in some cases when the FLV is loaded if | ||
112 : | * autoPlay is false (state may go to stopped instead). Event Object has | ||
113 : | * properties state and playheadTime.</p> | ||
114 : | * | ||
115 : | * <p>"stateChange" event will also be dispatched.</p> | ||
116 : | * | ||
117 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
118 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
119 : | * | ||
120 : | * @see #PAUSED | ||
121 : | * @see #pause() | ||
122 : | * @tiptext paused event | ||
123 : | * @helpid 3489 | ||
124 : | */ | ||
125 : | [Event("paused")] | ||
126 : | |||
127 : | /** | ||
128 : | * <p>Event dispatched when play state entered. This may not occur | ||
129 : | * immediately after the <code>play()</code> API is called or | ||
130 : | * corresponding control is clicked; often the buffering state is | ||
131 : | * entered first, and then playing. Event Object has properties state and | ||
132 : | * playheadTime.</p> | ||
133 : | * | ||
134 : | * <p>"stateChange" event will also be dispatched.</p> | ||
135 : | * | ||
136 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
137 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
138 : | * | ||
139 : | * @see #PLAYING | ||
140 : | * @see #play() | ||
141 : | * @tiptext playing event | ||
142 : | * @helpid ??? | ||
143 : | */ | ||
144 : | [Event("playing")] | ||
145 : | |||
146 : | /** | ||
147 : | * <p>While FLV is playing, this event is dispatched every .25 | ||
148 : | * seconds. Not dispatched when we are paused or stopped, unless a | ||
149 : | * seek occurs. Event Object has properties state and playheadTime.</p> | ||
150 : | * | ||
151 : | * @tiptext change event | ||
152 : | * @helpid 3480 | ||
153 : | */ | ||
154 : | [Event("playheadUpdate")] | ||
155 : | |||
156 : | /** | ||
157 : | * <p>Indicates progress made in number of bytes downloaded. User can | ||
158 : | * use this to check bytes loaded or number of bytes in the buffer. | ||
159 : | * Fires every .25 seconds, starting when load is called and ending | ||
160 : | * when all bytes are loaded or if there is a network error. Event Object is | ||
161 : | * of type <code>mx.events.ProgressEvent</code>.</p> | ||
162 : | * | ||
163 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
164 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
165 : | * | ||
166 : | * @tiptext progress event | ||
167 : | * @helpid 3485 | ||
168 : | */ | ||
169 : | [Event("progress")] | ||
170 : | |||
171 : | /** | ||
172 : | * <p>Event dispatched when FLV is loaded and ready to display. Event | ||
173 : | * object has properties state and playheadTime.</p> | ||
174 : | * | ||
175 : | * <p>Fired the first time we enter a responsive state after we | ||
176 : | * load a new flv with play() or load() API. Only fires once | ||
177 : | * for each FLV loaded.</p> | ||
178 : | * | ||
179 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
180 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
181 : | */ | ||
182 : | [Event("ready")] | ||
183 : | |||
184 : | /** | ||
185 : | * <p>Event dispatched when video is resized. Event Object has | ||
186 : | * properties x, y, width, height, auto and vp, index number of | ||
187 : | * VideoPlayer to which this event applies. See activeVideoPlayerIndex and | ||
188 : | * visibleVideoPlayerIndex.</p> | ||
189 : | * | ||
190 : | * <p>Auto is true when resize is automatic due to maintainAspectRatio | ||
191 : | * or autoSize set to true. In this case, the event may be firing for | ||
192 : | * a VideoPlayer other than the visible VideoPlayer. May be | ||
193 : | * dispatched even if the dimensions were not actually changed after | ||
194 : | * an attempt to autoresize occurs.</p> | ||
195 : | * | ||
196 : | * <p>When auto is false, the event always applies to the visible | ||
197 : | * VideoPlayer. The vp property still appears, but will always be | ||
198 : | * equal to visibleVideoPlayerIndex.</p> | ||
199 : | * | ||
200 : | * <p>Will be triggered (with auto = fals) when setting | ||
201 : | * visibleVideoPlayerIndex if switching to a player with different | ||
202 : | * dimensions than the currently visible player.</p> | ||
203 : | * | ||
204 : | * @tiptext resize event | ||
205 : | * @helpid ???? | ||
206 : | */ | ||
207 : | [Event("resize")] | ||
208 : | |||
209 : | /** | ||
210 : | * <p>Event dispatched when location of playhead is moved backward by | ||
211 : | * a call to <code>seek()</code> or when the an autoRewind is | ||
212 : | * completed. The <code>playheadTime</code> property will reflect the | ||
213 : | * destination time. Event Object has properties auto, state and | ||
214 : | * playheadTime. Property auto is true if event was triggered by | ||
215 : | * autoRewind, false otherwise.</p> | ||
216 : | * | ||
217 : | * <p>"stateChange" event will be dispatched with a state of | ||
218 : | * <code>FLVPlayback.REWINDING</code> when the autoRewind is | ||
219 : | * triggered; this event will not fire until it has completed. | ||
220 : | * "seek" will be dispatched when there is a seek. "playheadUpdate" | ||
221 : | * will be dispatched.</p> | ||
222 : | * | ||
223 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
224 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
225 : | * | ||
226 : | * @see #REWINDING | ||
227 : | * @see #autoRewind | ||
228 : | * @see #seek() | ||
229 : | * @tiptext rewind event | ||
230 : | * @helpid ??? | ||
231 : | */ | ||
232 : | [Event("rewind")] | ||
233 : | |||
234 : | /** | ||
235 : | * <p>Event dispatched when user finishes scrubbing timeline with | ||
236 : | * seekbar. Event object has properties state and playheadTime.</p> | ||
237 : | * | ||
238 : | * <p>Event "stateChange" will also be dispatched with new state | ||
239 : | * (should be PLAYING, PAUSED, STOPPED or BUFFERING). State will | ||
240 : | * be <code>SEEKING</code> until user finishes scrubbing.</p> | ||
241 : | */ | ||
242 : | [Event("scrubFinish")] | ||
243 : | |||
244 : | /** | ||
245 : | * <p>Event dispatched when user starts scrubbing timeline with | ||
246 : | * seekbar. Event object has properties state and playheadTime.</p> | ||
247 : | * | ||
248 : | * <p>Event "stateChange" will also be dispatched with state | ||
249 : | * <code>SEEKING</code>. State will remain <code>SEEKING</code> | ||
250 : | * while user is scrubbing.</p> | ||
251 : | */ | ||
252 : | [Event("scrubStart")] | ||
253 : | |||
254 : | /** | ||
255 : | * <p>Event dispatched when location of playhead is changed by a call to | ||
256 : | * <code>seek()</code> or by using the corresponding control. The | ||
257 : | * <code>playheadTime</code> property will reflect the destination | ||
258 : | * time. Event Object has properties state and playheadTime.</p> | ||
259 : | * | ||
260 : | * <p>"stateChange" event also may be dispatched, but may not. | ||
261 : | * "rewind" will be dispatched when the seek is backwards and | ||
262 : | * "fastForward" will be dispatched when the seek is forwards. | ||
263 : | * "playheadUpdate" will be dispatched.</p> | ||
264 : | * | ||
265 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
266 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
267 : | * | ||
268 : | * @see #seek() | ||
269 : | * @tiptext seek event | ||
270 : | * @helpid ??? | ||
271 : | */ | ||
272 : | [Event("seek")] | ||
273 : | |||
274 : | /** | ||
275 : | * <p>Event dispatched when error occurs loading skin swf. Has | ||
276 : | * message property with error message. If a skin swf is set, | ||
277 : | * playback will not begin until "ready" event and "skinLoaded" (or | ||
278 : | * "skinError") event have both fired.</p> | ||
279 : | * | ||
280 : | * @see #skin | ||
281 : | */ | ||
282 : | [Event("skinError")] | ||
283 : | |||
284 : | /** | ||
285 : | * <p>Event dispatched when skin swf is loaded. No properties (other | ||
286 : | * than normal target property). If a skin swf is set, playback will | ||
287 : | * not begin until "ready" event and "skinLoaded" (or "skinError") | ||
288 : | * event have both fired.</p> | ||
289 : | * | ||
290 : | * @see #skin | ||
291 : | */ | ||
292 : | [Event("skinLoaded")] | ||
293 : | |||
294 : | /** | ||
295 : | * <p>Event dispatched when playback state changes. Event Object has | ||
296 : | * properties state and playheadTime.</p> | ||
297 : | * | ||
298 : | * <p>This event can be used to track when playback enters/leaves | ||
299 : | * unresponsive states (for example in the middle of connecting, | ||
300 : | * resizing or rewinding) during which times APIs <code>play()</code>, | ||
301 : | * <code>pause()</code>, <code>stop()</code> and <code>seek()</code> | ||
302 : | * will queue the requests to be executed when the player enters | ||
303 : | * a responsive state.</p> | ||
304 : | * | ||
305 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
306 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
307 : | * | ||
308 : | * @see #state | ||
309 : | */ | ||
310 : | [Event("stateChange")] | ||
311 : | |||
312 : | /** | ||
313 : | * <p>Event dispatched when <code>FLVPlayback.STOPPED</code> state entered. | ||
314 : | * This happens when the <code>stop()</code> API is called or the | ||
315 : | * corresponding control is clicked and also happens in some cases | ||
316 : | * when the FLV is loaded if autoPlay is false (state may go to paused | ||
317 : | * instead). The event is also dispatched when the playhead stops | ||
318 : | * because it has reached the end of the timeline. Event Object has | ||
319 : | * properties state and playheadTime.</p> | ||
320 : | * | ||
321 : | * <p>"stateChange" event will also be dispatched.</p> | ||
322 : | * | ||
323 : | * <p>Event has property vp, index number of VideoPlayer to which this | ||
324 : | * event applies. See activeVideoPlayerIndex and visibleVideoPlayerIndex.</p> | ||
325 : | * | ||
326 : | * @see #STOPPED | ||
327 : | * @see #stop() | ||
328 : | * @tiptext stopped event | ||
329 : | * @helpid 3487 | ||
330 : | */ | ||
331 : | [Event("stopped")] | ||
332 : | |||
333 : | /** | ||
334 : | * <p>Event dispatched when volume is changed by changing | ||
335 : | * <code>volume</code> property (a.k.a. by user). | ||
336 : | * Event Object has a volume property.</p> | ||
337 : | * | ||
338 : | * @tiptext volumeUpdate event | ||
339 : | * @helpid 3486 | ||
340 : | */ | ||
341 : | [Event("volumeUpdate")] | ||
342 : | |||
343 : | [IconFile("FLVPlayback.png")] | ||
344 : | [minimumPlayerVersion("8")] | ||
345 : | [RequiresDataBinding(true)] | ||
346 : | [LivePreviewVersion("1")] | ||
347 : | |||
348 : | /** | ||
349 : | * <p>FLVPlayback extends MovieClip and wraps a VideoPlayer object. | ||
350 : | * It also "extends" EventDispatcher using mixins.</p> | ||
351 : | * | ||
352 : | * @author copyright 2004-2005 Macromedia, Inc. | ||
353 : | * @tiptext FLVPlayback | ||
354 : | * @helpid ??? | ||
355 : | */ | ||
356 : | |||
357 : | class mx.video.FLVPlayback extends MovieClip { | ||
358 : | |||
359 : | #include "ComponentVersion.as" | ||
360 : | |||
361 : | // | ||
362 : | // public state constants | ||
363 : | // | ||
364 : | |||
365 : | /** | ||
366 : | * <p>State constant. This is the state when the VideoPlayer is | ||
367 : | * constructed and when the stream is closed by a call to | ||
368 : | * <code>close()</code> or timed out on idle.</p> | ||
369 : | * | ||
370 : | * <p>This is a responsive state.</p> | ||
371 : | * | ||
372 : | * @see #state | ||
373 : | * @see #stateResponsive | ||
374 : | * @see #idleTimeout | ||
375 : | * @see #closeVideoPlayer() | ||
376 : | */ | ||
377 : | public static var DISCONNECTED:String = "disconnected"; | ||
378 : | |||
379 : | /** | ||
380 : | * <p>State constant. FLV is loaded and play is stopped. This state | ||
381 : | * is entered when <code>stop()</code> is called and when the | ||
382 : | * playhead reaches the end of the stream.</p> | ||
383 : | * | ||
384 : | * <p>This is a responsive state.</p> | ||
385 : | * | ||
386 : | * @see #state | ||
387 : | * @see #stateResponsive | ||
388 : | * @see #stopped | ||
389 : | * @see #stop() | ||
390 : | */ | ||
391 : | public static var STOPPED:String = "stopped"; | ||
392 : | |||
393 : | /** | ||
394 : | * <p>State constant. FLV is loaded and is playing. | ||
395 : | * This state is entered when <code>play()</code> | ||
396 : | * is called.</p> | ||
397 : | * | ||
398 : | * <p>This is a responsive state.</p> | ||
399 : | * | ||
400 : | * @see #playing | ||
401 : | * @see #state | ||
402 : | * @see #stateResponsive | ||
403 : | * @see #play() | ||
404 : | */ | ||
405 : | public static var PLAYING:String = "playing"; | ||
406 : | |||
407 : | /** | ||
408 : | * <p>State constant. FLV is loaded, but play is paused. | ||
409 : | * This state is entered when <code>pause()</code> is | ||
410 : | * called or when <code>load()</code> is called.</p> | ||
411 : | * | ||
412 : | * <p>This is a responsive state.</p> | ||
413 : | * | ||
414 : | * @see #paused | ||
415 : | * @see #state | ||
416 : | * @see #stateResponsive | ||
417 : | * @see #pause() | ||
418 : | * @see #load() | ||
419 : | */ | ||
420 : | public static var PAUSED:String = "paused"; | ||
421 : | |||
422 : | /** | ||
423 : | * <p>State constant. State entered immediately after | ||
424 : | * <code>play()</code> or <code>load()</code> is called.</p> | ||
425 : | * | ||
426 : | * <p>This is a responsive state.</p> | ||
427 : | * | ||
428 : | * @see #buffering | ||
429 : | * @see #state | ||
430 : | * @see #stateResponsive | ||
431 : | */ | ||
432 : | public static var BUFFERING:String = "buffering"; | ||
433 : | |||
434 : | /** | ||
435 : | * <p>State constant. State entered immediately after | ||
436 : | * <code>play()</code> or <code>load()</code> is called or | ||
437 : | * after <code>contentPath</code> property is set.</p> | ||
438 : | * | ||
439 : | * <p>This is a unresponsive state.</p> | ||
440 : | * | ||
441 : | * @see #contentPath | ||
442 : | * @see #state | ||
443 : | * @see #stateResponsive | ||
444 : | * @see #load() | ||
445 : | * @see #play() | ||
446 : | */ | ||
447 : | public static var LOADING:String = "loading"; | ||
448 : | |||
449 : | /** | ||
450 : | * <p>State constant. Stream attempted to load was unable to load | ||
451 : | * for some reason. Could be no connection to server, stream not | ||
452 : | * found, etc.</p> | ||
453 : | * | ||
454 : | * <p>This is a unresponsive state.</p> | ||
455 : | * | ||
456 : | * @see #state | ||
457 : | * @see #stateResponsive | ||
458 : | */ | ||
459 : | public static var CONNECTION_ERROR:String = "connectionError"; | ||
460 : | |||
461 : | /** | ||
462 : | * <p>State constant. State entered during a autorewind triggered | ||
463 : | * by a stop. After rewind is complete, the state will be | ||
464 : | * <code>STOPPED</code>.</p> | ||
465 : | * | ||
466 : | * <p>This is a unresponsive state.</p> | ||
467 : | * | ||
468 : | * @see #autoRewind | ||
469 : | * @see #state | ||
470 : | * @see #stateResponsive | ||
471 : | */ | ||
472 : | public static var REWINDING:String = "rewinding"; | ||
473 : | |||
474 : | /** | ||
475 : | * <p>State constant. State entered after <code>seek()</code> | ||
476 : | * is called and also while user is scrubbing with seek bar.</p> | ||
477 : | * | ||
478 : | * <p>This is a unresponsive state.</p> | ||
479 : | * | ||
480 : | * @see #stateResponsive | ||
481 : | * @see #state | ||
482 : | * @see #seek() | ||
483 : | */ | ||
484 : | public static var SEEKING:String = "seeking"; | ||
485 : | |||
486 : | /** | ||
487 : | * Constant passed into findCuePoint or findNearestCuePoint type parameter. | ||
488 : | */ | ||
489 : | public static var ALL = "all"; | ||
490 : | |||
491 : | /** | ||
492 : | * Constant passed into findCuePoint or findNearestCuePoint type parameter. | ||
493 : | */ | ||
494 : | public static var EVENT = "event"; | ||
495 : | |||
496 : | /** | ||
497 : | * Constant passed into findCuePoint or findNearestCuePoint type parameter. | ||
498 : | */ | ||
499 : | public static var NAVIGATION = "navigation"; | ||
500 : | |||
501 : | /** | ||
502 : | * Constant passed into findCuePoint or findNearestCuePoint type parameter. | ||
503 : | */ | ||
504 : | public static var FLV = "flv"; | ||
505 : | |||
506 : | /** | ||
507 : | * Constant passed into findCuePoint or findNearestCuePoint type parameter. | ||
508 : | */ | ||
509 : | public static var ACTIONSCRIPT = "actionscript"; | ||
510 : | |||
511 : | // | ||
512 : | // private instance vars | ||
513 : | // | ||
514 : | |||
515 : | /** | ||
516 : | * bounding box movie clip inside of component on stage | ||
517 : | * | ||
518 : | * @private | ||
519 : | */ | ||
520 : | public var boundingBox_mc:MovieClip; | ||
521 : | |||
522 : | // live preview movie clip | ||
523 : | private var preview_mc:MovieClip; | ||
524 : | |||
525 : | // the VideoPlayers | ||
526 : | private var _vp:Array; | ||
527 : | var _vpState:Array; | ||
528 : | private var _activeVP:Number; | ||
529 : | private var _visibleVP:Number; | ||
530 : | private var _topVP:Number; | ||
531 : | private static var VP_DEPTH_OFFSET:Number = 100; | ||
532 : | |||
533 : | // the UIManager | ||
534 : | private var _uiMgr:UIManager; | ||
535 : | |||
536 : | // the CuePointManagers (one for each VideoPlayer) | ||
537 : | private var _cpMgr:Array; | ||
538 : | |||
539 : | // state | ||
540 : | private var _preSeekTime:Number; | ||
541 : | private var _firstStreamReady:Boolean; | ||
542 : | private var _firstStreamShown:Boolean; // true once we have shown the first stream | ||
543 : | private var _prevWidth:Number; | ||
544 : | private var _prevHeight:Number; | ||
545 : | |||
546 : | // properties | ||
547 : | private var _autoPlay:Boolean; | ||
548 : | private var _autoRewind:Boolean; | ||
549 : | private var _autoSize:Boolean; | ||
550 : | private var _bufferTime:Number; | ||
551 : | private var _contentPath:String; | ||
552 : | private var _cuePoints:Array; | ||
553 : | private var _idleTimeout:Number; | ||
554 : | private var _isLive:Boolean; | ||
555 : | private var _aspectRatio:Boolean; | ||
556 : | private var _playheadUpdateInterval:Number; | ||
557 : | private var _progressInterval:Number; | ||
558 : | private var _origWidth:Number; | ||
559 : | private var _origHeight:Number; | ||
560 : | private var _scaleX:Number; | ||
561 : | private var _scaleY:Number; | ||
562 : | private var _seekToPrevOffset:Number; | ||
563 : | private var _totalTime:Number; | ||
564 : | private var _transform:Object; | ||
565 : | private var _volume:Number; | ||
566 : | private var __height:Number; | ||
567 : | private var __width:Number; | ||
568 : | |||
569 : | // cache properties set directly on UIManager | ||
570 : | private var _backButton:MovieClip; | ||
571 : | private var _bufferingBar:MovieClip; | ||
572 : | private var _bufferingBarHides:Boolean; | ||
573 : | private var _forwardButton:MovieClip; | ||
574 : | private var _pauseButton:MovieClip; | ||
575 : | private var _playButton:MovieClip; | ||
576 : | private var _playPauseButton:MovieClip; | ||
577 : | private var _seekBar:MovieClip; | ||
578 : | private var _seekBarInterval:Number; | ||
579 : | private var _seekBarScrubTolerance:Number; | ||
580 : | private var _skin:String; | ||
581 : | private var _skinAutoHide:Boolean; | ||
582 : | private var _stopButton:MovieClip; | ||
583 : | private var _muteButton:MovieClip; | ||
584 : | private var _volumeBar:MovieClip; | ||
585 : | private var _volumeBarInterval:Number; | ||
586 : | private var _volumeBarScrubTolerance:Number; | ||
587 : | |||
588 : | // EventDispatcher mixins | ||
589 : | public var addEventListener:Function; | ||
590 : | public var removeEventListener:Function; | ||
591 : | public var dispatchEvent:Function; | ||
592 : | public var dispatchQueue:Function; | ||
593 : | |||
594 : | // this line forces compilation of the NCManager | ||
595 : | private var __forceNCMgr:NCManager; | ||
596 : | |||
597 : | //ifdef DEBUG | ||
598 : | ///** | ||
599 : | // * @private | ||
600 : | // */ | ||
601 : | //var _debuggingOn:Boolean = false; | ||
602 : | ///** | ||
603 : | // * @private | ||
604 : | // */ | ||
605 : | //var _debugFn:Function = null; | ||
606 : | //endif | ||
607 : | |||
608 : | // when seekToPrevNavCuePoint compares its time against the | ||
609 : | // previous cue point, it uses this delta to be sure that if | ||
610 : | // you are just ahead of a cue point, you can hop over it to | ||
611 : | // the previous and not get stuck going to the same one over | ||
612 : | // and over if you are playing. In seconds | ||
613 : | private static var SEEK_TO_PREV_OFFSET_DEFAULT:Number = 1; | ||
614 : | |||
615 : | // | ||
616 : | // public methods | ||
617 : | // | ||
618 : | |||
619 : | /** | ||
620 : | * constructor | ||
621 : | */ | ||
622 : | public function FLVPlayback() { | ||
623 : | // add EventDispatcher mixins | ||
624 : | EventDispatcher.initialize(this); | ||
625 : | |||
626 : | // set properties to defaults note that these faults are | ||
627 : | // in line with the VideoPlayer defaults, so they do not | ||
628 : | // have to be set on the VideoPlayer object as well. | ||
629 : | if (_autoPlay == undefined) _autoPlay = true; | ||
630 : | if (_autoRewind == undefined) _autoRewind = true; | ||
631 : | if (_autoSize == undefined) _autoSize = false; | ||
632 : | if (_bufferTime == undefined) _bufferTime = 0.1; | ||
633 : | if (_contentPath == undefined) _contentPath = ""; | ||
634 : | if (_cuePoints == undefined) _cuePoints = null; | ||
635 : | if (_idleTimeout == undefined) _idleTimeout = VideoPlayer.DEFAULT_IDLE_TIMEOUT_INTERVAL; | ||
636 : | if (_isLive == undefined) _isLive = false; | ||
637 : | if (_aspectRatio == undefined) _aspectRatio = true; | ||
638 : | if (_seekToPrevOffset == undefined) _seekToPrevOffset = SEEK_TO_PREV_OFFSET_DEFAULT; | ||
639 : | if (_playheadUpdateInterval == undefined) _playheadUpdateInterval = VideoPlayer.DEFAULT_UPDATE_PROGRESS_INTERVAL; | ||
640 : | if (_progressInterval == undefined) _progressInterval = VideoPlayer.DEFAULT_UPDATE_TIME_INTERVAL | ||
641 : | if (_totalTime == undefined) _totalTime = 0; | ||
642 : | if (_transform == undefined) _transform = null; | ||
643 : | if (_volume == undefined) _volume = 100; | ||
644 : | if (_skinAutoHide == undefined) _skinAutoHide = false; | ||
645 : | if (_bufferingBarHides == undefined) _bufferingBarHides = false; | ||
646 : | |||
647 : | // have to manage our own height and width and set scale | ||
648 : | // to 100 otherwise VideoPlayer and skins within component | ||
649 : | // will be scaled. | ||
650 : | _origHeight =_prevHeight = __height = this._height; | ||
651 : | _origWidth = _prevWidth = __width = this._width; | ||
652 : | _scaleX = 100; | ||
653 : | _scaleY = 100; | ||
654 : | this._xscale = 100; | ||
655 : | this._yscale = 100; | ||
656 : | |||
657 : | // state | ||
658 : | _preSeekTime = -1; | ||
659 : | _firstStreamReady = false; | ||
660 : | _firstStreamShown = false; | ||
661 : | |||
662 : | // create UIManager | ||
663 : | createUIManager(); | ||
664 : | |||
665 : | // create VideoPlayer and CuePointManager | ||
666 : | _activeVP = 0; | ||
667 : | _visibleVP = 0; | ||
668 : | _topVP = 0; | ||
669 : | _vp = new Array(); | ||
670 : | _vpState = new Array(); | ||
671 : | _cpMgr = new Array(); | ||
672 : | createVideoPlayer(0); | ||
673 : | // hide until skin and stream ready | ||
674 : | _vp[0].visible = false; | ||
675 : | _vp[0].volume = 0; | ||
676 : | |||
677 : | // remove boundingBox_mc | ||
678 : | boundingBox_mc._visible = false; | ||
679 : | boundingBox_mc.unloadMovie(); | ||
680 : | delete boundingBox_mc; | ||
681 : | |||
682 : | // setup live preview look | ||
683 : | if (_global.isLivePreview) { | ||
684 : | createLivePreviewMovieClip(); | ||
685 : | setSize(__width, __height); | ||
686 : | } | ||
687 : | |||
688 : | // if cuePoints property set, add and disable now that CuePointManager is created | ||
689 : | _cpMgr[0].processCuePointsProperty(_cuePoints); | ||
690 : | delete _cuePoints; | ||
691 : | _cuePoints = null; | ||
692 : | } | ||
693 : | |||
694 : | /** | ||
695 : | * <p>set width and height simultaneously. Since setting either | ||
696 : | * one can trigger an autoresize, this can be better than invoking | ||
697 : | * set width and set height individually.</p> | ||
698 : | * | ||
699 : | * <p>If autoSize is true then this has no effect, since the player | ||
700 : | * sets its own dimensions. If maintainAspectRatio is true and | ||
701 : | * autoSize is false, then changing width or height will trigger | ||
702 : | * an autoresize.</p> | ||
703 : | * | ||
704 : | * @param width | ||
705 : | * @param height | ||
706 : | * @see width | ||
707 : | * @see height | ||
708 : | */ | ||
709 : | public function setSize(w:Number, h:Number):Void | ||
710 : | { | ||
711 : | if (_global.isLivePreview) { | ||
712 : | if (preview_mc == undefined) createLivePreviewMovieClip(); | ||
713 : | preview_mc.box_mc._width = w; | ||
714 : | preview_mc.box_mc._height = h; | ||
715 : | if ( preview_mc.box_mc._width < preview_mc.icon_mc._width || | ||
716 : | preview_mc.box_mc._height < preview_mc.icon_mc._height ) { | ||
717 : | preview_mc.icon_mc._visible = false; | ||
718 : | } else { | ||
719 : | preview_mc.icon_mc._visible = true; | ||
720 : | preview_mc.icon_mc._x = (preview_mc.box_mc._width - preview_mc.icon_mc._width) / 2; | ||
721 : | preview_mc.icon_mc._y = (preview_mc.box_mc._height - preview_mc.icon_mc._height) / 2; | ||
722 : | } | ||
723 : | } | ||
724 : | if (w == width && h == height) return; | ||
725 : | _prevWidth = __width = w; | ||
726 : | _prevHeight = __height = h; | ||
727 : | for (var i:Number = 0; i < _vp.length; i++) { | ||
728 : | if (_vp[i] != undefined) { | ||
729 : | _vp[i].setSize(w, h); | ||
730 : | } | ||
731 : | } | ||
732 : | dispatchEvent({type:"resize", x:this.x, y:this.y, width:w, height:h}); | ||
733 : | } | ||
734 : | |||
735 : | /** | ||
736 : | * <p>set scaleX and scaleY simultaneously. Since setting either | ||
737 : | * one can trigger an autoresize, this can be better than invoking | ||
738 : | * set width and set height individually.</p> | ||
739 : | * | ||
740 : | * <p>If autoSize is true then this has no effect, since the player | ||
741 : | * sets its own dimensions. If maintainAspectRatio is true and | ||
742 : | * autoSize is false, then changing scaleX or scaleY will trigger an | ||
743 : | * autoresize.</p> | ||
744 : | * | ||
745 : | * @param scaleX | ||
746 : | * @param scaleY | ||
747 : | * @see scaleX | ||
748 : | * @see scaleY | ||
749 : | */ | ||
750 : | public function setScale(xs:Number, ys:Number) { | ||
751 : | if (xs == scaleX && ys == scaleY) return; | ||
752 : | _scaleX = xs; | ||
753 : | _scaleY = ys; | ||
754 : | for (var i:Number = 0; i < _vp.length; i++) { | ||
755 : | if (_vp[i] != undefined) { | ||
756 : | _vp[i].setSize(_origWidth * xs / 100, _origHeight * ys / 100); | ||
757 : | } | ||
758 : | } | ||
759 : | dispatchEvent({type:"resize", x:this.x, y:this.y, width:this.width, height:this.height}); | ||
760 : | } | ||
761 : | |||
762 : | /** | ||
763 : | * Sets scaleX and scaleY simultaneously. | ||
764 : | * | ||
765 : | * @private | ||
766 : | */ | ||
767 : | private function handleEvent(e:Object):Void { | ||
768 : | var eventState:String = e.state; | ||
769 : | if (e.state != undefined && e.target._name == _visibleVP && scrubbing) { | ||
770 : | eventState = SEEKING; | ||
771 : | } | ||
772 : | if (e.type == "metadataReceived") { | ||
773 : | _cpMgr[e.target._name].processFLVCuePoints(e.info.cuePoints); | ||
774 : | dispatchEvent({type:e.type, info:e.info, vp:e.target._name}); | ||
775 : | } else if (e.type == "cuePoint") { | ||
776 : | if (_cpMgr[e.target._name].isFLVCuePointEnabled(e.info)) { | ||
777 : | dispatchEvent({type:e.type, info:e.info, vp:e.target._name}); | ||
778 : | } | ||
779 : | } else if (e.type == "rewind") { | ||
780 : | dispatchEvent({type:e.type, auto:true, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
781 : | _cpMgr[e.target._name].resetASCuePointIndex(e.playheadTime); | ||
782 : | } else if (e.type == "resize") { | ||
783 : | dispatchEvent({type:e.type, x:x, y:y, width:width, height:height, auto:true, vp:e.target._name}); | ||
784 : | _prevWidth = __width; | ||
785 : | _prevHeight = __height; | ||
786 : | } else if (e.type == "playheadUpdate") { | ||
787 : | dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
788 : | if (_preSeekTime >= 0 && e.target.state != SEEKING) { | ||
789 : | var preSeekTime:Number = _preSeekTime; | ||
790 : | _preSeekTime = -1; | ||
791 : | _cpMgr[e.target._name].resetASCuePointIndex(e.playheadTime); | ||
792 : | dispatchEvent({type:"seek", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
793 : | if (preSeekTime < e.playheadTime) { | ||
794 : | dispatchEvent({type:"fastForward", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
795 : | } else if (preSeekTime > e.playheadTime) { | ||
796 : | dispatchEvent({type:"rewind", auto:false, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
797 : | } | ||
798 : | } | ||
799 : | _cpMgr[e.target._name].dispatchASCuePoints(); | ||
800 : | } else if (e.type == "stateChange") { | ||
801 : | var whichVP:Number = e.target._name; | ||
802 : | |||
803 : | // suppress stateChange events while scrubbing | ||
804 : | if (whichVP == _visibleVP && scrubbing) return; | ||
805 : | |||
806 : | // suppress RESIZING state, just needed for internal | ||
807 : | // VideoPlayer use anyways, make it LOADING, less confusing | ||
808 : | // for user, esp when suppressing STOPPED as we do below... | ||
809 : | if (e.state == VideoPlayer.RESIZING) return; | ||
810 : | |||
811 : | // suppress STOPPED stateChange at beginning when autoPlay | ||
812 : | // is on and waiting for skin to download to show all at once | ||
813 : | if (_vpState[whichVP].prevState == LOADING && _vpState[whichVP].autoPlay && e.state == STOPPED) { | ||
814 : | return; | ||
815 : | } | ||
816 : | |||
817 : | _vpState[whichVP].prevState = e.state; | ||
818 : | dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
819 : | |||
820 : | // check to be sure did not change out from under me before dispatching second event | ||
821 : | if (_vp[e.target._name].state != eventState) return; | ||
822 : | |||
823 : | switch (eventState) { | ||
824 : | case BUFFERING: | ||
825 : | dispatchEvent({type:"buffering", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
826 : | break; | ||
827 : | case PAUSED: | ||
828 : | dispatchEvent({type:"paused", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
829 : | break; | ||
830 : | case PLAYING: | ||
831 : | dispatchEvent({type:"playing", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
832 : | break; | ||
833 : | case STOPPED: | ||
834 : | dispatchEvent({type:"stopped", state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
835 : | break; | ||
836 : | } // switch | ||
837 : | |||
838 : | } else if (e.type == "progress") { | ||
839 : | dispatchEvent({type:e.type, bytesLoaded:e.bytesLoaded, bytesTotal:e.bytesTotal, vp:e.target._name}); | ||
840 : | } else if(e.type == "ready") { | ||
841 : | var whichVP:Number = e.target._name; | ||
842 : | if (!_firstStreamReady) { | ||
843 : | if (whichVP == _visibleVP) { | ||
844 : | _firstStreamReady = true; | ||
845 : | if (_uiMgr.skinReady && !_firstStreamShown) { | ||
846 : | _uiMgr.visible = true; | ||
847 : | showFirstStream(); | ||
848 : | } | ||
849 : | } | ||
850 : | } else if (_firstStreamShown && eventState == STOPPED && _vpState[whichVP].autoPlay) { | ||
851 : | _vp[whichVP].play(); | ||
852 : | } | ||
853 : | dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
854 : | } else if (e.type == "close" || e.type == "complete") { | ||
855 : | dispatchEvent({type:e.type, state:eventState, playheadTime:e.playheadTime, vp:e.target._name}); | ||
856 : | } | ||
857 : | } | ||
858 : | |||
859 : | /** | ||
860 : | * <p>Shortcut for setting property <code>autoPlay</code> to false | ||
861 : | * and setting isLive, totalTime and contentPath properties if | ||
862 : | * given. If totalTime and/or isLive properties are undefined | ||
863 : | * then they will not be set. If contentPath is undefined, null | ||
864 : | * or empty string then this function does nothing.</p> | ||
865 : | * | ||
866 : | * @param contentPath | ||
867 : | * @param totalTime | ||
868 : | * @param isLive | ||
869 : | */ | ||
870 : | public function load(contentPath:String, totalTime:Number, isLive:Boolean):Void { | ||
871 : | if (_vp[_activeVP] == undefined) return; | ||
872 : | if (contentPath == undefined || contentPath == null || contentPath == "") { | ||
873 : | return; | ||
874 : | } | ||
875 : | this.autoPlay = false; | ||
876 : | if (totalTime != undefined) this.totalTime = totalTime; | ||
877 : | if (isLive != undefined) this.isLive = isLive; | ||
878 : | this.contentPath = contentPath; | ||
879 : | } | ||
880 : | |||
881 : | /** | ||
882 : | * <p>play. With no args, just takes FLV from paused or stop | ||
883 : | * state to play state.</p> | ||
884 : | * | ||
885 : | * <p>With args, acts as a shortcut for setting property | ||
886 : | * <code>autoPlay</code> to true and setting isLive, totalTime and | ||
887 : | * contentPath properties if given. If totalTime and/or isLive | ||
888 : | * properties are undefined then they will not be set.</p> | ||
889 : | * | ||
890 : | * @param contentPath | ||
891 : | * @param totalTime | ||
892 : | * @param isLive | ||
893 : | */ | ||
894 : | public function play(contentPath:String, totalTime:Number, isLive:Boolean):Void { | ||
895 : | if (_vp[_activeVP] == undefined) return; | ||
896 : | if (contentPath == undefined) { | ||
897 : | _vp[_activeVP].play(); | ||
898 : | } else { | ||
899 : | this.autoPlay = true; | ||
900 : | if (totalTime != undefined) this.totalTime = totalTime; | ||
901 : | if (isLive != undefined) this.isLive = isLive; | ||
902 : | this.contentPath = contentPath; | ||
903 : | } | ||
904 : | } | ||
905 : | |||
906 : | /** | ||
907 : | * pause | ||
908 : | */ | ||
909 : | public function pause():Void { | ||
910 : | if (_vp[_activeVP] == undefined) return; | ||
911 : | _vp[_activeVP].pause(); | ||
912 : | } | ||
913 : | |||
914 : | /** | ||
915 : | * stop | ||
916 : | */ | ||
917 : | public function stop():Void { | ||
918 : | if (_vp[_activeVP] == undefined) return; | ||
919 : | _vp[_activeVP].stop(); | ||
920 : | } | ||
921 : | |||
922 : | /** | ||
923 : | * <p>Seeks to a given time in the file, given in seconds, | ||
924 : | * decimal precision up to milliseconds.</p> | ||
925 : | * | ||
926 : | * @throws VideoError if time is < 0 | ||
927 : | * @see VideoPlayer#seek() | ||
928 : | */ | ||
929 : | public function seek(time:Number):Void { | ||
930 : | if (_vp[_activeVP] == undefined) return; | ||
931 : | _preSeekTime = playheadTime; | ||
932 : | _vp[_activeVP].seek(time); | ||
933 : | } | ||
934 : | |||
935 : | /** | ||
936 : | * <p>Same as <code>seek()</code></p> | ||
937 : | * | ||
938 : | * @see #seek() | ||
939 : | */ | ||
940 : | public function seekSeconds(time:Number):Void { | ||
941 : | seek(time); | ||
942 : | } | ||
943 : | |||
944 : | /** | ||
945 : | * <p>Seeks to a percentage of the way through the file. | ||
946 : | * Takes a number between 0 and 100.</p> | ||
947 : | * | ||
948 : | * @throws VideoError if percent is invalid or if totalTime is | ||
949 : | * undefined, null or <= 0 | ||
950 : | * @see #seek() | ||
951 : | */ | ||
952 : | public function seekPercent(percent:Number):Void { | ||
953 : | if (_vp[_activeVP] == undefined) return; | ||
954 : | if ( percent < 0 || percent > 100 || | ||
955 : | _vp[_activeVP].totalTime == undefined || | ||
956 : | _vp[_activeVP].totalTime == null || | ||
957 : | _vp[_activeVP].totalTime <= 0 ) { | ||
958 : | throw new VideoError(VideoError.INVALID_SEEK); | ||
959 : | } | ||
960 : | seek(_vp[_activeVP].totalTime * percent / 100); | ||
961 : | } | ||
962 : | |||
963 : | /** | ||
964 : | * <p>Gets the percentage played. | ||
965 : | * Returns a number between 0 and 100.</p> | ||
966 : | * | ||
967 : | */ | ||
968 : | public function get playheadPercentage():Number | ||
969 : | { | ||
970 : | if ( _vp[_activeVP].totalTime == undefined || | ||
971 : | _vp[_activeVP].totalTime == null || | ||
972 : | _vp[_activeVP].totalTime <= 0 ) { | ||
973 : | return undefined; | ||
974 : | } | ||
975 : | return _vp[_activeVP].playheadTime / _vp[_activeVP].totalTime * 100; | ||
976 : | } | ||
977 : | |||
978 : | /** | ||
979 : | * <p>Seeks to a percentage of the way through the file. | ||
980 : | * Takes a number between 0 and 100.</p> | ||
981 : | * | ||
982 : | * @throws VideoError if percent is invalid or if totalTime is | ||
983 : | * undefined, null or <= 0 | ||
984 : | * @see #seek() | ||
985 : | */ | ||
986 : | public function set playheadPercentage(percent:Number) | ||
987 : | { | ||
988 : | seekPercent(percent); | ||
989 : | } | ||
990 : | |||
991 : | /** | ||
992 : | * <p>Seeks to navigation cue point with the given name at or | ||
993 : | * after given time. Starts search at time 0 if time is | ||
994 : | * undefined, null or less than 0. If name is undefined or null, | ||
995 : | * behaves like seekToNextNavCuePoint().</p> | ||
996 : | * | ||
997 : | * @param timeNameOrCuePoint If String, then name of cue point to | ||
998 : | * search for. Seeks to first enabled navigation cue point with | ||
999 : | * this name. | ||
1000 : | * | ||
1001 : | * <p>If Number, time of cue point to seek to. If only time | ||
1002 : | * given, behaves like seekToNextNavCuePoint</p> | ||
1003 : | * | ||
1004 : | * <p>If Object, then cuepoint object containing time and/or name | ||
1005 : | * properties for search. Seek to next cue point with this name | ||
1006 : | * at or after the given time. | ||
1007 : | * @throws VideoError if no cue point that matches criteria is found | ||
1008 : | * @see #seek() | ||
1009 : | * @see #seekToPrevNavCuePoint() | ||
1010 : | * @see #seekToNextNavCuePoint() | ||
1011 : | * @see #findCuePoint() | ||
1012 : | * @see #isFLVCuePointEnabled() | ||
1013 : | */ | ||
1014 : | public function seekToNavCuePoint(timeNameOrCuePoint:Object):Void { | ||
1015 : | var cuePoint:Object; | ||
1016 : | switch (typeof timeNameOrCuePoint) { | ||
1017 : | case "string": | ||
1018 : | cuePoint = {name:timeNameOrCuePoint}; | ||
1019 : | break; | ||
1020 : | case "number": | ||
1021 : | cuePoint = {time:timeNameOrCuePoint}; | ||
1022 : | break; | ||
1023 : | case "object": | ||
1024 : | cuePoint = timeNameOrCuePoint; | ||
1025 : | break; | ||
1026 : | } // switch | ||
1027 : | |||
1028 : | // just seek to next if no name | ||
1029 : | if ( cuePoint.name == null || | ||
1030 : | cuePoint.name == undefined || | ||
1031 : | typeof cuePoint.name != "string" ) { | ||
1032 : | seekToNextNavCuePoint(cuePoint.time); | ||
1033 : | return; | ||
1034 : | } | ||
1035 : | |||
1036 : | // get next enabled cue point with this name | ||
1037 : | if (isNaN(cuePoint.time)) cuePoint.time = 0; | ||
1038 : | var navCuePoint:Object = findNearestCuePoint(timeNameOrCuePoint, NAVIGATION); | ||
1039 : | while ( navCuePoint != null && | ||
1040 : | ( navCuePoint.time < cuePoint.time || (!isFLVCuePointEnabled(navCuePoint)) ) ) { | ||
1041 : | navCuePoint = findNextCuePointWithName(navCuePoint); | ||
1042 : | } | ||
1043 : | if (navCuePoint == null) throw new VideoError(VideoError.INVALID_SEEK); | ||
1044 : | seek(navCuePoint.time); | ||
1045 : | } | ||
1046 : | |||
1047 : | /** | ||
1048 : | * <p>Seeks to next navigation cue point, based on current | ||
1049 : | * playheadTime. Goes to the end if there is no next cue | ||
1050 : | * point. Navigation cue points disabled by ActionScript | ||
1051 : | * will be skipped.</p> | ||
1052 : | * | ||
1053 : | * @param time starting time from where to look for next | ||
1054 : | * navigation cue point. Default is current playheadTime | ||
1055 : | * @see #cuePoints | ||
1056 : | * @see #seek() | ||
1057 : | * @see #seekToNavCuePoint() | ||
1058 : | * @see #seekToPrevNavCuePoint() | ||
1059 : | * @see #findCuePoint() | ||
1060 : | * @see #isFLVCuePointEnabled() | ||
1061 : | */ | ||
1062 : | public function seekToNextNavCuePoint(time:Number):Void { | ||
1063 : | if (_vp[_activeVP] == undefined) return; | ||
1064 : | if (isNaN(time) || time < 0) { | ||
1065 : | time = _vp[_activeVP].playheadTime + 0.001; | ||
1066 : | } | ||
1067 : | var cuePoint:Object; | ||
1068 : | cuePoint = findNearestCuePoint(time, NAVIGATION); | ||
1069 : | if (cuePoint == null) { | ||
1070 : | //if no cue points could be found, go to the end | ||
1071 : | seek(_vp[_activeVP].totalTime); | ||
1072 : | return; | ||
1073 : | } | ||
1074 : | var index:Number = cuePoint.index; | ||
1075 : | if (cuePoint.time < time) index++; | ||
1076 : | while (index < cuePoint.array.length && !isFLVCuePointEnabled(cuePoint.array[index])) { | ||
1077 : | index++; | ||
1078 : | } | ||
1079 : | if (index >= cuePoint.array.length) { | ||
1080 : | //if no cue points could be found, go to the end | ||
1081 : | var seekTime:Number = _vp[_activeVP].totalTime; | ||
1082 : | // if the last navigation point in the array is past what | ||
1083 : | // we think is the end time, use that instead (even if | ||
1084 : | // disabled). | ||
1085 : | if (cuePoint.array[cuePoint.array.length - 1].time > seekTime) { | ||
1086 : | seekTime = cuePoint.array[cuePoint.array.length - 1]; | ||
1087 : | } | ||
1088 : | seek(seekTime); | ||
1089 : | } else { | ||
1090 : | seek(cuePoint.array[index].time); | ||
1091 : | } | ||
1092 : | } | ||
1093 : | |||
1094 : | /** | ||
1095 : | * <p>Seeks to previous navigation cue point, based on current | ||
1096 : | * playheadTime. Goes to beginning if there is no previous | ||
1097 : | * cue point. Navigation cue points disabled by ActionScript | ||
1098 : | * will be skipped.</p> | ||
1099 : | * | ||
1100 : | * @param time starting time from where to look for next | ||
1101 : | * navigation cue point. Default is current playheadTime | ||
1102 : | * @see #cuePoints | ||
1103 : | * @see #seek() | ||
1104 : | * @see #seekToNavCuePoint() | ||
1105 : | * @see #seekToNextNavCuePoint() | ||
1106 : | * @see #findCuePoint() | ||
1107 : | * @see #isFLVCuePointEnabled() | ||
1108 : | */ | ||
1109 : | public function seekToPrevNavCuePoint(time:Number):Void { | ||
1110 : | if (_vp[_activeVP] == undefined) return; | ||
1111 : | if (isNaN(time) || time < 0) { | ||
1112 : | time = _vp[_activeVP].playheadTime; | ||
1113 : | } | ||
1114 : | var cuePoint:Object = findNearestCuePoint(time, NAVIGATION); | ||
1115 : | if (cuePoint == null) { | ||
1116 : | // if no cue points could be found, go to the beginning | ||
1117 : | seek(0); | ||
1118 : | return; | ||
1119 : | } | ||
1120 : | var index:Number = cuePoint.index; | ||
1121 : | while ( index >= 0 && | ||
1122 : | ( !isFLVCuePointEnabled(cuePoint.array[index]) || | ||
1123 : | cuePoint.array[index].time >= time - _seekToPrevOffset ) ) { | ||
1124 : | index--; | ||
1125 : | } | ||
1126 : | if (index < 0) { | ||
1127 : | seek(0); | ||
1128 : | } else { | ||
1129 : | seek(cuePoint.array[index].time); | ||
1130 : | } | ||
1131 : | } | ||
1132 : | |||
1133 : | /** | ||
1134 : | * <p>Add an ActionScript cue point.</p> | ||
1135 : | * | ||
1136 : | * <p>Cue point information is wiped out when contentPath property | ||
1137 : | * is set, so to set cue point info for the next FLV to be loaded, | ||
1138 : | * set contentPath first.</p> | ||
1139 : | * | ||
1140 : | * <p>It is legal to add multiple AS cue points with the same | ||
1141 : | * name and time. When removeASCuePoint is called with this | ||
1142 : | * name and time, all will be removed.</p> | ||
1143 : | * | ||
1144 : | * @param timeOrCuePoint If Object, then object describing the cue | ||
1145 : | * point. Must have a name:String and time:Number (in seconds) | ||
1146 : | * property. May have a parameters:Object property that holds | ||
1147 : | * name/value pairs. May have type:String set to "actionscript", | ||
1148 : | * if it is missing or set to something else it will be set | ||
1149 : | * automatically. If the Object does not conform to these | ||
1150 : | * conventions, a <code>VideoError</code> will be thrown. | ||
1151 : | * | ||
1152 : | * <p>If Number, then time for new cue point to be added | ||
1153 : | * and name parameter must follow.</p> | ||
1154 : | * @param name Name for cuePoint if timeOrCuePoint parameter | ||
1155 : | * is a Number. | ||
1156 : | * @param parameters Optional parameters for cuePoint if | ||
1157 : | * timeOrCuePoint parameter is a Number. | ||
1158 : | * @returns The cuePoint Object added. Read only: edits to this | ||
1159 : | * Object will effect "cuePoint" event dispatch. | ||
1160 : | * | ||
1161 : | * @throws VideoError if parameters are invalid | ||
1162 : | * @see #findCuePoint() | ||
1163 : | * @see #removeASCuePoint() | ||
1164 : | * @see CuePointManager#addASCuePoint() | ||
1165 : | */ | ||
1166 : | public function addASCuePoint(timeOrCuePoint:Object, name:String, parameters:Object):Number { | ||
1167 : | return _cpMgr[_activeVP].addASCuePoint(timeOrCuePoint, name, parameters); | ||
1168 : | } | ||
1169 : | |||
1170 : | /** | ||
1171 : | * <p>Remove an ActionScript cue point from the currently | ||
1172 : | * loaded FLV. Only the name and time properties are used | ||
1173 : | * from the cuePoint parameter to find the cue point to be | ||
1174 : | * removed.</p> | ||
1175 : | * | ||
1176 : | * <p>If multiple AS cue points match the search criteria, only | ||
1177 : | * one will be removed. To remove all, call this function | ||
1178 : | * repeatedly in a loop with the same parameters until it returns | ||
1179 : | * <code>null</code>.</p> | ||
1180 : | * | ||
1181 : | * <p>Cue point information is wiped out when contentPath property | ||
1182 : | * is set, so to set cue point info for the next FLV to be loaded, | ||
1183 : | * set contentPath first.</p> | ||
1184 : | * | ||
1185 : | * @param timeNameOrCuePoint If string, name of cue point to | ||
1186 : | * remove; remove first cue point with this name. If number, time | ||
1187 : | * of cue point to remove; remove first cue point at this time. | ||
1188 : | * If Object, then object with name and time properties, remove | ||
1189 : | * cue point with both this name and time. | ||
1190 : | * @returns The cue point that was removed. If there was no | ||
1191 : | * matching cue point then <code>null</code> is returned. | ||
1192 : | * @see #addASCuePoint() | ||
1193 : | * @see #findCuePoint() | ||
1194 : | * @see #removeASCuePoint() | ||
1195 : | */ | ||
1196 : | public function removeASCuePoint(timeNameOrCuePoint:Object):Object { | ||
1197 : | return _cpMgr[_activeVP].removeASCuePoint(timeNameOrCuePoint); | ||
1198 : | } | ||
1199 : | |||
1200 : | /** | ||
1201 : | * <p>Find the cue point at the given time and/or with given name. | ||
1202 : | * Which type of cue points searched is determined by optional | ||
1203 : | * <code>type</code> parameter. Default is to search all cue | ||
1204 : | * points. Note that disabled cue points are also included in the | ||
1205 : | * search, use isFLVCuePointEnabled. How the cue points are | ||
1206 : | * searched depends on the type of the first argument.</p> | ||
1207 : | * | ||
1208 : | * @param timeNameOrCuePoint If String, then name of cue point to | ||
1209 : | * search for. Return the first cue point with this name, or null | ||
1210 : | * if no match. | ||
1211 : | * | ||
1212 : | * <p>If Number, time of cue point to search for. Only first | ||
1213 : | * three decimal places of time used for search, any more than | ||
1214 : | * that will be rounded. Returns the first cue point with this | ||
1215 : | * time (If there are multiples with same time, which is only | ||
1216 : | * possible with ActionScript cue points, then the one with the | ||
1217 : | * first name alphabetically will be returned.) Returns null if | ||
1218 : | * no match.</p> | ||
1219 : | * | ||
1220 : | * <p>If Object, then cuepoint object containing time and/or name | ||
1221 : | * properties for search. If name is undefined or null, then | ||
1222 : | * search behaves same as described above for time only search. | ||
1223 : | * If time is undefined, null or less than 0, then search behaves | ||
1224 : | * same as described above for name only search. If both time | ||
1225 : | * and name are defined and a cue point exists with both that | ||
1226 : | * time and name, then it is returned, otherwise null is returned.</p> | ||
1227 : | * | ||
1228 : | * <p>If time is null, undefined or less than 0 and name is null | ||
1229 : | * or undefined, a VideoError is thrown.</p> | ||
1230 : | * | ||
1231 : | * @param type determines what class of cue points is searched. | ||
1232 : | * possible values are "all", "navigation", "event", "flv", | ||
1233 : | * "actionscript". There are constants defined for each of these. | ||
1234 : | * | ||
1235 : | * @returns <code>null</code> if no match was found, otherwise | ||
1236 : | * copy of cuePoint object with additional properties: | ||
1237 : | * | ||
1238 : | * <ul> | ||
1239 : | * | ||
1240 : | * <li><code>array</code> - the array of cue points that was | ||
1241 : | * searched. Treat this array as read only as adding, removing or | ||
1242 : | * editing objects within it can cause cue points to | ||
1243 : | * malfunction.</li> | ||
1244 : | * | ||
1245 : | * <li><code>index</code> - the index into the array for the | ||
1246 : | * returned cuepoint.</li> | ||
1247 : | * | ||
1248 : | * </ul> | ||
1249 : | * @see #ALL | ||
1250 : | * @see #EVENT | ||
1251 : | * @see #NAVIGATION | ||
1252 : | * @see #FLV | ||
1253 : | * @see #ACTIONSCRIPT | ||
1254 : | * @see #cuePoints | ||
1255 : | * @see #addASCuePoint() | ||
1256 : | * @see #removeASCuePoint() | ||
1257 : | * @see #findNearestCuePoint() | ||
1258 : | * @see CuePointManager#getCuePoint() | ||
1259 : | */ | ||
1260 : | public function findCuePoint(timeNameOrCuePoint:Object, type:String):Object { | ||
1261 : | switch (type) { | ||
1262 : | case "event": | ||
1263 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].eventCuePoints, false, timeNameOrCuePoint); | ||
1264 : | case "navigation": | ||
1265 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].navCuePoints, false, timeNameOrCuePoint); | ||
1266 : | case "flv": | ||
1267 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].flvCuePoints, false, timeNameOrCuePoint); | ||
1268 : | case "actionscript": | ||
1269 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].asCuePoints, false, timeNameOrCuePoint); | ||
1270 : | case "all": | ||
1271 : | default: | ||
1272 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].allCuePoints, false, timeNameOrCuePoint); | ||
1273 : | } | ||
1274 : | } | ||
1275 : | |||
1276 : | /** | ||
1277 : | * <p>Find the cue point at or near the given time and/or with | ||
1278 : | * given name. Which type of cue points searched is determined by | ||
1279 : | * optional <code>type</code> parameter. Default is to search all | ||
1280 : | * cue points. Note that disabled cue points are also included in | ||
1281 : | * the search, use isFLVCuePointEnabled. How the cue points are | ||
1282 : | * searched depends on the type of the first argument.</p> | ||
1283 : | * | ||
1284 : | * @param timeNameOrCuePoint If String, then name of cue point to | ||
1285 : | * search for. Return the first cue point with this name, or null | ||
1286 : | * if no match. | ||
1287 : | * | ||
1288 : | * <p>If Number, time of cue point to search for. Only first | ||
1289 : | * three decimal places of time used for search, any more than | ||
1290 : | * that will be rounded. If there is an exact time match, returns | ||
1291 : | * the first cue point with this time (If there are multiples with | ||
1292 : | * same time, which is only possible with ActionScript cue points, | ||
1293 : | * then the one with the first name alphabetically will be | ||
1294 : | * returned.) If the specific time is not found then the closest | ||
1295 : | * time earlier than that is returned. If there is no cue point | ||
1296 : | * earlier than time, the first cue point is returned. If there | ||
1297 : | * are no cue points, null is returned.</p> | ||
1298 : | * | ||
1299 : | * <p>If Object, then cuepoint object containing time and/or name | ||
1300 : | * properties for search. If name is undefined or null, then | ||
1301 : | * search behaves same as described above for time only search. | ||
1302 : | * If time is undefined, null or less than 0, then search behaves | ||
1303 : | * same as described above for name only search. If both time | ||
1304 : | * and name are defined and a cue point exists with both that | ||
1305 : | * time and name, then it is returned. If there is no exact | ||
1306 : | * match, then the cue point with that exact name and with the | ||
1307 : | * closest time earlier than that is returned. If there is | ||
1308 : | * no cue point with that name earlier than that time, then | ||
1309 : | * the first cue point with that name is returned. If there | ||
1310 : | * are no cue points with that name, null is returned.</p> | ||
1311 : | * | ||
1312 : | * <p>If time is null, undefined or less than 0 and name is null | ||
1313 : | * or undefined, a VideoError is thrown.</p> | ||
1314 : | * | ||
1315 : | * @param type determines what class of cue points is searched. | ||
1316 : | * possible values are "all", "navigation", "event", "flv", | ||
1317 : | * "actionscript". There are constants defined for each of these. | ||
1318 : | * | ||
1319 : | * @returns <code>null</code> if no match was found, otherwise | ||
1320 : | * copy of cuePoint object with additional properties: | ||
1321 : | * | ||
1322 : | * <ul> | ||
1323 : | * | ||
1324 : | * <li><code>array</code> - the array of cue points that was | ||
1325 : | * searched. Treat this array as read only as adding, removing or | ||
1326 : | * editing objects within it can cause cue points to | ||
1327 : | * malfunction.</li> | ||
1328 : | * | ||
1329 : | * <li><code>index</code> - the index into the array for the | ||
1330 : | * returned cuepoint.</li> | ||
1331 : | * | ||
1332 : | * </ul> | ||
1333 : | * @see #ALL | ||
1334 : | * @see #EVENT | ||
1335 : | * @see #NAVIGATION | ||
1336 : | * @see #FLV | ||
1337 : | * @see #ACTIONSCRIPT | ||
1338 : | * @see #cuePoints | ||
1339 : | * @see #addASCuePoint() | ||
1340 : | * @see #removeASCuePoint() | ||
1341 : | * @see #findCuePoint() | ||
1342 : | * @see CuePointManager#getCuePoint() | ||
1343 : | */ | ||
1344 : | public function findNearestCuePoint(timeNameOrCuePoint:Object, type:String):Object { | ||
1345 : | switch (type) { | ||
1346 : | case "event": | ||
1347 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].eventCuePoints, true, timeNameOrCuePoint); | ||
1348 : | case "navigation": | ||
1349 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].navCuePoints, true, timeNameOrCuePoint); | ||
1350 : | case "flv": | ||
1351 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].flvCuePoints, true, timeNameOrCuePoint); | ||
1352 : | case "actionscript": | ||
1353 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].asCuePoints, true, timeNameOrCuePoint); | ||
1354 : | case "all": | ||
1355 : | default: | ||
1356 : | return _cpMgr[_activeVP].getCuePoint(_cpMgr[_activeVP].allCuePoints, true, timeNameOrCuePoint); | ||
1357 : | } | ||
1358 : | } | ||
1359 : | |||
1360 : | /** | ||
1361 : | * <p>Given a cue point object returned from findCuePoint or | ||
1362 : | * findNearestCuePoint (needs the index and array properties added | ||
1363 : | * to those cue points), returns the next cue point in that array | ||
1364 : | * after that one with the same name. Returns null if no cue | ||
1365 : | * point after that one with that name. Throws VideoError if | ||
1366 : | * argument is invalid.</p> | ||
1367 : | * | ||
1368 : | * @returns <code>null</code> if no match was found, otherwise | ||
1369 : | * copy of cuePoint object with additional properties: | ||
1370 : | * | ||
1371 : | * <ul> | ||
1372 : | * | ||
1373 : | * <li><code>array</code> - the array that was searched. Treat | ||
1374 : | * this array as read only as adding, removing or editing objects | ||
1375 : | * within it can cause cue points to malfunction.</li> | ||
1376 : | * | ||
1377 : | * <li><code>index</code> - the index into the array for the | ||
1378 : | * returned cuepoint.</li> | ||
1379 : | * | ||
1380 : | * </ul> | ||
1381 : | */ | ||
1382 : | public function findNextCuePointWithName(cuePoint:Object):Object { | ||
1383 : | return _cpMgr[_activeVP].getNextCuePointWithName(cuePoint); | ||
1384 : | } | ||
1385 : | |||
1386 : | /** | ||
1387 : | * <p>Enable or disable one or more FLV cue point. Disabled cue | ||
1388 : | * points are disabled for being dispatched as events and | ||
1389 : | * navigating to them with <code>seekToPrevNavCuePoint()</code>, | ||
1390 : | * <code>seekToNextNavCuePoint()</code> and | ||
1391 : | * <code>seekToNavCuePoint()</code>.</p> | ||
1392 : | * | ||
1393 : | * <p>Cue point information is wiped out when contentPath property | ||
1394 : | * is set, so to set cue point info for the next FLV to be loaded, | ||
1395 : | * set contentPath first.</p> | ||
1396 : | * | ||
1397 : | * <p>Changes caused by calls to this function will not be | ||
1398 : | * reflected in results returned from | ||
1399 : | * <code>isFLVCuePointEnabled</code> until | ||
1400 : | * <code>metadataLoaded</code> is true.</p> | ||
1401 : | * | ||
1402 : | * @param enabled whether to enable or disable FLV cue point | ||
1403 : | * @param timeNameOrCuePoint If string, name of cue point to | ||
1404 : | * enable/disable. If number, time of cue point to | ||
1405 : | * enable/disable. If Object, then object with name and time | ||
1406 : | * properties, enable/disable cue point that matches both name and | ||
1407 : | * time. | ||
1408 : | * @returns If <code>metadataLoaded</code> is true, returns number | ||
1409 : | * of cue points whose enabled state was changed. If | ||
1410 : | * <code>metadataLoaded</code> is false, always returns -1. | ||
1411 : | * @see #cuePoints | ||
1412 : | * @see #isFLVCuePointEnabled() | ||
1413 : | * @see #findCuePoint() | ||
1414 : | * @see #findNearestCuePoint() | ||
1415 : | * @see #findNextCuePointWithName() | ||
1416 : | * @see CuePointManager#setFLVCuePointEnabled() | ||
1417 : | */ | ||
1418 : | public function setFLVCuePointEnabled(enabled:Boolean, timeNameOrCuePoint:Object):Number { | ||
1419 : | return _cpMgr[_activeVP].setFLVCuePointEnabled(enabled, timeNameOrCuePoint); | ||
1420 : | } | ||
1421 : | |||
1422 : | /** | ||
1423 : | * <p>Returns false if FLV embedded cue point is disabled by | ||
1424 : | * ActionScript. Cue points are disabled via setting the | ||
1425 : | * <code>cuePoints</code> property or by calling | ||
1426 : | * <code>setFLVCuePointEnabled()</code>.</p> | ||
1427 : | * | ||
1428 : | * <p>The return value from this function is only meaningful when | ||
1429 : | * <code>metadataLoaded</code> is true (or <code>metadata</code> | ||
1430 : | * property is nonnull, or after "metadataReceived" event). It always | ||
1431 : | * returns true when <code>metadataLoaded</code> is false.</p> | ||
1432 : | * | ||
1433 : | * @param timeNameOrCuePoint If string, name of cue point to | ||
1434 : | * check; return false only if ALL cue points with this name are | ||
1435 : | * disabled. If number, time of cue point to check. If Object, | ||
1436 : | * then object with name and time properties, check cue point that | ||
1437 : | * matches both name and time. | ||
1438 : | * @returns false if cue point(s) is found and is disabled, true | ||
1439 : | * either if no such cue point exists or if it is not disabled. | ||
1440 : | * If time given is undefined, null or less than 0 then returns | ||
1441 : | * false only if all cue points with this name are disabled. | ||
1442 : | * | ||
1443 : | * <p>The return value from this function is only meaningful when | ||
1444 : | * <code>metadataLoaded</code> is true. It always returns true when it | ||
1445 : | * is false.</p> | ||
1446 : | * @see #findCuePoint() | ||
1447 : | * @see #findNearestCuePoint() | ||
1448 : | * @see #findNextCuePointWithName() | ||
1449 : | * @see #setFLVCuePointEnabled() | ||
1450 : | * @see CuePointManager#isFLVCuePointEnabled() | ||
1451 : | */ | ||
1452 : | public function isFLVCuePointEnabled(timeNameOrCuePoint:Object):Boolean { | ||
1453 : | return _cpMgr[_activeVP].isFLVCuePointEnabled(timeNameOrCuePoint); | ||
1454 : | } | ||
1455 : | |||
1456 : | /** | ||
1457 : | * Override MovieClip functionality to reserve depths less than | ||
1458 : | * 1000 for internal use (used for VideoPlayer and live preview | ||
1459 : | * placeholder. | ||
1460 : | */ | ||
1461 : | public function getNextHighestDepth():Number { | ||
1462 : | var depth:Number = super.getNextHighestDepth(); | ||
1463 : | return (depth < 1000) ? 1000 : depth; | ||
1464 : | } | ||
1465 : | |||
1466 : | /** | ||
1467 : | * Brings VideoPlayer to the front of the stack of VideoPlayers. | ||
1468 : | * Useful for custom transitions between VideoPlayers. | ||
1469 : | */ | ||
1470 : | public function bringVideoPlayerToFront(index:Number):Void { | ||
1471 : | if (index == _topVP || _vp[index] == undefined) return; | ||
1472 : | _vp[_topVP].swapDepths(_vp[index].getDepth()); | ||
1473 : | _topVP = index; | ||
1474 : | } | ||
1475 : | |||
1476 : | /** | ||
1477 : | * Get VideoPlayer with given index. When possible, it is | ||
1478 : | * best to access VideoPlayer APIs via FLVPlayback APIs. | ||
1479 : | * Each VideoPlayer._name proprety is its index. | ||
1480 : | */ | ||
1481 : | public function getVideoPlayer(index:Number):VideoPlayer { | ||
1482 : | return _vp[index]; | ||
1483 : | } | ||
1484 : | |||
1485 : | /** | ||
1486 : | * Close VideoPlayer with given index. Closes NetStream and | ||
1487 : | * deletes VideoPlayer. If the closed video player is the active | ||
1488 : | * or visible VideoPlayer, then active and/or visible VideoPlayer | ||
1489 : | * will be set to the default player (with index 0). You cannot | ||
1490 : | * close the default player, and trying to will throw an error. | ||
1491 : | */ | ||
1492 : | public function closeVideoPlayer(index:Number):VideoPlayer { | ||
1493 : | if (_vp[index] == undefined) return; | ||
1494 : | if (index == 0) throw new VideoError(VideoError.DELETE_DEFAULT_PLAYER); | ||
1495 : | if (_visibleVP == index) visibleVideoPlayerIndex = 0; | ||
1496 : | if (_activeVP == index) activeVideoPlayerIndex = 0; | ||
1497 : | _vp[index].close(); | ||
1498 : | _vp[index].unloadMovie(); | ||
1499 : | delete _vp[index]; | ||
1500 : | _vp[index] = undefined; | ||
1501 : | } | ||
1502 : | |||
1503 : | // | ||
1504 : | // public properties | ||
1505 : | // | ||
1506 : | |||
1507 : | |||
1508 : | /** | ||
1509 : | * <p>Use activeVideoPlayerIndex to manage multiple FLV streams. Sets | ||
1510 : | * which <code>VideoPlayer</code> instance is affected by most | ||
1511 : | * other APIs. Default is 0. Does not make the | ||
1512 : | * <code>VideoPlayer</code> visible, to do this use | ||
1513 : | * <code>visibleVideoPlayerIndex</code>.</p> | ||
1514 : | * | ||
1515 : | * <p>A new VideoPlayer is created the first time | ||
1516 : | * <code>activeVideoPlayerIndex</code> is set to a given number. When | ||
1517 : | * the new VideoPlayer is created, its properties are set to the | ||
1518 : | * value of the default VideoPlayer (<code>activeVideoPlayerIndex == | ||
1519 : | * 0</code>) except for contentPath, totalTime and isLive, which | ||
1520 : | * are always set to the default values (empty string, 0 and | ||
1521 : | * false, respectively), autoPlay which is always false (default | ||
1522 : | * is true for the default VideoPlayer, aka 0), and height and | ||
1523 : | * width which match those of the visibleVideoPlayerIndex. Note that | ||
1524 : | * the cuePoints property will have no effect, just as it would | ||
1525 : | * have no effect on a subsequent load into the default | ||
1526 : | * VideoPlayer.</p> | ||
1527 : | * | ||
1528 : | * <p>APIs that control volume, positioning, dimensions, | ||
1529 : | * visibility and UI controls are always global and their behavior | ||
1530 : | * is NOT affected by setting <code>activeVideoPlayerIndex</code>. The | ||
1531 : | * APIs unaffected are: backButton, bufferingBar, | ||
1532 : | * bufferingBarHidesAndDisablesOthers, forwardButton, height, | ||
1533 : | * muteButton, pauseButton, playButton, playPauseButton, scaleX, | ||
1534 : | * scaleY, seekBar, seekBarInterval, seekBarScrubTolerance, | ||
1535 : | * seekToPrevOffset, skin, transform, stopButton, visible, volume, | ||
1536 : | * volumeBar, volumeBarInterval, volumeBarScrubTolerance, width, | ||
1537 : | * x, y, setSize(), setScale()</p> | ||
1538 : | * | ||
1539 : | * <p>APIs that control dimensions do interact with | ||
1540 : | * <code>visibleVideoPlayerIndex</code>, however. See that property | ||
1541 : | * for more on that.</p> | ||
1542 : | * | ||
1543 : | * <p>APIs that target specific VideoPlayer depending on setting | ||
1544 : | * of activeVideoPlayerIndex: all the rest!</p> | ||
1545 : | * | ||
1546 : | * <p>When listening for events, you will get all events for all | ||
1547 : | * VideoPlayers. To distinguish which VideoPlayer the vent is for | ||
1548 : | * use the events <code>vp</code> property, a Number corresponding | ||
1549 : | * to the number set in activeVideoPlayerIndex and | ||
1550 : | * visibleVideoPlayerIndex. All events have this property EXCEPT for | ||
1551 : | * "resize" and "volumeUpdate" which are not specific to a VideoPlayer | ||
1552 : | * but are global for the FLVPlayback instance.</p> | ||
1553 : | * | ||
1554 : | * <p>For example, to load a second FLV in the background, set | ||
1555 : | * <code>activeVideoPlayerIndex</code> to 1 and call <code>load()</code>. | ||
1556 : | * When you are ready to show this one and hide the other one, set | ||
1557 : | * visibleVideoPlayerIndex to 1.</p> | ||
1558 : | * | ||
1559 : | * @see #visibleVideoPlayerIndex | ||
1560 : | */ | ||
1561 : | [Bindable] | ||
1562 : | public function get activeVideoPlayerIndex():Number { | ||
1563 : | return _activeVP; | ||
1564 : | } | ||
1565 : | public function set activeVideoPlayerIndex(i:Number):Void { | ||
1566 : | if (_activeVP == i) return; | ||
1567 : | // if have not done the delay load of first FLV, force it now. | ||
1568 : | if (_vp[_activeVP].onEnterFrame != undefined) { | ||
1569 : | doContentPathConnect(); | ||
1570 : | } | ||
1571 : | _activeVP = i; | ||
1572 : | if (_vp[_activeVP] == undefined) { | ||
1573 : | createVideoPlayer(_activeVP); | ||
1574 : | _vp[_activeVP].visible = false; | ||
1575 : | _vp[_activeVP].volume = 0; | ||
1576 : | } | ||
1577 : | } | ||
1578 : | |||
1579 : | /** | ||
1580 : | * <p>Determines whether the FLV is played immediately when | ||
1581 : | * contentPath property is set or if we wait. Even if | ||
1582 : | * autoPlay is false, we do load the content immediately.</p> | ||
1583 : | * | ||
1584 : | * <p>If set between loads of new FLVs, has no effect until | ||
1585 : | * next set of contentPath.</p> | ||
1586 : | * | ||
1587 : | * @see #contentPath | ||
1588 : | * @helpid 0 | ||
1589 : | */ | ||
1590 : | [Inspectable(defaultValue=true)] | ||
1591 : | public function get autoPlay():Boolean | ||
1592 : | { | ||
1593 : | if (_vpState[_activeVP] == undefined) return _autoPlay; | ||
1594 : | return _vpState[_activeVP].autoPlay; | ||
1595 : | } | ||
1596 : | public function set autoPlay(flag:Boolean):Void | ||
1597 : | { | ||
1598 : | if (_activeVP == 0 || _activeVP == undefined) _autoPlay = flag; | ||
1599 : | _vpState[_activeVP].autoPlay = flag; | ||
1600 : | } | ||
1601 : | |||
1602 : | /** | ||
1603 : | * <p>Determines whether the FLV is rewound to the first frame | ||
1604 : | * when play stops, either by calling <code>stop()</code> or by | ||
1605 : | * reaching the end of the stream. Meaningless for live streams.</p> | ||
1606 : | * | ||
1607 : | * @helpid 0 | ||
1608 : | */ | ||
1609 : | [Inspectable(defaultValue=true)] | ||
1610 : | public function get autoRewind():Boolean | ||
1611 : | { | ||
1612 : | if (_vp[_activeVP] == undefined) return _autoRewind; | ||
1613 : | return _vp[_activeVP].autoRewind; | ||
1614 : | } | ||
1615 : | public function set autoRewind(flag:Boolean):Void | ||
1616 : | { | ||
1617 : | if (_activeVP == 0 || _activeVP == undefined) _autoRewind = flag; | ||
1618 : | _vp[_activeVP].autoRewind = flag; | ||
1619 : | } | ||
1620 : | |||
1621 : | /** | ||
1622 : | * <p>Determines whether the instance is automatically resized to | ||
1623 : | * the source dimensions. If this is set from false to true after | ||
1624 : | * an FLV has been loaded, an automatic resize will start | ||
1625 : | * immediately.</p> | ||
1626 : | * | ||
1627 : | * @see #maintainAspectRatio | ||
1628 : | * @see #preferredHeight | ||
1629 : | * @see #preferredWidth | ||
1630 : | * @tiptext Determines whether the display sizes itself according to the preferred size of the media | ||
1631 : | * @helpid 3543 | ||
1632 : | */ | ||
1633 : | [Inspectable(defaultValue=false)] | ||
1634 : | public function get autoSize():Boolean | ||
1635 : | { | ||
1636 : | if (_vp[_activeVP] == undefined) return _autoSize; | ||
1637 : | return _vp[_activeVP].autoSize; | ||
1638 : | } | ||
1639 : | public function set autoSize(flag:Boolean):Void | ||
1640 : | { | ||
1641 : | if (_activeVP == 0 || _activeVP == undefined) _autoSize = flag; | ||
1642 : | _vp[_activeVP].autoSize = flag; | ||
1643 : | } | ||
1644 : | |||
1645 : | /** | ||
1646 : | * <p>Get the bandwidth. Numerical Value in bits per second.</p> | ||
1647 : | * | ||
1648 : | * <p>When streaming from FCS, can provide SMIL file that | ||
1649 : | * describes how to switch between multiple streams based on | ||
1650 : | * bandwidth. Bandwidth is automatically detected by FCS server | ||
1651 : | * and if this value is set, it will be ignored.</p> | ||
1652 : | * | ||
1653 : | * <p>When doing http progressive download, can use the same SMIL | ||
1654 : | * format, but must set the bitrate as there is no automatic | ||
1655 : | * detection.</p> | ||
1656 : | */ | ||
1657 : | public function get bitrate():Number { | ||
1658 : | return ncMgr.getBitrate(); | ||
1659 : | } | ||
1660 : | public function set bitrate(b:Number):Void { | ||
1661 : | ncMgr.setBitrate(b); | ||
1662 : | } | ||
1663 : | |||
1664 : | /** | ||
1665 : | * If state is buffering. Read only. | ||
1666 : | */ | ||
1667 : | public function get buffering():Boolean { | ||
1668 : | if (_vp[_activeVP] == undefined) return false; | ||
1669 : | return (_vp[_activeVP].state == BUFFERING); | ||
1670 : | } | ||
1671 : | |||
1672 : | /** | ||
1673 : | * <p>buffering bar control. Displays when in loading or | ||
1674 : | * buffering type state.</p> | ||
1675 : | */ | ||
1676 : | public function get bufferingBar():MovieClip { | ||
1677 : | if (_uiMgr != null && _uiMgr != undefined) _bufferingBar = _uiMgr.getControl(UIManager.BUFFERING_BAR); | ||
1678 : | return _bufferingBar; | ||
1679 : | } | ||
1680 : | public function set bufferingBar(s:MovieClip):Void { | ||
1681 : | _bufferingBar = s; | ||
1682 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.BUFFERING_BAR, s); | ||
1683 : | } | ||
1684 : | |||
1685 : | /** | ||
1686 : | * <p>If true, we hide and disable certain controls when the | ||
1687 : | * buffering bar is displayed. The seek bar will be hidden, the | ||
1688 : | * play, pause, play/pause, forward and back buttons would be | ||
1689 : | * disabled. Default is false. This only has effect if there | ||
1690 : | * is a buffering bar control.</p> | ||
1691 : | */ | ||
1692 : | public function get bufferingBarHidesAndDisablesOthers():Boolean { | ||
1693 : | if (_uiMgr != null && _uiMgr != undefined) { | ||
1694 : | _bufferingBarHides = _uiMgr.bufferingBarHidesAndDisablesOthers; | ||
1695 : | } | ||
1696 : | return _bufferingBarHides; | ||
1697 : | } | ||
1698 : | public function set bufferingBarHidesAndDisablesOthers(b:Boolean):Void { | ||
1699 : | _bufferingBarHides = b; | ||
1700 : | if (_uiMgr != null && _uiMgr != undefined) { | ||
1701 : | _uiMgr.bufferingBarHidesAndDisablesOthers = b; | ||
1702 : | } | ||
1703 : | } | ||
1704 : | |||
1705 : | /** | ||
1706 : | * <p>back button control. Clicking calls | ||
1707 : | * seekToPrevNavCuePoint(). | ||
1708 : | * | ||
1709 : | * @see #seekToPrevNavCuePoint()</p> | ||
1710 : | */ | ||
1711 : | public function get backButton():MovieClip { | ||
1712 : | if (_uiMgr != null && _uiMgr != undefined) _backButton = _uiMgr.getControl(UIManager.BACK_BUTTON); | ||
1713 : | return _backButton; | ||
1714 : | } | ||
1715 : | public function set backButton(s:MovieClip):Void { | ||
1716 : | _backButton = s; | ||
1717 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.BACK_BUTTON, s); | ||
1718 : | } | ||
1719 : | |||
1720 : | /** | ||
1721 : | * <p>Sets number of seconds to buffer in memory before playing | ||
1722 : | * back stream. For slow connections streaming over rtmp, it is | ||
1723 : | * important to increase this from the default. Default is | ||
1724 : | * 0.1</p> | ||
1725 : | */ | ||
1726 : | [Inspectable(defaultValue=0.1)] | ||
1727 : | public function get bufferTime():Number | ||
1728 : | { | ||
1729 : | if (_vp[_activeVP] == undefined) return _bufferTime; | ||
1730 : | return _vp[_activeVP].bufferTime; | ||
1731 : | } | ||
1732 : | public function set bufferTime(aTime:Number):Void | ||
1733 : | { | ||
1734 : | if (_activeVP == 0 || _activeVP == undefined) _bufferTime = aTime; | ||
1735 : | _vp[_activeVP].bufferTime = aTime; | ||
1736 : | } | ||
1737 : | |||
1738 : | /** | ||
1739 : | * <p>property bytesLoaded, read only. Returns -1 when there | ||
1740 : | * is no stream, when the stream is FCS or if the information | ||
1741 : | * is not yet available. Return value only useful for HTTP | ||
1742 : | * download.</p> | ||
1743 : | * | ||
1744 : | * @tiptext Number of bytes already loaded | ||
1745 : | * @helpid 3455 | ||
1746 : | */ | ||
1747 : | [ChangeEvent("progress")] | ||
1748 : | [Bindable] | ||
1749 : | public function get bytesLoaded():Number | ||
1750 : | { | ||
1751 : | return _vp[_activeVP].bytesLoaded; | ||
1752 : | } | ||
1753 : | |||
1754 : | /** | ||
1755 : | * <p>property bytesTotal, read only. Returns -1 when there | ||
1756 : | * is no stream, when the stream is FCS or if the information | ||
1757 : | * is not yet available. Return value only useful for HTTP | ||
1758 : | * download.</p> | ||
1759 : | * | ||
1760 : | * @tiptext Number of bytes to be loaded | ||
1761 : | * @helpid 3456 | ||
1762 : | */ | ||
1763 : | [ChangeEvent("progress")] | ||
1764 : | [Bindable] | ||
1765 : | public function get bytesTotal():Number | ||
1766 : | { | ||
1767 : | return _vp[_activeVP].bytesTotal; | ||
1768 : | } | ||
1769 : | |||
1770 : | /** | ||
1771 : | * <p>URL that determines FLV to stream and how to stream it. | ||
1772 : | * URL can be http URL to an FLV, rtmp URL to a stream or | ||
1773 : | * http URL to an XML file.</p> | ||
1774 : | * | ||
1775 : | * <p>If set via component inspector or property inspector, the | ||
1776 : | * loading and/or playing of FLV starts on next "enterFrame" event. | ||
1777 : | * Delay is to allow time to set isLive, autoPlay and cuePoints | ||
1778 : | * properties, among others, which effect loading, as well as to | ||
1779 : | * allow ActionScript on frame one to effect the FLVPlayback | ||
1780 : | * component before it starts playing.</p> | ||
1781 : | * | ||
1782 : | * <p>If set via ActionScript, it immediately calls | ||
1783 : | * <code>VideoPlayer.load()</code> if <code>autoPlay</code> is | ||
1784 : | * false or <code>VideoPlayer.play()</code> if | ||
1785 : | * <code>autoPlay</code> is true. Also sends properties | ||
1786 : | * <code>totalTime</code> and <code>isLive</code> into those | ||
1787 : | * <code>VideoPlayer</code> APIs, so be sure to set those BEFORE | ||
1788 : | * setting this property.</p> | ||
1789 : | * | ||
1790 : | * @see #autoPlay | ||
1791 : | * @see #isLive | ||
1792 : | * @see #totalTime | ||
1793 : | * @see #load() | ||
1794 : | * @see #play() | ||
1795 : | * @see VideoPlayer#load() | ||
1796 : | * @see VideoPlayer#play() | ||
1797 : | */ | ||
1798 : | [Inspectable(type="Video Content Path")] | ||
1799 : | [Bindable] | ||
1800 : | public function get contentPath():String { | ||
1801 : | if (_vp[_activeVP] == undefined || _vp[_activeVP].onEnterFrame != undefined) { | ||
1802 : | return _contentPath; | ||
1803 : | } | ||
1804 : | return _vp[_activeVP].url; | ||
1805 : | } | ||
1806 : | public function set contentPath(url:String):Void { | ||
1807 : | if (_global.isLivePreview) return; | ||
1808 : | if (_vp[_activeVP] == undefined) { | ||
1809 : | // if set by component inspector, before constructor called | ||
1810 : | if (url == _contentPath) return; | ||
1811 : | _contentPath = url; | ||
1812 : | } else { | ||
1813 : | if (_vp[_activeVP].url == url) return; | ||
1814 : | _vpState[_activeVP].minProgressPercent = undefined; | ||
1815 : | if (_vp[_activeVP].onEnterFrame != undefined) { | ||
1816 : | delete _vp[_activeVP].onEnterFrame; | ||
1817 : | _vp[_activeVP].onEnterFrame = undefined; | ||
1818 : | } | ||
1819 : | _cpMgr[_activeVP].reset(); | ||
1820 : | if (_vpState[_activeVP].autoPlay && _firstStreamShown) { | ||
1821 : | _vp[_activeVP].play(url, _vpState[_activeVP].isLive, _vpState[_activeVP].totalTime); | ||
1822 : | } else { | ||
1823 : | _vp[_activeVP].load(url, _vpState[_activeVP].isLive, _vpState[_activeVP].totalTime); | ||
1824 : | } | ||
1825 : | _vpState[_activeVP].isLiveSet = false; | ||
1826 : | _vpState[_activeVP].totalTimeSet = false; | ||
1827 : | } | ||
1828 : | } | ||
1829 : | |||
1830 : | /** | ||
1831 : | * <p>Write only Array that describes ActionScript cue points and | ||
1832 : | * disabled embedded FLV cue points. This API is created | ||
1833 : | * specifically to be used by the component inspector and | ||
1834 : | * will not work if set in any other way. Its value only | ||
1835 : | * has an effect on the first FLV loaded, and only if it | ||
1836 : | * is loaded by setting the contentPath property in the | ||
1837 : | * component inspector or property inspector.</p> | ||
1838 : | * | ||
1839 : | * <p>To add, remove, enable or disable cue points with | ||
1840 : | * ActionScript, use use <code>addASCuePoint()</code>, | ||
1841 : | * <code>removeASCuePoint()</code>, | ||
1842 : | * <code>setFLVCuePointEnabled()</code>.</p> | ||
1843 : | * | ||
1844 : | * @see #contentPath | ||
1845 : | * @see #addASCuePoint() | ||
1846 : | * @see #removeASCuePoint() | ||
1847 : | * @see #setFLVCuePointEnabled() | ||
1848 : | */ | ||
1849 : | [Inspectable(type="Video Cue Points")] | ||
1850 : | public function set cuePoints(cp:Array):Void { | ||
1851 : | // this can only be set once, and only before the constructor is called | ||
1852 : | if (_cuePoints != undefined) return; | ||
1853 : | _cuePoints = cp; | ||
1854 : | } | ||
1855 : | |||
1856 : | //ifdef DEBUG | ||
1857 : | ///** | ||
1858 : | // * temporary for development | ||
1859 : | // */ | ||
1860 : | //[Inspectable(defaultValue=false)] | ||
1861 : | //public function get debuggingOn():Boolean { | ||
1862 : | // return _debuggingOn; | ||
1863 : | //} | ||
1864 : | //public function set debuggingOn(d:Boolean):Void { | ||
1865 : | // _debuggingOn = d; | ||
1866 : | //} | ||
1867 : | |||
1868 : | ///** | ||
1869 : | // * temporary for development. Should be a function that takes | ||
1870 : | // * a String argument. | ||
1871 : | // */ | ||
1872 : | //public function get debuggingOutputFunction():Function { | ||
1873 : | // return _debugFn; | ||
1874 : | //} | ||
1875 : | //public function set debuggingOutputFunction(d:Function):Void { | ||
1876 : | // _debugFn = d; | ||
1877 : | //} | ||
1878 : | //endif | ||
1879 : | |||
1880 : | /** | ||
1881 : | * <p>forward button control. Clicking calls | ||
1882 : | * seekToNextNavCuePoint().</p> | ||
1883 : | * | ||
1884 : | * @see #seekToNextNavCuePoint() | ||
1885 : | */ | ||
1886 : | public function get forwardButton():MovieClip { | ||
1887 : | if (_uiMgr != null && _uiMgr != undefined) _forwardButton = _uiMgr.getControl(UIManager.FORWARD_BUTTON); | ||
1888 : | return _forwardButton; | ||
1889 : | } | ||
1890 : | public function set forwardButton(s:MovieClip):Void { | ||
1891 : | _forwardButton = s; | ||
1892 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.FORWARD_BUTTON, s); | ||
1893 : | } | ||
1894 : | |||
1895 : | /** | ||
1896 : | * <p>Height of video</p> | ||
1897 : | * | ||
1898 : | * @see #setSize() | ||
1899 : | * @helpid 0 | ||
1900 : | */ | ||
1901 : | [ChangeEvent("resize")] | ||
1902 : | [Bindable] | ||
1903 : | public function get height():Number { | ||
1904 : | if (_global.isLivePreview) return __height; | ||
1905 : | if (_vp[_visibleVP] != undefined) __height = _vp[_visibleVP].height; | ||
1906 : | return __height; | ||
1907 : | } | ||
1908 : | public function set height(h:Number):Void { | ||
1909 : | setSize(this.width, h); | ||
1910 : | } | ||
1911 : | |||
1912 : | /** | ||
1913 : | * <p>Property idleTimeout, which is amount of time in | ||
1914 : | * milliseconds before connection is idle (playing is paused | ||
1915 : | * or stopped) before connection to the FCS server is | ||
1916 : | * terminated. Has no effect to HTTP download of FLV.</p> | ||
1917 : | * | ||
1918 : | * <p>If set when stream already idle, restarts idle timeout with | ||
1919 : | * new value.</p> | ||
1920 : | */ | ||
1921 : | public function get idleTimeout():Number { | ||
1922 : | if (_vp[_activeVP] == undefined) return _idleTimeout; | ||
1923 : | return _vp[_activeVP].idleTimeout; | ||
1924 : | } | ||
1925 : | public function set idleTimeout(aTime:Number):Void { | ||
1926 : | if (_activeVP == 0 || _activeVP == undefined) _idleTimeout = aTime; | ||
1927 : | _vp[_activeVP].idleTimeout = aTime; | ||
1928 : | } | ||
1929 : | |||
1930 : | /** | ||
1931 : | * True if stream is RTMP download (streaming from Flash | ||
1932 : | * Communication Server), read only. | ||
1933 : | * | ||
1934 : | * @see VideoPlayer#isRTMP | ||
1935 : | */ | ||
1936 : | public function get isRTMP():Boolean { | ||
1937 : | if (_global.isLivePreview) return true; | ||
1938 : | if (_vp[_activeVP] == undefined) return undefined; | ||
1939 : | return _vp[_activeVP].isRTMP; | ||
1940 : | } | ||
1941 : | |||
1942 : | /** | ||
1943 : | * <p>Whether stream is live. This property only matters when | ||
1944 : | * streaming from FVSS or FCS; value is ignored when doing | ||
1945 : | * http download.</p> | ||
1946 : | * | ||
1947 : | * <p>If set between loads of new FLVs, has no effect until | ||
1948 : | * next set of contentPath.</p> | ||
1949 : | * | ||
1950 : | * @see #contentPath | ||
1951 : | * @see VideoPlayer#isLive | ||
1952 : | */ | ||
1953 : | [Inspectable(defaultValue=false)] | ||
1954 : | public function get isLive():Boolean { | ||
1955 : | if (_vp[_activeVP] == undefined) { | ||
1956 : | return _isLive; | ||
1957 : | } else if(_vpState[_activeVP].isLiveSet) { | ||
1958 : | return _vpState[_activeVP].isLive; | ||
1959 : | } else { | ||
1960 : | return _vp[_activeVP].isLive; | ||
1961 : | } | ||
1962 : | } | ||
1963 : | public function set isLive(flag:Boolean):Void { | ||
1964 : | if (_activeVP == 0 || _activeVP == undefined) _isLive = flag; | ||
1965 : | _vpState[_activeVP].isLive = flag; | ||
1966 : | _vpState[_activeVP].isLiveSet = true; | ||
1967 : | } | ||
1968 : | |||
1969 : | /** | ||
1970 : | * <p>Determines whether video aspect ratio is maintained. If | ||
1971 : | * this is set from false to true and <code>autoSize</code> is | ||
1972 : | * false after an FLV has been loaded, an automatic resize will | ||
1973 : | * start immediately.</p> | ||
1974 : | * | ||
1975 : | * @see #autoSize | ||
1976 : | * @see #preferredHeight | ||
1977 : | * @see #preferredWidth | ||
1978 : | * @tiptext Determines whether a Display or Playback instance maintains aspect ratio | ||
1979 : | * @helpid 3451 | ||
1980 : | */ | ||
1981 : | [Inspectable(defaultValue=true)] | ||
1982 : | public function get maintainAspectRatio():Boolean | ||
1983 : | { | ||
1984 : | if (_vp[_activeVP] == undefined) return _aspectRatio; | ||
1985 : | return _vp[_activeVP].maintainAspectRatio; | ||
1986 : | } | ||
1987 : | public function set maintainAspectRatio(flag:Boolean):Void | ||
1988 : | { | ||
1989 : | if (_activeVP == 0 || _activeVP == undefined) _aspectRatio = flag; | ||
1990 : | _vp[_activeVP].maintainAspectRatio = flag; | ||
1991 : | } | ||
1992 : | |||
1993 : | /** | ||
1994 : | * <p>Read only. Metadata info packet received in onMetaData | ||
1995 : | * callback, if available. Ready when "metadataReceived" event | ||
1996 : | * dispatched.</p> | ||
1997 : | * | ||
1998 : | * @see VideoPlayer#metadata | ||
1999 : | */ | ||
2000 : | public function get metadata():Object { | ||
2001 : | if (_vp[_activeVP] == undefined) return null; | ||
2002 : | return _vp[_activeVP].metadata; | ||
2003 : | } | ||
2004 : | |||
2005 : | /** | ||
2006 : | * <p>Read only. True if metadata packet has been encountered and | ||
2007 : | * processed OR if it is clear that it will not be. Use this to | ||
2008 : | * check if useful information can be retreived from there various | ||
2009 : | * cue point APIs (findCuePoint, findNearestCuePoint, | ||
2010 : | * findNextCuePointWithName, isFLVCuePointEnabled) for FLV | ||
2011 : | * embedded cue points. | ||
2012 : | * | ||
2013 : | * @see #findCuePoint() | ||
2014 : | * @see #findNearestCuePoint() | ||
2015 : | * @see #findNextCuePointWithName() | ||
2016 : | * @see #isFLVCuePointEnabled() | ||
2017 : | * @see CuePointManager#metadataLoaded | ||
2018 : | */ | ||
2019 : | public function get metadataLoaded():Boolean { | ||
2020 : | if (_vp[_activeVP] == undefined) return false; | ||
2021 : | return _cpMgr[_activeVP].metadataLoaded; | ||
2022 : | } | ||
2023 : | |||
2024 : | /** | ||
2025 : | * <p>mute button control.</p> | ||
2026 : | */ | ||
2027 : | public function get muteButton():MovieClip { | ||
2028 : | if (_uiMgr != null && _uiMgr != undefined) _muteButton = _uiMgr.getControl(UIManager.MUTE_BUTTON); | ||
2029 : | return _muteButton; | ||
2030 : | } | ||
2031 : | public function set muteButton(s:MovieClip):Void { | ||
2032 : | _muteButton = s; | ||
2033 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.MUTE_BUTTON, s); | ||
2034 : | } | ||
2035 : | |||
2036 : | /** | ||
2037 : | * <p>Access to instance of the class implementing | ||
2038 : | * <code>INCManager</code>. Read only.</p> | ||
2039 : | * | ||
2040 : | * <p>One use case for this is that a custom | ||
2041 : | * <code>INCManager</code> implementation may require custom | ||
2042 : | * initialization.</p> | ||
2043 : | * | ||
2044 : | * VideoPlayer#ncMgr | ||
2045 : | */ | ||
2046 : | public function get ncMgr():INCManager { | ||
2047 : | if (_vp[_activeVP] == undefined) return null; | ||
2048 : | return _vp[_activeVP].ncMgr; | ||
2049 : | } | ||
2050 : | |||
2051 : | /** | ||
2052 : | * <p>pause button control.</p> | ||
2053 : | */ | ||
2054 : | public function get pauseButton():MovieClip { | ||
2055 : | if (_uiMgr != null && _uiMgr != undefined) _pauseButton = _uiMgr.getControl(UIManager.PAUSE_BUTTON); | ||
2056 : | return _pauseButton; | ||
2057 : | } | ||
2058 : | public function set pauseButton(s:MovieClip):Void { | ||
2059 : | _pauseButton = s; | ||
2060 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PAUSE_BUTTON, s); | ||
2061 : | } | ||
2062 : | |||
2063 : | /** | ||
2064 : | * If state is paused. Read only. | ||
2065 : | */ | ||
2066 : | [ChangeEvent("stateChange")] | ||
2067 : | [ChangeEvent("paused")] | ||
2068 : | [Bindable] | ||
2069 : | public function get paused():Boolean { | ||
2070 : | if (_vp[_activeVP] == undefined) return false; | ||
2071 : | return (_vp[_activeVP].state == PAUSED); | ||
2072 : | } | ||
2073 : | |||
2074 : | /** | ||
2075 : | * <p>play button control.</p> | ||
2076 : | */ | ||
2077 : | public function get playButton():MovieClip { | ||
2078 : | if (_uiMgr != null && _uiMgr != undefined) _playButton = _uiMgr.getControl(UIManager.PLAY_BUTTON); | ||
2079 : | return _playButton; | ||
2080 : | } | ||
2081 : | public function set playButton(s:MovieClip):Void { | ||
2082 : | _playButton = s; | ||
2083 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PLAY_BUTTON, s); | ||
2084 : | } | ||
2085 : | |||
2086 : | /** | ||
2087 : | * <p>The current playhead time in seconds. Setting does a seek | ||
2088 : | * and has all the restrictions of a seek.</p> | ||
2089 : | * | ||
2090 : | * <p>The event "playheadUpdate" is dispatched when the playhead | ||
2091 : | * time changes, including every .25 seconds while the FLV is | ||
2092 : | * playing.</p> | ||
2093 : | * | ||
2094 : | * @return The playhead position, measured in seconds since the start. Will return a fractional value. | ||
2095 : | * @tiptext Current position of the playhead in seconds | ||
2096 : | * @helpid 3463 | ||
2097 : | * @see #seek() | ||
2098 : | * @see VideoPlayer#playheadTime | ||
2099 : | */ | ||
2100 : | [ChangeEvent("playheadUpdate")] | ||
2101 : | [Bindable] | ||
2102 : | public function get playheadTime():Number | ||
2103 : | { | ||
2104 : | if (_vp[_activeVP] == undefined) return 0; | ||
2105 : | return _vp[_activeVP].playheadTime; | ||
2106 : | } | ||
2107 : | public function set playheadTime(position:Number):Void | ||
2108 : | { | ||
2109 : | seek(position); | ||
2110 : | } | ||
2111 : | |||
2112 : | /** | ||
2113 : | * <p>Property playheadUpdateInterval, which is amount of time | ||
2114 : | * in milliseconds between each "playheadUpdate" event.</p> | ||
2115 : | * | ||
2116 : | * <p>If set when stream is playing, will restart timer.</p> | ||
2117 : | * | ||
2118 : | * @see VideoPlayer#playheadUpdateInterval | ||
2119 : | */ | ||
2120 : | public function get playheadUpdateInterval():Number { | ||
2121 : | if (_vp[_activeVP] == undefined) return _playheadUpdateInterval; | ||
2122 : | return _vp[_activeVP].playheadUpdateInterval; | ||
2123 : | } | ||
2124 : | public function set playheadUpdateInterval(aTime:Number):Void { | ||
2125 : | if (_activeVP == 0 || _activeVP == undefined) _playheadUpdateInterval = aTime; | ||
2126 : | _cpMgr[_activeVP].playheadUpdateInterval = aTime; | ||
2127 : | _vp[_activeVP].playheadUpdateInterval = aTime; | ||
2128 : | } | ||
2129 : | |||
2130 : | /** | ||
2131 : | * If state is playing. Read only. | ||
2132 : | */ | ||
2133 : | [ChangeEvent("stateChange")] | ||
2134 : | [ChangeEvent("playing")] | ||
2135 : | [Bindable] | ||
2136 : | public function get playing():Boolean { | ||
2137 : | if (_vp[_activeVP] == undefined) return false; | ||
2138 : | return (_vp[_activeVP].state == PLAYING); | ||
2139 : | } | ||
2140 : | |||
2141 : | /** | ||
2142 : | * <p>play/pause button control</p> | ||
2143 : | */ | ||
2144 : | public function get playPauseButton():MovieClip { | ||
2145 : | if (_uiMgr != null && _uiMgr != undefined) _playPauseButton = _uiMgr.getControl(UIManager.PLAY_PAUSE_BUTTON); | ||
2146 : | return _playPauseButton; | ||
2147 : | } | ||
2148 : | public function set playPauseButton(s:MovieClip):Void { | ||
2149 : | _playPauseButton = s; | ||
2150 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.PLAY_PAUSE_BUTTON, s); | ||
2151 : | } | ||
2152 : | |||
2153 : | /** | ||
2154 : | * <p>property preferredHeight, get only. Gives the height of the | ||
2155 : | * source FLV. This information is not valid immediately upon | ||
2156 : | * calling <code>play()</code> or <code>load()</code>. It is | ||
2157 : | * ready when the "ready" event fires. | ||
2158 : | * | ||
2159 : | * @return The preferred height of the display. | ||
2160 : | * This is the height of the source FLV. | ||
2161 : | * @see #autoSize | ||
2162 : | * @see #maintainAspectRatio | ||
2163 : | * @tiptext The preferred height of the display | ||
2164 : | * @helpid 3465 | ||
2165 : | */ | ||
2166 : | [ChangeEvent("metadataReceived")] | ||
2167 : | [Bindable] | ||
2168 : | public function get preferredHeight():Number | ||
2169 : | { | ||
2170 : | if (_vp[_activeVP] == undefined) return 0; | ||
2171 : | return _vp[_activeVP].videoHeight; | ||
2172 : | } | ||
2173 : | |||
2174 : | /** | ||
2175 : | * <p>property preferredWidth, get only. Gives the width of the | ||
2176 : | * source FLV. This information is not valid immediately upon | ||
2177 : | * calling <code>play()</code> or <code>load()</code>. It is | ||
2178 : | * ready when the "ready" event fires. | ||
2179 : | * | ||
2180 : | * @return The preferred width of the display. | ||
2181 : | * This is the width of the source FLV. | ||
2182 : | * @see #autoSize | ||
2183 : | * @see #maintainAspectRatio | ||
2184 : | * @tiptext The preferred width of the display | ||
2185 : | * @helpid 3466 | ||
2186 : | */ | ||
2187 : | [ChangeEvent("metadataReceived")] | ||
2188 : | [Bindable] | ||
2189 : | public function get preferredWidth():Number | ||
2190 : | { | ||
2191 : | if (_vp[_activeVP] == undefined) return 0; | ||
2192 : | return _vp[_activeVP].videoWidth; | ||
2193 : | } | ||
2194 : | |||
2195 : | /** | ||
2196 : | * <p>Property progressInterval, which is amount of time | ||
2197 : | * in milliseconds between each "progress" event.</p> | ||
2198 : | * | ||
2199 : | * <p>If set when stream is playing, will restart timer.</p> | ||
2200 : | * | ||
2201 : | * @see VideoPlayer#progressInterval | ||
2202 : | */ | ||
2203 : | public function get progressInterval():Number { | ||
2204 : | if (_vp[_activeVP] == undefined) return _progressInterval; | ||
2205 : | return _vp[_activeVP].progressInterval; | ||
2206 : | } | ||
2207 : | public function set progressInterval(aTime:Number):Void { | ||
2208 : | if (_activeVP == 0 || _activeVP == undefined) _progressInterval = aTime; | ||
2209 : | _vp[_activeVP].progressInterval = aTime; | ||
2210 : | } | ||
2211 : | |||
2212 : | /** | ||
2213 : | * 100 is standard scale | ||
2214 : | * | ||
2215 : | * @see #setScale() | ||
2216 : | * @tiptext Specifies the horizontal scale factor | ||
2217 : | * @helpid 3974 | ||
2218 : | */ | ||
2219 : | [ChangeEvent("resize")] | ||
2220 : | [Bindable] | ||
2221 : | function get scaleX():Number | ||
2222 : | { | ||
2223 : | if (_vp[_visibleVP] != undefined) _scaleX = _vp[_visibleVP].width / _origWidth * 100; | ||
2224 : | return this._scaleX; | ||
2225 : | } | ||
2226 : | function set scaleX(xs:Number):Void | ||
2227 : | { | ||
2228 : | setScale(xs, this.scaleY); | ||
2229 : | } | ||
2230 : | |||
2231 : | /** | ||
2232 : | * 100 is standard scale | ||
2233 : | * | ||
2234 : | * @see #setScale() | ||
2235 : | * @tiptext Specifies the vertical scale factor | ||
2236 : | * @helpid 3975 | ||
2237 : | */ | ||
2238 : | [ChangeEvent("resize")] | ||
2239 : | [Bindable] | ||
2240 : | function get scaleY():Number | ||
2241 : | { | ||
2242 : | if (_vp[_visibleVP] != undefined) _scaleY = _vp[_visibleVP].height / _origHeight * 100; | ||
2243 : | return this._scaleY; | ||
2244 : | } | ||
2245 : | function set scaleY(ys:Number):Void | ||
2246 : | { | ||
2247 : | setScale(this.scaleX, ys); | ||
2248 : | } | ||
2249 : | |||
2250 : | /** | ||
2251 : | * <p>True if user is currently scrubbing with the seek bar. read only</p> | ||
2252 : | */ | ||
2253 : | public function get scrubbing():Boolean { | ||
2254 : | var seekBar:MovieClip = this.seekBar; | ||
2255 : | if (seekBar == undefined || seekBar.isDragging == undefined) { | ||
2256 : | return false; | ||
2257 : | } | ||
2258 : | return seekBar.isDragging; | ||
2259 : | } | ||
2260 : | |||
2261 : | /** | ||
2262 : | * <p>seek bar control</p> | ||
2263 : | */ | ||
2264 : | public function get seekBar():MovieClip { | ||
2265 : | if (_uiMgr != null && _uiMgr != undefined) _seekBar = _uiMgr.getControl(UIManager.SEEK_BAR); | ||
2266 : | return _seekBar; | ||
2267 : | } | ||
2268 : | public function set seekBar(s:MovieClip):Void { | ||
2269 : | _seekBar = s; | ||
2270 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.SEEK_BAR, s); | ||
2271 : | } | ||
2272 : | |||
2273 : | /** | ||
2274 : | * Determines how often check the seek bar handle location when | ||
2275 : | * scubbing, in milliseconds. Default is 250. | ||
2276 : | * | ||
2277 : | * @see UIManager#seekBarInterval | ||
2278 : | * @see UIManager#SEEK_BAR_INTERVAL_DEFAULT | ||
2279 : | */ | ||
2280 : | public function get seekBarInterval():Number { | ||
2281 : | if (_uiMgr != null && _uiMgr != undefined) _seekBarInterval = _uiMgr.seekBarInterval | ||
2282 : | return _seekBarInterval; | ||
2283 : | } | ||
2284 : | public function set seekBarInterval(s:Number) { | ||
2285 : | _seekBarInterval = s; | ||
2286 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.seekBarInterval = _seekBarInterval; | ||
2287 : | } | ||
2288 : | |||
2289 : | /** | ||
2290 : | * <p>Determines how far user can move scrub bar before an update | ||
2291 : | * will occur. Specified in percentage from 1 to 100. Set to 0 | ||
2292 : | * to indicate no scrub tolerance--always update position on | ||
2293 : | * seekBarInterval regardless of how far user has moved handle. | ||
2294 : | * Default is 5.</p> | ||
2295 : | * | ||
2296 : | * @see UIManager#seekBarScrubTolerance | ||
2297 : | * @see UIManager#SEEK_BAR_SCRUB_TOLERANCE_DEFAULT | ||
2298 : | */ | ||
2299 : | public function get seekBarScrubTolerance():Number { | ||
2300 : | if (_uiMgr != null && _uiMgr != undefined) _seekBarScrubTolerance = _uiMgr.seekBarScrubTolerance; | ||
2301 : | return _seekBarScrubTolerance; | ||
2302 : | } | ||
2303 : | public function set seekBarScrubTolerance(s:Number) { | ||
2304 : | _seekBarScrubTolerance = s; | ||
2305 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.seekBarScrubTolerance = _seekBarScrubTolerance; | ||
2306 : | } | ||
2307 : | |||
2308 : | /** | ||
2309 : | * <p>when seekToPrevNavCuePoint compares its time against the | ||
2310 : | * previous cue point, it uses this delta to be sure that if you | ||
2311 : | * are just ahead of a cue point, you can hop over it to the | ||
2312 : | * previous and not get stuck going to the same one over and over | ||
2313 : | * if you are playing. In seconds</p> | ||
2314 : | * | ||
2315 : | */ | ||
2316 : | public function get seekToPrevOffset():Number { | ||
2317 : | return _seekToPrevOffset; | ||
2318 : | } | ||
2319 : | public function set seekToPrevOffset(s:Number):Void { | ||
2320 : | _seekToPrevOffset = s; | ||
2321 : | } | ||
2322 : | |||
2323 : | /** | ||
2324 : | * <p>Skin swf</p> | ||
2325 : | */ | ||
2326 : | [Inspectable(type="Video Skin")] | ||
2327 : | public function get skin():String { | ||
2328 : | if (_uiMgr != null && _uiMgr != undefined) _skin = _uiMgr.skin; | ||
2329 : | return _skin; | ||
2330 : | } | ||
2331 : | public function set skin(s:String):Void { | ||
2332 : | _skin = s; | ||
2333 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.skin = s; | ||
2334 : | } | ||
2335 : | |||
2336 : | /** | ||
2337 : | * <p>Whether to hide the skin when the mouse is not over the video. | ||
2338 : | * Defaults to false.</p> | ||
2339 : | */ | ||
2340 : | [Inspectable(defaultValue=false)] | ||
2341 : | public function get skinAutoHide():Boolean { | ||
2342 : | if (_uiMgr != null && _uiMgr != undefined) _skinAutoHide = _uiMgr.skinAutoHide; | ||
2343 : | return _skinAutoHide; | ||
2344 : | } | ||
2345 : | public function set skinAutoHide(b:Boolean):Void { | ||
2346 : | // in live preview always leave to default of false | ||
2347 : | if (_global.isLivePreview) return; | ||
2348 : | _skinAutoHide = b; | ||
2349 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.skinAutoHide = b; | ||
2350 : | } | ||
2351 : | |||
2352 : | /** | ||
2353 : | * <p>Provides direct access to the | ||
2354 : | * <code>Sound.setTransform()</code> and | ||
2355 : | * <code>Sound.getTransform()</code> APIs. to expose more sound | ||
2356 : | * control. Must set property for changes to take effect, get | ||
2357 : | * property just to get a copy of the current settings to tweak.</p> | ||
2358 : | * | ||
2359 : | * @see #volume | ||
2360 : | * @see VideoPlayer#transform | ||
2361 : | */ | ||
2362 : | public function get transform():Object { | ||
2363 : | return _transform; | ||
2364 : | } | ||
2365 : | public function set transform(s:Object):Void { | ||
2366 : | _transform = s; | ||
2367 : | if (_vp[_activeVP] != undefined) _vp[_activeVP].transform = _transform; | ||
2368 : | } | ||
2369 : | |||
2370 : | /** | ||
2371 : | * <p>Get state. Read only. Set with <code>load()</code>, | ||
2372 : | * <code>play()</code>, <code>stop()</code>, | ||
2373 : | * <code>pause()</code> and <code>seek()</code>.</p> | ||
2374 : | * | ||
2375 : | * <p>Descriptive constants for values are defined.</p> | ||
2376 : | * | ||
2377 : | * @see #DISCONNECTED | ||
2378 : | * @see #STOPPED | ||
2379 : | * @see #PLAYING | ||
2380 : | * @see #PAUSED | ||
2381 : | * @see #BUFFERING | ||
2382 : | * @see #LOADING | ||
2383 : | * @see #CONNECTION_ERROR | ||
2384 : | * @see #REWINDING | ||
2385 : | * @see #SEEKING | ||
2386 : | */ | ||
2387 : | [Bindable] | ||
2388 : | [ChangeEvent("stateChange")] | ||
2389 : | public function get state():String { | ||
2390 : | // for live preview, always make state STOPPED | ||
2391 : | if (_global.isLivePreview) { | ||
2392 : | return STOPPED; | ||
2393 : | } | ||
2394 : | |||
2395 : | // if no VideoPlayer exists (would only happen constructor | ||
2396 : | // called), return DISCONNECTED | ||
2397 : | if (_vp[_activeVP] == undefined) return DISCONNECTED; | ||
2398 : | |||
2399 : | // force state to SEEKING while scrubbing | ||
2400 : | if (_activeVP == _visibleVP && scrubbing) return SEEKING; | ||
2401 : | |||
2402 : | var currentState:String = _vp[_activeVP].state; | ||
2403 : | |||
2404 : | // force state to LOADING if it is RESIZING. RESIZING is just | ||
2405 : | // needed for internal VideoPlayer use anyways, make it | ||
2406 : | // LOADING, less confusing for user, esp when suppressing | ||
2407 : | // STOPPED as we do below... | ||
2408 : | if (currentState == VideoPlayer.RESIZING) return LOADING; | ||
2409 : | |||
2410 : | // force state to LOADING when STOPPED because autoPlay is | ||
2411 : | // true and waiting for skin to download to show all at once | ||
2412 : | if ( _vpState[_activeVP].prevState == LOADING && | ||
2413 : | _vpState[_activeVP].autoPlay && | ||
2414 : | currentState == STOPPED ) { | ||
2415 : | return LOADING; | ||
2416 : | } | ||
2417 : | |||
2418 : | return currentState; | ||
2419 : | } | ||
2420 : | |||
2421 : | /** | ||
2422 : | * <p>Read only. Gets whether state is responsive, | ||
2423 : | * i.e. whether controls should be enabled in the current | ||
2424 : | * state.</p> | ||
2425 : | * | ||
2426 : | * @see VideoPlayer#stateResponsive | ||
2427 : | */ | ||
2428 : | public function get stateResponsive():Boolean { | ||
2429 : | if (_vp[_activeVP] == undefined) return false; | ||
2430 : | return _vp[_activeVP].stateResponsive; | ||
2431 : | } | ||
2432 : | |||
2433 : | /** | ||
2434 : | * <p>stop button control.</p> | ||
2435 : | */ | ||
2436 : | public function get stopButton():MovieClip { | ||
2437 : | if (_uiMgr != null && _uiMgr != undefined) _stopButton = _uiMgr.getControl(UIManager.STOP_BUTTON); | ||
2438 : | return _stopButton; | ||
2439 : | } | ||
2440 : | public function set stopButton(s:MovieClip):Void { | ||
2441 : | _stopButton = s; | ||
2442 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.STOP_BUTTON, s); | ||
2443 : | } | ||
2444 : | |||
2445 : | /** | ||
2446 : | * If state is stopped. Read only. | ||
2447 : | */ | ||
2448 : | [ChangeEvent("stateChange")] | ||
2449 : | [ChangeEvent("stopped")] | ||
2450 : | [Bindable] | ||
2451 : | public function get stopped():Boolean { | ||
2452 : | if (_vp[_activeVP] == undefined) return false; | ||
2453 : | return (_vp[_activeVP].state == STOPPED); | ||
2454 : | } | ||
2455 : | |||
2456 : | /** | ||
2457 : | * <p>property totalTime.</p> | ||
2458 : | * | ||
2459 : | * <p>When streaming from FCS and using the default | ||
2460 : | * <code>NCManager</code>, this will be determined | ||
2461 : | * automatically using server side APIs and that value will | ||
2462 : | * override anything set through this property or gathered | ||
2463 : | * from metadata. The property is ready for read when the | ||
2464 : | * STOPPED or PLAYING state is reached after setting the | ||
2465 : | * <code>contentPath</code> property. When live streaming | ||
2466 : | * from FCS, this property is meaningless.</p> | ||
2467 : | * | ||
2468 : | * <p>With HTTP download, this property will be determined | ||
2469 : | * automatically if the FLV has metadata embedded, otherwise | ||
2470 : | * it must be set explicitly or it will be 0. If it is set | ||
2471 : | * explicitly than the metadata value in the stream will be | ||
2472 : | * ignored.</p> | ||
2473 : | * | ||
2474 : | * <p>When this is set, the setting takes effect for the next | ||
2475 : | * FLV loaded by setting contentPath, it will have no effect | ||
2476 : | * on a flv that has already been loaded. Also, reading this | ||
2477 : | * property will not return the new value passed in until an | ||
2478 : | * flv is loaded.</p> | ||
2479 : | * | ||
2480 : | * <p>Playback will still work if this is never set (either | ||
2481 : | * explicitly or automatically), but it may cause problems | ||
2482 : | * with seek controls.</p> | ||
2483 : | * | ||
2484 : | * @return The total running time of the FLV in seconds | ||
2485 : | * @see #contentPath | ||
2486 : | * @tiptext The total length of the FLV in seconds | ||
2487 : | * @helpid 3467 | ||
2488 : | */ | ||
2489 : | [Inspectable(defaultValue=0)] | ||
2490 : | [ChangeEvent("metadataReceived")] | ||
2491 : | [Bindable] | ||
2492 : | public function get totalTime():Number | ||
2493 : | { | ||
2494 : | if (_global.isLivePreview) return 1; | ||
2495 : | if (_vp[_activeVP] == undefined) { | ||
2496 : | return _totalTime; | ||
2497 : | } else if (_vpState[_activeVP].totalTimeSet) { | ||
2498 : | return _vpState[_activeVP].totalTime; | ||
2499 : | } else { | ||
2500 : | return _vp[_activeVP].totalTime; | ||
2501 : | } | ||
2502 : | } | ||
2503 : | public function set totalTime(aTime:Number):Void | ||
2504 : | { | ||
2505 : | if (_activeVP == 0 || _activeVP == undefined) _totalTime = aTime; | ||
2506 : | _vpState[_activeVP].totalTime = aTime; | ||
2507 : | _vpState[_activeVP].totalTimeSet = true; | ||
2508 : | } | ||
2509 : | |||
2510 : | public function get visible():Boolean { | ||
2511 : | return this._visible; | ||
2512 : | } | ||
2513 : | public function set visible(v:Boolean) { | ||
2514 : | this._visible = v; | ||
2515 : | } | ||
2516 : | |||
2517 : | /** | ||
2518 : | * <p>Use visibleVideoPlayerIndex to manage multiple FLV streams. | ||
2519 : | * qSets which <code>VideoPlayer</code> instance is visible and | ||
2520 : | * audible--only one at a time can be, the rest are hidden and | ||
2521 : | * muted. Default is 0. Does not make the <code>VideoPlayer</code> | ||
2522 : | * targeted by most APIs, for that use <code>activeVideoPlayerIndex</code></p> | ||
2523 : | * | ||
2524 : | * <p>APIs that control dimensions interact with this property. | ||
2525 : | * All that set the dimensions (setScale, setSize, set width, set | ||
2526 : | * height, set scaleX, set scaleY) effect all VideoPlayers. | ||
2527 : | * However, depending on whether autoSize or maintaintAspectRatio | ||
2528 : | * are set on those VideoPlayers, they may have different | ||
2529 : | * dimensions. So APIs that get the dimensions (get width, get | ||
2530 : | * height, get scaleX, get scaleY) get the dimensions of the | ||
2531 : | * visible VideoPlayer only, and while other VideoPlayers may | ||
2532 : | * have the same dimensions, they may not.</p> | ||
2533 : | * | ||
2534 : | * <p>To get the dimensions of various VideoPlayers when they are | ||
2535 : | * not visible, listen for the "resize" event and cache the size | ||
2536 : | * value yourself.</p> | ||
2537 : | * | ||
2538 : | * <p>Does not have any implications for visibility of the | ||
2539 : | * component as a whole, just which VideoPlayer is visible when | ||
2540 : | * the component is visible. To set visibility for the entire | ||
2541 : | * component, use <code>visible</code> property.</p> | ||
2542 : | * | ||
2543 : | * @see #activeVideoPlayerIndex | ||
2544 : | * @see #visible | ||
2545 : | */ | ||
2546 : | public function get visibleVideoPlayerIndex():Number { | ||
2547 : | return _visibleVP; | ||
2548 : | } | ||
2549 : | public function set visibleVideoPlayerIndex(i:Number) { | ||
2550 : | if (_visibleVP == i) return; | ||
2551 : | var oldIndex:Number = _visibleVP; | ||
2552 : | if (_vp[i] == undefined) { | ||
2553 : | createVideoPlayer(i); | ||
2554 : | } | ||
2555 : | var needResize:Boolean = (_vp[i].height != _vp[_visibleVP].height || _vp[i].width != _vp[_visibleVP].width); | ||
2556 : | _vp[_visibleVP].visible = false; | ||
2557 : | _vp[_visibleVP].volume = 0; | ||
2558 : | _visibleVP = i; | ||
2559 : | // only show it if stream and skin ready | ||
2560 : | if (_firstStreamShown) { | ||
2561 : | _uiMgr.setupSkinAutoHide(oldIndex); | ||
2562 : | _vp[_visibleVP].visible = true; | ||
2563 : | if (!scrubbing) { | ||
2564 : | _vp[_visibleVP].volume = _volume; | ||
2565 : | } | ||
2566 : | } else if (_vp[_visibleVP].stateResponsive && _vp[_visibleVP].state != DISCONNECTED && _uiMgr.skinReady) { | ||
2567 : | _uiMgr.visible = true; | ||
2568 : | _uiMgr.setupSkinAutoHide(oldIndex); | ||
2569 : | _firstStreamReady = true; | ||
2570 : | showFirstStream(); | ||
2571 : | } | ||
2572 : | |||
2573 : | if (_vp[oldIndex].height != _vp[_visibleVP].height || _vp[oldIndex].width != _vp[_visibleVP].width) { | ||
2574 : | dispatchEvent({type:"resize", x:this.x, y:this.y, width:this.width, height:this.height, auto:false, vp:_visibleVP}); | ||
2575 : | } | ||
2576 : | // sending extra bogus events to UIManager so UI is updated propertly for new vp | ||
2577 : | _uiMgr.handleEvent({type: "stateChange", state: _vp[_visibleVP].state, vp:_visibleVP}); | ||
2578 : | _uiMgr.handleEvent({type: "playheadUpdate", playheadTime: _vp[_visibleVP].playheadTime, vp:_visibleVP}); | ||
2579 : | if (_vp[_visibleVP].isRTMP) { | ||
2580 : | _uiMgr.handleEvent({type: "ready", vp:_visibleVP}); | ||
2581 : | } else { | ||
2582 : | _uiMgr.handleEvent({type: "progress", bytesLoaded: _vp[_visibleVP].bytesLoaded, bytesTotal: _vp[_visibleVP].bytesTotal, vp:_visibleVP}); | ||
2583 : | } | ||
2584 : | } | ||
2585 : | |||
2586 : | /** | ||
2587 : | * <p>Volume control in range from 0 to 100.</p> | ||
2588 : | * | ||
2589 : | * @return The most recent volume setting | ||
2590 : | * @tiptext The volume setting in value range from 0 to 100. | ||
2591 : | * @helpid 3468 | ||
2592 : | * @see #transform | ||
2593 : | */ | ||
2594 : | [Inspectable(defaultValue=100)] | ||
2595 : | [ChangeEvent("volumeUpdate")] | ||
2596 : | [Bindable] | ||
2597 : | public function get volume():Number | ||
2598 : | { | ||
2599 : | return _volume; | ||
2600 : | } | ||
2601 : | public function set volume(aVol:Number):Void | ||
2602 : | { | ||
2603 : | if (_volume == aVol) return; | ||
2604 : | _volume = aVol; | ||
2605 : | if (!scrubbing) { | ||
2606 : | _vp[_visibleVP].volume = _volume; | ||
2607 : | } | ||
2608 : | dispatchEvent({type:"volumeUpdate", volume:aVol}); | ||
2609 : | } | ||
2610 : | |||
2611 : | /** | ||
2612 : | * <p>volume control</p> | ||
2613 : | */ | ||
2614 : | public function get volumeBar():MovieClip { | ||
2615 : | if (_uiMgr != null && _uiMgr != undefined) _volumeBar = _uiMgr.getControl(UIManager.VOLUME_BAR); | ||
2616 : | return _volumeBar; | ||
2617 : | } | ||
2618 : | public function set volumeBar(s:MovieClip):Void { | ||
2619 : | _volumeBar = s; | ||
2620 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.setControl(UIManager.VOLUME_BAR, s); | ||
2621 : | } | ||
2622 : | |||
2623 : | /** | ||
2624 : | * Determines how often check the volume bar handle location | ||
2625 : | * when scubbing, in milliseconds. Default is 250. | ||
2626 : | * | ||
2627 : | * @see UIManager#volumeBarInterval | ||
2628 : | * @see UIManager#VOLUME_BAR_INTERVAL_DEFAULT | ||
2629 : | */ | ||
2630 : | public function get volumeBarInterval():Number { | ||
2631 : | if (_uiMgr != null && _uiMgr != undefined) _volumeBarInterval = _uiMgr.volumeBarInterval | ||
2632 : | return _volumeBarInterval; | ||
2633 : | } | ||
2634 : | public function set volumeBarInterval(s:Number) { | ||
2635 : | _volumeBarInterval = s; | ||
2636 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.volumeBarInterval = _volumeBarInterval; | ||
2637 : | } | ||
2638 : | |||
2639 : | /** | ||
2640 : | * <p>Determines how far user can move scrub bar before an update | ||
2641 : | * will occur. Specified in percentage from 1 to 100. Set to 0 | ||
2642 : | * to indicate no scrub tolerance--always update volume on | ||
2643 : | * volumeBarInterval regardless of how far user has moved handle. | ||
2644 : | * Default is 0.</p> | ||
2645 : | * | ||
2646 : | * @see UIManager#volumeBarScrubTolerance | ||
2647 : | * @see UIManager#VOLUME_BAR_SCRUB_TOLERANCE_DEFAULT | ||
2648 : | */ | ||
2649 : | public function get volumeBarScrubTolerance():Number { | ||
2650 : | if (_uiMgr != null && _uiMgr != undefined) _volumeBarScrubTolerance = _uiMgr.volumeBarScrubTolerance; | ||
2651 : | return _volumeBarScrubTolerance; | ||
2652 : | } | ||
2653 : | public function set volumeBarScrubTolerance(s:Number) { | ||
2654 : | _volumeBarScrubTolerance = s; | ||
2655 : | if (_uiMgr != null && _uiMgr != undefined) _uiMgr.volumeBarScrubTolerance = _volumeBarScrubTolerance; | ||
2656 : | } | ||
2657 : | |||
2658 : | /** | ||
2659 : | * <p>Width of video</p> | ||
2660 : | * | ||
2661 : | * @see #setSize() | ||
2662 : | * @helpid 0 | ||
2663 : | */ | ||
2664 : | [ChangeEvent("resize")] | ||
2665 : | [Bindable] | ||
2666 : | public function get width():Number { | ||
2667 : | if (_global.isLivePreview) return __width; | ||
2668 : | if (_vp[_visibleVP] != undefined) __width = _vp[_visibleVP].width; | ||
2669 : | return __width; | ||
2670 : | } | ||
2671 : | public function set width(w:Number):Void { | ||
2672 : | setSize(w, this.height); | ||
2673 : | } | ||
2674 : | |||
2675 : | [Bindable] | ||
2676 : | public function get x():Number { | ||
2677 : | return this._x; | ||
2678 : | } | ||
2679 : | public function set x(xpos:Number) { | ||
2680 : | this._x = xpos; | ||
2681 : | } | ||
2682 : | |||
2683 : | [Bindable] | ||
2684 : | public function get y():Number { | ||
2685 : | return this._y; | ||
2686 : | } | ||
2687 : | public function set y(ypos:Number) { | ||
2688 : | this._y = ypos; | ||
2689 : | } | ||
2690 : | |||
2691 : | |||
2692 : | // | ||
2693 : | // private and package internal methods | ||
2694 : | // | ||
2695 : | |||
2696 : | |||
2697 : | /** | ||
2698 : | * Creates and configures VideoPlayer movie clip | ||
2699 : | * | ||
2700 : | * @private | ||
2701 : | */ | ||
2702 : | private function createVideoPlayer(index:Number):Void { | ||
2703 : | if (_global.isLivePreview) return; | ||
2704 : | // create | ||
2705 : | var setWidth:Number = this.width; | ||
2706 : | var setHeight:Number = this.height; | ||
2707 : | _vp[index] = VideoPlayer(this.attachMovie("VideoPlayer", String(index), VP_DEPTH_OFFSET + index)); | ||
2708 : | _vp[index].setSize(setWidth, setHeight); | ||
2709 : | _topVP = index; | ||
2710 : | // init | ||
2711 : | _vp[index].autoRewind = _autoRewind; | ||
2712 : | _vp[index].autoSize = _autoSize; | ||
2713 : | _vp[index].bufferTime = _bufferTime; | ||
2714 : | _vp[index].idleTimeout = _idleTimeout; | ||
2715 : | _vp[index].maintainAspectRatio = _aspectRatio; | ||
2716 : | _vp[index].playheadUpdateInterval = _playheadUpdateInterval; | ||
2717 : | _vp[index].progressInterval = _progressInterval; | ||
2718 : | _vp[index].transform = _transform; | ||
2719 : | _vp[index].volume = _volume; | ||
2720 : | |||
2721 : | // init state object and start onEnterFrame if contentPath set | ||
2722 : | if (index == 0) { | ||
2723 : | _vpState[index] = { id:index, isLive:_isLive, isLiveSet:true, totalTime:_totalTime, totalTimeSet:true, autoPlay:_autoPlay }; | ||
2724 : | if (_contentPath != null && _contentPath != undefined && _contentPath != "") { | ||
2725 : | _vp[index].onEnterFrame = Delegate.create(this, this.doContentPathConnect); | ||
2726 : | } | ||
2727 : | } else { | ||
2728 : | _vpState[index] = { id:index, isLive:false, isLiveSet:true, totalTime:0, totalTimeSet:true, autoPlay:false }; | ||
2729 : | } | ||
2730 : | |||
2731 : | |||
2732 : | // listen to events from VideoPlayer | ||
2733 : | _vp[index].addEventListener("resize", this); | ||
2734 : | _vp[index].addEventListener("close", this); | ||
2735 : | _vp[index].addEventListener("complete", this); | ||
2736 : | _vp[index].addEventListener("cuePoint", this); | ||
2737 : | _vp[index].addEventListener("playheadUpdate", this); | ||
2738 : | _vp[index].addEventListener("progress", this); | ||
2739 : | _vp[index].addEventListener("metadataReceived", this); | ||
2740 : | _vp[index].addEventListener("stateChange", this); | ||
2741 : | _vp[index].addEventListener("ready", this); | ||
2742 : | _vp[index].addEventListener("rewind", this); | ||
2743 : | |||
2744 : | // create CuePointManager to pair with VideoPlayer | ||
2745 : | _cpMgr[index] = new CuePointManager(this, index); | ||
2746 : | _cpMgr[index].playheadUpdateInterval = _playheadUpdateInterval; | ||
2747 : | } | ||
2748 : | |||
2749 : | /** | ||
2750 : | * Creates UIManager and sets any properties that need setting | ||
2751 : | * | ||
2752 : | * @private | ||
2753 : | */ | ||
2754 : | private function createUIManager():Void { | ||
2755 : | // create UIManager | ||
2756 : | _uiMgr = new UIManager(this); | ||
2757 : | |||
2758 : | // make skin invisible until "ready" and "skinLoaded" fired | ||
2759 : | _uiMgr.visible = false; | ||
2760 : | |||
2761 : | // set cached properties | ||
2762 : | if (_backButton != undefined && _backButton != null) { | ||
2763 : | _uiMgr.setControl(UIManager.BACK_BUTTON, _backButton); | ||
2764 : | } | ||
2765 : | if (_bufferingBar != undefined && _bufferingBar != null) { | ||
2766 : | _uiMgr.setControl(UIManager.BUFFERING_BAR, _bufferingBar); | ||
2767 : | } | ||
2768 : | _uiMgr.bufferingBarHidesAndDisablesOthers = _bufferingBarHides; | ||
2769 : | if (_forwardButton != undefined && _forwardButton != null) { | ||
2770 : | _uiMgr.setControl(UIManager.FORWARD_BUTTON, _forwardButton); | ||
2771 : | } | ||
2772 : | if (_pauseButton != undefined && _pauseButton != null) { | ||
2773 : | _uiMgr.setControl(UIManager.PAUSE_BUTTON, _pauseButton); | ||
2774 : | } | ||
2775 : | if (_playButton != undefined && _playButton != null) { | ||
2776 : | _uiMgr.setControl(UIManager.PLAY_BUTTON, _playButton); | ||
2777 : | } | ||
2778 : | if (_playPauseButton != undefined && _playPauseButton != null) { | ||
2779 : | _uiMgr.setControl(UIManager.PLAY_PAUSE_BUTTON, _playPauseButton); | ||
2780 : | } | ||
2781 : | if (_stopButton != undefined && _stopButton != null) { | ||
2782 : | _uiMgr.setControl(UIManager.STOP_BUTTON, _stopButton); | ||
2783 : | } | ||
2784 : | if (_seekBar != undefined && _seekBar != null) { | ||
2785 : | _uiMgr.setControl(UIManager.SEEK_BAR, _seekBar); | ||
2786 : | } | ||
2787 : | if (_seekBarInterval != undefined && _seekBarInterval != null) { | ||
2788 : | _uiMgr.seekBarInterval = _seekBarInterval; | ||
2789 : | } | ||
2790 : | if (_seekBarScrubTolerance != undefined && _seekBarScrubTolerance != null) { | ||
2791 : | _uiMgr.seekBarScrubTolerance = _seekBarScrubTolerance; | ||
2792 : | } | ||
2793 : | if (_skin != undefined && _skin != null) { | ||
2794 : | _uiMgr.skin = _skin; | ||
2795 : | } | ||
2796 : | if (_skinAutoHide != undefined && _skinAutoHide != null) { | ||
2797 : | _uiMgr.skinAutoHide = _skinAutoHide; | ||
2798 : | } | ||
2799 : | if (_muteButton != undefined && _muteButton != null) { | ||
2800 : | _uiMgr.setControl(UIManager.MUTE_BUTTON, _muteButton); | ||
2801 : | } | ||
2802 : | if (_volumeBar != undefined && _volumeBar != null) { | ||
2803 : | _uiMgr.setControl(UIManager.VOLUME_BAR, _volumeBar); | ||
2804 : | } | ||
2805 : | if (_volumeBarInterval != undefined && _volumeBarInterval != null) { | ||
2806 : | _uiMgr.volumeBarInterval = _volumeBarInterval; | ||
2807 : | } | ||
2808 : | if (_volumeBarScrubTolerance != undefined && _volumeBarScrubTolerance != null) { | ||
2809 : | _uiMgr.volumeBarScrubTolerance = _volumeBarScrubTolerance; | ||
2810 : | } | ||
2811 : | } | ||
2812 : | |||
2813 : | /** | ||
2814 : | |||
2815 : | * Creates live preview placeholder | ||
2816 : | * | ||
2817 : | * @private | ||
2818 : | */ | ||
2819 : | private function createLivePreviewMovieClip():Void { | ||
2820 : | preview_mc = this.createEmptyMovieClip("preview_mc", 10); | ||
2821 : | preview_mc.createEmptyMovieClip("box_mc", 10); | ||
2822 : | preview_mc.box_mc.beginFill(0x000000); | ||
2823 : | preview_mc.box_mc.moveTo(0, 0); | ||
2824 : | preview_mc.box_mc.lineTo(0, 100); | ||
2825 : | preview_mc.box_mc.lineTo(100, 100); | ||
2826 : | preview_mc.box_mc.lineTo(100, 0); | ||
2827 : | preview_mc.box_mc.lineTo(0, 0); | ||
2828 : | preview_mc.box_mc.endFill(); | ||
2829 : | preview_mc.attachMovie("Icon", "icon_mc", 20); | ||
2830 : | } | ||
2831 : | |||
2832 : | /** | ||
2833 : | * Called on <code>onEnterFrame</code> to initiate loading the new | ||
2834 : | * contentPath url. We delay to give the user time to set other | ||
2835 : | * vars as well. Only done this way when contentPath set from the | ||
2836 : | * component inspector or property inspector, not when set with AS. | ||
2837 : | * | ||
2838 : | * @see #contentPath | ||
2839 : | * @private | ||
2840 : | */ | ||
2841 : | private function doContentPathConnect():Void { | ||
2842 : | delete _vp[0].onEnterFrame; | ||
2843 : | _vp[0].onEnterFrame = undefined; | ||
2844 : | if (_global.isLivePreview) return; | ||
2845 : | if (_vpState[0].autoPlay && _firstStreamShown) { | ||
2846 : | _vp[0].play(_contentPath, _isLive, _totalTime); | ||
2847 : | } else { | ||
2848 : | _vp[0].load(_contentPath, _isLive, _totalTime); | ||
2849 : | } | ||
2850 : | _vpState[0].isLiveSet = false; | ||
2851 : | _vpState[0].totalTimeSet = false; | ||
2852 : | } | ||
2853 : | |||
2854 : | private function showFirstStream():Void { | ||
2855 : | _firstStreamShown = true; | ||
2856 : | _vp[_visibleVP].visible = true; | ||
2857 : | if (!scrubbing) { | ||
2858 : | _vp[_visibleVP].volume = _volume; | ||
2859 : | } | ||
2860 : | // play all autoPlay streams loaded into other video players | ||
2861 : | // that have been waiting | ||
2862 : | for (var i:Number = 0; i < _vp.length; i++) { | ||
2863 : | if (_vp[i] != undefined && _vp[i].state == STOPPED && _vpState[i].autoPlay) { | ||
2864 : | _vp[i].play(); | ||
2865 : | } | ||
2866 : | } | ||
2867 : | } | ||
2868 : | |||
2869 : | /** | ||
2870 : | * Called by UIManager when seekbar scrubbing starts | ||
2871 : | * | ||
2872 : | * @private | ||
2873 : | */ | ||
2874 : | function _scrubStart():Void { | ||
2875 : | var nowTime:Number = playheadTime; | ||
2876 : | _vp[_visibleVP].volume = 0; | ||
2877 : | dispatchEvent({type:"stateChange", state:SEEKING, playheadTime:nowTime, vp:_visibleVP}); | ||
2878 : | dispatchEvent({type:"scrubStart", state:SEEKING, playheadTime:nowTime}); | ||
2879 : | } | ||
2880 : | |||
2881 : | /** | ||
2882 : | * Called by UIManager when seekbar scrubbing finishes | ||
2883 : | * | ||
2884 : | * @private | ||
2885 : | */ | ||
2886 : | function _scrubFinish():Void { | ||
2887 : | var nowTime:Number = playheadTime; | ||
2888 : | var nowState:String = state; | ||
2889 : | _vp[_visibleVP].volume = _volume; | ||
2890 : | if (nowState != SEEKING) { | ||
2891 : | dispatchEvent({type:"stateChange", state:nowState, playheadTime:nowTime, vp:_visibleVP}); | ||
2892 : | } | ||
2893 : | dispatchEvent({type:"scrubFinish", state:nowState, playheadTime:nowTime}); | ||
2894 : | } | ||
2895 : | |||
2896 : | /** | ||
2897 : | * Called by UIManager when skin errors | ||
2898 : | * | ||
2899 : | * @private | ||
2900 : | */ | ||
2901 : | function skinError(message:String):Void { | ||
2902 : | if (_firstStreamReady && !_firstStreamShown) { | ||
2903 : | showFirstStream(); | ||
2904 : | } | ||
2905 : | dispatchEvent({type:"skinError", message:message}); | ||
2906 : | } | ||
2907 : | |||
2908 : | /** | ||
2909 : | * Called by UIManager when skin loads | ||
2910 : | * | ||
2911 : | * @private | ||
2912 : | */ | ||
2913 : | function skinLoaded():Void { | ||
2914 : | if (_firstStreamReady) { | ||
2915 : | _uiMgr.visible = true; | ||
2916 : | if (!_firstStreamShown) { | ||
2917 : | showFirstStream(); | ||
2918 : | } | ||
2919 : | } else if (_contentPath == undefined || _contentPath == null || _contentPath == "") { | ||
2920 : | _uiMgr.visible = true; | ||
2921 : | } | ||
2922 : | dispatchEvent({type:"skinLoaded"}); | ||
2923 : | } | ||
2924 : | |||
2925 : | |||
2926 : | //ifdef DEBUG | ||
2927 : | ///** | ||
2928 : | // * @private | ||
2929 : | // */ | ||
2930 : | //function debugTrace(s:String):Void { | ||
2931 : | // if (_debuggingOn) { | ||
2932 : | // if (_debugFn != null && _debugFn != undefined) { | ||
2933 : | // _debugFn.call(null, s); | ||
2934 : | // } else { | ||
2935 : | // trace(s); | ||
2936 : | // } | ||
2937 : | // } | ||
2938 : | //} | ||
2939 : | //endif | ||
2940 : | } // class mx.video.FLVPlayback |
cvs-admin | ViewVC Help |
Powered by ViewVC 1.0.0 |