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
32 /*jslint glovar: true, browser: true */
33 /*global flowplayer, $f */
35 // {{{ private utility methods
37 function log( args ) {
39 // write into opera console
40 if ( typeof opera == 'object' ) {
41 opera.postError( "$f.fireEvent: " + args.join( " | " ) );
44 } else if ( typeof console == 'object' ) {
45 console.log( "$f.fireEvent", [].slice.call( args ) );
49 // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
50 function clone ( obj ) {
51 if ( !obj || typeof obj != 'object' ) { return obj; }
52 var temp = new obj.constructor();
53 for ( var key in obj ) {
54 if ( obj.hasOwnProperty( key ) ) {
55 temp[key] = clone ( obj[key] );
61 // stripped from jQuery, thanks John Resig
62 function each( obj, fn ) {
63 if ( !obj ) { return; }
65 var name, i = 0, length = obj.length;
68 if ( length === undefined ) {
70 if ( fn.call( obj[name], name, obj[name] ) === false ) { break; }
75 for ( var value = obj[0];
76 i < length && fn.call( value, i, value ) !== false; value = obj[++i] ) {
85 return document.getElementById( id );
88 // used extensively. a very simple implementation.
89 function extend( to, from, skipFuncs ) {
91 each( from, function( name, value ) {
92 if ( !skipFuncs || typeof value != 'function' ) {
99 // var arr = select("elem.className");
100 function select( query ) {
101 var index = query.indexOf( "." );
102 if ( index != - 1 ) {
103 var tag = query.substring( 0, index ) || "*";
104 var klass = query.substring( index + 1, query.length );
106 each( document.getElementsByTagName( tag ), function() {
107 if ( this.className && this.className.indexOf( klass ) != - 1 ) {
115 // fix event inconsistencies across browsers
116 function stopEvent( e ) {
117 e = e || window.event;
119 if ( e.preventDefault ) {
124 e.returnValue = false;
125 e.cancelBubble = true;
130 // push an event listener into existing array of listeners
131 function bind( to, evt, fn ) {
132 to[evt] = to[evt] || [];
137 // generates an unique id
139 return "_" + ( "" + Math.random() ).substring( 2, 10 );
144 var Clip = function( json, index, player ) {
151 // instance variables
152 if ( typeof json == 'string' ) {
156 extend( this, json, true );
159 each( ( "Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop" ).split( "," ),
162 var evt = "on" + this;
165 if ( evt.indexOf( "*" ) != - 1 ) {
166 evt = evt.substring( 0, evt.length - 1 );
167 var before = "onBefore" + evt.substring( 2 );
169 self[before] = function( fn ) {
170 bind( listeners, before, fn );
175 self[evt] = function( fn ) {
176 bind( listeners, evt, fn );
180 // set common clip event listeners to player level
181 if ( index == - 1 ) {
182 if ( self[before] ) {
183 player[before] = self[before];
186 player[evt] = self[evt];
192 onCuepoint: function( points, fn ) {
194 // embedded cuepoints
195 if ( arguments.length == 1 ) {
196 cuepoints.embedded = [null, points];
200 if ( typeof points == 'number' ) {
205 cuepoints[fnId] = [points, fn];
207 if ( player.isLoaded() ) {
208 player._api().fp_addCuepoints( points, index, fnId );
213 update: function( json ) {
214 extend( self, json );
216 if ( player.isLoaded() ) {
217 player._api().fp_updateClip( json, index );
219 var conf = player.getConfig();
220 var clip = ( index == - 1 ) ? conf.clip : conf.playlist[index];
221 extend( clip, json, true );
223 // internal event for performing clip tasks. should be made private someday
224 _fireEvent: function( evt, arg1, arg2, target ) {
226 if ( evt == 'onLoad' ) {
227 each( cuepoints, function( key, val ) {
228 player._api().fp_addCuepoints( val[0], index, key );
233 // target clip we are working against
234 if ( index != - 1 ) {
238 if ( evt == 'onCuepoint' ) {
239 var fn = cuepoints[arg1];
241 return fn[1].call( player, target, arg2 );
245 if ( evt == 'onStart' || evt == 'onUpdate' ) {
247 extend( target, arg1 );
249 if ( !target.duration ) {
250 target.duration = arg1.metaData.duration;
252 target.fullDuration = arg1.metaData.duration;
257 each( listeners[evt], function() {
258 ret = this.call( player, target, arg1 );
264 // get cuepoints from config
265 if ( json.onCuepoint ) {
266 self.onCuepoint.apply( self, json.onCuepoint );
267 delete json.onCuepoint;
271 each( json, function( key, val ) {
272 if ( typeof val == 'function' ) {
273 bind( listeners, key, val );
278 // setup common clip event callbacks for Player object too (shortcuts)
279 if ( index == - 1 ) {
280 player.onCuepoint = this.onCuepoint;
286 var Plugin = function( name, json, player, fn ) {
289 var hasMethods = false;
292 extend( listeners, fn );
295 // custom callback functions in configuration
296 each( json, function( key, val ) {
297 if ( typeof val == 'function' ) {
298 listeners[key] = val;
303 // core plugin methods
305 animate: function( props, speed, fn ) {
310 if ( typeof speed == 'function' ) {
315 if ( typeof props == 'string' ) {
324 listeners[fnId] = fn;
327 if ( speed === undefined ) { speed = 500; }
328 json = player._api().fp_animate( name, props, speed, fnId );
331 css: function( props, val ) {
332 if ( val !== undefined ) {
338 json = player._api().fp_css( name, props );
339 extend( self, json );
342 js_log( 'flow player could not set css: ' + json );
346 this.display = 'block';
347 player._api().fp_showPlugin( name );
351 this.display = 'none';
352 player._api().fp_hidePlugin( name );
356 this.display = player._api().fp_togglePlugin( name );
359 fadeTo: function( o, speed, fn ) {
361 if ( typeof speed == 'function' ) {
368 listeners[fnId] = fn;
370 this.display = player._api().fp_fadeTo( name, o, speed, fnId );
374 fadeIn: function( speed, fn ) {
375 return self.fadeTo( 1, speed, fn );
377 fadeOut: function( speed, fn ) {
378 return self.fadeTo( 0, speed, fn );
380 getName: function() {
383 // internal method not meant to be used by clients
384 _fireEvent: function( evt, arg ) {
385 // update plugins properties & methods
386 if ( evt == 'onUpdate' ) {
387 var json = arg || player._api().fp_getPlugin( name );
388 if ( !json ) { return; }
390 Extend( self, json );
394 each( json.methods, function() {
395 var method = "" + this;
397 self[method] = function() {
398 var a = [].slice.call( arguments );
399 var ret = player._api().fp_invoke( name, method, a );
400 return ret == 'undefined' ? self : ret;
408 var fn = listeners[evt];
411 fn.call( self, arg );
413 // "one-shot" callback
414 if ( evt.substring( 0, 1 ) == "_" ) {
415 delete listeners[evt];
425 function Player( wrapper, params, conf ) {
426 // private variables (+ arguments)
441 // {{{ public methods
446 isLoaded: function() {
447 return ( api !== null );
449 getParent: function() {
452 hide: function( all ) {
453 if ( all ) { wrapper.style.height = "0px"; }
454 if ( api ) { api.style.height = "0px"; }
458 wrapper.style.height = wrapperHeight + "px";
459 if ( api ) { api.style.height = swfHeight + "px"; }
462 isHidden: function() {
463 return api && parseInt( api.style.height, 10 ) === 0;
465 load: function( fn ) {
467 if ( !api && self._fireEvent( "onBeforeLoad" ) !== false ) {
469 // unload all instances
470 each( players, function() {
474 html = wrapper.innerHTML;
475 flashembed( wrapper, params, { config: conf } );
480 bind( listeners, "onLoad", fn );
487 if ( api && html.replace( /\s/g, '' ) !== '' && !api.fp_isFullscreen() &&
488 self._fireEvent( "onBeforeUnload" ) !== false ) {
490 wrapper.innerHTML = html;
491 self._fireEvent( "onUnload" );
497 getClip: function( index ) {
498 if ( index === undefined ) {
501 return playlist[index];
503 getCommonClip: function() {
506 getPlaylist: function() {
509 getPlugin: function( name ) {
510 var plugin = plugins[name];
511 // create plugin if nessessary
512 if ( !plugin && self.isLoaded() ) {
513 var json = self._api().fp_getPlugin( name );
515 plugin = new Plugin( name, json, self );
516 plugins[name] = plugin;
521 getScreen: function() {
522 return self.getPlugin( "screen" );
524 getControls: function() {
525 return self.getPlugin( "controls" );
527 getConfig: function() {
528 return clone ( conf );
530 getFlashParams: function() {
533 loadPlugin: function( name, url, props, fn ) {
534 // properties not supplied
535 if ( typeof props == 'function' ) {
540 // if fn not given, make a fake id so that plugin's onUpdate get's fired
541 var fnId = fn ? makeId() : "_";
542 self._api().fp_loadPlugin( name, url, props, fnId );
547 var p = new Plugin( name, null, self, arg );
551 getState: function() {
552 return api ? api.fp_getState() : - 1;
555 play: function( clip ) {
557 if ( clip !== undefined ) {
558 self._api().fp_play( clip );
560 if ( typeof self._api().fp_play == 'function' )
561 self._api().fp_play();
568 self.load( function() {
575 getVersion: function() {
576 var js = "flowplayer.js 3.0.0-rc5";
578 var ver = api.fp_getVersion();
586 throw "Flowplayer " + self.id() + " not loaded. Try moving your call to player's onLoad event";
591 console.log( listeners );
596 each( ( "Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error" ).split( "," ),
598 var name = "on" + this;
601 if ( name.indexOf( "*" ) != - 1 ) {
602 name = name.substring( 0, name.length - 1 );
603 var name2 = "onBefore" + name.substring( 2 );
604 self[name2] = function( fn ) {
605 bind( listeners, name2, fn );
611 self[name] = function( fn ) {
612 bind( listeners, name, fn );
619 each( ( "pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset" ).split( "," ),
623 self[name] = function( arg ) {
624 if ( !api ) { return self; }
626 var ret = ( arg === undefined ) ? api["fp_" + name]() : api["fp_" + name]( arg );
627 return ret == 'undefined' ? self : ret;
629 js_log( 'flowplayer could not access fp_ ' + name );
636 // {{{ public method: _fireEvent
637 self._fireEvent = function( evt, arg0, arg1, arg2 ) {
643 if ( evt == 'onLoad' && !api ) {
644 api = api || el( apiId );
645 swfHeight = api.clientHeight;
647 each( playlist, function() {
648 this._fireEvent( "onLoad" );
651 each( plugins, function( name, p ) {
652 p._fireEvent( "onUpdate" );
655 commonClip._fireEvent( "onLoad" );
658 if ( evt == 'onContextMenu' ) {
659 each( conf.contextMenu[arg0], function( key, fn ) {
665 if ( evt == 'onPluginEvent' ) {
666 var name = arg0.name || arg0;
667 var p = plugins[name];
670 p._fireEvent( "onUpdate", arg0 );
672 p._fireEvent( arg1 );
678 if ( evt == 'onPlaylistReplace' ) {
681 each( arg0, function() {
682 playlist.push( new Clip( this, index++ ) );
689 if ( arg0 === 0 || ( arg0 && arg0 >= 0 ) ) {
691 var clip = playlist[arg0];
694 ret = clip._fireEvent( evt, arg1, arg2 );
697 if ( !clip || ret !== false ) {
698 // clip argument is given for common clip, because it behaves as the target
699 ret = commonClip._fireEvent( evt, arg1, arg2, clip );
705 each( listeners[evt], function() {
706 ret = this.call( self, arg0 );
708 // remove cached entry
710 listeners[evt].splice( i, 1 );
714 if ( ret === false ) { return false; }
725 if ( $f( wrapper ) ) {
729 wrapperHeight = parseInt( wrapper.style.height ) || wrapper.clientHeight;
731 // register this player into global array of instances
732 players.push( self );
735 // flashembed parameters
736 if ( typeof params == 'string' ) {
737 params = { src: params };
741 playerId = wrapper.id || "fp" + makeId();
742 apiId = params.id || playerId + "_api";
744 conf.playerId = playerId;
747 // plain url is given as config
748 if ( typeof conf == 'string' ) {
749 conf = { clip: { url:conf } };
752 // common clip is always there
753 conf.clip = conf.clip || { };
754 commonClip = new Clip( conf.clip, - 1, self );
757 // wrapper href as playlist
758 if ( wrapper.getAttribute( "href" ) ) {
759 conf.playlist = [ { url:wrapper.getAttribute( "href", 2 ) }];
763 conf.playlist = conf.playlist || [conf.clip];
766 each( conf.playlist, function() {
770 // clip is an array, we don't allow that
771 if ( typeof clip == 'object' && clip.length ) {
775 if ( !clip.url && typeof clip == 'string' ) {
776 clip = { url: clip };
779 // populate common clip properties to each clip
780 extend( clip, conf.clip, true );
782 // modify configuration playlist
783 conf.playlist[index] = clip;
785 // populate playlist array
786 clip = new Clip( clip, index, self );
787 playlist.push( clip );
793 each( conf, function( key, val ) {
794 if ( typeof val == 'function' ) {
795 bind( listeners, key, val );
802 each( conf.plugins, function( name, val ) {
804 plugins[name] = new Plugin( name, val, self );
809 // setup controlbar plugin if not explicitly defined
810 if ( !conf.plugins || conf.plugins.controls === undefined ) {
811 plugins.controls = new Plugin( "controls", null, self );
814 // Flowplayer uses black background by default
815 params.bgcolor = params.bgcolor || "#000000";
818 // setup default settings for express install
819 params.version = params.version || [9, 0];
820 params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
824 function doClick( e ) {
825 if ( self._fireEvent( "onBeforeClick" ) !== false ) {
828 return stopEvent( e );
831 // defer loading upon click
832 html = wrapper.innerHTML;
833 if ( html.replace( /\s/g, '' ) !== '' ) {
835 if ( wrapper.addEventListener ) {
836 wrapper.addEventListener( "click", doClick, false );
838 } else if ( wrapper.attachEvent ) {
839 wrapper.attachEvent( "onclick", doClick );
842 // player is loaded upon page load
845 // prevent default action from wrapper (safari problem) loaded
846 if ( wrapper.addEventListener ) {
847 wrapper.addEventListener( "click", stopEvent, false );
856 // possibly defer initialization until DOM get's loaded
857 if ( typeof wrapper == 'string' ) {
858 flashembed.domReady( function() {
859 var node = el( wrapper );
862 throw "Flowplayer cannot access element: " + wrapper;
869 // we have a DOM element so page is already loaded
876 // {{{ flowplayer() & statics
877 // container for player instances
880 // this object is returned when multiple player's are requested
881 function Iterator( arr ) {
882 this.length = arr.length;
884 this.each = function( fn ) {
888 this.size = function() {
893 // these two variables are the only global variables
894 window.flowplayer = window.$f = function() {
896 var arg = arguments[0];
899 if ( !arguments.length ) {
900 each( players, function() {
901 if ( this.isLoaded() ) {
907 return instance || players[0];
910 if ( arguments.length == 1 ) {
912 if ( typeof arg == 'number' ) {
915 // $f(wrapper || 'containerId' || '*');
919 return new Iterator( players );
922 // $f(wrapper || 'containerId');
923 each( players, function() {
924 if ( this.id() == arg.id || this.id() == arg || this.getParent() == arg ) {
935 if ( arguments.length > 1 ) {
936 var swf = arguments[1];
937 var conf = ( arguments.length == 3 ) ? arguments[2] : { };
939 if ( typeof arg == 'string' ) {
940 // select arg by classname
941 if ( arg.indexOf( "." ) != - 1 ) {
944 each( select( arg ), function() {
945 instances.push( new Player( this, clone ( swf ), clone ( conf ) ) );
948 return new Iterator( instances );
952 var node = el( arg );
953 return new Player( node !== null ? node : arg, swf, conf );
957 // arg is a DOM element
959 return new Player( arg, swf, conf );
967 // called by Flash External Interface
968 fireEvent: function( id, evt, a0, a1, a2 ) {
970 return p ? p._fireEvent( evt, a0, a1, a2 ) : null;
973 // create plugins by modifying Player's prototype
974 addPlugin: function( name, fn ) {
975 Player.prototype[name] = fn;
979 // utility methods for plugin developers
986 // {{{ jQuery support
988 if ( typeof jQuery == 'function' ) {
989 jQuery.prototype.flowplayer = function( params, conf ) {
992 if ( !arguments.length || typeof arguments[0] == 'number' ) {
994 this.each( function() {
1000 return arguments.length ? arr[arguments[0]] : new Iterator( arr );
1003 // create flowplayer instances
1004 return this.each( function() {
1005 $f( this, clone ( params ), conf ? clone ( conf ) : { } );
1017 * flashembed 0.34. Adobe Flash embedding script
1019 * http://flowplayer.org/tools/flash-embed.html
1021 * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
1023 * Released under the MIT License:
1024 * http://www.opensource.org/licenses/mit-license.php
1026 * >> Basically you can do anything you want but leave this header as is <<
1028 * first version 0.01 - 03/11/2008
1029 * version 0.34 - Tue Nov 11 2008 09:09:52 GMT-0000 (GMT+00:00)
1033 // {{{ utility functions
1035 var jQ = typeof jQuery == 'function';
1038 // from "Pro JavaScript techniques" by John Resig
1039 function isDomReady() {
1041 if ( domReady.done ) { return false; }
1044 if ( d && d.getElementsByTagName && d.getElementById && d.body ) {
1045 clearInterval( domReady.timer );
1046 domReady.timer = null;
1048 for ( var i = 0; i < domReady.ready.length; i++ ) {
1049 domReady.ready[i].call();
1052 domReady.ready = null;
1053 domReady.done = true;
1057 // if jQuery is present, use it's more effective domReady method
1058 var domReady = jQ ? jQuery : function( f ) {
1060 if ( domReady.done ) {
1064 if ( domReady.timer ) {
1065 domReady.ready.push( f );
1068 domReady.ready = [f];
1069 domReady.timer = setInterval( isDomReady, 13 );
1074 // override extend params function
1075 function extend( to, from ) {
1077 for ( key in from ) {
1078 if ( from.hasOwnProperty( key ) ) {
1079 to[key] = from[key];
1088 function concatVars( vars ) {
1091 for ( var key in vars ) {
1093 out += [key] + '=' + asString( vars[key] ) + '&';
1096 return out.substring( 0, out.length - 1 );
1101 // JSON.asString() function
1102 function asString( obj ) {
1104 switch ( typeOf( obj ) ) {
1106 obj = obj.replace( new RegExp( '(["\\\\])', 'g' ), '\\$1' );
1108 // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
1109 obj = obj.replace( /^\s?(\d+)%/, "$1pct" );
1110 return '"' + obj + '"';
1113 return '[' + map( obj, function( el ) {
1114 return asString( el );
1115 } ).join( ',' ) + ']';
1118 return '"function()"';
1122 for ( var prop in obj ) {
1123 if ( obj.hasOwnProperty( prop ) ) {
1124 str.push( '"' + prop + '":' + asString( obj[prop] ) );
1127 return '{' + str.join( ',' ) + '}';
1130 // replace ' --> " and remove spaces
1131 return String( obj ).replace( /\s/g, " ").replace( /\'/g, "\"" );
1135 // private functions
1136 function typeOf(obj) {
1137 if (obj === null || obj === undefined) { return false; }
1138 var type = typeof obj;
1139 return (type == 'object' && obj.push) ? 'array' : type;
1143 // version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
1144 if (window.attachEvent) {
1145 window.attachEvent("onbeforeunload", function() {
1146 __flash_unloadHandler = function() {};
1147 __flash_savedUnloadHandler = function() {};
1151 function map(arr, func) {
1153 for (var i in arr) {
1154 if (arr.hasOwnProperty(i)) {
1155 newArr[i] = func(arr[i]);
1161 function getEmbedCode(p, c) {
1162 var html = ' < embed type = "application/x-shockwave-flash" ';
1164 if (p.id) { extend(p, {name:p.id}); }
1166 for (var key in p) {
1167 if (p[key] !== null) {
1168 html += key + '="' + p[key] + '"\n\t';
1173 html += 'flashvars=\'' + concatVars( c ) + '\'';
1176 // thanks Tom Price (07/17/2008)
1182 function getObjectCode( p, c, embeddable ) {
1184 var html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
1185 html += 'width="' + p.width + '" height="' + p.height + '"';
1187 // force id for IE. otherwise embedded Flash object cannot be returned
1188 if ( !p.id && document.all ) {
1189 p.id = "_" + ( "" + Math.random() ).substring( 5 );
1193 html += ' id="' + p.id + '"';
1198 // sometimes ie fails to load flash if it's on cache
1199 if ( document.all ) {
1200 p.src += ( ( p.src.indexOf( "?" ) != - 1 ? "&" : "?" ) + Math.random() );
1203 html += '\n\t<param name="movie" value="' + p.src + '" />';
1205 var e = extend( { }, p );
1206 e.id = e.width = e.height = e.src = null;
1208 for ( var k in e ) {
1209 if ( e[k] !== null ) {
1210 html += '\n\t<param name="' + k + '" value="' + e[k] + '" />';
1215 html += '\n\t<param name="flashvars" value=\'' + concatVars( c ) + '\' />';
1219 html += getEmbedCode( p, c );
1222 html += "</object>";
1227 function getFullHTML( p, c ) {
1228 return getObjectCode( p, c, true );
1231 function getHTML( p, c ) {
1232 var isNav = navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length;
1233 return ( isNav ) ? getEmbedCode( p, c ) : getObjectCode( p, c );
1239 window.flashembed = function( root, userParams, flashvars ) {
1247 // very common params
1252 // flashembed specific options
1255 expressInstall:null,
1258 // flashembed defaults
1259 // bgcolor: 'transparent',
1260 allowfullscreen: true,
1261 allowscriptaccess: 'always',
1263 type: 'application/x-shockwave-flash',
1264 pluginspage: 'http://www.adobe.com/go/getflashplayer'
1268 if ( typeof userParams == 'string' ) {
1269 userParams = { src: userParams };
1272 extend( params, userParams );
1274 var version = flashembed.getVersion();
1275 var required = params.version;
1276 var express = params.expressInstall;
1277 var debug = params.debug;
1280 if ( typeof root == 'string' ) {
1281 var el = document.getElementById( root );
1285 domReady( function() {
1286 flashembed( root, userParams, flashvars );
1292 if ( !root ) { return; }
1296 if ( !required || flashembed.isSupported( required ) ) {
1297 params.onFail = params.version = params.expressInstall = params.debug = null;
1299 // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
1300 // thanks to: Ryan Rud
1301 // var tmp = document.createElement("extradiv");
1302 // tmp.innerHTML = getHTML();
1303 // root.appendChild(tmp);
1305 root.innerHTML = getHTML( params, flashvars );
1308 return root.firstChild;
1310 // custom fail event
1311 } else if ( params.onFail ) {
1312 var ret = params.onFail.call( params, flashembed.getVersion(), flashvars );
1313 if ( ret === true ) { root.innerHTML = ret; }
1317 } else if ( required && express && flashembed.isSupported( [6, 65] ) ) {
1319 extend( params, { src: express } );
1322 MMredirectURL: location.href,
1323 MMplayerType: 'PlugIn',
1324 MMdoctitle: document.title
1327 root.innerHTML = getHTML( params, flashvars );
1332 // minor bug fixed here 08.04.2008 (thanks JRodman)
1334 if ( root.innerHTML.replace( /\s/g, '') !== '' ) {
1335 // custom content was supplied
1339 "<h2>Flash version " + required + " or greater is required</h2>" +
1341 ( version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed" ) +
1343 "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
1355 // {{{ static methods
1357 extend( window.flashembed, {
1359 // returns arr[major, fix]
1360 getVersion: function() {
1362 var version = [0, 0];
1364 if ( navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object" ) {
1365 var _d = navigator.plugins["Shockwave Flash"].description;
1366 if ( typeof _d != "undefined" ) {
1367 _d = _d.replace( /^.*\s+(\S+\s+\S+$ )/, "$1" );
1368 var _m = parseInt( _d.replace( /^(.*)\..*$/, "$1" ), 10 );
1369 var _r = / r / .test( _d ) ? parseInt( _d.replace( /^.*r(.*)$/ , "$1" ), 10 ) : 0;
1373 } else if ( window.ActiveXObject ) {
1375 try { // avoid fp 6 crashes
1376 var _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.7" );
1380 _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.6" );
1382 _a.AllowScriptAccess = "always"; // throws if fp < 6.47
1385 if ( version[0] == 6 ) { return; }
1388 _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash" );
1395 if ( typeof _a == "object" ) {
1396 _d = _a.GetVariable( "$version" ); // bugs in fp 6.21 / 6.23
1397 if ( typeof _d != "undefined" ) {
1398 _d = _d.replace( /^\S+\s+(.*)$/, "$1" ).split( "," );
1399 version = [parseInt( _d[0], 10 ), parseInt( _d[2], 10 )];
1407 isSupported: function( version ) {
1408 var now = flashembed.getVersion();
1409 var ret = ( now[0] > version[0] ) || ( now[0] == version[0] && now[1] >= version[1] );
1415 // returns a String representation from JSON object
1420 getFullHTML: getFullHTML
1427 // setup jquery support
1430 jQuery.prototype.flashembed = function( params, flashvars ) {
1431 return this.each( function() {
1432 flashembed( this, params, flashvars );
1440 /************************************************
1441 ********* mv_embed extension to flowplayer.js ***
1442 ************************************************/
1443 var flowplayerEmbed = {
1444 instanceOf:'flowplayerEmbed',
1448 startedTimedPlayback:false,
1449 didDateStartTimeRestore:false,
1454 'time_display' : true,
1455 'volume_control' : true
1457 getEmbedHTML: function () {
1458 setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 150 );
1459 return this.wrapEmebedContainer( this.getEmbedObj() );
1461 getEmbedObj:function() {
1462 // give the embed element a unique pid (work around for flowplayer persistence)
1463 if ( this.old_pid != 0 ) {
1464 this.pid = this.pid + '_' + this.old_pid;
1467 'href="' + this.getSrc() + '" ' +
1468 'style="display:block;width:' + parseInt( this.width ) + 'px;height:' + parseInt( this.height ) + 'px" ' +
1469 'id="' + this.pid + '">' +
1472 postEmbedJS: function()
1475 js_log( 'embedFlow: uri:' + this.getSrc() + "\n" + mv_embed_path + 'libEmbedVideo/binPlayers/flowplayer/flowplayer-3.0.1.swf' ) ;
1479 // when this is false playback does not start until play button is pressed
1486 backgroundColor: 'transparent',
1487 backgroundGradient: 'none',
1498 // if in preview mode set grey and lower volume until "ready"
1499 if ( this.preview_mode ) {
1500 flowConfig.screen.opacity = 0.2;
1503 $f( this.pid, mv_embed_path + 'binPlayers/flowplayer/flowplayer-3.0.1.swf', flowConfig );
1504 // get the this.fla value:
1506 // set up bindings (for when interacting with the swf causes action:
1507 this.fla.onPause( function() {
1508 _this.parent_pause(); // update the interface
1510 this.fla.onResume( function() {
1511 _this.parent_play(); // update the interface
1518 /* js hooks/controls */
1521 // update play/pause button etc
1526 // on a resume make sure volume and opacity are correct
1527 this.restorePlayer();
1528 setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 250 );
1531 // @@todo support mute
1532 toggleMute: function() {
1533 this.parent_toggleMute();
1543 // @@ Suport UpDateVolumen
1544 updateVolumen:function( perc ) {
1546 if ( this.fla )this.fla.setVolume( perc * 100 );
1550 getVolumen:function() {
1553 return this.fla.getVolume() / 100;
1555 fullscreen:function() {
1557 this.fla.fullscreen();
1559 js_log( 'must be playing before you can go fullscreen' );
1565 if ( !this.thumbnail_disp ) {
1566 this.parent_pause();
1568 js_log( "Flash:Pause: " + this.fla.isPaused() );
1569 if ( this.fla['pause'] ) {
1570 if ( ! this.fla.isPaused() ) {
1571 js_log( 'calling plugin pause' );
1574 // restore volume and opacity
1575 this.restorePlayer();
1581 monitor : function()
1585 if ( !this.dateStartTime ) {
1587 this.dateStartTime = d.getTime();
1591 if ( !this.didDateStartTimeRestore && this.preview_mode )
1592 this.fla.setVolume( 0 );
1594 if ( ( d.getTime() - this.dateStartTime ) > 6000 && !this.didDateStartTimeRestore ) {
1595 this.restorePlayer();
1599 var flash_state = this.fla.getStatus();
1600 // update the duration from the clip if its zero or not set:
1601 if ( !this.duration || this.duration == 0 ) {
1602 if ( this.fla.getClip() ) {
1603 this.duration = this.fla.getClip().fullDuration;
1604 js_log( 'set duration via clip value: ' + this.getDuration() );
1607 // update the duration ntp values:
1610 if ( typeof flash_state == 'undefined' ) {
1612 "time" : this.fla.getTime()
1614 // we are not getting buffered data restore volume and opacity
1615 this.restorePlayer();
1617 // simplification of buffer state ... should move to support returning time rages like:
1618 // http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object
1619 this.bufferedPercent = flash_state.bufferEnd / this.getDuration();
1621 // set the current Time (based on timeFormat)
1622 if ( this.supportsURLTimeEncoding() ) {
1623 this.currentTime = flash_state.time;
1624 // js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration());
1626 this.currentTime = flash_state.time + this.start_offset;
1627 // stop buffering if greater than the duration:
1628 if ( flash_state.bufferEnd > this.getDuration() + 5 ) {
1629 // js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() );
1630 this.fla.stopBuffering();
1634 if ( this.currentTime > npt2seconds( this.start_ntp ) && !this.startedTimedPlayback ) {
1638 this.restorePlayer();
1642 js_log( 'failed to set values' );
1646 this.startedTimedPlayback = true;
1649 /* to support local seeks */
1650 if ( this.currentTime > 1 && this.seek_time_sec != 0 && !this.supportsURLTimeEncoding() )
1652 js_log( 'flashEmbed: _local_ Seeking to ' + this.seek_time_sec );
1653 this.fla.seek( this.seek_time_sec );
1654 this.seek_time_sec = 0;
1657 // checks to see if we reached the end of playback:
1658 if ( this.duration && this.startedTimedPlayback &&
1659 ( this.currentTime > ( npt2seconds( this.end_ntp ) + 2 )
1661 ( this.currentTime > ( npt2seconds( this.end_ntp ) - 1 )
1662 && this.prevTime == this.currentTime ) )
1664 js_log( 'prbally reached end of stream: ' + seconds2npt( this.currentTime ) );
1668 // update the status and check timmer via universal parent monitor
1669 this.parent_monitor();
1672 this.prevTime = this.currentTime;
1673 // js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - npt2seconds(this.start_ntp)) +' / ' +(npt2seconds(this.end_ntp)-npt2seconds(this.start_ntp)));
1675 restorePlayer:function() {
1679 js_log( 'f:do restorePlayer' );
1680 this.fla.setVolume( 90 );
1681 $f().getPlugin( 'screen' ).css( { 'opacity':'1.0' } );
1682 // set the fallback date restore flag to true:
1683 this.didDateStartTimeRestore = true;
1686 // get the embed fla object
1687 getFLA : function () {
1688 this.fla = $f( this.pid );
1691 js_log( 'f:flashEmbed:stop' );
1692 this.startedTimedPlayback = false;
1693 if ( this.monitorTimerId != 0 )
1695 clearInterval( this.monitorTimerId );
1696 this.monitorTimerId = 0;
1702 onStop: function() {
1703 js_log( 'f:onStop' );
1705 if ( this.monitorTimerId != 0 )
1707 clearInterval( this.monitorTimerId );
1708 this.monitorTimerId = 0;
1711 onClipDone: function() {
1712 js_log( 'f:flash:onClipDone' );
1713 if ( ! this.startedTimedPlayback ) {
1714 js_log( 'clip done before timed playback started .. not good. (ignoring) ' );
1718 js_log( 'clip done and ' + this.startedTimedPlayback );
1719 // stop the clip if its not stopped already:
1721 this.setStatus( "Clip Done..." );
1722 // run the onClip done action:
1723 this.parent_onClipDone();