summaryrefslogtreecommitdiff
path: root/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js')
-rw-r--r--extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js485
1 files changed, 485 insertions, 0 deletions
diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js
new file mode 100644
index 00000000..739a7769
--- /dev/null
+++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js
@@ -0,0 +1,485 @@
+/*
+ * The "kaltura player" embedPlayer interface for fallback h.264 and flv video format support
+ */
+( function( mw, $ ) { "use strict";
+
+// Called from the kdp.swf
+window.jsInterfaceReadyFunc = function() {
+ return true;
+}
+
+mw.EmbedPlayerKplayer = {
+
+ // Instance name:
+ instanceOf : 'Kplayer',
+
+ bindPostfix: '.kPlayer',
+
+ // List of supported features:
+ supports : {
+ 'playHead' : true,
+ 'pause' : true,
+ 'stop' : true,
+ 'timeDisplay' : true,
+ 'volumeControl' : true,
+ 'overlays' : true,
+ 'fullscreen' : true
+ },
+
+ // Stores the current time as set from flash player
+ flashCurrentTime : 0,
+
+ /*
+ * Write the Embed html to the target
+ */
+ embedPlayerHTML : function() {
+ var _this = this;
+
+ mw.log("EmbedPlayerKplayer:: embed src::" + _this.getSrc());
+ var flashvars = {};
+ flashvars.autoPlay = "true";
+ flashvars.loop = "false";
+
+ var playerPath = mw.absoluteUrl( mw.getEmbedPlayerPath() + '/binPlayers/kaltura-player' );
+ flashvars.entryId = mw.absoluteUrl( _this.getSrc() );
+
+ // Use a relative url if the protocol is file://
+ if ( new mw.Uri( document.URL ).protocol == 'file' ) {
+ playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player';
+ flashvars.entryId = _this.getSrc();
+ }
+
+ flashvars.debugMode = "false";
+ flashvars.fileSystemMode = "true";
+ flashvars.widgetId = "_7463";
+ flashvars.partnerId = "7463";
+ flashvars.pluginDomain = "kdp3/plugins/";
+ flashvars.kml = "local";
+ flashvars.kmlPath = playerPath + '/config.xml';
+ flashvars.sourceType = "url";
+ flashvars.jsInterfaceReadyFunc = "jsInterfaceReadyFunc";
+
+ // flashvars.host = "www.kaltura.com";
+ flashvars.externalInterfaceDisabled = "false";
+ flashvars.skinPath = playerPath + '/skin.swf';
+
+ flashvars["full.skinPath"] = playerPath + '/LightDoodleskin.swf';
+ var flashVarParam = '';
+ $.each( flashvars, function( fKey, fVal ){
+ flashVarParam += '&' + fKey + '=' + encodeURIComponent( fVal );
+ } );
+
+ var kdpPath = playerPath + "/kdp3.3.5.27.swf";
+
+ mw.log( "KPlayer:: embedPlayerHTML" );
+ // remove any existing pid ( if present )
+ $( '#' + this.pid ).remove();
+
+ var orgJsReadyCallback = window.jsCallbackReady;
+ window.jsCallbackReady = function( playerId ){
+ _this.postEmbedActions();
+ window.jsCallbackReady = orgJsReadyCallback;
+ };
+ // attributes and params:
+ flashembed( $( this ).attr('id'),
+ {
+ id : this.pid,
+ src : kdpPath,
+ height : '100%',
+ width : '100%',
+ bgcolor : "#000000",
+ allowNetworking : "all",
+ version : [10,0],
+ wmode : "opaque"
+ },
+ flashvars
+ )
+ // Remove any old bindings:
+ $(_this).unbind( this.bindPostfix );
+
+ // Flash player loses its bindings once it changes sizes::
+ $(_this).bind('onOpenFullScreen' + this.bindPostfix , function() {
+ _this.postEmbedActions();
+ });
+ $(_this).bind('onCloseFullScreen' + this.bindPostfix, function() {
+ _this.postEmbedActions();
+ });
+ },
+
+ // The number of times we have tried to bind the player
+ bindTryCount : 0,
+
+ /**
+ * javascript run post player embedding
+ */
+ postEmbedActions : function() {
+ var _this = this;
+ this.getPlayerElement();
+ if ( this.playerElement && this.playerElement.addJsListener ) {
+ var bindEventMap = {
+ 'playerPaused' : 'onPause',
+ 'playerPlayed' : 'onPlay',
+ 'durationChange' : 'onDurationChange',
+ 'playerPlayEnd' : 'onClipDone',
+ 'playerUpdatePlayhead' : 'onUpdatePlayhead',
+ 'bytesTotalChange' : 'onBytesTotalChange',
+ 'bytesDownloadedChange' : 'onBytesDownloadedChange'
+ };
+
+ $.each( bindEventMap, function( bindName, localMethod ) {
+ _this.bindPlayerFunction(bindName, localMethod);
+ });
+ this.bindTryCount = 0;
+ // Start the monitor
+ this.monitor();
+ } else {
+ this.bindTryCount++;
+ // Keep trying to get the player element
+ if( this.bindTryCount > 500 ){ // 5 seconds
+ mw.log('Error:: KDP player never ready for bindings!');
+ return ;
+ }
+ setTimeout(function() {
+ _this.postEmbedActions();
+ }, 100);
+ }
+ },
+
+ /**
+ * Bind a Player Function,
+ *
+ * Build a global callback to bind to "this" player instance:
+ *
+ * @param {String}
+ * flash binding name
+ * @param {String}
+ * function callback name
+ */
+ bindPlayerFunction : function(bindName, methodName) {
+ mw.log( 'EmbedPlayerKplayer:: bindPlayerFunction:' + bindName );
+ // The kaltura kdp can only call a global function by given name
+ var gKdpCallbackName = 'kdp_' + methodName + '_cb_' + this.id.replace(/[^a-zA-Z 0-9]+/g,'');
+
+ // Create an anonymous function with local player scope
+ var createGlobalCB = function(cName, embedPlayer) {
+ window[ cName ] = function(data) {
+ // Track all events ( except for playerUpdatePlayhead )
+ if( bindName != 'playerUpdatePlayhead' ){
+ mw.log("EmbedPlayerKplayer:: event: " + bindName);
+ }
+ if ( embedPlayer._propagateEvents ) {
+ embedPlayer[methodName](data);
+ }
+ };
+ }(gKdpCallbackName, this);
+ // Remove the listener ( if it exists already )
+ this.playerElement.removeJsListener( bindName, gKdpCallbackName );
+ // Add the listener to the KDP flash player:
+ this.playerElement.addJsListener( bindName, gKdpCallbackName);
+ },
+
+ /**
+ * on Pause callback from the kaltura flash player calls parent_pause to
+ * update the interface
+ */
+ onPause : function() {
+ this.parent_pause();
+ },
+
+ /**
+ * onPlay function callback from the kaltura flash player directly call the
+ * parent_play
+ */
+ onPlay : function() {
+ this.parent_play();
+ },
+
+ onDurationChange : function(data, id) {
+ // Update the duration ( only if not in url time encoding mode:
+ if( !this.supportsURLTimeEncoding() ){
+ this.duration = data.newValue;
+ this.triggerHelper('durationchange');
+ }
+ },
+
+ /**
+ * play method calls parent_play to update the interface
+ */
+ play: function() {
+ if ( this.playerElement && this.playerElement.sendNotification ) {
+ this.playerElement.sendNotification('doPlay');
+ }
+ this.parent_play();
+ },
+
+ /**
+ * pause method calls parent_pause to update the interface
+ */
+ pause: function() {
+ if (this.playerElement && this.playerElement.sendNotification) {
+ this.playerElement.sendNotification('doPause');
+ }
+ this.parent_pause();
+ },
+ /**
+ * playerSwitchSource switches the player source working around a few bugs in browsers
+ *
+ * @param {object}
+ * source Video Source object to switch to.
+ * @param {function}
+ * switchCallback Function to call once the source has been switched
+ * @param {function}
+ * doneCallback Function to call once the clip has completed playback
+ */
+ playerSwitchSource: function( source, switchCallback, doneCallback ){
+ var _this = this;
+ var waitCount = 0;
+ var src = source.getSrc();
+ // Check if the source is already set to the target:
+ if( !src || src == this.getSrc() ){
+ if( switchCallback ){
+ switchCallback();
+ }
+ setTimeout(function(){
+ if( doneCallback )
+ doneCallback();
+ }, 100);
+ return ;
+ }
+
+ var waitForJsListen = function( callback ){
+ if( _this.getPlayerElement() && _this.getPlayerElement().addJsListener ){
+ callback();
+ } else {
+ // waited for 2 seconds fail
+ if( waitCount > 20 ){
+ mw.log( "Error: Failed to swtich player source!");
+ if( switchCallback )
+ switchCallback();
+ if( doneCallback )
+ doneCallback();
+ return;
+ }
+
+ setTimeout(function(){
+ waitCount++;
+ waitForJsListen( callback );
+ },100)
+ }
+ };
+ // wait for jslistener to be ready:
+ waitForJsListen( function(){
+ var gPlayerReady = 'kdp_switch_' + _this.id + '_switchSrcReady';
+ var gDoneName = 'kdp_switch_' + _this.id + '_switchSrcEnd';
+ var gChangeMedia = 'kdp_switch_' + _this.id + '_changeMedia';
+ window[ gPlayerReady ] = function(){
+ mw.log("EmbedPlayerKplayer:: playerSwitchSource: " + src);
+ // remove the binding as soon as possible ( we only want this event once )
+ _this.getPlayerElement().removeJsListener( 'playerReady', gPlayerReady );
+
+ _this.getPlayerElement().sendNotification("changeMedia", { 'entryId': src } );
+
+ window[ gChangeMedia ] = function (){
+ mw.log("EmbedPlayerKplayer:: Media changed: " + src);
+ if( $.isFunction( switchCallback) ){
+ switchCallback( _this );
+ switchCallback = null
+ }
+ // restore monitor:
+ _this.monitor();
+ }
+ // Add change media binding
+ _this.getPlayerElement().removeJsListener('changeMedia', gChangeMedia);
+ _this.getPlayerElement().addJsListener( 'changeMedia', gChangeMedia);
+
+ window[ gDoneName ] = function(){
+ if( $.isFunction( doneCallback ) ){
+ doneCallback();
+ doneCallback = null;
+ }
+ };
+ _this.getPlayerElement().removeJsListener('playerPlayEnd', gDoneName);
+ _this.getPlayerElement().addJsListener( 'playerPlayEnd', gDoneName);
+ };
+ // Remove then add the event:
+ _this.getPlayerElement().removeJsListener( 'playerReady', gPlayerReady );
+ _this.getPlayerElement().addJsListener( 'playerReady', gPlayerReady );
+ });
+ },
+
+ /**
+ * Issues a seek to the playerElement
+ *
+ * @param {Float}
+ * percentage Percentage of total stream length to seek to
+ */
+ seek : function(percentage) {
+ var _this = this;
+ var seekTime = percentage * this.getDuration();
+ mw.log( 'EmbedPlayerKalturaKplayer:: seek: ' + percentage + ' time:' + seekTime );
+ if (this.supportsURLTimeEncoding()) {
+
+ // Make sure we could not do a local seek instead:
+ if (!(percentage < this.bufferedPercent
+ && this.playerElement.duration && !this.didSeekJump)) {
+ // We support URLTimeEncoding call parent seek:
+ this.parent_seek( percentage );
+ return;
+ }
+ }
+ // Add a seeked callback event:
+ var seekedCallback = 'kdp_seek_' + this.id + '_' + new Date().getTime();
+ window[ seekedCallback ] = function(){
+ _this.seeking = false;
+ _this.triggerHelper( 'seeked' );
+ if( seekInterval ) {
+ clearInterval( seekInterval );
+ }
+ };
+ this.playerElement.addJsListener('playerSeekEnd', seekedCallback );
+
+ if ( this.getPlayerElement() ) {
+ // trigger the html5 event:
+ _this.triggerHelper( 'seeking' );
+
+ // Issue the seek to the flash player:
+ this.playerElement.sendNotification('doSeek', seekTime);
+
+ // Include a fallback seek timer: in case the kdp does not fire 'playerSeekEnd'
+ var orgTime = this.flashCurrentTime;
+ var seekInterval = setInterval( function(){
+ if( _this.flashCurrentTime != orgTime ){
+ _this.seeking = false;
+ clearInterval( seekInterval );
+ this.triggerHelper( 'seeked' );
+ }
+ }, mw.config.get( 'EmbedPlayer.MonitorRate' ) );
+
+ } else {
+ // try to do a play then seek:
+ this.doPlayThenSeek(percentage);
+ }
+
+ // Run the onSeeking interface update
+ this.controlBuilder.onSeek();
+ },
+
+ /**
+ * Seek in a existing stream
+ *
+ * @param {Float}
+ * percentage Percentage of the stream to seek to between 0 and 1
+ */
+ doPlayThenSeek : function(percentage) {
+ mw.log('EmbedPlayerKplayer::doPlayThenSeek::');
+ var _this = this;
+ // issue the play request
+ this.play();
+
+ // let the player know we are seeking
+ _this.seeking = true;
+ this.triggerHelper( 'seeking' );
+
+ var getPlayerCount = 0;
+ var readyForSeek = function() {
+ _this.getPlayerElement();
+ // if we have duration then we are ready to do the seek ( flash can't
+ // seek untill there is some buffer )
+ if (_this.playerElement && _this.playerElement.sendNotification
+ && _this.getDuration() && _this.bufferedPercent) {
+ var seekTime = percentage * _this.getDuration();
+ // Issue the seek to the flash player:
+ _this.playerElement.sendNotification('doSeek', seekTime);
+ } else {
+ // Try to get player for 20 seconds:
+ if (getPlayerCount < 400) {
+ setTimeout(readyForSeek, 50);
+ getPlayerCount++;
+ } else {
+ mw.log('Error: doPlayThenSeek failed');
+ }
+ }
+ };
+ readyForSeek();
+ },
+
+ /**
+ * Issues a volume update to the playerElement
+ *
+ * @param {Float}
+ * percentage Percentage to update volume to
+ */
+ setPlayerElementVolume : function(percentage) {
+ if ( this.getPlayerElement() && this.playerElement.sendNotification ) {
+ this.playerElement.sendNotification('changeVolume', percentage);
+ }
+ },
+
+ /**
+ * function called by flash at set interval to update the playhead.
+ */
+ onUpdatePlayhead : function( playheadValue ) {
+ //mw.log('Update play head::' + playheadValue);
+ this.flashCurrentTime = playheadValue;
+ },
+
+ /**
+ * function called by flash when the total media size changes
+ */
+ onBytesTotalChange : function(data, id) {
+ this.bytesTotal = data.newValue;
+ },
+
+ /**
+ * function called by flash applet when download bytes changes
+ */
+ onBytesDownloadedChange : function(data, id) {
+ //mw.log('onBytesDownloadedChange');
+ this.bytesLoaded = data.newValue;
+ this.bufferedPercent = this.bytesLoaded / this.bytesTotal;
+
+ // Fire the parent html5 action
+ this.triggerHelper('progress', {
+ 'loaded' : this.bytesLoaded,
+ 'total' : this.bytesTotal
+ });
+ },
+
+ /**
+ * Get the embed player time
+ */
+ getPlayerElementTime : function() {
+ // update currentTime
+ return this.flashCurrentTime;
+ },
+
+ /**
+ * Get the embed fla object player Element
+ */
+ getPlayerElement : function() {
+ this.playerElement = document.getElementById( this.pid );
+ return this.playerElement;
+ }
+};
+
+} )( mediaWiki, jQuery );
+
+/*
+ * jQuery Tools 1.2.5 - The missing UI library for the Web
+ *
+ * [toolbox.flashembed]
+ *
+ * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
+ *
+ * http://flowplayer.org/tools/
+ *
+ * File generated: Fri Oct 22 13:51:38 GMT 2010
+ */
+(function(){function f(a,b){if(b)for(var c in b)if(b.hasOwnProperty(c))a[c]=b[c];return a}function l(a,b){var c=[];for(var d in a)if(a.hasOwnProperty(d))c[d]=b(a[d]);return c}function m(a,b,c){if(e.isSupported(b.version))a.innerHTML=e.getHTML(b,c);else if(b.expressInstall&&e.isSupported([6,65]))a.innerHTML=e.getHTML(f(b,{src:b.expressInstall}),{MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title});else{if(!a.innerHTML.replace(/\s/g,"")){a.innerHTML="<h2>Flash version "+b.version+
+" or greater is required</h2><h3>"+(g[0]>0?"Your version is "+g:"You have no flash plugin installed")+"</h3>"+(a.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='"+k+"'>here</a></p>");if(a.tagName=="A")a.onclick=function(){location.href=k}}if(b.onFail){var d=b.onFail.call(this);if(typeof d=="string")a.innerHTML=d}}if(i)window[b.id]=document.getElementById(b.id);f(this,{getRoot:function(){return a},getOptions:function(){return b},getConf:function(){return c},
+getApi:function(){return a.firstChild}})}var i=document.all,k="http://www.adobe.com/go/getflashplayer",n=typeof jQuery=="function",o=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,j={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};window.attachEvent&&window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}});
+window.flashembed=function(a,b,c){if(typeof a=="string")a=document.getElementById(a.replace("#",""));if(a){if(typeof b=="string")b={src:b};return new m(a,f(f({},j),b),c)}};var e=f(window.flashembed,{conf:j,getVersion:function(){var a,b;try{b=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(c){try{b=(a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"))&&a.GetVariable("$version")}catch(d){try{b=(a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"))&&a.GetVariable("$version")}catch(h){}}}return(b=
+o.exec(b))?[b[1],b[3]]:[0,0]},asString:function(a){if(a===null||a===undefined)return null;var b=typeof a;if(b=="object"&&a.push)b="array";switch(b){case "string":a=a.replace(new RegExp('(["\\\\])',"g"),"\\$1");a=a.replace(/^\s?(\d+\.?\d+)%/,"$1pct");return'"'+a+'"';case "array":return"["+l(a,function(d){return e.asString(d)}).join(",")+"]";case "function":return'"function()"';case "object":b=[];for(var c in a)a.hasOwnProperty(c)&&b.push('"'+c+'":'+e.asString(a[c]));return"{"+b.join(",")+"}"}return String(a).replace(/\s/g,
+" ").replace(/\'/g,'"')},getHTML:function(a,b){a=f({},a);var c='<object width="'+a.width+'" height="'+a.height+'" id="'+a.id+'" name="'+a.id+'"';if(a.cachebusting)a.src+=(a.src.indexOf("?")!=-1?"&":"?")+Math.random();c+=a.w3c||!i?' data="'+a.src+'" type="application/x-shockwave-flash"':' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';c+=">";if(a.w3c||i)c+='<param name="movie" value="'+a.src+'" />';a.width=a.height=a.id=a.w3c=a.src=null;a.onFail=a.version=a.expressInstall=null;for(var d in a)if(a[d])c+=
+'<param name="'+d+'" value="'+a[d]+'" />';a="";if(b){for(var h in b)if(b[h]){d=b[h];a+=h+"="+(/function|object/.test(typeof d)?e.asString(d):d)+"&"}a=a.slice(0,-1);c+='<param name="flashvars" value=\''+a+"' />"}c+="</object>";return c},isSupported:function(a){return g[0]>a[0]||g[0]==a[0]&&g[1]>=a[1]}}),g=e.getVersion();if(n){jQuery.tools=jQuery.tools||{version:"1.2.5"};jQuery.tools.flashembed={conf:j};jQuery.fn.flashembed=function(a,b){return this.each(function(){$(this).data("flashembed",flashembed(this,
+a,b))})}}})();