summaryrefslogtreecommitdiff
path: root/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js')
-rw-r--r--extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js307
1 files changed, 307 insertions, 0 deletions
diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js
new file mode 100644
index 00000000..f6271621
--- /dev/null
+++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js
@@ -0,0 +1,307 @@
+/**
+ * Used to Overlay images and take over player controls
+ *
+ * extends EmbedPlayerNative object image overlay support
+ */
+
+mw.EmbedPlayerImageOverlay = {
+
+ instanceOf: 'ImageOverlay',
+
+ // If the player is "ready to play"
+ playerReady : true,
+
+ // Pause time used to track player time between pauses
+ lastPauseTime: 0,
+
+ // currentTime updated via internal clockStartTime var
+ currentTime:0,
+
+ // StartOffset support seeking into the virtual player
+ startOffset:0,
+
+ // The local clock used to emulate playback time
+ clockStartTime: 0,
+
+ /**
+ * Build the player interface:
+ */
+ init: function(){
+ // Check if features are already updated:
+ if( this['native_instaceOf'] == 'Native' ){
+ return ;
+ }
+ // inherit mw.EmbedPlayerNative (
+ for( var i in mw.EmbedPlayerNative ){
+ if( typeof mw.EmbedPlayerImageOverlay[ i ] != 'undefined' ){
+ this['native_' + i ] = mw.EmbedPlayerNative[i];
+ } else {
+ this[ i ] = mw.EmbedPlayerNative[i];
+ }
+ }
+ },
+
+ /**
+ * When on playback method switch remove imageOverlay
+ * @param {function} callback
+ */
+ updatePlaybackInterface: function( callback ){
+ mw.log( 'EmbedPlayerImageOverlay:: updatePlaybackInterface remove imageOverlay: ' + $(this).siblings( '.imageOverlay' ).length );
+ // Reset lastPauseTime
+ this.lastPauseTime = 0;
+ // Clear imageOverlay sibling:
+ $( this ).find( '.imageOverlay' ).remove();
+ // Restore the video element on screen position:
+ $( this.getPlayerElement() ).css('left', 0 );
+ // Call normal parent updatePlaybackInterface
+ this.parent_updatePlaybackInterface( callback );
+ },
+
+ /**
+ * The method called to "show the player"
+ * For image overlay we want to:
+ * Set black video urls for player source
+ * Add an image overlay
+ */
+ updatePosterHTML: function(){
+ var vid = this.getPlayerElement();
+ $( vid ).empty()
+
+ // Provide modules the opportunity to supply black sources ( for registering event click )
+ // this is need for iPad to capture the play click to auto continue after "playing an image"
+ // ( iOS requires a user gesture to initiate video playback )
+
+ // We don't just include the sources as part of core config, since it would result in
+ // a possible privacy leakage i.e hitting the kaltura servers when playing images.
+ this.triggerHelper( 'AddEmptyBlackSources', [ vid ] );
+
+ // embed the image:
+ this.embedPlayerHTML();
+
+ // add the play btn:
+ this.addLargePlayBtn();
+ },
+
+ /**
+ * Play function starts the video playback
+ */
+ play: function() {
+ mw.log( 'EmbedPlayerImageOverlay::play> lastPauseTime:' + this.lastPauseTime + ' ct: ' + this.currentTime );
+ this.applyIntrinsicAspect();
+ // Check for image duration
+
+ // Reset playback if currentTime > duration:
+ if( this.currentTime > this.getDuration() ) {
+ this.currentTime = this.pauseTime = 0;
+ }
+
+ // No longer in a stopped state:
+ this.stopped = false;
+
+ // 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') ){
+ // Update the previousInstanceOf flag:
+ $( this ).data('previousInstanceOf', this.instanceOf );
+ var vid = this.getPlayerElement();
+ // populate the video with black video sources:
+ this.triggerHelper( 'AddEmptyBlackSources', [ vid ] );
+ // run play:
+ vid.play();
+ // inline pause
+ setTimeout(function(){
+ vid.pause();
+ },0);
+ // add another pause request after 500 ms ( iOS sometimes does not listen the first time )
+ setTimeout(function(){
+ vid.pause();
+ }, mw.config.get( 'EmbedPlayer.MonitorRate' ) * 2 );
+ }
+ // call the parent play ( to update interface and call respective triggers )
+ this.parent_play();
+ // make sure we are in play interface:
+ this.playInterfaceUpdate();
+
+ this.clockStartTime = new Date().getTime();
+ // Start up monitor:
+ this.monitor();
+ },
+ getDuration: function(){
+ if( this.duration ){
+ return this.duration;
+ }
+ if( this.imageDuration ){
+ this.duration = this.imageDuration ;
+ } else {
+ this.duration = mw.config.get( "EmbedPlayer.DefaultImageDuration" );
+ }
+ // make sure duration has type float:
+ this.duration = parseFloat( this.duration );
+ return this.duration;
+ },
+ /**
+ * Stops the playback
+ */
+ stop: function() {
+ this.currentTime = 0;
+ this.parent_stop();
+ },
+ _onpause: function(){
+ // catch the native event ( and do nothing )
+ },
+ /**
+ * Preserves the pause time across for timed playback
+ */
+ pause: function( ) {
+ this.lastPauseTime = this.currentTime;
+ mw.log( 'EmbedPlayerImageOverlay::pause, lastPauseTime: ' + this.lastPauseTime );
+ // run parent pause;
+ this.parent_pause();
+ this.stopMonitor();
+ },
+
+ monitor: function(){
+ if( this.duration == 0 ){
+ this.disablePlayControls();
+ return ;
+ }
+ $( this ).trigger( 'timeupdate' );
+
+ if ( this.currentTime >= this.duration ) {
+ $( this ).trigger( 'ended' );
+ } else {
+ // Run the parent monitor:
+ this.parent_monitor();
+ }
+ },
+ /**
+ * Seeks to a given percent and updates the lastPauseTime
+ *
+ * @param {Float} seekPercent Percentage to seek into the virtual player
+ */
+ seek: function( seekPercent ) {
+ this.lastPauseTime = seekPercent * this.getDuration();
+ this.seeking = false;
+ // start seeking:
+ $( this ).trigger( 'seeking' );
+ // Done seeking
+ $( this ).trigger( 'seeked' );
+ this.play();
+ },
+
+ /**
+ * Sets the current Time
+ *
+ * @param {Float} perc Percentage to seek into the virtual player
+ * @param {Function} callback Function called once time has been updated
+ */
+ setCurrentTime: function( time, callback ) {
+ this.lastPauseTime = time;
+ // start seeking:
+ $( this ).trigger( 'seeking' );
+ // Done seeking
+ $( this ).trigger( 'seeked' );
+ if( callback ){
+ callback();
+ }
+ },
+ /**
+ * Switch the image playback
+ */
+ playerSwitchSource: function( source, switchCallback, doneCallback ){
+ var _this = this;
+ this.selectedSource = source;
+ this.embedPlayerHTML();
+ this.applyIntrinsicAspect();
+ this.play();
+ if( switchCallback ){
+ switchCallback( this );
+ }
+ // Wait for ended event to tr
+ $( this ).bind('ended.playerSwitchSource', function(){
+ $( _this ).unbind('ended.playerSwitchSource');
+ if( doneCallback ) {
+ doneCallback( this );
+ }
+ })
+ },
+ /**
+ * Get the embed player time
+ */
+ getPlayerElementTime: function() {
+ this.currentTime = ( ( new Date().getTime() - this.clockStartTime ) / 1000 ) + this.lastPauseTime;
+ return this.currentTime;
+ },
+ /**
+ * Get the "embed" html for the html player
+ */
+ embedPlayerHTML: function() {
+ var _this = this;
+ // remove any old imageOverlay:
+ this.$interface.find('.imageOverlay').remove();
+ mw.log( 'EmbedPlayerImageOverlay :doEmbedHTML: ' + this.id );
+
+ var currentSoruceObj = this.selectedSource;
+
+ if( !currentSoruceObj ){
+ mw.log("Error:: EmbedPlayerImageOverlay:embedPlayerHTML> missing source" );
+ return ;
+ }
+ var $image =
+ $( '<img />' )
+ .css({
+ 'position': 'relative',
+ 'width': '100%',
+ 'height': '100%'
+ })
+ .attr({
+ 'src' : currentSoruceObj.getSrc()
+ })
+ .addClass( 'imageOverlay' )
+ .load( function(){
+ // reset clock time:
+ _this.clockStartTime = new Date().getTime();
+ _this.monitor();
+ })
+
+ // move the video element off screen:
+ $( this.getPlayerElement() ).css({
+ 'left': this.getWidth()+50,
+ 'position' : 'absolute'
+ });
+
+ // Add the image before the video element or before the playerInterface
+ $( this ).html( $image );
+
+ this.applyIntrinsicAspect();
+ },
+ // wrap the parent rewize player to apply intensic apsect
+ resizePlayer: function( size , animate, callback){
+ this.parent_resizePlayer( size , animate, callback );
+ this.applyIntrinsicAspect();
+ },
+ applyIntrinsicAspect: function(){
+ var $this = this.$interface;
+ // Check if a image thumbnail is present:
+ /*if( this.$interface && this.$interface.find('.imageOverlay').length ){
+ var img = this.$interface.find('.imageOverlay')[0];
+ var pHeight = $this.height();
+ // Check for intrinsic width and maintain aspect ratio
+ if( img.naturalWidth && img.naturalHeight ){
+ var pWidth = parseInt( img.naturalWidth / img.naturalHeight * pHeight);
+ if( pWidth > $this.width() ){
+ pWidth = $this.width();
+ pHeight = parseInt( img.naturalHeight / img.naturalWidth * pWidth );
+ }
+ $( img ).css({
+ 'height' : pHeight + 'px',
+ 'width': pWidth + 'px',
+ 'left': ( ( $this.width() - pWidth ) * .5 ) + 'px',
+ 'top': ( ( $this.height() - pHeight ) * .5 ) + 'px',
+ 'position' : 'absolute'
+ });
+ }
+ }*/
+ }
+}; \ No newline at end of file