580cf0bd5edea80216e7995db729f9244cdc7a27
2 * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file)
3 * THIS WILL BE DEPRECIATED SOON
7 * flowplayer.js 3.0.0-rc5. The Flowplayer API.
9 * This file is part of Flowplayer, http://flowplayer.org
11 * Author: Tero Piirainen, <support@flowplayer.org>
12 * Copyright (c) 2008 Flowplayer Ltd
14 * Released under the MIT License:
15 * http://www.opensource.org/licenses/mit-license.php
17 * Version: 3.0.0-rc5 - Thu Nov 20 2008 22:09:49 GMT-0000 (GMT+00:00)
24 - handling multiple instances
25 - Flowplayer programming API
26 - Flowplayer event model
27 - player loading / unloading
33 /*jslint glovar: true, browser: true */
34 /*global flowplayer, $f */
36 // {{{ private utility methods
38 function log( args
) {
40 // write into opera console
41 if ( typeof opera
== 'object' ) {
42 opera
.postError( "$f.fireEvent: " + args
.join( " | " ) );
45 } else if ( typeof console
== 'object' ) {
46 console
.log( "$f.fireEvent", [].slice
.call( args
) );
51 // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
52 function clone ( obj
) {
53 if ( !obj
|| typeof obj
!= 'object' ) { return obj
; }
54 var temp
= new obj
.constructor();
55 for ( var key
in obj
) {
56 if ( obj
.hasOwnProperty( key
) ) {
57 temp
[key
] = clone ( obj
[key
] );
63 // stripped from jQuery, thanks John Resig
64 function each( obj
, fn
) {
65 if ( !obj
) { return; }
67 var name
, i
= 0, length
= obj
.length
;
70 if ( length
=== undefined ) {
72 if ( fn
.call( obj
[name
], name
, obj
[name
] ) === false ) { break; }
77 for ( var value
= obj
[0];
78 i
< length
&& fn
.call( value
, i
, value
) !== false; value
= obj
[++i
] ) {
88 return document
.getElementById( id
);
92 // used extensively. a very simple implementation.
93 function extend( to
, from, skipFuncs
) {
95 each( from, function( name
, value
) {
96 if ( !skipFuncs
|| typeof value
!= 'function' ) {
103 // var arr = select("elem.className");
104 function select( query
) {
105 var index
= query
.indexOf( "." );
106 if ( index
!= - 1 ) {
107 var tag
= query
.substring( 0, index
) || "*";
108 var klass
= query
.substring( index
+ 1, query
.length
);
110 each( document
.getElementsByTagName( tag
), function() {
111 if ( this.className
&& this.className
.indexOf( klass
) != - 1 ) {
119 // fix event inconsistencies across browsers
120 function stopEvent( e
) {
121 e
= e
|| window
.event
;
123 if ( e
.preventDefault
) {
128 e
.returnValue
= false;
129 e
.cancelBubble
= true;
134 // push an event listener into existing array of listeners
135 function bind( to
, evt
, fn
) {
136 to
[evt
] = to
[evt
] || [];
141 // generates an unique id
143 return "_" + ( "" + Math
.random() ).substring( 2, 10 );
151 var Clip = function( json
, index
, player
) {
159 // instance variables
160 if ( typeof json
== 'string' ) {
164 extend( this, json
, true );
167 each( ( "Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop" ).split( "," ),
170 var evt
= "on" + this;
173 if ( evt
.indexOf( "*" ) != - 1 ) {
174 evt
= evt
.substring( 0, evt
.length
- 1 );
175 var before
= "onBefore" + evt
.substring( 2 );
177 self
[before
] = function( fn
) {
178 bind( listeners
, before
, fn
);
183 self
[evt
] = function( fn
) {
184 bind( listeners
, evt
, fn
);
189 // set common clip event listeners to player level
190 if ( index
== - 1 ) {
191 if ( self
[before
] ) {
192 player
[before
] = self
[before
];
195 player
[evt
] = self
[evt
];
204 onCuepoint: function( points
, fn
) {
206 // embedded cuepoints
207 if ( arguments
.length
== 1 ) {
208 cuepoints
.embedded
= [null, points
];
212 if ( typeof points
== 'number' ) {
217 cuepoints
[fnId
] = [points
, fn
];
219 if ( player
.isLoaded() ) {
220 player
._api().fp_addCuepoints( points
, index
, fnId
);
226 update: function( json
) {
227 extend( self
, json
);
229 if ( player
.isLoaded() ) {
230 player
._api().fp_updateClip( json
, index
);
232 var conf
= player
.getConfig();
233 var clip
= ( index
== - 1 ) ? conf
.clip
: conf
.playlist
[index
];
234 extend( clip
, json
, true );
238 // internal event for performing clip tasks. should be made private someday
239 _fireEvent: function( evt
, arg1
, arg2
, target
) {
241 if ( evt
== 'onLoad' ) {
242 each( cuepoints
, function( key
, val
) {
243 player
._api().fp_addCuepoints( val
[0], index
, key
);
248 // target clip we are working against
249 if ( index
!= - 1 ) {
253 if ( evt
== 'onCuepoint' ) {
254 var fn
= cuepoints
[arg1
];
256 return fn
[1].call( player
, target
, arg2
);
260 if ( evt
== 'onStart' || evt
== 'onUpdate' ) {
262 extend( target
, arg1
);
264 if ( !target
.duration
) {
265 target
.duration
= arg1
.metaData
.duration
;
267 target
.fullDuration
= arg1
.metaData
.duration
;
272 each( listeners
[evt
], function() {
273 ret
= this.call( player
, target
, arg1
);
281 // get cuepoints from config
282 if ( json
.onCuepoint
) {
283 self
.onCuepoint
.apply( self
, json
.onCuepoint
);
284 delete json
.onCuepoint
;
288 each( json
, function( key
, val
) {
289 if ( typeof val
== 'function' ) {
290 bind( listeners
, key
, val
);
296 // setup common clip event callbacks for Player object too (shortcuts)
297 if ( index
== - 1 ) {
298 player
.onCuepoint
= this.onCuepoint
;
308 var Plugin = function( name
, json
, player
, fn
) {
312 var hasMethods
= false;
315 extend( listeners
, fn
);
318 // custom callback functions in configuration
319 each( json
, function( key
, val
) {
320 if ( typeof val
== 'function' ) {
321 listeners
[key
] = val
;
326 // core plugin methods
329 animate: function( props
, speed
, fn
) {
334 if ( typeof speed
== 'function' ) {
339 if ( typeof props
== 'string' ) {
348 listeners
[fnId
] = fn
;
351 if ( speed
=== undefined ) { speed
= 500; }
352 json
= player
._api().fp_animate( name
, props
, speed
, fnId
);
356 css: function( props
, val
) {
357 if ( val
!== undefined ) {
363 json
= player
._api().fp_css( name
, props
);
364 extend( self
, json
);
367 js_log( 'flow player could not set css: ' + json
);
372 this.display
= 'block';
373 player
._api().fp_showPlugin( name
);
378 this.display
= 'none';
379 player
._api().fp_hidePlugin( name
);
384 this.display
= player
._api().fp_togglePlugin( name
);
388 fadeTo: function( o
, speed
, fn
) {
390 if ( typeof speed
== 'function' ) {
397 listeners
[fnId
] = fn
;
399 this.display
= player
._api().fp_fadeTo( name
, o
, speed
, fnId
);
404 fadeIn: function( speed
, fn
) {
405 return self
.fadeTo( 1, speed
, fn
);
408 fadeOut: function( speed
, fn
) {
409 return self
.fadeTo( 0, speed
, fn
);
412 getName: function() {
417 // internal method not meant to be used by clients
418 _fireEvent: function( evt
, arg
) {
421 // update plugins properties & methods
422 if ( evt
== 'onUpdate' ) {
423 var json
= arg
|| player
._api().fp_getPlugin( name
);
424 if ( !json
) { return; }
426 extend( self
, json
);
430 each( json
.methods
, function() {
431 var method
= "" + this;
433 self
[method
] = function() {
434 var a
= [].slice
.call( arguments
);
435 var ret
= player
._api().fp_invoke( name
, method
, a
);
436 return ret
== 'undefined' ? self
: ret
;
444 var fn
= listeners
[evt
];
448 fn
.call( self
, arg
);
450 // "one-shot" callback
451 if ( evt
.substring( 0, 1 ) == "_" ) {
452 delete listeners
[evt
];
465 function Player( wrapper
, params
, conf
) {
467 // private variables (+ arguments)
483 // {{{ public methods
491 isLoaded: function() {
492 return ( api
!== null );
495 getParent: function() {
499 hide: function( all
) {
500 if ( all
) { wrapper
.style
.height
= "0px"; }
501 if ( api
) { api
.style
.height
= "0px"; }
506 wrapper
.style
.height
= wrapperHeight
+ "px";
507 if ( api
) { api
.style
.height
= swfHeight
+ "px"; }
511 isHidden: function() {
512 return api
&& parseInt( api
.style
.height
, 10 ) === 0;
516 load: function( fn
) {
518 if ( !api
&& self
._fireEvent( "onBeforeLoad" ) !== false ) {
520 // unload all instances
521 each( players
, function() {
525 html
= wrapper
.innerHTML
;
526 flashembed( wrapper
, params
, { config
: conf
} );
531 bind( listeners
, "onLoad", fn
);
540 if ( api
&& html
.replace( /\s/g, '' ) !== '' && !api
.fp_isFullscreen() &&
541 self
._fireEvent( "onBeforeUnload" ) !== false ) {
543 wrapper
.innerHTML
= html
;
544 self
._fireEvent( "onUnload" );
551 getClip: function( index
) {
552 if ( index
=== undefined ) {
555 return playlist
[index
];
559 getCommonClip: function() {
563 getPlaylist: function() {
567 getPlugin: function( name
) {
568 var plugin
= plugins
[name
];
570 // create plugin if nessessary
571 if ( !plugin
&& self
.isLoaded() ) {
572 var json
= self
._api().fp_getPlugin( name
);
574 plugin
= new Plugin( name
, json
, self
);
575 plugins
[name
] = plugin
;
581 getScreen: function() {
582 return self
.getPlugin( "screen" );
585 getControls: function() {
586 return self
.getPlugin( "controls" );
589 getConfig: function() {
590 return clone ( conf
);
593 getFlashParams: function() {
597 loadPlugin: function( name
, url
, props
, fn
) {
599 // properties not supplied
600 if ( typeof props
== 'function' ) {
605 // if fn not given, make a fake id so that plugin's onUpdate get's fired
606 var fnId
= fn
? makeId() : "_";
607 self
._api().fp_loadPlugin( name
, url
, props
, fnId
);
612 var p
= new Plugin( name
, null, self
, arg
);
618 getState: function() {
619 return api
? api
.fp_getState() : - 1;
623 play: function( clip
) {
626 if ( clip
!== undefined ) {
627 self
._api().fp_play( clip
);
629 if ( typeof self
._api().fp_play
== 'function' )
630 self
._api().fp_play();
638 self
.load( function() {
646 getVersion: function() {
647 var js
= "flowplayer.js 3.0.0-rc5";
649 var ver
= api
.fp_getVersion();
658 throw "Flowplayer " + self
.id() + " not loaded. Try moving your call to player's onLoad event";
664 console
.log( listeners
);
671 each( ( "Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error" ).split( "," ),
673 var name
= "on" + this;
676 if ( name
.indexOf( "*" ) != - 1 ) {
677 name
= name
.substring( 0, name
.length
- 1 );
678 var name2
= "onBefore" + name
.substring( 2 );
679 self
[name2
] = function( fn
) {
680 bind( listeners
, name2
, fn
);
686 self
[name
] = function( fn
) {
687 bind( listeners
, name
, fn
);
695 each( ( "pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset" ).split( "," ),
699 self
[name
] = function( arg
) {
700 if ( !api
) { return self
; }
702 var ret
= ( arg
=== undefined ) ? api
["fp_" + name
]() : api
["fp_" + name
]( arg
);
703 return ret
== 'undefined' ? self
: ret
;
705 js_log( 'flowplayer could not access fp_ ' + name
);
714 // {{{ public method: _fireEvent
716 self
._fireEvent = function( evt
, arg0
, arg1
, arg2
) {
723 if ( evt
== 'onLoad' && !api
) {
725 api
= api
|| el( apiId
);
726 swfHeight
= api
.clientHeight
;
728 each( playlist
, function() {
729 this._fireEvent( "onLoad" );
732 each( plugins
, function( name
, p
) {
733 p
._fireEvent( "onUpdate" );
737 commonClip
._fireEvent( "onLoad" );
740 if ( evt
== 'onContextMenu' ) {
741 each( conf
.contextMenu
[arg0
], function( key
, fn
) {
747 if ( evt
== 'onPluginEvent' ) {
748 var name
= arg0
.name
|| arg0
;
749 var p
= plugins
[name
];
752 p
._fireEvent( "onUpdate", arg0
);
754 p
._fireEvent( arg1
);
760 if ( evt
== 'onPlaylistReplace' ) {
763 each( arg0
, function() {
764 playlist
.push( new Clip( this, index
++ ) );
771 if ( arg0
=== 0 || ( arg0
&& arg0
>= 0 ) ) {
774 var clip
= playlist
[arg0
];
777 ret
= clip
._fireEvent( evt
, arg1
, arg2
);
780 if ( !clip
|| ret
!== false ) {
782 // clip argument is given for common clip, because it behaves as the target
783 ret
= commonClip
._fireEvent( evt
, arg1
, arg2
, clip
);
789 each( listeners
[evt
], function() {
790 ret
= this.call( self
, arg0
);
792 // remove cached entry
794 listeners
[evt
].splice( i
, 1 );
798 if ( ret
=== false ) { return false; }
813 if ( $f( wrapper
) ) {
817 wrapperHeight
= parseInt( wrapper
.style
.height
) || wrapper
.clientHeight
;
819 // register this player into global array of instances
820 players
.push( self
);
823 // flashembed parameters
824 if ( typeof params
== 'string' ) {
825 params
= { src
: params
};
829 playerId
= wrapper
.id
|| "fp" + makeId();
830 apiId
= params
.id
|| playerId
+ "_api";
832 conf
.playerId
= playerId
;
835 // plain url is given as config
836 if ( typeof conf
== 'string' ) {
837 conf
= { clip
: { url
:conf
} };
840 // common clip is always there
841 conf
.clip
= conf
.clip
|| { };
842 commonClip
= new Clip( conf
.clip
, - 1, self
);
845 // wrapper href as playlist
846 if ( wrapper
.getAttribute( "href" ) ) {
847 conf
.playlist
= [ { url
:wrapper
.getAttribute( "href", 2 ) }];
851 conf
.playlist
= conf
.playlist
|| [conf
.clip
];
854 each( conf
.playlist
, function() {
858 // clip is an array, we don't allow that
859 if ( typeof clip
== 'object' && clip
.length
) {
863 if ( !clip
.url
&& typeof clip
== 'string' ) {
864 clip
= { url
: clip
};
867 // populate common clip properties to each clip
868 extend( clip
, conf
.clip
, true );
870 // modify configuration playlist
871 conf
.playlist
[index
] = clip
;
873 // populate playlist array
874 clip
= new Clip( clip
, index
, self
);
875 playlist
.push( clip
);
881 each( conf
, function( key
, val
) {
882 if ( typeof val
== 'function' ) {
883 bind( listeners
, key
, val
);
890 each( conf
.plugins
, function( name
, val
) {
892 plugins
[name
] = new Plugin( name
, val
, self
);
897 // setup controlbar plugin if not explicitly defined
898 if ( !conf
.plugins
|| conf
.plugins
.controls
=== undefined ) {
899 plugins
.controls
= new Plugin( "controls", null, self
);
902 // Flowplayer uses black background by default
903 params
.bgcolor
= params
.bgcolor
|| "#000000";
906 // setup default settings for express install
907 params
.version
= params
.version
|| [9, 0];
908 params
.expressInstall
= 'http://www.flowplayer.org/swf/expressinstall.swf';
912 function doClick( e
) {
913 if ( self
._fireEvent( "onBeforeClick" ) !== false ) {
916 return stopEvent( e
);
919 // defer loading upon click
920 html
= wrapper
.innerHTML
;
921 if ( html
.replace( /\s/g, '' ) !== '' ) {
923 if ( wrapper
.addEventListener
) {
924 wrapper
.addEventListener( "click", doClick
, false );
926 } else if ( wrapper
.attachEvent
) {
927 wrapper
.attachEvent( "onclick", doClick
);
930 // player is loaded upon page load
933 // prevent default action from wrapper (safari problem) loaded
934 if ( wrapper
.addEventListener
) {
935 wrapper
.addEventListener( "click", stopEvent
, false );
944 // possibly defer initialization until DOM get's loaded
945 if ( typeof wrapper
== 'string' ) {
946 flashembed
.domReady( function() {
947 var node
= el( wrapper
);
950 throw "Flowplayer cannot access element: " + wrapper
;
957 // we have a DOM element so page is already loaded
969 // {{{ flowplayer() & statics
971 // container for player instances
975 // this object is returned when multiple player's are requested
976 function Iterator( arr
) {
978 this.length
= arr
.length
;
980 this.each = function( fn
) {
984 this.size = function() {
989 // these two variables are the only global variables
990 window
.flowplayer
= window
.$f = function() {
993 var arg
= arguments
[0];
997 if ( !arguments
.length
) {
998 each( players
, function() {
999 if ( this.isLoaded() ) {
1005 return instance
|| players
[0];
1008 if ( arguments
.length
== 1 ) {
1011 if ( typeof arg
== 'number' ) {
1012 return players
[arg
];
1015 // $f(wrapper || 'containerId' || '*');
1020 return new Iterator( players
);
1023 // $f(wrapper || 'containerId');
1024 each( players
, function() {
1025 if ( this.id() == arg
.id
|| this.id() == arg
|| this.getParent() == arg
) {
1036 if ( arguments
.length
> 1 ) {
1038 var swf
= arguments
[1];
1039 var conf
= ( arguments
.length
== 3 ) ? arguments
[2] : { };
1041 if ( typeof arg
== 'string' ) {
1043 // select arg by classname
1044 if ( arg
.indexOf( "." ) != - 1 ) {
1047 each( select( arg
), function() {
1048 instances
.push( new Player( this, clone ( swf
), clone ( conf
) ) );
1051 return new Iterator( instances
);
1053 // select node by id
1055 var node
= el( arg
);
1056 return new Player( node
!== null ? node
: arg
, swf
, conf
);
1060 // arg is a DOM element
1062 return new Player( arg
, swf
, conf
);
1070 extend( window
.$f
, {
1072 // called by Flash External Interface
1073 fireEvent: function( id
, evt
, a0
, a1
, a2
) {
1075 return p
? p
._fireEvent( evt
, a0
, a1
, a2
) : null;
1079 // create plugins by modifying Player's prototype
1080 addPlugin: function( name
, fn
) {
1081 Player
.prototype[name
] = fn
;
1085 // utility methods for plugin developers
1095 // {{{ jQuery support
1097 if ( typeof jQuery
== 'function' ) {
1099 jQuery
.prototype.flowplayer = function( params
, conf
) {
1102 if ( !arguments
.length
|| typeof arguments
[0] == 'number' ) {
1104 this.each( function() {
1110 return arguments
.length
? arr
[arguments
[0]] : new Iterator( arr
);
1113 // create flowplayer instances
1114 return this.each( function() {
1115 $f( this, clone ( params
), conf
? clone ( conf
) : { } );
1127 * flashembed 0.34. Adobe Flash embedding script
1129 * http://flowplayer.org/tools/flash-embed.html
1131 * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
1133 * Released under the MIT License:
1134 * http://www.opensource.org/licenses/mit-license.php
1136 * >> Basically you can do anything you want but leave this header as is <<
1138 * first version 0.01 - 03/11/2008
1139 * version 0.34 - Tue Nov 11 2008 09:09:52 GMT-0000 (GMT+00:00)
1143 // {{{ utility functions
1145 var jQ
= typeof jQuery
== 'function';
1148 // from "Pro JavaScript techniques" by John Resig
1149 function isDomReady() {
1151 if ( domReady
.done
) { return false; }
1154 if ( d
&& d
.getElementsByTagName
&& d
.getElementById
&& d
.body
) {
1155 clearInterval( domReady
.timer
);
1156 domReady
.timer
= null;
1158 for ( var i
= 0; i
< domReady
.ready
.length
; i
++ ) {
1159 domReady
.ready
[i
].call();
1162 domReady
.ready
= null;
1163 domReady
.done
= true;
1167 // if jQuery is present, use it's more effective domReady method
1168 var domReady
= jQ
? jQuery : function( f
) {
1170 if ( domReady
.done
) {
1174 if ( domReady
.timer
) {
1175 domReady
.ready
.push( f
);
1178 domReady
.ready
= [f
];
1179 domReady
.timer
= setInterval( isDomReady
, 13 );
1184 // override extend params function
1185 function extend( to
, from ) {
1187 for ( key
in from ) {
1188 if ( from.hasOwnProperty( key
) ) {
1189 to
[key
] = from[key
];
1198 function concatVars( vars
) {
1201 for ( var key
in vars
) {
1203 out
+= [key
] + '=' + asString( vars
[key
] ) + '&';
1206 return out
.substring( 0, out
.length
- 1 );
1211 // JSON.asString() function
1212 function asString( obj
) {
1214 switch ( typeOf( obj
) ) {
1216 obj
= obj
.replace( new RegExp( '(["\\\\])', 'g' ), '\\$1' );
1218 // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
1219 obj
= obj
.replace( /^\s?(\d+)%/, "$1pct" );
1220 return '"' + obj
+ '"';
1223 return '[' + map( obj
, function( el
) {
1224 return asString( el
);
1225 } ).join( ',' ) + ']';
1228 return '"function()"';
1232 for ( var prop
in obj
) {
1233 if ( obj
.hasOwnProperty( prop
) ) {
1234 str
.push( '"' + prop
+ '":' + asString( obj
[prop
] ) );
1237 return '{' + str
.join( ',' ) + '}';
1240 // replace ' --> " and remove spaces
1241 return String( obj
).replace( /\s/g, " ").replace( /\'/g, "\"" );
1245 // private functions
1246 function typeOf(obj
) {
1247 if (obj
=== null || obj
=== undefined) { return false; }
1248 var type
= typeof obj
;
1249 return (type
== 'object' && obj
.push
) ? 'array' : type
;
1253 // version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
1254 if (window
.attachEvent
) {
1255 window
.attachEvent("onbeforeunload", function() {
1256 __flash_unloadHandler = function() {};
1257 __flash_savedUnloadHandler = function() {};
1261 function map(arr
, func
) {
1263 for (var i
in arr
) {
1264 if (arr
.hasOwnProperty(i
)) {
1265 newArr
[i
] = func(arr
[i
]);
1271 function getEmbedCode(p
, c
) {
1272 var html
= ' < embed type = "application/x-shockwave-flash" ';
1274 if (p
.id
) { extend(p
, {name
:p
.id
}); }
1276 for (var key
in p
) {
1277 if (p
[key
] !== null) {
1278 html
+= key
+ '="' + p
[key
] + '"\n\t';
1283 html
+= 'flashvars=\'' + concatVars( c
) + '\'';
1286 // thanks Tom Price (07/17/2008)
1292 function getObjectCode( p
, c
, embeddable
) {
1294 var html
= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
1295 html
+= 'width="' + p
.width
+ '" height="' + p
.height
+ '"';
1297 // force id for IE. otherwise embedded Flash object cannot be returned
1298 if ( !p
.id
&& document
.all
) {
1299 p
.id
= "_" + ( "" + Math
.random() ).substring( 5 );
1303 html
+= ' id="' + p
.id
+ '"';
1308 // sometimes ie fails to load flash if it's on cache
1309 if ( document
.all
) {
1310 p
.src
+= ( ( p
.src
.indexOf( "?" ) != - 1 ? "&" : "?" ) + Math
.random() );
1313 html
+= '\n\t<param name="movie" value="' + p
.src
+ '" />';
1315 var e
= extend( { }, p
);
1316 e
.id
= e
.width
= e
.height
= e
.src
= null;
1318 for ( var k
in e
) {
1319 if ( e
[k
] !== null ) {
1320 html
+= '\n\t<param name="' + k
+ '" value="' + e
[k
] + '" />';
1325 html
+= '\n\t<param name="flashvars" value=\'' + concatVars( c
) + '\' />';
1329 html
+= getEmbedCode( p
, c
);
1332 html
+= "</object>";
1337 function getFullHTML( p
, c
) {
1338 return getObjectCode( p
, c
, true );
1341 function getHTML( p
, c
) {
1342 var isNav
= navigator
.plugins
&& navigator
.mimeTypes
&& navigator
.mimeTypes
.length
;
1343 return ( isNav
) ? getEmbedCode( p
, c
) : getObjectCode( p
, c
);
1349 window
.flashembed = function( root
, userParams
, flashvars
) {
1357 // very common params
1362 // flashembed specific options
1365 expressInstall
:null,
1368 // flashembed defaults
1369 // bgcolor: 'transparent',
1370 allowfullscreen
: true,
1371 allowscriptaccess
: 'always',
1373 type
: 'application/x-shockwave-flash',
1374 pluginspage
: 'http://www.adobe.com/go/getflashplayer'
1378 if ( typeof userParams
== 'string' ) {
1379 userParams
= { src
: userParams
};
1382 extend( params
, userParams
);
1384 var version
= flashembed
.getVersion();
1385 var required
= params
.version
;
1386 var express
= params
.expressInstall
;
1387 var debug
= params
.debug
;
1390 if ( typeof root
== 'string' ) {
1391 var el
= document
.getElementById( root
);
1395 domReady( function() {
1396 flashembed( root
, userParams
, flashvars
);
1402 if ( !root
) { return; }
1406 if ( !required
|| flashembed
.isSupported( required
) ) {
1407 params
.onFail
= params
.version
= params
.expressInstall
= params
.debug
= null;
1409 // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
1410 // thanks to: Ryan Rud
1411 // var tmp = document.createElement("extradiv");
1412 // tmp.innerHTML = getHTML();
1413 // root.appendChild(tmp);
1415 root
.innerHTML
= getHTML( params
, flashvars
);
1418 return root
.firstChild
;
1420 // custom fail event
1421 } else if ( params
.onFail
) {
1422 var ret
= params
.onFail
.call( params
, flashembed
.getVersion(), flashvars
);
1423 if ( ret
=== true ) { root
.innerHTML
= ret
; }
1427 } else if ( required
&& express
&& flashembed
.isSupported( [6, 65] ) ) {
1429 extend( params
, { src
: express
} );
1432 MMredirectURL
: location
.href
,
1433 MMplayerType
: 'PlugIn',
1434 MMdoctitle
: document
.title
1437 root
.innerHTML
= getHTML( params
, flashvars
);
1442 // minor bug fixed here 08.04.2008 (thanks JRodman)
1444 if ( root
.innerHTML
.replace( /\s/g, '') !== '' ) {
1445 // custom content was supplied
1449 "<h2>Flash version " + required
+ " or greater is required</h2>" +
1451 ( version
[0] > 0 ? "Your version is " + version
: "You have no flash plugin installed" ) +
1453 "<p>Download latest version from <a href='" + params
.pluginspage
+ "'>here</a></p>";
1465 // {{{ static methods
1467 extend( window
.flashembed
, {
1469 // returns arr[major, fix]
1470 getVersion: function() {
1472 var version
= [0, 0];
1474 if ( navigator
.plugins
&& typeof navigator
.plugins
["Shockwave Flash"] == "object" ) {
1475 var _d
= navigator
.plugins
["Shockwave Flash"].description
;
1476 if ( typeof _d
!= "undefined" ) {
1477 _d
= _d
.replace( /^.*\s+(\S+\s+\S+$ )/, "$1" );
1478 var _m
= parseInt( _d
.replace( /^(.*)\..*$/, "$1" ), 10 );
1479 var _r
= / r
/ .test( _d
) ? parseInt( _d
.replace( /^.*r(.*)$/ , "$1" ), 10 ) : 0;
1483 } else if ( window
.ActiveXObject
) {
1485 try { // avoid fp 6 crashes
1486 var _a
= new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.7" );
1490 _a
= new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.6" );
1492 _a
.AllowScriptAccess
= "always"; // throws if fp < 6.47
1495 if ( version
[0] == 6 ) { return; }
1498 _a
= new ActiveXObject( "ShockwaveFlash.ShockwaveFlash" );
1505 if ( typeof _a
== "object" ) {
1506 _d
= _a
.GetVariable( "$version" ); // bugs in fp 6.21 / 6.23
1507 if ( typeof _d
!= "undefined" ) {
1508 _d
= _d
.replace( /^\S+\s+(.*)$/, "$1" ).split( "," );
1509 version
= [parseInt( _d
[0], 10 ), parseInt( _d
[2], 10 )];
1517 isSupported: function( version
) {
1518 var now
= flashembed
.getVersion();
1519 var ret
= ( now
[0] > version
[0] ) || ( now
[0] == version
[0] && now
[1] >= version
[1] );
1525 // returns a String representation from JSON object
1530 getFullHTML
: getFullHTML
1537 // setup jquery support
1540 jQuery
.prototype.flashembed = function( params
, flashvars
) {
1541 return this.each( function() {
1542 flashembed( this, params
, flashvars
);
1550 /************************************************
1551 ********* mv_embed extension to flowplayer.js ***
1552 ************************************************/
1553 var flowplayerEmbed
= {
1554 instanceOf
:'flowplayerEmbed',
1558 startedTimedPlayback
:false,
1559 didDateStartTimeRestore
:false,
1564 'time_display' : true,
1565 'volume_control' : true
1567 getEmbedHTML: function () {
1568 setTimeout( 'document.getElementById(\'' + this.id
+ '\').postEmbedJS()', 150 );
1569 return this.wrapEmebedContainer( this.getEmbedObj() );
1571 getEmbedObj:function() {
1572 // give the embed element a unique pid (work around for flowplayer persistence)
1573 if ( this.old_pid
!= 0 ) {
1574 this.pid
= this.pid
+ '_' + this.old_pid
;
1577 'href="' + this.getSrc() + '" ' +
1578 'style="display:block;width:' + parseInt( this.width
) + 'px;height:' + parseInt( this.height
) + 'px" ' +
1579 'id="' + this.pid
+ '">' +
1582 postEmbedJS: function()
1585 js_log( 'embedFlow: uri:' + this.getSrc() + "\n" + mv_embed_path
+ 'binPlayers/flowplayer/flowplayer-3.0.1.swf' ) ;
1589 // when this is false playback does not start until play button is pressed
1596 backgroundColor
: 'transparent',
1597 backgroundGradient
: 'none',
1608 // if in preview mode set grey and lower volume until "ready"
1609 if ( this.preview_mode
) {
1610 flowConfig
.screen
.opacity
= 0.2;
1613 $f( this.pid
, mv_embed_path
+ 'binPlayers/flowplayer/flowplayer-3.0.1.swf', flowConfig
);
1614 // get the this.fla value:
1616 // set up bindings (for when interacting with the swf causes action:
1617 this.fla
.onPause( function() {
1618 _this
.parent_pause(); // update the interface
1620 this.fla
.onResume( function() {
1621 _this
.parent_play(); // update the interface
1628 /* js hooks/controls */
1631 // update play/pause button etc
1636 // on a resume make sure volume and opacity are correct
1637 this.restorePlayer();
1638 setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 250 );
1641 // @@todo support mute
1642 toggleMute: function() {
1643 this.parent_toggleMute();
1653 // @@ Suport UpDateVolumen
1654 updateVolumen:function( perc ) {
1656 if ( this.fla )this.fla.setVolume( perc * 100 );
1660 getVolumen:function() {
1663 return this.fla.getVolume() / 100;
1665 fullscreen:function() {
1667 this.fla.fullscreen();
1669 js_log( 'must be playing before you can go fullscreen' );
1675 if ( !this.thumbnail_disp ) {
1676 this.parent_pause();
1678 js_log( "Flash:Pause: " + this.fla.isPaused() );
1679 if ( this.fla['pause'] ) {
1680 if ( ! this.fla.isPaused() ) {
1681 js_log( 'calling plugin pause' );
1684 // restore volume and opacity
1685 this.restorePlayer();
1691 monitor : function()
1695 if ( !this.dateStartTime ) {
1697 this.dateStartTime = d.getTime();
1701 if ( !this.didDateStartTimeRestore && this.preview_mode )
1702 this.fla.setVolume( 0 );
1704 if ( ( d.getTime() - this.dateStartTime ) > 6000 && !this.didDateStartTimeRestore ) {
1705 this.restorePlayer();
1709 var flash_state = this.fla.getStatus();
1710 // update the duration from the clip if its zero or not set:
1711 if ( !this.duration || this.duration == 0 ) {
1712 if ( this.fla.getClip() ) {
1713 this.duration = this.fla.getClip().fullDuration;
1714 js_log( 'set duration via clip value: ' + this.getDuration() );
1717 // update the duration ntp values:
1720 if ( typeof flash_state == 'undefined' ) {
1722 "time" : this.fla.getTime()
1724 // we are not getting buffered data restore volume and opacity
1725 this.restorePlayer();
1727 // simplification of buffer state ... should move to support returning time rages like:
1728 // http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object
1729 this.bufferedPercent = flash_state.bufferEnd / this.getDuration();
1731 // set the current Time (based on timeFormat)
1732 if ( this.supportsURLTimeEncoding() ) {
1733 this.currentTime = flash_state.time;
1734 // js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration());
1736 this.currentTime = flash_state.time + this.start_offset;
1737 // stop buffering if greater than the duration:
1738 if ( flash_state.bufferEnd > this.getDuration() + 5 ) {
1739 // js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() );
1740 this.fla.stopBuffering();
1744 if ( this.currentTime > npt2seconds( this.start_ntp ) && !this.startedTimedPlayback ) {
1748 this.restorePlayer();
1752 js_log( 'failed to set values' );
1756 this.startedTimedPlayback = true;
1759 /* to support local seeks */
1760 if ( this.currentTime
> 1 && this.seek_time_sec
!= 0 && !this.supportsURLTimeEncoding() )
1762 js_log( 'flashEmbed: _local_ Seeking to ' + this.seek_time_sec
);
1763 this.fla
.seek( this.seek_time_sec
);
1764 this.seek_time_sec
= 0;
1767 // checks to see if we reached the end of playback:
1768 if ( this.duration
&& this.startedTimedPlayback
&&
1769 ( this.currentTime
> ( npt2seconds( this.end_ntp
) + 2 )
1771 ( this.currentTime
> ( npt2seconds( this.end_ntp
) - 1 )
1772 && this.prevTime
== this.currentTime
) )
1774 js_log( 'prbally reached end of stream: ' + seconds2npt( this.currentTime
) );
1778 // update the status and check timmer via universal parent monitor
1779 this.parent_monitor();
1782 this.prevTime
= this.currentTime
;
1783 // js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - npt2seconds(this.start_ntp)) +' / ' +(npt2seconds(this.end_ntp)-npt2seconds(this.start_ntp)));
1785 restorePlayer:function() {
1789 js_log( 'f:do restorePlayer' );
1790 this.fla
.setVolume( 90 );
1791 $f().getPlugin( 'screen' ).css( { 'opacity':'1.0' } );
1792 // set the fallback date restore flag to true:
1793 this.didDateStartTimeRestore
= true;
1796 // get the embed fla object
1797 getFLA : function () {
1798 this.fla
= $f( this.pid
);
1801 js_log( 'f:flashEmbed:stop' );
1802 this.startedTimedPlayback
= false;
1803 if ( this.monitorTimerId
!= 0 )
1805 clearInterval( this.monitorTimerId
);
1806 this.monitorTimerId
= 0;
1812 onStop: function() {
1813 js_log( 'f:onStop' );
1815 if ( this.monitorTimerId
!= 0 )
1817 clearInterval( this.monitorTimerId
);
1818 this.monitorTimerId
= 0;
1821 onClipDone: function() {
1822 js_log( 'f:flash:onClipDone' );
1823 if ( ! this.startedTimedPlayback
) {
1824 js_log( 'clip done before timed playback started .. not good. (ignoring) ' );
1828 js_log( 'clip done and ' + this.startedTimedPlayback
);
1829 // stop the clip if its not stopped already:
1831 this.setStatus( "Clip Done..." );
1832 // run the onClip done action:
1833 this.parent_onClipDone();