2 * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file)
6 * flowplayer.js 3.0.0-rc5. The Flowplayer API.
8 * This file is part of Flowplayer, http://flowplayer.org
10 * Author: Tero Piirainen, <support@flowplayer.org>
11 * Copyright (c) 2008 Flowplayer Ltd
13 * Released under the MIT License:
14 * http://www.opensource.org/licenses/mit-license.php
16 * Version: 3.0.0-rc5 - Thu Nov 20 2008 22:09:49 GMT-0000 (GMT+00:00)
23 - handling multiple instances
24 - Flowplayer programming API
25 - Flowplayer event model
26 - player loading / unloading
32 /*jslint glovar: true, browser: true */
33 /*global flowplayer, $f */
35 // {{{ private utility methods
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));
50 // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
52 if (!obj || typeof obj != 'object') { return obj; }
53 var temp = new obj.constructor();
54 for (var key in obj) {
55 if (obj.hasOwnProperty(key)) {
56 temp[key] = clone(obj[key]);
62 // stripped from jQuery, thanks John Resig
63 function each(obj, fn) {
66 var name, i = 0, length = obj.length;
69 if (length === undefined) {
71 if (fn.call(obj[name], name, obj[name]) === false) { break; }
76 for (var value = obj[0];
77 i < length && fn.call( value, i, value ) !== false; value = obj[++i]) {
87 return document.getElementById(id);
91 // used extensively. a very simple implementation.
92 function extend(to, from, skipFuncs) {
94 each(from, function(name, value) {
95 if (!skipFuncs || typeof value != 'function') {
102 // var arr = select("elem.className");
103 function select(query) {
104 var index = query.indexOf(".");
106 var tag = query.substring(0, index) || "*";
107 var klass = query.substring(index + 1, query.length);
109 each(document.getElementsByTagName(tag), function() {
110 if (this.className && this.className.indexOf(klass) != -1) {
118 // fix event inconsistencies across browsers
119 function stopEvent(e) {
120 e = e || window.event;
122 if (e.preventDefault) {
127 e.returnValue = false;
128 e.cancelBubble = true;
133 // push an event listener into existing array of listeners
134 function bind(to, evt, fn) {
135 to[evt] = to[evt] || [];
140 // generates an unique id
142 return "_" + ("" + Math.random()).substring(2, 10);
150 var Clip = function(json, index, player) {
158 // instance variables
159 if (typeof json == 'string') {
163 extend(this, json, true);
166 each(("Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop").split(","),
169 var evt = "on" + this;
172 if (evt.indexOf("*") != -1) {
173 evt = evt.substring(0, evt.length -1);
174 var before = "onBefore" + evt.substring(2);
176 self[before] = function(fn) {
177 bind(listeners, before, fn);
182 self[evt] = function(fn) {
183 bind(listeners, evt, fn);
188 // set common clip event listeners to player level
191 player[before] = self[before];
194 player[evt] = self[evt];
203 onCuepoint: function(points, fn) {
205 // embedded cuepoints
206 if (arguments.length == 1) {
207 cuepoints.embedded = [null, points];
211 if (typeof points == 'number') {
216 cuepoints[fnId] = [points, fn];
218 if (player.isLoaded()) {
219 player._api().fp_addCuepoints(points, index, fnId);
225 update: function(json) {
228 if (player.isLoaded()) {
229 player._api().fp_updateClip(json, index);
231 var conf = player.getConfig();
232 var clip = (index == -1) ? conf.clip : conf.playlist[index];
233 extend(clip, json, true);
237 // internal event for performing clip tasks. should be made private someday
238 _fireEvent: function(evt, arg1, arg2, target) {
240 if (evt == 'onLoad') {
241 each(cuepoints, function(key, val) {
242 player._api().fp_addCuepoints(val[0], index, key);
247 // target clip we are working against
252 if (evt == 'onCuepoint') {
253 var fn = cuepoints[arg1];
255 return fn[1].call(player, target, arg2);
259 if (evt == 'onStart' || evt == 'onUpdate') {
261 extend(target, arg1);
263 if (!target.duration) {
264 target.duration = arg1.metaData.duration;
266 target.fullDuration = arg1.metaData.duration;
271 each(listeners[evt], function() {
272 ret = this.call(player, target, arg1);
280 // get cuepoints from config
281 if (json.onCuepoint) {
282 self.onCuepoint.apply(self, json.onCuepoint);
283 delete json.onCuepoint;
287 each(json, function(key, val) {
288 if (typeof val == 'function') {
289 bind(listeners, key, val);
295 // setup common clip event callbacks for Player object too (shortcuts)
297 player.onCuepoint = this.onCuepoint;
307 var Plugin = function(name, json, player, fn) {
311 var hasMethods = false;
314 extend(listeners, fn);
317 // custom callback functions in configuration
318 each(json, function(key, val) {
319 if (typeof val == 'function') {
320 listeners[key] = val;
325 // core plugin methods
328 animate: function(props, speed, fn) {
333 if (typeof speed == 'function') {
338 if (typeof props == 'string') {
347 listeners[fnId] = fn;
350 if (speed === undefined) { speed = 500; }
351 json = player._api().fp_animate(name, props, speed, fnId);
355 css: function(props, val) {
356 if (val !== undefined) {
362 json = player._api().fp_css(name, props);
366 js_log('flow player could not set css: ' + json);
371 this.display = 'block';
372 player._api().fp_showPlugin(name);
377 this.display = 'none';
378 player._api().fp_hidePlugin(name);
383 this.display = player._api().fp_togglePlugin(name);
387 fadeTo: function(o, speed, fn) {
389 if (typeof speed == 'function') {
396 listeners[fnId] = fn;
398 this.display = player._api().fp_fadeTo(name, o, speed, fnId);
403 fadeIn: function(speed, fn) {
404 return self.fadeTo(1, speed, fn);
407 fadeOut: function(speed, fn) {
408 return self.fadeTo(0, speed, fn);
411 getName: function() {
416 // internal method not meant to be used by clients
417 _fireEvent: function(evt, arg) {
420 // update plugins properties & methods
421 if (evt == 'onUpdate') {
422 var json = arg || player._api().fp_getPlugin(name);
423 if (!json) { return; }
429 each(json.methods, function() {
430 var method = "" + this;
432 self[method] = function() {
433 var a = [].slice.call(arguments);
434 var ret = player._api().fp_invoke(name, method, a);
435 return ret == 'undefined' ? self : ret;
443 var fn = listeners[evt];
449 // "one-shot" callback
450 if (evt.substring(0, 1) == "_") {
451 delete listeners[evt];
464 function Player(wrapper, params, conf) {
466 // private variables (+ arguments)
482 // {{{ public methods
490 isLoaded: function() {
491 return (api !== null);
494 getParent: function() {
498 hide: function(all) {
499 if (all) { wrapper.style.height = "0px"; }
500 if (api) { api.style.height = "0px"; }
505 wrapper.style.height = wrapperHeight + "px";
506 if (api) { api.style.height = swfHeight + "px"; }
510 isHidden: function() {
511 return api && parseInt(api.style.height, 10) === 0;
517 if (!api && self._fireEvent("onBeforeLoad") !== false) {
519 // unload all instances
520 each(players, function() {
524 html = wrapper.innerHTML;
525 flashembed(wrapper, params, {config: conf});
530 bind(listeners, "onLoad", fn);
539 if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() &&
540 self._fireEvent("onBeforeUnload") !== false) {
542 wrapper.innerHTML = html;
543 self._fireEvent("onUnload");
550 getClip: function(index) {
551 if (index === undefined) {
554 return playlist[index];
558 getCommonClip: function() {
562 getPlaylist: function() {
566 getPlugin: function(name) {
567 var plugin = plugins[name];
569 // create plugin if nessessary
570 if (!plugin && self.isLoaded()) {
571 var json = self._api().fp_getPlugin(name);
573 plugin = new Plugin(name, json, self);
574 plugins[name] = plugin;
580 getScreen: function() {
581 return self.getPlugin("screen");
584 getControls: function() {
585 return self.getPlugin("controls");
588 getConfig: function() {
592 getFlashParams: function() {
596 loadPlugin: function(name, url, props, fn) {
598 // properties not supplied
599 if (typeof props == 'function') {
604 // if fn not given, make a fake id so that plugin's onUpdate get's fired
605 var fnId = fn ? makeId() : "_";
606 self._api().fp_loadPlugin(name, url, props, fnId);
611 var p = new Plugin(name, null, self, arg);
617 getState: function() {
618 return api ? api.fp_getState() : -1;
622 play: function(clip) {
625 if (clip !== undefined) {
626 self._api().fp_play(clip);
628 if(typeof self._api().fp_play == 'function')
629 self._api().fp_play();
637 self.load(function() {
645 getVersion: function() {
646 var js = "flowplayer.js 3.0.0-rc5";
648 var ver = api.fp_getVersion();
657 throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event";
663 console.log(listeners);
670 each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),
672 var name = "on" + this;
675 if (name.indexOf("*") != -1) {
676 name = name.substring(0, name.length -1);
677 var name2 = "onBefore" + name.substring(2);
678 self[name2] = function(fn) {
679 bind(listeners, name2, fn);
685 self[name] = function(fn) {
686 bind(listeners, name, fn);
694 each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),
698 self[name] = function(arg) {
699 if (!api) { return self; }
701 var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg);
702 return ret == 'undefined' ? self : ret;
704 js_log('flowplayer could not access fp_ '+ name);
713 // {{{ public method: _fireEvent
715 self._fireEvent = function(evt, arg0, arg1, arg2) {
722 if (evt == 'onLoad' && !api) {
724 api = api || el(apiId);
725 swfHeight = api.clientHeight;
727 each(playlist, function() {
728 this._fireEvent("onLoad");
731 each(plugins, function(name, p) {
732 p._fireEvent("onUpdate");
736 commonClip._fireEvent("onLoad");
739 if (evt == 'onContextMenu') {
740 each(conf.contextMenu[arg0], function(key, fn) {
746 if (evt == 'onPluginEvent') {
747 var name = arg0.name || arg0;
748 var p = plugins[name];
751 p._fireEvent("onUpdate", arg0);
759 if (evt == 'onPlaylistReplace') {
762 each(arg0, function() {
763 playlist.push(new Clip(this, index++));
770 if (arg0 === 0 || (arg0 && arg0 >= 0)) {
773 var clip = playlist[arg0];
776 ret = clip._fireEvent(evt, arg1, arg2);
779 if (!clip || ret !== false) {
781 // clip argument is given for common clip, because it behaves as the target
782 ret = commonClip._fireEvent(evt, arg1, arg2, clip);
788 each(listeners[evt], function() {
789 ret = this.call(self, arg0);
791 // remove cached entry
793 listeners[evt].splice(i, 1);
797 if (ret === false) { return false; }
816 wrapperHeight = parseInt(wrapper.style.height) || wrapper.clientHeight;
818 // register this player into global array of instances
822 // flashembed parameters
823 if (typeof params == 'string') {
824 params = {src: params};
828 playerId = wrapper.id || "fp" + makeId();
829 apiId = params.id || playerId + "_api";
831 conf.playerId = playerId;
834 // plain url is given as config
835 if (typeof conf == 'string') {
836 conf = {clip:{url:conf}};
839 // common clip is always there
840 conf.clip = conf.clip || {};
841 commonClip = new Clip(conf.clip, -1, self);
844 // wrapper href as playlist
845 if (wrapper.getAttribute("href")) {
846 conf.playlist = [{url:wrapper.getAttribute("href", 2)}];
850 conf.playlist = conf.playlist || [conf.clip];
853 each(conf.playlist, function() {
857 // clip is an array, we don't allow that
858 if (typeof clip == 'object' && clip.length) {
862 if (!clip.url && typeof clip == 'string') {
866 // populate common clip properties to each clip
867 extend(clip, conf.clip, true);
869 // modify configuration playlist
870 conf.playlist[index] = clip;
872 // populate playlist array
873 clip = new Clip(clip, index, self);
880 each(conf, function(key, val) {
881 if (typeof val == 'function') {
882 bind(listeners, key, val);
889 each(conf.plugins, function(name, val) {
891 plugins[name] = new Plugin(name, val, self);
896 // setup controlbar plugin if not explicitly defined
897 if (!conf.plugins || conf.plugins.controls === undefined) {
898 plugins.controls = new Plugin("controls", null, self);
901 // Flowplayer uses black background by default
902 params.bgcolor = params.bgcolor || "#000000";
905 // setup default settings for express install
906 params.version = params.version || [9,0];
907 params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
911 function doClick(e) {
912 if (self._fireEvent("onBeforeClick") !== false) {
918 // defer loading upon click
919 html = wrapper.innerHTML;
920 if (html.replace(/\s/g, '') !== '') {
922 if (wrapper.addEventListener) {
923 wrapper.addEventListener("click", doClick, false);
925 } else if (wrapper.attachEvent) {
926 wrapper.attachEvent("onclick", doClick);
929 // player is loaded upon page load
932 // prevent default action from wrapper (safari problem) loaded
933 if (wrapper.addEventListener) {
934 wrapper.addEventListener("click", stopEvent, false);
943 // possibly defer initialization until DOM get's loaded
944 if (typeof wrapper == 'string') {
945 flashembed.domReady(function() {
946 var node = el(wrapper);
949 throw "Flowplayer cannot access element: " + wrapper;
956 // we have a DOM element so page is already loaded
968 // {{{ flowplayer() & statics
970 // container for player instances
974 // this object is returned when multiple player's are requested
975 function Iterator(arr) {
977 this.length = arr.length;
979 this.each = function(fn) {
983 this.size = function() {
988 // these two variables are the only global variables
989 window.flowplayer = window.$f = function() {
992 var arg = arguments[0];
996 if (!arguments.length) {
997 each(players, function() {
998 if (this.isLoaded()) {
1004 return instance || players[0];
1007 if (arguments.length == 1) {
1010 if (typeof arg == 'number') {
1011 return players[arg];
1014 // $f(wrapper || 'containerId' || '*');
1019 return new Iterator(players);
1022 // $f(wrapper || 'containerId');
1023 each(players, function() {
1024 if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) {
1035 if (arguments.length > 1) {
1037 var swf = arguments[1];
1038 var conf = (arguments.length == 3) ? arguments[2] : {};
1040 if (typeof arg == 'string') {
1042 // select arg by classname
1043 if (arg.indexOf(".") != -1) {
1046 each(select(arg), function() {
1047 instances.push(new Player(this, clone(swf), clone(conf)));
1050 return new Iterator(instances);
1052 // select node by id
1055 return new Player(node !== null ? node : arg, swf, conf);
1059 // arg is a DOM element
1061 return new Player(arg, swf, conf);
1071 // called by Flash External Interface
1072 fireEvent: function(id, evt, a0, a1, a2) {
1074 return p ? p._fireEvent(evt, a0, a1, a2) : null;
1078 // create plugins by modifying Player's prototype
1079 addPlugin: function(name, fn) {
1080 Player.prototype[name] = fn;
1084 // utility methods for plugin developers
1094 //{{{ jQuery support
1096 if (typeof jQuery == 'function') {
1098 jQuery.prototype.flowplayer = function(params, conf) {
1101 if (!arguments.length || typeof arguments[0] == 'number') {
1103 this.each(function() {
1109 return arguments.length ? arr[arguments[0]] : new Iterator(arr);
1112 // create flowplayer instances
1113 return this.each(function() {
1114 $f(this, clone(params), conf ? clone(conf) : {});
1126 * flashembed 0.34. Adobe Flash embedding script
1128 * http://flowplayer.org/tools/flash-embed.html
1130 * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
1132 * Released under the MIT License:
1133 * http://www.opensource.org/licenses/mit-license.php
1135 * >> Basically you can do anything you want but leave this header as is <<
1137 * first version 0.01 - 03/11/2008
1138 * version 0.34 - Tue Nov 11 2008 09:09:52 GMT-0000 (GMT+00:00)
1142 //{{{ utility functions
1144 var jQ = typeof jQuery == 'function';
1147 // from "Pro JavaScript techniques" by John Resig
1148 function isDomReady() {
1150 if (domReady.done) { return false; }
1153 if (d && d.getElementsByTagName && d.getElementById && d.body) {
1154 clearInterval(domReady.timer);
1155 domReady.timer = null;
1157 for (var i = 0; i < domReady.ready.length; i++) {
1158 domReady.ready[i].call();
1161 domReady.ready = null;
1162 domReady.done = true;
1166 // if jQuery is present, use it's more effective domReady method
1167 var domReady = jQ ? jQuery : function(f) {
1169 if (domReady.done) {
1173 if (domReady.timer) {
1174 domReady.ready.push(f);
1177 domReady.ready = [f];
1178 domReady.timer = setInterval(isDomReady, 13);
1183 // override extend params function
1184 function extend(to, from) {
1187 if (from.hasOwnProperty(key)) {
1188 to[key] = from[key];
1197 function concatVars(vars) {
1200 for (var key in vars) {
1202 out += [key] + '=' + asString(vars[key]) + '&';
1205 return out.substring(0, out.length -1);
1210 // JSON.asString() function
1211 function asString(obj) {
1213 switch (typeOf(obj)){
1215 obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
1217 // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
1218 obj = obj.replace(/^\s?(\d+)%/, "$1pct");
1219 return '"' +obj+ '"';
1222 return '['+ map(obj, function(el) {
1223 return asString(el);
1227 return '"function()"';
1231 for (var prop in obj) {
1232 if (obj.hasOwnProperty(prop)) {
1233 str.push('"'+prop+'":'+ asString(obj[prop]));
1236 return '{'+str.join(',')+'}';
1239 // replace ' --> " and remove spaces
1240 return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
1244 // private functions
1245 function typeOf(obj) {
1246 if (obj === null || obj === undefined) { return false; }
1247 var type = typeof obj;
1248 return (type == 'object' && obj.push) ? 'array' : type;
1252 // version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
1253 if (window.attachEvent) {
1254 window.attachEvent("onbeforeunload", function() {
1255 __flash_unloadHandler = function() {};
1256 __flash_savedUnloadHandler = function() {};
1260 function map(arr, func) {
1262 for (var i in arr) {
1263 if (arr.hasOwnProperty(i)) {
1264 newArr[i] = func(arr[i]);
1270 function getEmbedCode(p, c) {
1271 var html = '<embed type="application/x-shockwave-flash" ';
1273 if (p.id) { extend(p, {name:p.id}); }
1275 for (var key in p) {
1276 if (p[key] !== null) {
1277 html += key + '="' +p[key]+ '"\n\t';
1282 html += 'flashvars=\'' + concatVars(c) + '\'';
1285 // thanks Tom Price (07/17/2008)
1291 function getObjectCode(p, c, embeddable) {
1293 var html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
1294 html += 'width="' + p.width + '" height="' + p.height + '"';
1296 // force id for IE. otherwise embedded Flash object cannot be returned
1297 if (!p.id && document.all) {
1298 p.id = "_" + ("" + Math.random()).substring(5);
1302 html += ' id="' + p.id + '"';
1307 // sometimes ie fails to load flash if it's on cache
1309 p.src += ((p.src.indexOf("?") != -1 ? "&" : "?") + Math.random());
1312 html += '\n\t<param name="movie" value="'+ p.src +'" />';
1314 var e = extend({}, p);
1315 e.id = e.width = e.height = e.src = null;
1318 if (e[k] !== null) {
1319 html += '\n\t<param name="'+ k +'" value="'+ e[k] +'" />';
1324 html += '\n\t<param name="flashvars" value=\'' + concatVars(c) + '\' />';
1328 html += getEmbedCode(p, c);
1331 html += "</object>";
1336 function getFullHTML(p, c) {
1337 return getObjectCode(p, c, true);
1340 function getHTML(p, c) {
1341 var isNav = navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length;
1342 return (isNav) ? getEmbedCode(p, c) : getObjectCode(p, c);
1348 window.flashembed = function(root, userParams, flashvars) {
1356 // very common params
1361 // flashembed specific options
1364 expressInstall:null,
1367 // flashembed defaults
1368 // bgcolor: 'transparent',
1369 allowfullscreen: true,
1370 allowscriptaccess: 'always',
1372 type: 'application/x-shockwave-flash',
1373 pluginspage: 'http://www.adobe.com/go/getflashplayer'
1377 if (typeof userParams == 'string') {
1378 userParams = {src: userParams};
1381 extend(params, userParams);
1383 var version = flashembed.getVersion();
1384 var required = params.version;
1385 var express = params.expressInstall;
1386 var debug = params.debug;
1389 if (typeof root == 'string') {
1390 var el = document.getElementById(root);
1394 domReady(function() {
1395 flashembed(root, userParams, flashvars);
1401 if (!root) { return; }
1405 if (!required || flashembed.isSupported(required)) {
1406 params.onFail = params.version = params.expressInstall = params.debug = null;
1408 // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
1409 // thanks to: Ryan Rud
1410 // var tmp = document.createElement("extradiv");
1411 // tmp.innerHTML = getHTML();
1412 // root.appendChild(tmp);
1414 root.innerHTML = getHTML(params, flashvars);
1417 return root.firstChild;
1419 // custom fail event
1420 } else if (params.onFail) {
1421 var ret = params.onFail.call(params, flashembed.getVersion(), flashvars);
1422 if (ret === true) { root.innerHTML = ret; }
1426 } else if (required && express && flashembed.isSupported([6,65])) {
1428 extend(params, {src: express});
1431 MMredirectURL: location.href,
1432 MMplayerType: 'PlugIn',
1433 MMdoctitle: document.title
1436 root.innerHTML = getHTML(params, flashvars);
1441 // minor bug fixed here 08.04.2008 (thanks JRodman)
1443 if (root.innerHTML.replace(/\s/g, '') !== '') {
1444 // custom content was supplied
1448 "<h2>Flash version " + required + " or greater is required</h2>" +
1450 (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") +
1452 "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
1464 //{{{ static methods
1466 extend(window.flashembed, {
1468 // returns arr[major, fix]
1469 getVersion: function() {
1471 var version = [0, 0];
1473 if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
1474 var _d = navigator.plugins["Shockwave Flash"].description;
1475 if (typeof _d != "undefined") {
1476 _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
1477 var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
1478 var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
1482 } else if (window.ActiveXObject) {
1484 try { // avoid fp 6 crashes
1485 var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
1489 _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
1491 _a.AllowScriptAccess = "always"; // throws if fp < 6.47
1494 if (version[0] == 6) { return; }
1497 _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
1504 if (typeof _a == "object") {
1505 _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
1506 if (typeof _d != "undefined") {
1507 _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
1508 version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
1516 isSupported: function(version) {
1517 var now = flashembed.getVersion();
1518 var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]);
1524 // returns a String representation from JSON object
1529 getFullHTML: getFullHTML
1536 // setup jquery support
1539 jQuery.prototype.flashembed = function(params, flashvars) {
1540 return this.each(function() {
1541 flashembed(this, params, flashvars);
1549 /************************************************
1550 ********* mv_embed extension to flowplayer.js ***
1551 ************************************************/
1553 instanceOf:'flashEmbed',
1557 startedTimedPlayback:false,
1558 didDateStartTimeRestore:false,
1563 //'fullscreen':true,
1564 'time_display':true,
1565 'volume_control':true,
1569 getEmbedHTML: function (){
1570 setTimeout('document.getElementById(\''+this.id+'\').postEmbedJS()', 150);
1571 return this.wrapEmebedContainer( this.getEmbedObj() );
1573 getEmbedObj:function(){
1574 //give the embed element a unique pid (work around for flowplayer persistence)
1575 if( this.old_pid!=0 ){
1576 this.pid = this.pid +'_'+ this.old_pid;
1579 'href="'+ this.getSrc() + '" '+
1580 'style="display:block;width:' + parseInt(this.width) + 'px;height:' + parseInt(this.height) + 'px" '+
1581 'id="'+this.pid+'">'+
1584 postEmbedJS: function()
1587 js_log('embedFlow: uri:'+ this.getSrc() + "\n"+ mv_embed_path + 'binPlayers/flowplayer/flowplayer-3.0.1.swf' ) ;
1591 // when this is false playback does not start until play button is pressed
1598 backgroundColor: 'transparent',
1599 backgroundGradient: 'none',
1610 //if in preview mode set grey and lower volume until "ready"
1611 if( this.preview_mode ){
1612 flowConfig.screen.opacity = 0.2;
1615 $f(this.pid, mv_embed_path + 'binPlayers/flowplayer/flowplayer-3.0.1.swf', flowConfig);
1616 //get the this.fla value:
1618 //set up bindings (for when interacting with the swf causes action:
1619 this.fla.onPause(function(){
1620 _this.parent_pause(); //update the interface
1622 this.fla.onResume( function(){
1623 _this.parent_play(); //update the interface
1630 /* js hooks/controls */
1633 //update play/pause button etc
1638 //on a resume make sure volume and opacity are correct
1639 this.restorePlayer();
1640 setTimeout('$j(\'#'+this.id+'\').get(0).monitor()', 250);
1643 //@@todo support mute
1644 toggleMute: function(){
1645 this.parent_toggleMute();
1655 //@@ Suport UpDateVolumen
1656 updateVolumen:function(perc){
1658 if(this.fla)this.fla.setVolume(perc*100);
1662 getVolumen:function(){
1665 return this.fla.getVolume() / 100;
1667 fullscreen:function(){
1669 this.fla.fullscreen();
1671 js_log('must be playing before you can go fullscreen');
1677 if(!this.thumbnail_disp){
1678 this.parent_pause();
1680 js_log("Flash:Pause: " + this.fla.isPaused() );
1681 if( this.fla['pause'] ){
1682 if( ! this.fla.isPaused() ){
1683 js_log('calling plugin pause');
1686 //restore volume and opacity
1687 this.restorePlayer();
1693 monitor : function()
1697 if( !this.dateStartTime ){
1699 this.dateStartTime = d.getTime();
1703 if( !this.didDateStartTimeRestore && this.preview_mode)
1704 this.fla.setVolume(0);
1706 if( (d.getTime() - this.dateStartTime) > 6000 && !this.didDateStartTimeRestore){
1707 this.restorePlayer();
1711 var flash_state = this.fla.getStatus();
1712 //update the duration from the clip if its zero or not set:
1713 if( !this.duration || this.duration==0 ){
1714 if( this.fla.getClip() ){
1715 this.duration = this.fla.getClip().fullDuration;
1716 js_log('set duration via clip value: ' + this.getDuration() );
1719 //update the duration ntp values:
1722 if( typeof flash_state == 'undefined' ){
1724 "time" : this.fla.getTime()
1726 //we are not getting buffered data restore volume and opacity
1727 this.restorePlayer();
1729 //simplification of buffer state ... should move to support returning time rages like:
1730 //http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object
1731 this.bufferedPercent = flash_state.bufferEnd / this.getDuration();
1733 //set the current Time (based on timeFormat)
1734 if( this.supportsURLTimeEncoding() ){
1735 this.currentTime = flash_state.time;
1736 //js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration());
1738 this.currentTime = flash_state.time + this.start_offset;
1739 //stop buffering if greater than the duration:
1740 if( flash_state.bufferEnd > this.getDuration() + 5 ){
1741 //js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() );
1742 this.fla.stopBuffering();
1746 if(this.currentTime > npt2seconds(this.start_ntp) && !this.startedTimedPlayback){
1750 this.restorePlayer();
1754 js_log('failed to set values');
1758 this.startedTimedPlayback=true;
1761 /* to support local seeks */
1762 if(this.currentTime > 1 && this.seek_time_sec != 0 && !this.supportsURLTimeEncoding() )
1764 js_log('flashEmbed: _local_ Seeking to ' + this.seek_time_sec);
1765 this.fla.seek( this.seek_time_sec );
1766 this.seek_time_sec = 0;
1769 //checks to see if we reached the end of playback:
1770 if(this.duration && this.startedTimedPlayback &&
1771 ( this.currentTime > (npt2seconds(this.end_ntp)+2)
1773 ( this.currentTime > (npt2seconds(this.end_ntp)-1)
1774 && this.prevTime == this.currentTime) )
1776 js_log('prbally reached end of stream: '+ seconds2npt( this.currentTime) );
1780 //update the status and check timmer via universal parent monitor
1781 this.parent_monitor();
1784 this.prevTime = this.currentTime;
1785 //js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - npt2seconds(this.start_ntp)) +' / ' +(npt2seconds(this.end_ntp)-npt2seconds(this.start_ntp)));
1787 restorePlayer:function(){
1791 js_log('f:do restorePlayer');
1792 this.fla.setVolume(90);
1793 $f().getPlugin('screen').css({'opacity':'1.0'} );
1794 //set the fallback date restore flag to true:
1795 this.didDateStartTimeRestore=true;
1798 // get the embed fla object
1799 getFLA : function (){
1800 this.fla = $f(this.pid);
1803 js_log('f:flashEmbed:stop');
1804 this.startedTimedPlayback=false;
1805 if (this.monitorTimerId != 0 )
1807 clearInterval(this.monitorTimerId);
1808 this.monitorTimerId = 0;
1817 if( this.monitorTimerId != 0 )
1819 clearInterval(this.monitorTimerId);
1820 this.monitorTimerId = 0;
1823 onClipDone: function(){
1824 js_log('f:flash:onClipDone');
1825 if( ! this.startedTimedPlayback){
1826 js_log('clip done before timed playback started .. not good. (ignoring) ');
1830 js_log('clip done and '+ this.startedTimedPlayback);
1831 //stop the clip if its not stopped already:
1833 this.setStatus("Clip Done...");
1834 //run the onClip done action:
1835 this.parent_onClipDone();