128 changes: 66 additions & 62 deletions modules/EmbedPlayer/binPlayers/nativeBridge.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
( function( mw, $ ) { "use strict";
/*globals kWidget, alert, console*/
( function ( mw, $ ) {
'use strict';

var NativeBridge = {
callbacksCount : 1,
callbacks : {},
callbacksCount: 1,
callbacks: {},

// Automatically called by native layer when a result is available
resultForCallback : function resultForCallback(callbackId, resultArray) {
resultForCallback: function resultForCallback( callbackId, resultArray ) {
try {
var callback = NativeBridge.callbacks[callbackId];
if (!callback) {
if ( !callback ) {
return;
}

callback.apply(null,resultArray);
} catch(e) {alert(e);}
callback.apply( null, resultArray );
} catch ( e ) {
alert( e );
}
},

// Use this in javascript to request native objective-c code
// functionName : string (I think the name is explicit :p)
// args : array of arguments
// callback : function with n-arguments that is going to be called when the native code returned
call : function call(functionName, args, callback) {
call: function call( functionName, args, callback ) {

var hasCallback = callback && typeof callback == "function";
var hasCallback = callback && typeof callback === 'function';
var callbackId = hasCallback ? NativeBridge.callbacksCount++ : 0;

if (hasCallback) {
if ( hasCallback ) {
NativeBridge.callbacks[callbackId] = callback;
}

var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-frame:" + functionName + ":" + callbackId+ ":" + encodeURIComponent(JSON.stringify(args)));
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
var iframe = document.createElement( 'IFRAME' );
iframe.setAttribute( 'src', 'js-frame:' + functionName + ':' + callbackId + ':' + encodeURIComponent( JSON.stringify( args ) ) );
document.documentElement.appendChild( iframe );
iframe.parentNode.removeChild( iframe );
iframe = null;
}
};
Expand All @@ -40,53 +45,53 @@ NativeBridge.videoPlayer = NativeBridge.videoPlayer || {
proxyElement: null,
embedPlayer: null,
isJsCallbackReady: false,
bindPostfix: ".nativeBridge",
bindPostfix: '.nativeBridge',
subscribed: [],
playerMethods: [ 'stop', 'play', 'pause', 'setPlayerSource', 'bindPlayerEvents', 'showNativePlayer', 'hideNativePlayer', 'toggleFullscreen', 'notifyKPlayerEvent', 'notifyKPlayerEvaluated', 'notifyJsReady', 'showChromecastDeviceList', 'notifyLayoutReady',
'doneFSBtnPressed', 'addNativeAirPlayButton', 'showNativeAirPlayButton', 'hideNativeAirPlayButton' ],

registePlayer: function (proxyElement) {
registePlayer: function ( proxyElement ) {
var _this = this;
this.proxyElement = proxyElement;
for (var i = 0; i < this.playerMethods.length; i++) {
(function (method) {
_this.proxyElement[method] = function (arg) {
_this.execute(method, arg);
}
};
})(this.playerMethods[i]);
}
this.proxyElement.attr = function( attributeName, attributeValue ){
if( attributeName && attributeValue === undefined ) {
this.proxyElement.attr = function ( attributeName, attributeValue ) {
if ( attributeName && attributeValue === undefined ) {
return _this.proxyElement[ attributeName ];
} else if( attributeName && attributeValue ){
} else if ( attributeName && attributeValue ) {
_this.proxyElement[attributeName] = attributeValue;
_this.execute('setAttribute', [ attributeName, attributeValue ]);
_this.execute( 'setAttribute', [ attributeName, attributeValue ] );
}
}
};

//TODO support more than 1 subscribe?
this.proxyElement.subscribe = function( callback, eventName ) {
this.proxyElement.subscribe = function ( callback, eventName ) {
_this.subscribed[eventName] = callback;
}
};

this.proxyElement.unsubscribe = function( eventName ) {
this.proxyElement.unsubscribe = function ( eventName ) {
_this.subscribed[eventName] = undefined;
}
};

this.bindNativeEvents();
},

notifyJsReadyFunc: function() {
notifyJsReadyFunc: function () {
if ( this.isJsCallbackReady && this.proxyElement ) {
this.proxyElement.notifyJsReady( [] );
}
},

registerEmbedPlayer: function( embedPlayer ) {
registerEmbedPlayer: function ( embedPlayer ) {
this.embedPlayer = embedPlayer;
this.notifyJsReadyFunc();
},
sendNotification: function( eventName, eventValue ) {
sendNotification: function ( eventName, eventValue ) {
this.embedPlayer.sendNotification( eventName, JSON.parse( eventValue ));
},
/**
Expand All @@ -96,55 +101,55 @@ NativeBridge.videoPlayer = NativeBridge.videoPlayer || {
*/
getObjectString: function ( object ) {
var stringValue = object;
if ( typeof object === "object" ) {
if ( typeof object === 'object' ) {
stringValue = JSON.stringify( object );
}
return stringValue;
},
addJsListener: function( eventName ){
addJsListener: function ( eventName ) {
var _this = this;
this.embedPlayer.addJsListener( eventName + this.bindPostfix, function( val ) {
this.embedPlayer.addJsListener( eventName + this.bindPostfix, function ( val ) {
_this.embedPlayer.getPlayerElement().notifyKPlayerEvent( [ eventName, _this.getObjectString( val ) ] );
});
} );
},
removeJsListener: function( eventName ) {
removeJsListener: function ( eventName ) {
this.embedPlayer.removeJsListener( eventName + this.bindPostfix );
},
setKDPAttribute: function( host, prop, value ) {
setKDPAttribute: function ( host, prop, value ) {
this.embedPlayer.setKDPAttribute( host, prop, value );
},
/**
* will evaluate given expression and send the resulted value back to native code with the given callbackName
* @param expression
* @param callbackName
*/
asyncEvaluate: function( expression, callbackName ) {
asyncEvaluate: function ( expression, callbackName ) {
var result = this.embedPlayer.evaluate( expression );
this.embedPlayer.getPlayerElement().notifyKPlayerEvaluated( [ callbackName, this.getObjectString( result ) ]);
},
//this function should be called from IOS/Andorid
trigger: function (eventName, eventValue) {
trigger: function ( eventName, eventValue ) {
// mw.log('nativeBridge.js --> trigger:' + eventName + ' ' + eventValue);

if (eventValue === "(null)") {
var jsEventValue;
if (eventValue === '(null)' ) {
//set undefined
eventValue = void(0);
}

if(eventValue != undefined){
var jsEventValue = this.stringConvertion( eventValue );
if ( eventValue !== undefined) {
jsEventValue = this.stringConvertion( eventValue );
}

$( this.proxyElement).trigger( eventName, [jsEventValue] );

if (eventName == 'timeupdate'){
this.proxyElement['currentTime'] = jsEventValue;
}else if (eventName == 'progress'){
this.proxyElement['progress'] = jsEventValue;
}else if (eventName == 'visible'){
this.proxyElement['visible'] = jsEventValue;
} else if (eventName == 'durationchange') {
this.proxyElement['duration'] = jsEventValue;
if (eventName === 'timeupdate') {
this.proxyElement.currentTime = jsEventValue;
}else if (eventName === 'progress') {
this.proxyElement.progress = jsEventValue;
}else if (eventName === 'visible') {
this.proxyElement.visible = jsEventValue;
} else if (eventName === 'durationchange') {
this.proxyElement.duration = jsEventValue;
}

if ( this.subscribed[eventName] ) {
Expand All @@ -155,25 +160,25 @@ NativeBridge.videoPlayer = NativeBridge.videoPlayer || {
args = args || [];
console.log(command);
console.log(args);
NativeBridge.call(command , args);
NativeBridge.call(command, args);
},
bindNativeEvents: function(){
bindNativeEvents: function () {
console.log('bindNativeEvents');
this.proxyElement.bindPlayerEvents( [] );
},
log:function(message,arg){
console.log(message,arg);
log: function ( message, arg ) {
console.log( message, arg );
},

stringConvertion: function (str){
stringConvertion: function (str ) {
var value = parseFloat(str);

if(isNaN(value)){
if(value == 'true'){
if (isNaN( value ) ) {
if ( value === 'true' ) {
return true;
}else if(value == 'false'){
} else if ( value === 'false' ) {
return false;
}else{
} else {
return str;
}
}
Expand All @@ -182,13 +187,12 @@ NativeBridge.videoPlayer = NativeBridge.videoPlayer || {
}
};


if ( mw.getConfig('EmbedPlayer.ForceNativeComponent') === true ) {
window["NativeBridge"] = NativeBridge;
kWidget.addReadyCallback( function() {
window.NativeBridge = NativeBridge;
kWidget.addReadyCallback( function () {
NativeBridge.videoPlayer.isJsCallbackReady = true;
NativeBridge.videoPlayer.notifyJsReadyFunc();
} );
}

})( window.mw, window.jQuery );
})( mediaWiki, jQuery );
17 changes: 9 additions & 8 deletions modules/EmbedPlayer/resources/EmbedPlayer.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
.mwPlayerContainer.fullscreen {
position: absolute !important;
width: 100% !important;
height: 100%! important;
height: 100% !important;
z-index: 9999;
min-height: 100%;
top: 0;
Expand All @@ -19,18 +19,19 @@
overflow: hidden;
}

.videoHolder {
position: relative;
overflow: hidden;
width: 100%;
.videoHolder {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
background: #000;
background: #000;
}

.videoDisplay {
position: absolute;
top: 0; left: 0;
width: 100%;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

Expand Down
1,406 changes: 696 additions & 710 deletions modules/EmbedPlayer/resources/mw.EmbedPlayer.js

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerGeneric.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
* Simple embed object for unknown application/ogg plugin
*/

( function( mw, $ ) { "use strict";
( function ( mw, $ ) {
'use strict';

mw.EmbedPlayerGeneric = {
// List of supported features of the generic plugin
supports: {
supports: {
'playHead':false,
'pause':false,
'stop':true,
Expand All @@ -22,9 +23,9 @@ mw.EmbedPlayerGeneric = {
* Generic embed html
*
* @return {String}
* embed code for generic ogg plugin
* embed code for generic ogg plugin
*/
embedPlayerHTML: function() {
embedPlayerHTML: function () {
$( this ).html(
'<object type="application/ogg" ' +
'width="' + this.getWidth() + '" height="' + this.getHeight() + '" ' +
Expand All @@ -33,4 +34,4 @@ mw.EmbedPlayerGeneric = {
}
};

} )( window.mediaWiki, window.jQuery );
} )( mediaWiki, jQuery );
158 changes: 78 additions & 80 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
* extends EmbedPlayerNative object image overlay support
*/

( function( mw, $ ) {"use strict";
( function ( mw, $ ) {
'use strict';

mw.EmbedPlayerImageOverlay = {

instanceOf: 'ImageOverlay',

// If the player is "ready to play"
playerReady : true,
playerReady: true,

// Pause time used to track player time between pauses
lastPauseTime: 0,
Expand All @@ -24,21 +25,21 @@

// The local clock used to emulate playback time
clockStartTime: 0,

// A flag to set if image is loaded
imageLoaded: false,

/**
* Build the player interface:
*/
init: function(){
init: function () {
// Check if features are already updated:
if( this['native_instaceOf'] == 'Native' ){
if ( this['native_instaceOf'] === 'Native' ) {
return ;
}
// inherit mw.EmbedPlayerNative (
for( var i in mw.EmbedPlayerNative ){
if( typeof mw.EmbedPlayerImageOverlay[ i ] != 'undefined' ){
for ( var i in mw.EmbedPlayerNative ) {
if ( typeof mw.EmbedPlayerImageOverlay[ i ] !== 'undefined' ) {
this['native_' + i ] = mw.EmbedPlayerNative[i];
} else {
this[ i ] = mw.EmbedPlayerNative[i];
Expand All @@ -50,8 +51,8 @@
* When on playback method switch remove imageOverlay
* @param {function} callback
*/
updatePlaybackInterface: function( callback ){
mw.log( 'EmbedPlayerImageOverlay:: updatePlaybackInterface: ' + $(this).siblings( '.playerPoster' ).length );
updatePlaybackInterface: function ( callback ) {
mw.log( 'EmbedPlayerImageOverlay:: updatePlaybackInterface: ' + $( this ).siblings( '.playerPoster' ).length );
// Clear imageOverlay sibling:
// Restore the video element on screen position:
$( this.getPlayerElement() ).css( 'left', 0 );
Expand All @@ -65,20 +66,20 @@
* Set black video urls for player source
* Add an image overlay
*/
updatePosterHTML: function(){
updatePosterHTML: function (){
var vid = this.getPlayerElement();
$( vid ).empty();

// embed the image:
this.embedPlayerHTML();
},

removePoster: function() {},
removePoster: function () {},

/**
* Play function starts the video playback
*/
play: function() {
play: function () {
mw.log( 'EmbedPlayerImageOverlay::play> lastPauseTime:' + this.lastPauseTime + ' ct: ' + this.currentTime );
// capture the user gesture ( if need )
this.captureUserGesture();
Expand All @@ -87,7 +88,7 @@
// Check for image duration

// Reset playback if currentTime > duration:
if( this.currentTime > this.getDuration() ) {
if ( this.currentTime > this.getDuration() ) {
this.currentTime = this.pauseTime = 0;
}
// No longer in a stopped state:
Expand All @@ -98,53 +99,53 @@
this.playInterfaceUpdate();
// Reset clock time for load
this.clockStartTime = new Date().getTime();

// Reset buffer:
this.bufferedPercent = 0;

// Start up monitor:
this.monitor();
this.hideSpinner();
$( this ).trigger( 'playing' );
},
getDuration: function(){
if( this.duration ){
getDuration: function () {
if ( this.duration ) {
return this.duration;
}
// update the duration if we don't have it:
this.updateDuration();
// make sure duration has type float:
return this.duration;
},
updateDuration: function(){
if( $( this ).data('imageDuration') ){
this.duration = parseFloat( $( this ).data('imageDuration') ) ;
updateDuration: function () {
if ( $( this ).data( 'imageDuration' ) ) {
this.duration = parseFloat( $( this ).data( 'imageDuration' ) ) ;
} else {
this.duration = parseFloat( mw.getConfig( "EmbedPlayer.DefaultImageDuration" ) );
this.duration = parseFloat( mw.getConfig( 'EmbedPlayer.DefaultImageDuration' ) );
}
},
/**
* Stops the playback
*/
stop: function() {
stop: function () {
this.currentTime = 0;
this.parent_stop();
},
_onpause: function(){
_onpause: function () {
// catch the native event ( and do nothing )
},
/**
* Preserves the pause time across for timed playback
*/
pause: function() {
pause: function () {
mw.log( 'EmbedPlayerImageOverlay::pause, lastPauseTime: ' + this.lastPauseTime );
this.lastPauseTime = this.currentTime;
// run parent pause;
this.parent_pause();
},

monitor: function(){
if( this.duration === 0 ){
monitor: function () {
if ( this.duration === 0 ) {
return ;
}
var oldCurrentTime = this.currentTime;
Expand All @@ -157,17 +158,17 @@
// Run the parent monitor:
this.parent_monitor();
}
if( oldCurrentTime != this.currentTime ){
if ( oldCurrentTime !== this.currentTime ) {
$( this ).trigger( 'timeupdate' );
}
},

/**
* Seeks to a given percent and updates the lastPauseTime
*
* @param {Float} seekPercent Percentage to seek into the virtual player
*/
seek: function( seekPercent ) {
seek: function ( seekPercent ) {
this.lastPauseTime = seekPercent * this.getDuration();
this.seeking = false;
// start seeking:
Expand All @@ -183,53 +184,53 @@
* @param {Float} perc Percentage to seek into the virtual player
* @param {Function} callback Function called once time has been updated
*/
setCurrentTime: function( time, callback ) {
setCurrentTime: function ( time, callback ) {
this.lastPauseTime = time;
// start seeking:
$( this ).trigger( 'seeking' );
// Done seeking
$( this ).trigger( 'seeked' );
if( callback ){
if ( callback ) {
callback();
}
},
/**
* Switch the image playback
* @param {Object} source
*/
playerSwitchSource: function( source, switchCallback, doneCallback ){
mw.log( "EmbedPlayerImageOverlay:: playerSwitchSource" );
playerSwitchSource: function ( source, switchCallback, doneCallback ) {
mw.log( 'EmbedPlayerImageOverlay:: playerSwitchSource' );
var _this = this;
this.mediaElement.selectedSource = source;
this.addPlayerSpinner();
this.captureUserGesture();
this.embedPlayerHTML( function(){
mw.log( "EmbedPlayerImageOverlay:: playerSwitchSource, embedPlayerHTML callback" );
this.embedPlayerHTML( function () {
mw.log( 'EmbedPlayerImageOverlay:: playerSwitchSource, embedPlayerHTML callback' );
_this.applyIntrinsicAspect();
_this.play();
if( switchCallback ){
if ( switchCallback ) {
switchCallback( _this );
}
// Wait for ended event to trigger
$( _this ).bind( 'ended.playerSwitchSource', function(){
$( _this ).bind( 'ended.playerSwitchSource', function () {
_this.stopMonitor();
$( _this ).unbind( 'ended.playerSwitchSource' );
if( doneCallback ) {
if ( doneCallback ) {
doneCallback( _this );
}
});
});
} );
} );
},
/** issue a load call on native element, so we can play it in the future */
captureUserGesture: function(){
captureUserGesture: function () {
// Capture the play event on the native player: ( should just be black silent sources )
// This is needed so that if a playlist starts with image, it can continue to play the
// subsequent video without on iOS without requiring another click.
if( ! $( this ).data('previousInstanceOf') ){
if ( !$( this ).data( 'previousInstanceOf' ) ) {
// Update the previousInstanceOf flag:
$( this ).data('previousInstanceOf', this.instanceOf );
$( this ).data( 'previousInstanceOf', this.instanceOf );
var vid = this.getPlayerElement();
$( vid ).attr('src', null);
$( vid ).attr( 'src', null );
// populate the video with black video sources:
this.triggerHelper( 'AddEmptyBlackSources', [ vid ] );
// run load ( to capture the play event for iOS ) :
Expand All @@ -238,68 +239,65 @@
}
}
},
updatePoster: function ( posterSrc ){
updatePoster: function ( posterSrc ) {
var _this = this;
if( ! posterSrc ) {
if ( !posterSrc ) {
posterSrc = mw.getConfig( 'EmbedPlayer.BlackPixel' );
}
this.poster = posterSrc;
$( this ).find('img.playerPoster')
.attr('src', this.poster )
.load(function(){
$( this ).find( 'img.playerPoster' )
.attr( 'src', this.poster )
.load( function () {
_this.applyIntrinsicAspect();
});
} );
},
embedPlayerHTML: function( callback ) {
embedPlayerHTML: function ( callback ) {
var _this = this;
mw.log( 'EmbedPlayerImageOverlay::embedPlayerHTML: ' + this.id );

// Update the duration per stored image duration type
this.updateDuration();

var currentSoruceObj = this.mediaElement.selectedSource;
// Rest imageLoaded flag:
// Rest imageLoaded flag:
_this.imageLoaded = false;
if( !currentSoruceObj ){
mw.log("Error:: EmbedPlayerImageOverlay:embedPlayerHTML> missing source" );

if ( !currentSoruceObj ) {
mw.log( 'Error:: EmbedPlayerImageOverlay:embedPlayerHTML> missing source' );
return ;
}
var loadedCallback = function(){

var loadedCallback = function () {
_this.applyIntrinsicAspect();
// reset clock time for loa
_this.clockStartTime = new Date().getTime();
// update image loaded:
_this.imageLoaded = true;
_this.monitor();
if( $.isFunction( callback ) ) {
if ( $.isFunction( callback ) ) {
callback();
}
};

var $image =
$( '<img />' )
.attr({
'src' : currentSoruceObj.getSrc()
})
$( '<img>' )
.attr( 'src', currentSoruceObj.getSrc() )
.addClass( 'playerPoster' )
.one('load', function(){
if( $.isFunction( loadedCallback ) ) {
.one( 'load', function () {
if ( $.isFunction( loadedCallback ) ) {
loadedCallback();
loadedCallback = null;
}
})
.each( function() {
if( this.complete ){
$(this).load();
} )
.each( function () {
if ( this.complete ) {
$( this ).load();
}
});
} );
// move the video element off screen:
$( this.getPlayerElement() ).css({
'left': this.getWidth()+50,
'position' : 'absolute'
});
$( this.getPlayerElement() ).css( {
'left': this.getWidth() + 50,
'position': 'absolute'
} );

// Add the image before the video element or before the playerInterface
$( this ).html( $image );
Expand All @@ -308,11 +306,11 @@
/**
* Get the embed player time
*/
getPlayerElementTime: function() {
if( ! this.imageLoaded ){
getPlayerElementTime: function () {
if ( !this.imageLoaded ) {
mw.log( 'image not loaded: 0' );
this.currentTime = 0;
} else if( this.paused ) {
} else if ( this.paused ) {
this.currentTime = this.lastPauseTime;
} else {
this.currentTime = ( ( new Date().getTime() - this.clockStartTime ) / 1000 ) + this.lastPauseTime;
Expand All @@ -321,4 +319,4 @@
}
};

})( window.mw, window.jQuery );
})( mediaWiki, jQuery );
86 changes: 43 additions & 43 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerJava.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
( function( mw, $ ) { "use strict";
( function ( mw, $ ) {
'use strict';

/**
* List of domains and hosted location of cortado. Lets clients avoid the security warning
* for cross domain java applet loading.
*/
window.cortadoDomainLocations = {
'upload.wikimedia.org' : 'http://upload.wikimedia.org/jars/cortado.jar'
'upload.wikimedia.org': 'http://upload.wikimedia.org/jars/cortado.jar'
};

// Set the default location for CortadoApplet
Expand All @@ -17,34 +19,33 @@ mw.EmbedPlayerJava = {

// Supported feature set of the cortado applet:
supports: {
'playHead' : true,
'pause' : true,
'stop' : true,
'fullscreen' : false,
'timeDisplay' : true,
'volumeControl' : false
'playHead': true,
'pause': true,
'stop': true,
'fullscreen': false,
'timeDisplay': true,
'volumeControl': false
},

/**
* Output the the embed html
*/
embedPlayerHTML: function () {
var _this = this;
mw.log( "EmbedPlayerJava:: java play url:" + this.getSrc( this.seekTimeSec ) );
mw.log( 'EmbedPlayerJava:: java play url:' + this.getSrc( this.seekTimeSec ) );

mw.log( 'EmbedPlayerJava:: Applet location: ' + this.getAppletLocation() );
mw.log( 'EmbedPlayerJava:: Play media: ' + this.getSrc() );


// load directly in the page..
// ( media must be on the same server or applet must be signed )
var appletCode = '' +
'<applet id="' + this.pid + '" ' +
'code="com.fluendo.player.Cortado.class" ' +
'width="' + parseInt( this.getWidth() ) + '" ' +
'height="' + parseInt( this.getVideoHolder().height() ) + '" ' +
'archive="' + mw.absoluteUrl( this.getAppletLocation() ) + '" >'+
'<param name="url" value="' + mw.absoluteUrl( this.getSrc() ) + '" /> ' + "\n" +
'width="' + parseInt( this.getWidth(), 10 ) + '" ' +
'height="' + parseInt( this.getVideoHolder().height(), 10 ) + '" ' +
'archive="' + mw.absoluteUrl( this.getAppletLocation() ) + '" >' +
'<param name="url" value="' + mw.absoluteUrl( this.getSrc() ) + '" /> ' + '\n' +
'<param name="local" value="false"/>' +
'<param name="keepaspect" value="true" />' +
'<param name="video" value="true" />' +
Expand All @@ -53,14 +54,14 @@ mw.EmbedPlayerJava = {
'<param name="seekable" value="true" />';

// Add the duration attribute if set:
if( this.getDuration() ){
appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + "\n";
if ( this.getDuration() ) {
appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + '\n';
}

appletCode += '<param name="BufferSize" value="4096" />' +
'<param name="BufferHigh" value="25">' +
'<param name="BufferLow" value="5">' +
'</applet>';
appletCode += '<param name="BufferSize" value="4096" />' +
'<param name="BufferHigh" value="25">' +
'<param name="BufferLow" value="5">' +
'</applet>';

$( this ).html( appletCode );

Expand All @@ -71,16 +72,15 @@ mw.EmbedPlayerJava = {
/**
* Get the applet location
*/
getAppletLocation: function() {
getAppletLocation: function () {
var mediaSrc = this.getSrc();
var appletLoc = false;
if (
!mw.isLocalDomain( mediaSrc )
||
!mw.isLocalDomain( mw.getMwEmbedPath()
||
mw.getConfig( 'relativeCortadoAppletPath' ) === false )
){
) {
if ( window.cortadoDomainLocations[ new mw.Uri( mediaSrc ).host ] ) {
return window.cortadoDomainLocations[ new mw.Uri( mediaSrc ).host ];
} else {
Expand All @@ -95,7 +95,7 @@ mw.EmbedPlayerJava = {
/**
* Get the embed player time
*/
getPlayerElementTime: function() {
getPlayerElementTime: function () {
this.getPlayerElement();
var currentTime = 0;
if ( this.playerElement ) {
Expand All @@ -112,8 +112,8 @@ mw.EmbedPlayerJava = {
} catch ( e ) {
mw.log( 'EmbedPlayerJava:: Could not get time from jPlayer: ' + e );
}
}else{
mw.log("EmbedPlayerJava:: Could not find playerElement " );
} else {
mw.log( 'EmbedPlayerJava:: Could not find playerElement' );
}
return currentTime;
},
Expand All @@ -123,15 +123,15 @@ mw.EmbedPlayerJava = {
* ( Cortado seek does not seem to work very well )
* @param {Float} percentage Percentage to seek into the stream
*/
seek: function( percentage ) {
seek: function ( percentage ) {
mw.log( 'EmbedPlayerJava :: seek: p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seekTimeSec );
this.getPlayerElement();

if ( this.supportsURLTimeEncoding() ) {
this.parent_seek( percentage );
} else if ( this.playerElement ) {
// do a (generally broken) local seek:
mw.log( "EmbedPlayerJava:: seek is not very accurate :: seek::" + ( percentage * parseFloat( this.getDuration() ) ) );
mw.log( 'EmbedPlayerJava:: seek is not very accurate :: seek::' + ( percentage * parseFloat( this.getDuration() ) ) );
this.playerElement.currentTime = ( percentage * parseFloat( this.getDuration() ) );
} else {
this.doPlayThenSeek( percentage );
Expand All @@ -145,12 +145,12 @@ mw.EmbedPlayerJava = {
* Issue a play request then seek to a percentage point in the stream
* @param {Float} percentage Percentage to seek into the stream
*/
doPlayThenSeek: function( percentage ) {
doPlayThenSeek: function ( percentage ) {
mw.log( 'EmbedPlayerJava:: doPlayThenSeek' );
var _this = this;
this.play();
var rfsCount = 0;
var readyForSeek = function() {
var readyForSeek = function () {
_this.getPlayerElement();
// if we have .jre ~in theory~ we can seek (but probably not)
if ( _this.playerElement ) {
Expand All @@ -171,10 +171,10 @@ mw.EmbedPlayerJava = {
/**
* Update the playerElement instance with a pointer to the embed object
*/
getPlayerElement: function() {
if( !$( '#' + this.pid ).length ) {
getPlayerElement: function () {
if ( !$( '#' + this.pid ).length ) {
return false;
};
}
this.playerElement = $( '#' + this.pid ).get( 0 );
return this.playerElement;
},
Expand All @@ -183,35 +183,35 @@ mw.EmbedPlayerJava = {
* Issue the doPlay request to the playerElement
* calls parent_play to update interface
*/
play: function() {
play: function () {
this.getPlayerElement();
this.parent_play();
if ( this.playerElement ) {
try{
try {
this.playerElement.play();
}catch( e ){
mw.log("EmbedPlayerJava::Could not issue play request");
} catch ( e ) {
mw.log( 'EmbedPlayerJava::Could not issue play request' );
}
}
},

/**
* Pause playback
* calls parent_pause to update interface
* calls parent_pause to update interface
*/
pause: function() {
pause: function () {
this.getPlayerElement();
// Update the interface
this.parent_pause();
// Call the pause function if it exists:
if ( this.playerElement ) {
try{
try {
this.playerElement.pause();
}catch( e ){
mw.log("EmbedPlayerJava::Could not issue pause request");
} catch ( e ) {
mw.log( 'EmbedPlayerJava::Could not issue pause request' );
}
}
}
};

} )( window.mediaWiki, window.jQuery );
} )( mediaWiki, jQuery );
398 changes: 200 additions & 198 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js

Large diffs are not rendered by default.

758 changes: 379 additions & 379 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerNative.js

Large diffs are not rendered by default.

220 changes: 108 additions & 112 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerNativeComponent.js

Large diffs are not rendered by default.

320 changes: 159 additions & 161 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerSilverlight.js

Large diffs are not rendered by default.

132 changes: 66 additions & 66 deletions modules/EmbedPlayer/resources/mw.EmbedPlayerVlc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
* javascript api: http://www.videolan.org/doc/play-howto/en/ch04.html
* assume version > 0.8.5.1
*/
( function( mw, $ ) { "use strict";
/*globals gM */
( function ( mw, $ ) {
'use strict';

mw.EmbedPlayerVlc = {

//Instance Name:
instanceOf : 'Vlc',
instanceOf: 'Vlc',

//What the vlc player / plug-in supports:
supports : {
supports: {
'playHead':true,
'pause':true,
'stop':true,
Expand All @@ -24,7 +26,7 @@ mw.EmbedPlayerVlc = {
},

// The previous state of the player instance
prevState : 0,
prevState: 0,

// Counter for waiting for vlc embed to be ready
waitForVlcCount:0,
Expand All @@ -35,7 +37,7 @@ mw.EmbedPlayerVlc = {
/**
* Get embed HTML
*/
embedPlayerHTML: function() {
embedPlayerHTML: function () {
var _this = this;
$( this ).html(
'<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' +
Expand All @@ -55,7 +57,7 @@ mw.EmbedPlayerVlc = {
'style="width:' + this.getWidth() + 'px;height:' + this.getHeight() + 'px;" ' +
'>' +
'</object>'
)
);
// Call postEmbedActions directly ( postEmbedJs will wait for player ready )
_this.postEmbedActions();
},
Expand All @@ -64,11 +66,11 @@ mw.EmbedPlayerVlc = {
* Javascript to run post vlc embedding
* Inserts the requested src to the embed instance
*/
postEmbedActions: function() {
postEmbedActions: function () {
var _this = this;
// Load a pointer to the vlc into the object (this.playerElement)
this.getPlayerElement();
if ( this.playerElement && this.playerElement.playlist) {
if ( this.playerElement && this.playerElement.playlist ) {
// manipulate the dom object to make sure vlc has the correct size:
this.playerElement.style.width = this.getWidth();
this.playerElement.style.height = this.getHeight();
Expand All @@ -77,22 +79,22 @@ mw.EmbedPlayerVlc = {
// VLC likes absolute urls:
var src = mw.absoluteUrl( this.getSrc() ) ;

mw.log( "EmbedPlayerVlc:: postEmbedActions play src:" + src );
mw.log( 'EmbedPlayerVlc:: postEmbedActions play src:' + src );
var itemId = this.playerElement.playlist.add( src );
if ( itemId != -1 ) {
if ( itemId !== -1 ) {
// Play
this.playerElement.playlist.playItem( itemId );
} else {
mw.log( "Error:: EmbedPlayerVlc can not play" );
mw.log( 'Error:: EmbedPlayerVlc can not play' );
}
setTimeout( function() {
setTimeout( function () {
_this.monitor();
}, 100 );
} else {
mw.log( 'EmbedPlayerVlc:: postEmbedActions: vlc not ready' );
this.waitForVlcCount++;
if ( this.waitForVlcCount < 10 ) {
setTimeout( function() {
setTimeout( function () {
_this.postEmbedActions();
}, 100 );
} else {
Expand All @@ -106,18 +108,18 @@ mw.EmbedPlayerVlc = {
*
* @param {Float} percent Seek to this percent of the stream
*/
seek : function( percent ) {
seek: function ( percent ) {
this.getPlayerElement();
// Use the parent (re) embed with new seek url method if urlTimeEncoding is supported.
if ( this.supportsURLTimeEncoding() ) {
this.parent_seek( percent );
} else if ( this.playerElement ) {
this.seeking = true;
mw.log( "EmbedPlayerVlc:: seek to: " + percent )
if ( ( this.playerElement.input.state == 3 ) && ( this.playerElement.input.position != percent ) )
mw.log( 'EmbedPlayerVlc:: seek to: ' + percent );
if ( ( this.playerElement.input.state === 3 ) && ( this.playerElement.input.position !== percent ) )
{
this.playerElement.input.position = percent;
this.layoutBuilder.setStatus( gM('mwe-embedplayer-seeking') );
this.layoutBuilder.setStatus( gM( 'mwe-embedplayer-seeking' ) );
}
} else {
this.doPlayThenSeek( percent );
Expand All @@ -130,16 +132,16 @@ mw.EmbedPlayerVlc = {
*
* @param {Float} percent Seek to this percent of the stream after playing
*/
doPlayThenSeek:function( percent ) {
doPlayThenSeek: function ( percent ) {
mw.log( 'EmbedPlayerVlc:: doPlayThenSeek' );
var _this = this;
this.play();
var seekCount = 0;
var readyForSeek = function() {
var readyForSeek = function () {
_this.getPlayerElement();
var newState = _this.playerElement.input.state;
// If playing we are ready to do the seek
if ( newState == 3 ) {
if ( newState === 3 ) {
_this.seek( percent );
} else {
// Try to get player for 10 seconds:
Expand All @@ -150,27 +152,27 @@ mw.EmbedPlayerVlc = {
mw.log( 'Error: EmbedPlayerVlc doPlayThenSeek failed' );
}
}
}
};
readyForSeek();
},

/**
* Updates the status time and player state
*/
monitor: function() {
monitor: function () {
this.getPlayerElement();
if ( ! this.playerElement ){
if ( !this.playerElement ) {
return ;
}
// Try to get relay vlc log messages to the console.
try{
try {
if ( this.playerElement.log.messages.count > 0 ) {
// there is one or more messages in the log
var iter = this.playerElement.log.messages.iterator();
while ( iter.hasNext ) {
var msg = iter.next();
var msgtype = msg.type.toString();
if ( ( msg.severity == 1 ) && ( msgtype == "input" ) )
if ( ( msg.severity === 1 ) && ( msgtype === 'input' ) )
{
mw.log( msg.message );
}
Expand All @@ -180,38 +182,34 @@ mw.EmbedPlayerVlc = {
}

var newState = this.playerElement.input.state;
if ( this.prevState != newState ) {
if ( newState == 0 )
{
if ( this.prevState !== newState ) {
if ( newState === 0 ) {
// current media has stopped
this.onStop();
}
else if ( newState == 1 )
{
else if ( newState === 1 ) {
// current media is opening/connecting
this.onOpen();
}
else if ( newState == 2 )
{
else if ( newState === 2 ) {
// current media is buffering data
this.onBuffer();
}
else if ( newState == 3 )
{
else if ( newState === 3 ) {
// current media is now playing
this.onPlay();
}
else if ( this.playerElement.input.state == 4 ) {
else if ( this.playerElement.input.state === 4 ) {
// current media is now paused
this.onPause();
}
this.prevState = newState;
} else if ( newState == 3 ) {
} else if ( newState === 3 ) {
// current media is playing
this.onPlaying();
}
} catch( e ){
mw.log("EmbedPlayerVlc:: Monitor error");
} catch ( e ) {
mw.log( 'EmbedPlayerVlc:: Monitor error' );
}
// Update the status and check timer via universal parent monitor
this.parent_monitor();
Expand All @@ -220,22 +218,22 @@ mw.EmbedPlayerVlc = {
/**
* Events:
*/
onOpen: function() {
onOpen: function () {
// Open is considered equivalent to other players buffer status:
this.layoutBuilder.setStatus( gM('mwe-embedplayer-buffering') );
this.layoutBuilder.setStatus( gM( 'mwe-embedplayer-buffering' ) );
},
onBuffer: function() {
this.layoutBuilder.setStatus( gM('mwe-embedplayer-buffering') );
onBuffer: function () {
this.layoutBuilder.setStatus( gM( 'mwe-embedplayer-buffering' ) );
},
onPlay: function() {
onPlay: function () {
this.onPlaying();
},
onPlaying: function() {
onPlaying: function () {
this.seeking = false;
// For now trust the duration from url over vlc input.length
if ( !this.getDuration() && this.playerElement.input.length > 0 )
{
// mw.log('setting duration to ' + this.playerElement.input.length /1000);
// mw.log( 'setting duration to ' + this.playerElement.input.length /1000 );
this.duration = this.playerElement.input.length / 1000;
}
this.vlcCurrentTime = this.playerElement.input.time / 1000;
Expand All @@ -244,25 +242,25 @@ mw.EmbedPlayerVlc = {
/**
* Get the embed player time
*/
getPlayerElementTime: function(){
getPlayerElementTime: function () {
return this.vlcCurrentTime;
},

onPause: function() {
onPause: function () {
// Update the interface if paused via native plugin
this.parent_pause();
},
onStop: function() {
onStop: function () {
mw.log( 'EmbedPlayerVlc:: onStop' );
if ( !this.seeking ){
if ( !this.seeking ) {
this.onClipDone();
}
},

/**
* Handles play requests
*/
play: function() {
play: function () {
mw.log( 'EmbedPlayerVlc:: play' );
// Update the interface
this.parent_play();
Expand All @@ -272,11 +270,13 @@ mw.EmbedPlayerVlc = {
if ( this.playerElement.log ) {
this.playerElement.log.messages.clear();
}
if ( this.playerElement.playlist && typeof this.playerElement.playlist.play == 'function')
if ( this.playerElement.playlist && typeof this.playerElement.playlist.play === 'function' ) {
this.playerElement.playlist.play();
}

if( typeof this.playerElement.play == 'function' )
if ( typeof this.playerElement.play === 'function' ) {
this.playerElement.play();
}

this.paused = false;

Expand All @@ -289,13 +289,13 @@ mw.EmbedPlayerVlc = {
* Passes the Pause request to the plugin.
* calls parent "pause" to update interface
*/
pause: function() {
pause: function () {
this.parent_pause(); // update the interface if paused via native control
if ( this.getPlayerElement() ) {
try{
try {
this.playerElement.playlist.togglePause();
} catch( e ){
mw.log("EmbedPlayerVlc:: Could not pause video " + e);
} catch ( e ) {
mw.log( 'EmbedPlayerVlc:: Could not pause video ' + e );
}
}
},
Expand All @@ -304,9 +304,9 @@ mw.EmbedPlayerVlc = {
* Mutes the video
* calls parent "toggleMute" to update interface
*/
toggleMute:function() {
toggleMute: function () {
this.parent_toggleMute();
if ( this.getPlayerElement() ){
if ( this.getPlayerElement() ) {
this.playerElement.audio.toggleMute();
}
},
Expand All @@ -325,22 +325,22 @@ mw.EmbedPlayerVlc = {
* Gets the current volume
* @return {Float} percent percent of total volume
*/
getVolumen:function() {
if ( this.getPlayerElement() ){
getVolumen: function () {
if ( this.getPlayerElement() ) {
return this.playerElement.audio.volume / 100;
}
},

/**
* Passes fullscreen request to plugin
*/
fullscreen : function() {
fullscreen: function () {
if ( this.playerElement ) {
if ( this.playerElement.video ){
try{
if ( this.playerElement.video ) {
try {
this.playerElement.video.toggleFullscreen();
} catch ( e ){
mw.log("EmbedPlayerVlc:: toggle fullscreen : possible error: " + e);
} catch ( e ) {
mw.log( 'EmbedPlayerVlc:: toggle fullscreen : possible error: ' + e );
}
}
}
Expand All @@ -349,7 +349,7 @@ mw.EmbedPlayerVlc = {
/**
* Get the embed vlc object
*/
getPlayerElement : function() {
getPlayerElement: function () {
this.playerElement = $( '#' + this.pid )[0];
return this.playerElement;
}
Expand Down
110 changes: 56 additions & 54 deletions modules/EmbedPlayer/resources/mw.EmbedTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
* closely mirrors OggHandler so that its easier to share efforts in this area:
* http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/OggHandler/OggPlayer.js
*/
( function( mw, $ ) { "use strict";
/*globals ActiveXObject*/
( function ( mw, $ ) {
'use strict';

/**
* Setup local players and supported mime types In an ideal world we would query the plugin
Expand Down Expand Up @@ -41,28 +43,27 @@ var imageOverlayPlayer = new mw.MediaPlayer( 'imageOverlay', ['image/jpeg', 'ima
// Generic plugin
//var oggPluginPlayer = new mw.MediaPlayer( 'oggPlugin', ['video/ogg', 'application/ogg'], 'Generic' );


mw.EmbedTypes = {

// MediaPlayers object ( supports methods for quering set of browser players )
mediaPlayers: null,

// Detect flag for completion
detect_done:false,
// Detect flag for completion
detect_done: false,

/**
* Runs the detect method and update the detect_done flag
*
* @constructor
*/
init: function() {
init: function () {
// detect supported types
this.detect();
this.detect_done = true;
},

getMediaPlayers: function(){
if( this.mediaPlayers ){
getMediaPlayers: function () {
if ( this.mediaPlayers ) {
return this.mediaPlayers;
}
this.mediaPlayers = new mw.MediaPlayers();
Expand All @@ -71,7 +72,7 @@ mw.EmbedTypes = {
return this.mediaPlayers;
},

getNativeComponentPlayerVideo: function(){
getNativeComponentPlayerVideo: function () {
return nativeComponentPlayerVideo;
},

Expand All @@ -81,128 +82,129 @@ mw.EmbedTypes = {
* @param {String}
* mimeType Mime type for browser plug-in check
*/
supportedMimeType: function( mimeType ) {
for ( var i =0; i < navigator.plugins.length; i++ ) {
supportedMimeType: function ( mimeType ) {
for ( var i = 0; i < navigator.plugins.length; i++ ) {
var plugin = navigator.plugins[i];
if ( typeof plugin[ mimeType ] != "undefined" ){
if ( typeof plugin[ mimeType ] !== 'undefined' ) {
return true;
}
}
return false;
},
addFlashPlayer: function(){
if( !mw.getConfig( 'EmbedPlayer.DisableHTML5FlashFallback' ) ){
addFlashPlayer: function () {
if ( !mw.getConfig( 'EmbedPlayer.DisableHTML5FlashFallback' ) ) {
this.mediaPlayers.addPlayer( kplayer );
}
},
addSilverlightPlayer:function(){
addSilverlightPlayer:function () {
this.mediaPlayers.addPlayer(splayer);
},

addJavaPlayer: function(){
if( !mw.getConfig( 'EmbedPlayer.DisableJava' ) ){
addJavaPlayer: function () {
if ( !mw.getConfig( 'EmbedPlayer.DisableJava' ) ) {
this.mediaPlayers.addPlayer( cortadoPlayer );
}
},
addNativeComponentPlayer: function(){
addNativeComponentPlayer: function () {
this.mediaPlayers.addPlayer( nativeComponentPlayerVideo );
},
/**
* Detects what plug-ins the client supports
*/
detectPlayers: function() {
mw.log( "EmbedTypes::detectPlayers running detect" );
detectPlayers: function () {
var javaEnabled;
mw.log( 'EmbedTypes::detectPlayers running detect' );

// All players support for playing "images"
this.mediaPlayers.addPlayer( imageOverlayPlayer );

// In Mozilla, navigator.javaEnabled() only tells us about preferences, we need to
// search navigator.mimeTypes to see if it's installed
try{
var javaEnabled = navigator.javaEnabled();
} catch ( e ){
try {
javaEnabled = navigator.javaEnabled();
} catch ( e ) {

}

// flag that is uniq for mobile devices
if ( mw.getConfig( "EmbedPlayer.ForceNativeComponent") ){
if ( mw.getConfig( 'EmbedPlayer.ForceNativeComponent' ) ) {
this.addNativeComponentPlayer();
}

// Opera will switch off javaEnabled in preferences if java can't be
// found. And it doesn't register an application/x-java-applet mime type like
// Mozilla does.

if ( javaEnabled && ( navigator.appName == 'Opera' ) ) {
if ( javaEnabled && ( navigator.appName === 'Opera' ) ) {
this.addJavaPlayer();
}

// Use core mw.supportsFlash check:
// Safari has cross domain issue - Flash external interface doesn't work, so we disable kplayer
if( mw.supportsFlash() ){
if ( mw.supportsFlash() ) {
this.addFlashPlayer();
}

if( mw.supportSilverlight() ) {
if ( mw.supportSilverlight() ) {
this.addSilverlightPlayer();
}

// Java ActiveX
if( mw.isIE() && this.testActiveX( 'JavaWebStart.isInstalled' ) ) {
if ( mw.isIE() && this.testActiveX( 'JavaWebStart.isInstalled' ) ) {
this.addJavaPlayer();
}

// <video> element
if ( ! mw.getConfig('EmbedPlayer.DisableVideoTagSupport' ) // to support testing limited / old browsers
if ( !mw.getConfig('EmbedPlayer.DisableVideoTagSupport' ) // to support testing limited / old browsers
&&
(
typeof HTMLVideoElement == 'object' // Firefox, Safari
typeof HTMLVideoElement === 'object' // Firefox, Safari
||
typeof HTMLVideoElement == 'function' // Opera
typeof HTMLVideoElement === 'function' // Opera
)
){
) {
// Test what codecs the native player supports:
try {
var dummyvid = document.createElement( "video" );
if( dummyvid.canPlayType ) {
var dummyvid = document.createElement( 'video' );
if ( dummyvid.canPlayType ) {
// Add the webm player
if( dummyvid.canPlayType('video/webm; codecs="vp8, vorbis"')
if ( dummyvid.canPlayType( 'video/webm; codecs="vp8, vorbis"' )
// &&
// ! mw.isMobileChrome() // current versions of mobile chrome should support webm
// left as a comment in cases we need to re disable
// ! mw.isMobileChrome()// current versions of mobile chrome should support webm
// left as a comment in cases we need to re disable
&&
! mw.isAndroid40() // android 4 'Internet browser' lies as well.
){
!mw.isAndroid40() // android 4 'Internet browser' lies as well.
) {
this.mediaPlayers.addPlayer( webmNativePlayer );
}

// Test for MP3:
if ( this.supportedMimeType('audio/mpeg') || dummyvid.canPlayType('audio/mpeg; codecs="mp3"') ) {
if ( this.supportedMimeType( 'audio/mpeg' ) || dummyvid.canPlayType( 'audio/mpeg; codecs="mp3"' ) ) {
this.mediaPlayers.addPlayer( mp3NativePlayer );
}

// Test for h264:
if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) {
if ( dummyvid.canPlayType( 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) {
this.mediaPlayers.addPlayer( h264NativePlayer );
// Check for vdn player support ( apple adaptive ) or vdn canPlayType != '' ( ie maybe/probably )
if( dummyvid.canPlayType( 'application/vnd.apple.mpegurl; codecs="avc1.42E01E"' ) || mw.isAndroid4andUp() ){
if ( dummyvid.canPlayType( 'application/vnd.apple.mpegurl; codecs="avc1.42E01E"' ) || mw.isAndroid4andUp() ) {
// Android 3x lies about HLS support ( only add if not Android 3.x )
if( navigator.userAgent.indexOf( 'Android 3.') == -1 ){
if ( navigator.userAgent.indexOf( 'Android 3.') === -1 ) {
this.mediaPlayers.addPlayer( appleVdnPlayer );
}
}
}
// For now if Android assume we support h264Native (FIXME
// test on real devices )
if ( mw.isAndroid2() ){
if ( mw.isAndroid2() ) {
this.mediaPlayers.addPlayer( h264NativePlayer );
}

// Test for ogg
if ( dummyvid.canPlayType( 'video/ogg; codecs="theora,vorbis"' ) ) {
this.mediaPlayers.addPlayer( oggNativePlayer );
// older versions of safari do not support canPlayType,
// but xiph qt registers mimetype via quicktime plugin
// but xiph qt registers mimetype via quicktime plugin
} else if ( this.supportedMimeType( 'video/ogg' ) ) {
this.mediaPlayers.addPlayer( oggNativePlayer );
}
Expand All @@ -212,7 +214,7 @@ mw.EmbedTypes = {
}
}

// "navigator" plugins
// "navigator" plugins
if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
for ( var i = 0; i < navigator.mimeTypes.length; i++ ) {
var type = navigator.mimeTypes[i].type;
Expand All @@ -231,17 +233,17 @@ mw.EmbedTypes = {
// continue;
//}

if ( type == 'application/x-java-applet' ) {
if ( type === 'application/x-java-applet' ) {
this.addJavaPlayer();
continue;
}

if ( (type == 'video/mpeg' || type == 'video/x-msvideo') ){
if ( (type === 'video/mpeg' || type === 'video/x-msvideo') ) {
//pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
//this.mediaPlayers.addPlayer( vlcMozillaPlayer );
}

if ( type == 'application/ogg' ) {
if ( type === 'application/ogg' ) {
//if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
//this.mediaPlayers.addPlayer( vlcMozillaPlayer );
//else if ( pluginName.indexOf( 'QuickTime' ) > -1 )
Expand All @@ -255,8 +257,8 @@ mw.EmbedTypes = {
}

// Allow extensions to detect and add their own "players"
mw.log("EmbedPlayer::trigger:EmbedPlayerUpdateMediaPlayers");
$( mw ).trigger( 'EmbedPlayerUpdateMediaPlayers' , this.mediaPlayers );
mw.log( 'EmbedPlayer::trigger:EmbedPlayerUpdateMediaPlayers' );
$( mw ).trigger( 'EmbedPlayerUpdateMediaPlayers', this.mediaPlayers );

},

Expand All @@ -266,8 +268,8 @@ mw.EmbedTypes = {
* @param {String}
* name Name of ActiveXObject to look for
*/
testActiveX : function ( name ) {
mw.log("EmbedPlayer::detect: test testActiveX: " + name);
testActiveX: function ( name ) {
mw.log( 'EmbedPlayer::detect: test testActiveX: ' + name);
var hasObj = true;
try {
// No IE, not a class called "name", it's a variable
Expand All @@ -278,10 +280,10 @@ mw.EmbedTypes = {
return hasObj;
},

getKplayer : function () {
getKplayer: function () {
return kplayer;
},
getSilverlightPlayer :function(){
getSilverlightPlayer: function () {
return splayer;
}
};
Expand Down
302 changes: 151 additions & 151 deletions modules/EmbedPlayer/resources/mw.FullScreenManager.js

Large diffs are not rendered by default.

297 changes: 149 additions & 148 deletions modules/EmbedPlayer/resources/mw.MediaElement.js

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions modules/EmbedPlayer/resources/mw.MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
* library external script containing the plugin interface code.
* @constructor
*/
( function( mw, $ ) { "use strict";
/*globals gM*/
( function ( mw ) {
'use strict';

mw.MediaPlayer = function( id, supportedTypes, library )
{
mw.MediaPlayer = function ( id, supportedTypes, library ) {
this.id = id;
this.supportedTypes = supportedTypes;
this.library = library;
this.loaded = false;
this.loading_callbacks = new Array();
this.loading_callbacks = [];
return this;
};
mw.MediaPlayer.prototype = {
Expand All @@ -41,18 +42,19 @@ mw.MediaPlayer.prototype = {
* @return {Boolean} true if mime type is supported false if mime type is
* unsupported
*/
supportsMIMEType: function( type ) {
supportsMIMEType: function ( type ) {
for ( var i = 0; i < this.supportedTypes.length; i++ ) {
if ( this.supportedTypes[i] == type )
if ( this.supportedTypes[i] === type ) {
return true;
}
}
return false;
},

/**
* Get the "name" of the player from a predictable msg key
*/
getName: function() {
getName: function () {
return gM( 'mwe-embedplayer-ogg-player-' + this.id );
},

Expand All @@ -63,16 +65,16 @@ mw.MediaPlayer.prototype = {
* @param {Function}
* callback Function to be called once player library is loaded.
*/
load: function( callback ) {
load: function ( callback ) {
// Load player library ( upper case the first letter of the library )
mw.load( [
'mw.EmbedPlayer' + this.library.substr(0,1).toUpperCase() + this.library.substr(1)
], function() {
if( callback ){
'mw.EmbedPlayer' + this.library.substr( 0, 1 ).toUpperCase() + this.library.substr( 1 )
], function () {
if ( callback ) {
callback();
}
} );
}
};

} )( mediaWiki, jQuery );
} )( mediaWiki );
80 changes: 41 additions & 39 deletions modules/EmbedPlayer/resources/mw.MediaPlayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,29 @@
*
* @constructor
*/
( function( mw, $ ) { "use strict";
( function ( mw, $ ) {
'use strict';

mw.MediaPlayers = function(){
mw.MediaPlayers = function () {
this.init();
};

mw.MediaPlayers.prototype = {
// The list of players supported
players : null,
players: null,

// Store per mime-type preferences for players
preference : { },
preference: {},

// Stores the default set of players for a given mime type
defaultPlayers : { },
defaultPlayers: {},

/**
* Initialization function sets the default order for players for a given
* mime type
*/
init: function() {
this.players = new Array();
init: function () {
this.players = [];
this.loadPreferences();

// Set up default players order for each library type
Expand All @@ -41,8 +42,8 @@ mw.MediaPlayers.prototype = {
this.defaultPlayers['video/webm'] = ['Native', 'Vlc'];
this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 'Java', 'Generic'];
this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'Java' ];
this.defaultPlayers['audio/mpeg']= ['Native', 'Kplayer'];
this.defaultPlayers['audio/mp3']= ['Native', 'Kplayer'];
this.defaultPlayers['audio/mpeg'] = ['Native', 'Kplayer'];
this.defaultPlayers['audio/mp3'] = ['Native', 'Kplayer'];
this.defaultPlayers['video/mpeg'] = ['Vlc'];
this.defaultPlayers['video/x-msvideo'] = ['Vlc'];
this.defaultPlayers['video/multicast'] = ['Silverlight'];
Expand All @@ -54,8 +55,8 @@ mw.MediaPlayers.prototype = {
this.defaultPlayers['image/jpeg'] = ['ImageOverlay'];
this.defaultPlayers['image/png'] = ['ImageOverlay'];

if ( mw.getConfig("LeadWithHLSOnFlash") ) {
this.defaultPlayers['application/vnd.apple.mpegurl'].push('Kplayer');
if ( mw.getConfig( 'LeadWithHLSOnFlash' ) ) {
this.defaultPlayers['application/vnd.apple.mpegurl'].push( 'Kplayer' );
}

},
Expand All @@ -66,9 +67,9 @@ mw.MediaPlayers.prototype = {
* @param {Object}
* player Player object to be added
*/
addPlayer: function( player ) {
addPlayer: function ( player ) {
for ( var i = 0; i < this.players.length; i++ ) {
if ( this.players[i].id == player.id ) {
if ( this.players[i].id === player.id ) {
// Player already found
return ;
}
Expand All @@ -80,17 +81,17 @@ mw.MediaPlayers.prototype = {
/**
* Checks if a player is supported by id
*/
isSupportedPlayer: function( playerId ){
for( var i=0; i < this.players.length; i++ ){
if( this.players[i].id == playerId ){
isSupportedPlayer: function ( playerId ) {
for ( var i = 0; i < this.players.length; i++ ) {
if ( this.players[i].id === playerId ) {
return true;
}
}
return false;
},
getPlayerById: function(playerId){
for( var i=0; i < this.players.length; i++ ){
if( this.players[i].id.toLowerCase() == playerId.toLowerCase() ){
getPlayerById: function ( playerId ) {
for ( var i = 0; i < this.players.length; i++ ) {
if ( this.players[i].id.toLowerCase() === playerId.toLowerCase() ) {
return this.players[i];
}
}
Expand All @@ -103,14 +104,14 @@ mw.MediaPlayers.prototype = {
* mimeType Mime type of player set
* @return {Array} Array of players that support a the requested mime type
*/
getMIMETypePlayers: function( mimeType ) {
var mimePlayers = new Array();
getMIMETypePlayers: function ( mimeType ) {
var mimePlayers = [];
var _this = this;
if ( this.defaultPlayers[mimeType] ) {
$.each( this.defaultPlayers[ mimeType ], function( d, lib ) {
$.each( this.defaultPlayers[ mimeType ], function ( d /*, lib */ ) {
var library = _this.defaultPlayers[ mimeType ][ d ];
for ( var i = 0; i < _this.players.length; i++ ) {
if ( _this.players[i].library == library && _this.players[i].supportsMIMEType( mimeType ) ) {
if ( _this.players[i].library === library && _this.players[i].supportsMIMEType( mimeType ) ) {
mimePlayers.push( _this.players[i] );
}
}
Expand All @@ -126,26 +127,27 @@ mw.MediaPlayers.prototype = {
* mimeType Mime type of the requested player
* @return Player for mime type null if no player found
*/
defaultPlayer : function( mimeType ) {
defaultPlayer: function ( mimeType ) {
// mw.log( "get defaultPlayer for " + mimeType );
if ( mw.getConfig( 'EmbedPlayer.ForceNativeComponent' )) {
if ( mw.getConfig( 'EmbedPlayer.ForceNativeComponent' ) ) {
return mw.EmbedTypes.getNativeComponentPlayerVideo();
}

if ( mw.getConfig( 'EmbedPlayer.ForceKPlayer' ) && this.isSupportedPlayer( 'kplayer' ) ) {
return mw.EmbedTypes.getKplayer();
}
if (mw.getConfig( 'EmbedPlayer.ForceSPlayer') && this.isSupportedPlayer('splayer')) {
if ( mw.getConfig( 'EmbedPlayer.ForceSPlayer' ) && this.isSupportedPlayer( 'splayer' ) ) {
return mw.EmbedTypes.getSilverlightPlayer();
}

var mimePlayers = this.getMIMETypePlayers( mimeType );

if ( mimePlayers.length > 0 ){
if ( mimePlayers.length > 0 ) {
// Check for prior preference for this mime type
for ( var i = 0; i < mimePlayers.length; i++ ) {
if ( mimePlayers[i].id == this.preference[mimeType] )
if ( mimePlayers[i].id === this.preference[mimeType] ) {
return mimePlayers[i];
}
}
// Otherwise just return the first compatible player
// (it will be chosen according to the defaultPlayers list
Expand All @@ -161,18 +163,18 @@ mw.MediaPlayers.prototype = {
* @param {String}
* mimeFormat Prefered format
*/
setFormatPreference : function ( mimeFormat ) {
this.preference['formatPreference'] = mimeFormat;
$.cookie( 'EmbedPlayer.Preference', JSON.stringify( this.preference) );
setFormatPreference: function ( mimeFormat ) {
this.preference.formatPreference = mimeFormat;
$.cookie( 'EmbedPlayer.Preference', JSON.stringify( this.preference ) );
},

/**
* Loads the user preference settings from a cookie
*/
loadPreferences : function ( ) {
loadPreferences: function ( ) {
this.preference = { };
// See if we have a cookie set to a clientSupported type:
if( $.cookie( 'EmbedPlayer.Preference' ) ) {
if ( $.cookie( 'EmbedPlayer.Preference' ) ) {
this.preference = JSON.parse( $.cookie( 'EmbedPlayer.Preference' ) );
}
},
Expand All @@ -185,10 +187,10 @@ mw.MediaPlayers.prototype = {
* @param {String}
* mimeType Mime type for the associated player stream
*/
setPlayerPreference : function( playerId, mimeType ) {
setPlayerPreference: function ( playerId, mimeType ) {
var selectedPlayer = null;
for ( var i = 0; i < this.players.length; i++ ) {
if ( this.players[i].id == playerId ) {
if ( this.players[i].id === playerId ) {
selectedPlayer = this.players[i];
mw.log( 'EmbedPlayer::setPlayerPreference: choosing ' + playerId + ' for ' + mimeType );
this.preference[ mimeType ] = playerId;
Expand All @@ -198,16 +200,16 @@ mw.MediaPlayers.prototype = {
}
// Update All the player instances on the page
if ( selectedPlayer ) {
$('.mwEmbedPlayer').each(function(inx, playerTarget ){
$( '.mwEmbedPlayer' ).each( function ( inx, playerTarget ) {
var embedPlayer = $( playerTarget ).get( 0 );
if ( embedPlayer.mediaElement.selectedSource
&& ( embedPlayer.mediaElement.selectedSource.mimeType == mimeType ) )
&& ( embedPlayer.mediaElement.selectedSource.mimeType === mimeType ) )
{
embedPlayer.selectPlayer( selectedPlayer );
}
});
} );
}
}
};

} )( mediaWiki, jQuery );
} )( mediaWiki, jQuery );
199 changes: 88 additions & 111 deletions modules/EmbedPlayer/resources/mw.MediaSource.js

Large diffs are not rendered by default.

840 changes: 419 additions & 421 deletions modules/EmbedPlayer/resources/mw.PlayerLayoutBuilder.js

Large diffs are not rendered by default.

44 changes: 23 additions & 21 deletions modules/EmbedPlayer/resources/mw.PluginManager.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
( function( mw, $ ) {
( function ( mw ) {

// exit if already defined
if( mw.PluginManager ) return ;
if ( mw.PluginManager ) {
return ;
}

mw.PluginManager = {

Expand All @@ -11,51 +13,51 @@ mw.PluginManager = {
initialisedPlugins: 0,

// Register a new Plugin
define: function( pluginName, pluginClass ){
if( this.registerdPlugins[ pluginName ] ) {
mw.log('PluginManager::register: Plugin "' + pluginName + '" already registered.');
define: function ( pluginName, pluginClass ) {
if ( this.registerdPlugins[ pluginName ] ) {
mw.log( 'PluginManager::register: Plugin "' + pluginName + '" already registered.' );
return;
}

this.registerdPlugins[ pluginName ] = pluginClass;
this.totalPlugins++;
},
getClass: function( pluginName ) {
if( !this.registerdPlugins[ pluginName ] ) {
mw.log('PluginManager::getClass: Plugin "' + pluginName + '" not registered.');
getClass: function ( pluginName ) {
if ( !this.registerdPlugins[ pluginName ] ) {
mw.log( 'PluginManager::getClass: Plugin "' + pluginName + '" not registered.' );
return false;
}
return this.registerdPlugins[ pluginName ];
},
make: function( pluginName, embedPlayer, callback ) {
var pluginClass = this.getClass( pluginName );
return ( pluginClass ) ? new pluginClass( embedPlayer, callback, pluginName ) : false;
make: function ( pluginName, embedPlayer, callback ) {
var PluginClass = this.getClass( pluginName );
return ( PluginClass ) ? new PluginClass( embedPlayer, callback, pluginName ) : false;
},
registerLoader: function( pluginName ){
if( !this.registerdPlugins[ pluginName ] ) {
mw.log('PluginManager::init: Plugin "' + pluginName + '" not registered.');
registerLoader: function ( pluginName ) {
if ( !this.registerdPlugins[ pluginName ] ) {
mw.log( 'PluginManager::init: Plugin "' + pluginName + '" not registered.' );
return;
}
var _this = this;
mw.addKalturaPlugin( pluginName, function( embedPlayer, callback ){
mw.addKalturaPlugin( pluginName, function ( embedPlayer, callback ) {
// Check if plugin initialise
if( embedPlayer.plugins[ pluginName ] ) {
if ( embedPlayer.plugins[ pluginName ] ) {
//mw.log('PluginManager::init: Plugin "' + pluginName + '" already initialised.');
callback();
return;
}
embedPlayer.plugins[ pluginName ] = _this.make( pluginName, embedPlayer, callback );
_this.initialisedPlugins++;
if( _this.totalPlugins === _this.initialisedPlugins ){
embedPlayer.triggerHelper( 'pluginsReady' , embedPlayer.plugins );
if ( _this.totalPlugins === _this.initialisedPlugins ) {
embedPlayer.triggerHelper( 'pluginsReady', embedPlayer.plugins );
}
});
} );
return this;
},
add: function( pluginName, pluginClass ) {
add: function ( pluginName, pluginClass ) {
this.define( pluginName, pluginClass );
this.registerLoader( pluginName );
}
};

} )( mediaWiki, jQuery );
} )( mediaWiki );
170 changes: 84 additions & 86 deletions modules/EmbedPlayer/resources/mw.processEmbedPlayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,31 @@
*
*/

( function( mw, $ ) { "use strict";
( function ( mw, $ ) {
'use strict';

mw.processEmbedPlayers = function( playerSelect, callback ) {
mw.log( 'processEmbedPlayers:: playerSelector: '+ playerSelect);
mw.processEmbedPlayers = function ( playerSelect, callback ) {
mw.log( 'processEmbedPlayers:: playerSelector: ' + playerSelect);
// trigger the start of ProcessEmbedPlayers
$( mw ).trigger('ProcessEmbedPlayers', [playerSelect] );
$( mw ).trigger('ProcessEmbedPlayers', [playerSelect] );
// The player id list container
var playerIdList = [];

// Check if the selected player set is ready if ready issue the parent callback
var areSelectedPlayersReady = function(){
var areSelectedPlayersReady = function () {
var playersLoaded = true;
$.each( playerIdList, function(inx, playerId){
if( ! $( '#' + playerId )[0].playerReadyFlag ){
$.each( playerIdList, function ( inx, playerId ) {
if ( !$( '#' + playerId )[0].playerReadyFlag ) {
playersLoaded = false;
return false;
}
})
if( playersLoaded ){
if( callback ){
} );
if ( playersLoaded ) {
if ( callback ) {
callback();
}
}
}
};

/**
* Adds a player element for the embedPlayer to rewrite
Expand All @@ -50,13 +51,12 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
* @param {Element}
* playerElement DOM element to be swapped
*/
var addPlayerElement = function( playerElement ) {
var _this = this;
var addPlayerElement = function ( playerElement ) {
mw.log('EmbedPlayer:: addElement:: ' + playerElement.id );

// Be sure to "stop" the target ( Firefox 3x keeps playing
// the video even though its been removed from the DOM )
if( playerElement.pause ){
if ( playerElement.pause ) {
playerElement.pause();
}

Expand All @@ -78,20 +78,20 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
// Local callback to runPlayer swap once playerElement has metadata
var runPlayerSwap = function () {
// Don't run player swap twice
if( ranPlayerSwapFlag ){
if ( ranPlayerSwapFlag ) {
return ;
}
ranPlayerSwapFlag = true;
mw.log( "processEmbedPlayers::runPlayerSwap::" + $( playerElement ).attr('id') );
mw.log( 'processEmbedPlayers::runPlayerSwap::' + $( playerElement ).attr( 'id' ) );

var playerInterface = new mw.EmbedPlayer( playerElement );
var inDomPlayer = swapEmbedPlayerElement( playerElement, playerInterface );
// Trigger the EmbedPlayerNewPlayer for embedPlayer interface
mw.log("processEmbedPlayers::trigger:: EmbedPlayerNewPlayer " + inDomPlayer.id );
mw.log( 'processEmbedPlayers::trigger:: EmbedPlayerNewPlayer ' + inDomPlayer.id );

// Allow plugins to add bindings to the inDomPlayer
$( mw ).trigger ( 'EmbedPlayerNewPlayer', inDomPlayer );

// Retain support for legacy new embed player trigger name:
$( mw ).trigger ( 'newEmbedPlayerEvent', inDomPlayer );

Expand All @@ -104,21 +104,21 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
// this is needed in cases where you need to do an asynchronous
// player interface setup. like iframes asynchronous announcing its ready for
// bindings that can affect player setup.
mw.log("EmbedPlayer::addPlayerElement :trigger startPlayerBuildOut:" + inDomPlayer.id );
$( '#' + inDomPlayer.id ).triggerQueueCallback( 'startPlayerBuildOut', function(){
mw.log( 'EmbedPlayer::addPlayerElement :trigger startPlayerBuildOut: ' + inDomPlayer.id );
$( '#' + inDomPlayer.id ).triggerQueueCallback( 'startPlayerBuildOut', function () {
// Issue the checkPlayerSources call to the new player
// interface: make sure to use the element that is in the DOM:
inDomPlayer.checkPlayerSources();
});
};

if( waitForMeta && mw.getConfig('EmbedPlayer.WaitForMeta' ) ) {
if ( waitForMeta && mw.getConfig('EmbedPlayer.WaitForMeta' ) ) {
mw.log('processEmbedPlayers::WaitForMeta ( video missing height (' +
$( playerElement ).attr('height') + '), width (' +
$( playerElement ).attr('width') + ') or duration: ' +
$( playerElement ).attr('duration')
$( playerElement ).attr( 'height' ) + '), width (' +
$( playerElement ).attr( 'width' ) + ') or duration: ' +
$( playerElement ).attr( 'duration' )
);
$( playerElement ).bind( "loadedmetadata", runPlayerSwap );
$( playerElement ).bind( 'loadedmetadata', runPlayerSwap );

// Time-out of 5 seconds ( maybe still playable but no timely metadata )
setTimeout( runPlayerSwap, 5000 );
Expand All @@ -135,39 +135,36 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
* @return true if the size is "likely" to be updated by waiting for metadata
* false if the size has been set via an attribute or is already loaded
*/
var waitForMetaCheck = function( playerElement ){
var waitForMetaCheck = function ( playerElement ) {
var waitForMeta = false;

// Don't wait for metadata for non html5 media elements
if( !playerElement ){
if ( !playerElement ) {
return false;
}
if( !playerElement.tagName || ( playerElement.tagName.toLowerCase() != 'audio' && playerElement.tagName.toLowerCase() != 'video' ) ){
if ( !playerElement.tagName || ( playerElement.tagName.toLowerCase() !== 'audio' && playerElement.tagName.toLowerCase() !== 'video' ) ) {
return false;
}
// If we don't have a native player don't wait for metadata
if( !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'oggNative') &&
if ( !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'oggNative') &&
!mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'webmNative') &&
!mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'h264Native' ) &&
!mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'appleVdnPlayer' ) )
{
return false;
}


var width = $( playerElement ).css( 'width' );
var height = $( playerElement ).css( 'height' );
// Css video defaults ( firefox )
if( $( playerElement ).css( 'width' ) == '300px' &&
$( playerElement ).css( 'height' ) == '150px'
){
if ( $( playerElement ).css( 'width' ) === '300px' &&
$( playerElement ).css( 'height' ) === '150px'
) {
waitForMeta = true;
} else {
// Check if we should wait for duration:
if( $( playerElement ).attr( 'duration') ||
$( playerElement ).attr( 'durationHint') ||
$( playerElement ).attr('data-durationhint')
){
if ( $( playerElement ).attr( 'duration' ) ||
$( playerElement ).attr( 'durationHint' ) ||
$( playerElement ).attr( 'data-durationhint' )
) {
// height, width and duration set; do not wait for meta data:
return false;
} else {
Expand All @@ -176,29 +173,29 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
}

// Firefox ~ sometimes~ gives -1 for unloaded media
if ( $(playerElement).attr( 'width' ) == -1 || $(playerElement).attr( 'height' ) == -1 ) {
if ( $(playerElement).attr( 'width' ) === -1 || $(playerElement).attr( 'height' ) === -1 ) {
waitForMeta = true;
}

// Google Chrome / safari gives 0 width height for unloaded media
if( $(playerElement).attr( 'width' ) === 0 ||
if ( $(playerElement).attr( 'width' ) === 0 ||
$(playerElement).attr( 'height' ) === 0
) {
waitForMeta = true;
}

// Firefox default width height is ~sometimes~ 150 / 300
if( playerElement.height == 150 && playerElement.width == 300 ){
if ( playerElement.height === 150 && playerElement.width === 300 ) {
waitForMeta = true;
}

// Make sure we have a src attribute or source child
// ( i.e not a video tag to be dynamically populated or looked up from
// xml resource description )
if( waitForMeta &&
if ( waitForMeta &&
(
$( playerElement ).attr('src') ||
$( playerElement ).find("source[src]").length !== 0
$( playerElement ).attr( 'src' ) ||
$( playerElement ).find( 'source[src]' ).length !== 0
)
) {
// Detect src type ( if no type set )
Expand All @@ -219,48 +216,48 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
* @param {Object}
* playerInterface Interface to swap into the target element
*/
var swapEmbedPlayerElement = function( targetElement, playerInterface ) {
var swapEmbedPlayerElement = function ( targetElement, playerInterface ) {
mw.log( 'processEmbedPlayers::swapEmbedPlayerElement: ' + targetElement.id );
// Create a new element to swap the player interface into
var swapPlayerElement = document.createElement('div');
var swapPlayerElement = document.createElement( 'div' );

// Add a class that identifies all embedPlayers:
$( swapPlayerElement ).addClass( 'mwEmbedPlayer' );

// Get properties / methods from playerInterface:
for ( var method in playerInterface ) {
if ( method != 'readyState' ) { // readyState crashes IE ( don't include )
if ( method !== 'readyState' ) { // readyState crashes IE ( don't include )
swapPlayerElement[ method ] = playerInterface[ method ];
}
}
// set width and height attr:
if( $( targetElement ).attr('width') ){
$( swapPlayerElement ).css('width', $( targetElement ).attr('width') );
if ( $( targetElement ).attr( 'width' ) ) {
$( swapPlayerElement ).css( 'width', $( targetElement ).attr('width') );
}
if( $( targetElement ).attr('height') ){
$( swapPlayerElement ).css('height', $( targetElement ).attr('height') );
if ( $( targetElement ).attr( 'height' ) ) {
$( swapPlayerElement ).css( 'height', $( targetElement ).attr('height') );
}
// copy over css text:
swapPlayerElement.style.cssText += targetElement.style.cssText;
// player element must always be relative to host video and image layout
swapPlayerElement.style.position = 'relative';

// Copy any data attributes from the target player element over to the swapPlayerElement
var dataAttributes = mw.getConfig("EmbedPlayer.DataAttributes");
if( dataAttributes ){
$.each( dataAttributes, function( attrName, na ){
if( $( targetElement ).data( attrName ) ){
var dataAttributes = mw.getConfig( 'EmbedPlayer.DataAttributes' );
if ( dataAttributes ) {
$.each( dataAttributes, function ( attrName/*, na*/ ) {
if ( $( targetElement ).data( attrName ) ) {
$( swapPlayerElement ).data( attrName, $( targetElement ).data( attrName ) );
}
});
}
// Check for Persistent native player ( should keep the video embed around )
if( ( playerInterface.isPersistentNativePlayer() && !mw.getConfig( 'EmbedPlayer.DisableVideoTagSupport' ) )
if ( ( playerInterface.isPersistentNativePlayer() && !mw.getConfig( 'EmbedPlayer.DisableVideoTagSupport' ) )
||
// Also check for native controls on a video or audio tag
( playerInterface.useNativePlayerControls()
&&
( targetElement.nodeName == 'video' || targetElement.nodeName == 'audio' )
( targetElement.nodeName === 'video' || targetElement.nodeName === 'audio' )
)
) {

Expand All @@ -277,27 +274,28 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
}

// If we don't already have a loadSpiner add one:
if( $('#loadingSpinner_' + playerInterface.id ).length == 0 ){
if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) {
var $spinner = $( targetElement )
if ( $( '#loadingSpinner_' + playerInterface.id ).length === 0 ) {
var $spinner;
if ( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) {
$spinner = $( targetElement )
.getAbsoluteOverlaySpinner();
}else{
var $spinner = $( swapPlayerElement ).getAbsoluteOverlaySpinner();
} else {
$spinner = $( swapPlayerElement ).getAbsoluteOverlaySpinner();
}
$spinner.attr('id', 'loadingSpinner_' + playerInterface.id );
$spinner.attr( 'id', 'loadingSpinner_' + playerInterface.id );
}
return swapPlayerElement;
};

// Add a loader for <div /> embed player rewrites:
$( playerSelect ).each( function( index, playerElement) {
$( playerSelect ).each( function ( index, playerElement) {

// Add the player Id to the playerIdList
playerIdList.push( $( playerElement ).attr( "id") );
playerIdList.push( $( playerElement ).attr( 'id' ) );

// If we are dynamically embedding on a "div" check if we can
// add a poster image behind the loader:
if( playerElement.nodeName.toLowerCase() == 'div'
if ( playerElement.nodeName.toLowerCase() === 'div'
&&
$(playerElement).attr( 'poster' ) )
{
Expand All @@ -306,47 +304,47 @@ mw.processEmbedPlayers = function( playerSelect, callback ) {
// Set image size:
var width = $( playerElement ).width();
var height = $( playerElement ).height();
if( !width ){
var width = '100%';
if ( !width ) {
width = '100%';
}
if( !height ){
var height = '100%';
if ( !height ) {
height = '100%';
}

mw.log('EmbedPlayer:: set loading background: ' + posterSrc);
mw.log( 'EmbedPlayer:: set loading background: ' + posterSrc );
$( playerElement ).append(
$( '<img />' )
.attr( 'src', posterSrc)
.css({
'position' : 'absolute',
'width' : width,
'height' : height
})
$( '<img>' )
.attr( 'src', posterSrc )
.css( {
'position': 'absolute',
'width': width,
'height': height
} )
);
}
});
} );

// Make sure we have user preference setup for setting preferences on video selection
var addedPlayersFlag = false;
//mw.log("processEmbedPlayers:: Do: " + $( playerSelect ).length + ' players ');
// Add each selected element to the player manager:
$( playerSelect ).each( function( index, playerElement) {
$( playerSelect ).each( function ( index, playerElement ) {
// Make sure the video tag was not generated by our library:
if( $( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){
$( '#loadingSpinner_' + $( playerElement ).attr('id') ).remove();
if ( $( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ) {
$( '#loadingSpinner_' + $( playerElement ).attr( 'id' ) ).remove();
mw.log( 'processEmbedPlayers::$.embedPlayer skip embedPlayer gennerated video: ' + playerElement );
} else {
addedPlayersFlag = true;
// Add the player
addPlayerElement( playerElement );
}
});
if( !addedPlayersFlag ){
if ( !addedPlayersFlag ) {
// Run the callback directly if no players were added
if( callback ){
if ( callback ) {
callback();
}
}
};

})( window.mw, jQuery );
} )( mediaWiki, jQuery );
21 changes: 11 additions & 10 deletions modules/EmbedPlayer/resources/playerElement/mw.PlayerElement.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
( function( mw, $ ) {"use strict";
/*globals Class*/
( function ( mw ) {
'use strict';

// Class defined in resources/class/class.js
mw.PlayerElement = Class.extend({
Expand All @@ -9,27 +11,26 @@
* @param holder player holder
* @param playerId element ID
*/
init: function( containerId , playerId ){
init: function ( /*containerId , playerId*/ ) {
mw.log('PlayerElement::Error: function init should be implemented by playerElement interface ');
},
getElement: function() {
getElement: function () {
return this.element;
},
play: function(){
play: function () {
mw.log('PlayerElement::Error: function play should be implemented by playerElement interface ');
},
pause: function(){
pause: function () {
mw.log('PlayerElement::Error: function pause should be implemented by playerElement interface ');
},
seek: function( val ){
seek: function ( /*val*/ ) {
mw.log('PlayerElement::Error: function seek should be implemented by playerElement interface ');
},
load: function(){
load: function () {
mw.log('PlayerElement::Error: function load should be implemented by playerElement interface ');
},
changeVolume: function( val ){
changeVolume: function ( /*val*/ ) {
mw.log('PlayerElement::Error: function changeVolume should be implemented by playerElement interface ');
}
});

} )( window.mw, window.jQuery );
} )( mediaWiki );
109 changes: 55 additions & 54 deletions modules/EmbedPlayer/resources/playerElement/mw.PlayerElementFlash.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
( function( mw, $ ) {"use strict";
( function ( mw, $ ) {
'use strict';

// Class defined in resources/class/class.js
mw.PlayerElementFlash = mw.PlayerElement.extend({
mw.PlayerElementFlash = mw.PlayerElement.extend( {
jsReadyFunName: 'elementJsReadyFunc',
playerElement: null,
currentTime: 0,
Expand All @@ -26,19 +27,19 @@
* @param readyCallback to run when player is ready
* @returns {*}
*/
init: function( containerId , playerId , elementFlashvars, target, readyCallback ){
init: function ( containerId, playerId, elementFlashvars, target, readyCallback ) {
var _this = this;
this.element = this;
this.element = this;
this.id = playerId;
this.targetObj = target;

var flashvars = {};
flashvars.jsCallBackReadyFunc = this.jsReadyFunName;
flashvars.externalInterfaceDisabled = "false";
flashvars.externalInterfaceDisabled = 'false';
flashvars.disableOnScreenClick = true;

//if debug mode
if( mw.getConfig( 'debug', true ) ){
if ( mw.getConfig( 'debug', true ) ) {
flashvars.debugMode = 'true';
}

Expand All @@ -49,14 +50,14 @@
var mwEmbedPath = mw.getMwEmbedPath();
//replace protocol with page protocol
if ( window.location.protocol ) {
mwEmbedPath = window.location.protocol + mwEmbedPath.substring( mwEmbedPath.indexOf(":") + 1);
mwEmbedPath = window.location.protocol + mwEmbedPath.substring( mwEmbedPath.indexOf( ':' ) + 1 );
}

var kdpPath = mwEmbedPath + 'modules/EmbedPlayer/binPlayers/kaltura-player/kdp3.swf';
// var kdpPath = "http://localhost/chromeless-kdp/KDP3/bin-debug/kdp3.swf";

window[this.jsReadyFunName] = function( playerId ){
if (!_this.initialized) {
window[this.jsReadyFunName] = function ( playerId ) {
if ( !_this.initialized ) {
_this.initialized = true;
// We wrap everything in setTimeout to avoid Firefox race condition with empty cache
setTimeout( function () {
Expand All @@ -78,7 +79,7 @@
'mute': 'onMute',
'unmute': 'onUnMute',
'volumeChanged': 'onVolumeChanged',
'mediaError' : 'onMediaError'
'mediaError': 'onMediaError'
};

$.each( bindEventMap, function ( bindName, localMethod ) {
Expand All @@ -102,68 +103,68 @@
// attributes and params:
flashembed( containerId,
{
id : playerId,
src : kdpPath,
bgcolor : "#000000",
allowNetworking : "all",
version : [10,0],
wmode : "transparent"
id: playerId,
src: kdpPath,
bgcolor: '#000000',
allowNetworking: 'all',
version: [10, 0],
wmode: 'transparent'
},
flashvars
);

return this;
},
play: function(){
play: function () {
this.sendNotification( 'doPlay' );
},
pause: function(){
pause: function () {
this.sendNotification( 'doPause' );
},
seek: function( val ){
seek: function ( val ) {
this.sendNotification( 'doSeek', val );
$( this ).trigger( 'seeking' );
},
load: function(){
this.sendNotification('changeMedia', {'entryUrl': this.src}) ;
load: function () {
this.sendNotification( 'changeMedia', { 'entryUrl': this.src } ) ;
},
changeVolume: function( volume ){
changeVolume: function ( volume ) {
this.sendNotification( 'changeVolume', volume );
},
sendNotification: function ( noteName, value ) {
if ( this.disabled ){
if ( this.disabled ) {
return false;
}
if ( this.playerElement ) {
this.playerElement.sendNotification( noteName, value ) ;
}else{
$( this ).bind('playerJsReady', function(){
if ( !this.disabled ){
} else {
$( this ).bind('playerJsReady', function () {
if ( !this.disabled ) {
this.playerElement.sendNotification( noteName, value );
}
});
} );
}
},
setKDPAttribute: function( obj, property, value ) {
setKDPAttribute: function ( obj, property, value ) {
if ( this.playerElement && !this.disabled ) {
this.playerElement.setKDPAttribute( obj, property, value );
}
},
addJsListener: function( eventName, methodName ) {
addJsListener: function ( eventName, methodName ) {
if ( this.playerElement ) {
this.bindPlayerFunction( eventName, methodName );
}
},
removeJsListener: function( eventName, methodName ) {
removeJsListener: function ( eventName, methodName ) {
if ( this.playerElement ) {
mw.log( 'PlayerElementFlash:: unbindPlayerFunction:' + eventName );
// 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,'');
var gKdpCallbackName = 'kdp_' + methodName + '_cb_' + this.id.replace( /[^a-zA-Z 0-9]+/g, '' );
// Remove the listener ( if it exists already )
this.playerElement.removeJsListener( eventName, gKdpCallbackName );
}
},
getCurrentTime: function() {
getCurrentTime: function () {
if ( this.playerElement ) {
return this.playerElement.getCurrentTime();
}
Expand Down Expand Up @@ -197,49 +198,49 @@
*@param {object}
* target object to call the listening func from
*/
bindPlayerFunction : function(bindName, methodName, target) {
bindPlayerFunction: function ( bindName, methodName /*, target*/ ) {
var _this = this;
mw.log( 'PlayerElementFlash:: 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,'');
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) {
window[ cName ] = function(data) {
var createGlobalCB = function ( cName ) {
window[ cName ] = function ( data ) {
// Track all events ( except for playerUpdatePlayhead and bytesDownloadedChange )
if( bindName != 'playerUpdatePlayhead' && bindName != 'bytesDownloadedChange' ){
mw.log("PlayerElementFlash:: event: " + bindName);
if ( bindName !== 'playerUpdatePlayhead' && bindName !== 'bytesDownloadedChange' ) {
mw.log( 'PlayerElementFlash:: event: ' + bindName );
}
_this.targetObj[methodName](data);
_this.targetObj[methodName]( data );
};
}(gKdpCallbackName, this);
}( 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);
},
onUpdatePlayhead : function ( playheadVal ) {
onUpdatePlayhead: function ( playheadVal ) {
this.currentTime = playheadVal;
},
onPause : function() {
onPause: function () {
this.paused = true;
//TODO trigger event?
},
onPlay : function() {
onPlay: function () {
this.paused = false;
$( this ).trigger( 'playing' );
},
onDurationChange : function( data, id ) {
onDurationChange: function ( data /*, id*/ ) {
this.duration = data.newValue;
$( this ).trigger( 'loadedmetadata' );
},
onClipDone : function() {
onClipDone: function () {
$( this ).trigger( 'ended' );
},
onPlayerSeekEnd: function() {
onPlayerSeekEnd: function () {
$( this ).trigger( 'seeked' );
},
onAlert : function ( data, id ) {
onAlert: function ( /*data, id*/ ) {
//TODO?
},
onMute: function () {
Expand All @@ -250,25 +251,25 @@
},
onVolumeChanged: function ( data ) {
this.volume = data.newVolume;
$( this).trigger( 'volumechange' );
$( this ).trigger( 'volumechange' );
},
onMediaError: function () {
$( this).trigger( 'error' );
$( this ).trigger( 'error' );
},
redrawObject: function ( timeout ) {
var _this = this;
//by default we will wait 250 ms
if ( !timeout ) {
timeout = 250;
}
this.playerElement.style.width = "99%";
setTimeout( function() {
_this.playerElement.style.width = "100%";
this.playerElement.style.width = '99%';
setTimeout( function () {
_this.playerElement.style.width = '100%';
}, timeout );
}
});
} );

} )( window.mw, jQuery );
} )( mediaWiki, jQuery );

/*
* jQuery Tools 1.2.5 - The missing UI library for the Web
Expand Down
29 changes: 15 additions & 14 deletions modules/EmbedPlayer/resources/playerElement/mw.PlayerElementHTML.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
( function( mw, $ ) {"use strict";
( function ( mw, $ ) {
'use strict';

// Class defined in resources/class/class.js
mw.PlayerElementHTML = mw.PlayerElement.extend({
init: function( containerId , playerId ){
init: function ( containerId, playerId ) {
// Create new video tag and append to container
var $vidSibling = $( '<video />' )
.attr({
'id' : playerId
}).css({
'id': playerId
} ).css({
'-webkit-transform-style': 'preserve-3d',
'position': 'relative',
'width': '100%',
'height': '100%'
});
} );

$( '#' + containerId ).append( $vidSibling );
this.element = $vidSibling[0];

return this;
},
play: function(){
play: function () {
this.element.play();
},
pause: function(){
mw.log('PlayerElement::Error: function pause should be implemented by playerElement interface ');
pause: function () {
mw.log( 'PlayerElement::Error: function pause should be implemented by playerElement interface' );
},
seek: function( val ){
mw.log('PlayerElement::Error: function seek should be implemented by playerElement interface ');
seek: function ( /*val*/ ) {
mw.log( 'PlayerElement::Error: function seek should be implemented by playerElement interface' );
},
load: function(){
load: function () {
this.element.src = this.src;
this.element.load();
},
changeVolume: function( val ){
changeVolume: function ( val ) {
this.element.volume = val;
}
});
} );

} )( window.mw, window.jQuery );
} )( mediaWiki, jQuery );
Original file line number Diff line number Diff line change
@@ -1,137 +1,139 @@
( function( mw, $ ) {"use strict";
/*globals Silverlight*/
( function ( mw, $ ) {
'use strict';

// Class defined in resources/class/class.js
mw.PlayerElementSilverlight = mw.PlayerElement.extend({
mw.PlayerElementSilverlight = mw.PlayerElement.extend( {

isStopped: false,
init: function(containerId , playerId , elementFlashvars, target, readyCallback ){
init: function ( containerId, playerId, elementFlashvars, target, readyCallback ) {
var _this = this;
this.element = this;
this.id = playerId;
this.targetObj = target;
var xapPath = mw.getMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/silverlight-player/Player.xap';
//var xapPath = 'http://192.168.162.72/lightKdp/Player.xap';
window["onError" + playerId]=function(sender, args){
var appSource = "";
if (sender != null && sender != 0) {
window['onError' + playerId] = function ( sender, args ) {
var appSource = '';
if (sender !== null && sender !== 0 ) {
appSource = sender.getHost().Source;
}

var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;

if (errorType == "ImageError" || errorType == "MediaError") {
if ( errorType === 'ImageError' || errorType === 'MediaError' ) {
return;
}

var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n" ;
var errMsg = 'Unhandled Error in Silverlight Application ' + appSource + '\n' ;

errMsg += "Code: "+ iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";
errMsg += 'Code: ' + iErrorCode + ' \n';
errMsg += 'Category: ' + errorType + ' \n';
errMsg += 'Message: ' + args.ErrorMessage + ' \n';

if (errorType == "ParserError") {
errMsg += "File: " + args.xamlFile + " \n";
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
if ( errorType === 'ParserError' ) {
errMsg += 'File: ' + args.xamlFile + ' \n';
errMsg += 'Line: ' + args.lineNumber + ' \n';
errMsg += 'Position: ' + args.charPosition + ' \n';
}
else if (errorType == "RuntimeError") {
if (args.lineNumber != 0) {
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
else if ( errorType === 'RuntimeError' ) {
if ( args.lineNumber !== 0 ) {
errMsg += 'Line: ' + args.lineNumber + ' \n';
errMsg += 'Position: ' + args.charPosition + ' \n';
}
errMsg += "MethodName: " + args.methodName + " \n";
errMsg += 'MethodName: ' + args.methodName + ' \n';
}
mw.log("Error occur in silverlight player:" +errMsg);
}
window["onLoad" + playerId] = function(sender,args){
mw.log( 'Error occur in silverlight player: ' + errMsg );
};
window['onLoad' + playerId] = function ( /*sender, args*/ ) {
var slCtl = document.getElementById( playerId );
_this.playerProxy = slCtl.Content.MediaElementJS;
//slCtl.Content.MediaElementJS.addJsListener("playerPlayed", "playing");
//slCtl.Content.MediaElementJS.addJsListener( 'playerPlayed', 'playing' );
// We wrap everything in setTimeout to avoid Firefox race condition with empty cache
_this.playerElement = _this.playerProxy;

//if this is the target object: add event listeners
//if a different object is the target: it should take care of its listeners (such as embedPlayerKPlayer)
if ( !_this.targetObj ) {
_this.targetObj = _this;

var bindEventMap = {
'playerPaused' : 'onPause',
'playerPlayed' : 'onPlay',
'durationChange' : 'onDurationChange',
'playerPlayEnd' : 'onClipDone',
'playerUpdatePlayhead' : 'onUpdatePlayhead',
'playerSeekEnd': 'onPlayerSeekEnd',
'alert': 'onAlert',
'mute': 'onMute',
'unmute': 'onUnMute',
'volumeChanged': 'onVolumeChanged',
'error': 'onError'
};

$.each( bindEventMap, function( bindName, localMethod ) {
_this.bindPlayerFunction(bindName, localMethod);
});
}
_this.playerElement = _this.playerProxy;

//if this is the target object: add event listeners
//if a different object is the target: it should take care of its listeners (such as embedPlayerKPlayer)
if ( !_this.targetObj ) {
_this.targetObj = _this;

var bindEventMap = {
'playerPaused': 'onPause',
'playerPlayed': 'onPlay',
'durationChange': 'onDurationChange',
'playerPlayEnd': 'onClipDone',
'playerUpdatePlayhead': 'onUpdatePlayhead',
'playerSeekEnd': 'onPlayerSeekEnd',
'alert': 'onAlert',
'mute': 'onMute',
'unmute': 'onUnMute',
'volumeChanged': 'onVolumeChanged',
'error': 'onError'
};

$.each( bindEventMap, function ( bindName, localMethod ) {
_this.bindPlayerFunction(bindName, localMethod );
} );
}

//imitate html5 video readyState
_this.readyState = 4;
// Run ready callback
if( $.isFunction( readyCallback ) ){
readyCallback.apply( _this );
}
//imitate html5 video readyState
_this.readyState = 4;
// Run ready callback
if ( $.isFunction( readyCallback ) ) {
readyCallback.apply( _this );
}

//notify player is ready
$( _this ).trigger('playerJsReady');
}
//notify player is ready
$( _this ).trigger( 'playerJsReady' );
};

elementFlashvars["onLoaded"] = "onLoad" + playerId;
var params = "";
for ( var i in elementFlashvars ){
params += i +"=" + elementFlashvars[i]+",";
elementFlashvars.onLoaded = 'onLoad' + playerId;
var params = '';
for ( var i in elementFlashvars ) {
params += i + '=' + elementFlashvars[i] + ',';
}

Silverlight.createObject(
xapPath,
$("#"+containerId).get(0),
playerId,
{
width:"100%",height:"100%",
background:"transparent",
windowless:"true",
version: "4.0.60310.0" },
xapPath,
$( '#' + containerId ).get( 0 ),
playerId,
{
width: '100%',
height: '100%',
background: 'transparent',
windowless: 'true',
version: '4.0.60310.0' },
{
onError: "onError" + playerId,
enableHtmlAccess: "true" },
onError: 'onError' + playerId,
enableHtmlAccess: 'true' },
params
// context: "row4"
);


},
onUpdatePlayhead : function ( playheadVal ) {
onUpdatePlayhead: function ( playheadVal ) {
this.currentTime = playheadVal;
},
onPause : function() {
onPause: function () {
this.paused = true;
//TODO trigger event?
},
onPlay : function() {
onPlay: function () {
$( this ).trigger( 'playing' );
this.stopped = this.paused = false;
},
onDurationChange : function( data, id ) {
onDurationChange: function ( data /*, id*/ ) {
this.duration = data.newValue;
$( this ).trigger( 'loadedmetadata' );
},
onClipDone : function() {
onClipDone: function () {
$( this ).trigger( 'ended' );
},
onPlayerSeekEnd: function() {
onPlayerSeekEnd: function () {
$( this ).trigger( 'seeked' );
},
onAlert : function ( data, id ) {
onAlert: function ( /*data, id*/ ) {
//TODO?
},
onMute: function () {
Expand All @@ -145,60 +147,60 @@
},
onVolumeChanged: function ( data ) {
this.volume = data.newVolume;
$( this).trigger( 'volumechange' );
$( this ).trigger( 'volumechange' );
},
addJsListener: function( eventName, methodName ) {
addJsListener: function ( eventName, methodName ) {
if ( this.playerElement ) {
this.bindPlayerFunction( eventName, methodName );
}
},
removeJsListener: function( eventName, methodName ) {
removeJsListener: function ( eventName, methodName ) {
if ( this.playerElement ) {
mw.log( 'PlayerElementSilverlight:: unbindPlayerFunction:' + eventName );
// The kaltura kdp can only call a global function by given name
var gKdpCallbackName = 'silverlight_' + methodName + '_cb_' + this.id.replace(/[^a-zA-Z 0-9]+/g,'');
var gKdpCallbackName = 'silverlight_' + methodName + '_cb_' + this.id.replace( /[^a-zA-Z 0-9]+/g, '' );
// Remove the listener ( if it exists already )
this.playerElement.removeJsListener( eventName, gKdpCallbackName );
}
},
play: function(){
play: function () {
this.playerProxy.playMedia();
this.isStopped = false;
},
stop: function(){
stop: function () {
this.playerElement.stopMedia();
this.isStopped = true;
},
pause: function(){
pause: function () {
this.playerProxy.pauseMedia();
},
seek: function( val ){
this.playerProxy.setCurrentTime(val);
seek: function ( val ) {
this.playerProxy.setCurrentTime( val );
$( this ).trigger( 'seeking' );
},
load: function(){
load: function () {
if ( this.src ) {
this.playerProxy.setSrc(this.src);
this.playerProxy.setSrc( this.src );
this.playerProxy.loadMedia();
}
},
changeVolume: function( volume ){
changeVolume: function ( volume ) {
this.playerProxy.setVolume( volume );
},
selectTrack: function( index ) {
selectTrack: function ( index ) {
this.playerProxy.selectTrack( index );
},
selectAudioTrack: function( index ) {
selectAudioTrack: function ( index ) {
this.playerProxy.selectAudioTrack( index );
},
selectTextTrack: function( index ) {
selectTextTrack: function ( index ) {
this.playerProxy.selectTextTrack( index );
},
reloadMedia: function() {
reloadMedia: function () {
this.playerProxy.reloadMedia();
this.isStopped = false;
},
stretchFill: function() {
stretchFill: function () {
this.playerProxy.stretchFill();
},

Expand All @@ -215,28 +217,26 @@
*@param {object}
* target object to call the listening func from
*/
bindPlayerFunction : function(bindName, methodName, target) {
bindPlayerFunction: function ( bindName, methodName /*, target*/ ) {
var _this = this;
mw.log( 'PlayerElementSilverlight:: bindPlayerFunction:' + bindName );
// The kaltura kdp can only call a global function by given name
var gKdpCallbackName = 'silverlight_' + methodName + '_cb_' + this.id.replace(/[^a-zA-Z 0-9]+/g,'');
var gKdpCallbackName = 'silverlight_' + methodName + '_cb_' + this.id.replace( /[^a-zA-Z 0-9]+/g, '' );

// Create an anonymous function with local player scope
var createGlobalCB = function(cName) {
window[ cName ] = function(data) {
( function createGlobalCB( cName ) {
window[ cName ] = function ( data ) {
// Track all events ( except for playerUpdatePlayhead and bytesDownloadedChange )
if( bindName != 'playerUpdatePlayhead' && bindName != 'bytesDownloadedChange' ){
mw.log("PlayerElementSilverlight:: event: " + bindName);
if ( bindName !== 'playerUpdatePlayhead' && bindName !== 'bytesDownloadedChange' ) {
mw.log( 'PlayerElementSilverlight:: event: ' + bindName ) ;
}
_this.targetObj[methodName](data);
_this.targetObj[methodName]( data );
};
}(gKdpCallbackName, this);
} )( gKdpCallbackName, this );
// Remove the listener ( if it exists already )
this.playerElement.removeJsListener( bindName, gKdpCallbackName );
// Add the listener to the Silvrtliht player:
this.playerElement.addJsListener( bindName, gKdpCallbackName);
this.playerElement.addJsListener( bindName, gKdpCallbackName );
}
});
} )( window.mw, jQuery );


} );
} )( mediaWiki, jQuery );
Loading