Index: branches/MwEmbedStandAlone/mwEmbed.js |
— | — | @@ -1804,8 +1804,8 @@ |
1805 | 1805 | */ |
1806 | 1806 | mw.npt2seconds = function ( npt_str ) { |
1807 | 1807 | if ( !npt_str ) { |
1808 | | - // mw.log('npt2seconds:not valid ntp:'+ntp); |
1809 | | - return false; |
| 1808 | + mw.log('npt2seconds:not valid ntp:'+ntp); |
| 1809 | + return 0; |
1810 | 1810 | } |
1811 | 1811 | // Strip {npt:}01:02:20 or 32{s} from time if present |
1812 | 1812 | npt_str = npt_str.replace( /npt:|s/g, '' ); |
Index: branches/MwEmbedStandAlone/modules/EmbedPlayer/mw.EmbedPlayer.js |
— | — | @@ -988,6 +988,7 @@ |
989 | 989 | */ |
990 | 990 | autoSelectSource: function() { |
991 | 991 | mw.log( 'EmbedPlayer::mediaElement::autoSelectSource' ); |
| 992 | + var _this = this; |
992 | 993 | // Select the default source |
993 | 994 | var playableSources = this.getPlayableSources(); |
994 | 995 | var flash_flag = ogg_flag = false; |
— | — | @@ -996,13 +997,16 @@ |
997 | 998 | if( playableSources.length == 0 ){ |
998 | 999 | return false; |
999 | 1000 | } |
| 1001 | + var setSelectedSource = function( source ){ |
| 1002 | + _this.selectedSource = source; |
| 1003 | + }; |
1000 | 1004 | |
1001 | 1005 | // Set via user-preference |
1002 | 1006 | for ( var source = 0; source < playableSources.length; source++ ) { |
1003 | 1007 | var mimeType = playableSources[source].mimeType; |
1004 | 1008 | if ( mw.EmbedTypes.players.preference[ 'format_preference' ] == mimeType ) { |
1005 | | - mw.log( 'Set via preference: ' + playableSources[source].mimeType ); |
1006 | | - this.selectedSource = playableSources[source]; |
| 1009 | + mw.log( 'EmbedPlayer::autoSelectSource: Set via preference: ' + playableSources[source].mimeType ); |
| 1010 | + setSelectedSource( playableSources[source] ); |
1007 | 1011 | return true; |
1008 | 1012 | } |
1009 | 1013 | } |
— | — | @@ -1010,8 +1014,8 @@ |
1011 | 1015 | // Set via marked default: |
1012 | 1016 | for ( var source = 0; source < playableSources.length; source++ ) { |
1013 | 1017 | if ( playableSources[ source ].markedDefault ) { |
1014 | | - mw.log( 'Set via marked default: ' + playableSources[source].markedDefault ); |
1015 | | - this.selectedSource = playableSources[source]; |
| 1018 | + mw.log( 'EmbedPlayer::autoSelectSource: Set via marked default: ' + playableSources[source].markedDefault ); |
| 1019 | + setSelectedSource( playableSources[source] ); |
1016 | 1020 | return true; |
1017 | 1021 | } |
1018 | 1022 | } |
— | — | @@ -1021,8 +1025,8 @@ |
1022 | 1026 | var mimeType = playableSources[source].mimeType; |
1023 | 1027 | var player = mw.EmbedTypes.players.defaultPlayer( mimeType ); |
1024 | 1028 | if ( player && player.library == 'Native' ) { |
1025 | | - mw.log('EmbedPlayer::Set native playback'); |
1026 | | - this.selectedSource = playableSources[ source ]; |
| 1029 | + mw.log('EmbedPlayer::autoSelectSource: Set via native playback'); |
| 1030 | + setSelectedSource( playableSources[ source ] ); |
1027 | 1031 | return true; |
1028 | 1032 | } |
1029 | 1033 | } |
— | — | @@ -1039,16 +1043,16 @@ |
1040 | 1044 | player.library == 'Kplayer' |
1041 | 1045 | ) |
1042 | 1046 | ) { |
1043 | | - mw.log('Set h264 via native or flash fallback'); |
1044 | | - this.selectedSource = playableSources[ source ]; |
| 1047 | + mw.log('EmbedPlayer::autoSelectSource: Set h264 via native or flash fallback'); |
| 1048 | + setSelectedSource( playableSources[ source ] ); |
1045 | 1049 | return true; |
1046 | 1050 | } |
1047 | 1051 | }; |
1048 | 1052 | |
1049 | 1053 | // Else just select first source |
1050 | 1054 | if ( !this.selectedSource ) { |
1051 | | - mw.log( 'set via first source:' + playableSources[0] ); |
1052 | | - this.selectedSource = playableSources[0]; |
| 1055 | + mw.log( 'EmbedPlayer::autoSelectSource: Set via first source:' + playableSources[0] ); |
| 1056 | + setSelectedSource( playableSources[0] ); |
1053 | 1057 | return true; |
1054 | 1058 | } |
1055 | 1059 | // No Source found so no source selected |
— | — | @@ -1255,7 +1259,10 @@ |
1256 | 1260 | // Buffer flags |
1257 | 1261 | 'bufferStartFlag' : false, |
1258 | 1262 | 'bufferEndFlag' : false, |
1259 | | - |
| 1263 | + |
| 1264 | + // For supporting media fragments stores the play end time |
| 1265 | + 'pauseTime' : null, |
| 1266 | + |
1260 | 1267 | // On done playing |
1261 | 1268 | 'donePlayingCount' : 0 |
1262 | 1269 | , |
— | — | @@ -2050,17 +2057,51 @@ |
2051 | 2058 | this.$interface.hide(); |
2052 | 2059 | } |
2053 | 2060 | |
| 2061 | + // Update temporal url if present |
| 2062 | + this.updateTemporalUrl(); |
| 2063 | + |
| 2064 | + |
2054 | 2065 | if ( this.autoplay ) { |
2055 | 2066 | mw.log( 'EmbedPlayer::showPlayer::activating autoplay' ); |
2056 | 2067 | // Issue a non-blocking play request |
2057 | 2068 | setTimeout(function(){ |
2058 | 2069 | _this.play(); |
2059 | | - },1) |
| 2070 | + },1); |
2060 | 2071 | } |
2061 | 2072 | |
2062 | 2073 | }, |
2063 | | - |
2064 | 2074 | /** |
| 2075 | + * Media framgments handler based on: |
| 2076 | + * http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#fragment-dimensions |
| 2077 | + * |
| 2078 | + * We support seconds and npt ( normal play time ) |
| 2079 | + * |
| 2080 | + * Updates the player per fragment url info if present |
| 2081 | + * |
| 2082 | + */ |
| 2083 | + updateTemporalUrl: function(){ |
| 2084 | + var sourceHash = /[^\#]+$/.exec( this.getSrc() ).toString(); |
| 2085 | + if( sourceHash.indexOf('t=') === 0 ){ |
| 2086 | + // parse the times |
| 2087 | + var times = sourceHash.substr(2).split(','); |
| 2088 | + if( times[0] ){ |
| 2089 | + // update the current time |
| 2090 | + this.currentTime = mw.npt2seconds( times[0].toString() ); |
| 2091 | + } |
| 2092 | + if( times[1] ){ |
| 2093 | + this.pauseTime = mw.npt2seconds( times[1].toString() ); |
| 2094 | + // ignore invalid ranges: |
| 2095 | + if( this.pauseTime < this.currentTime ){ |
| 2096 | + this.pauseTime = null; |
| 2097 | + } |
| 2098 | + } |
| 2099 | + // Update the play head |
| 2100 | + this.updatePlayHead( this.currentTime / this.duration ); |
| 2101 | + // Update status: |
| 2102 | + this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) ); |
| 2103 | + } |
| 2104 | + }, |
| 2105 | + /** |
2065 | 2106 | * Get missing plugin html (check for user included code) |
2066 | 2107 | * |
2067 | 2108 | * @param {String} |
— | — | @@ -2953,6 +2994,11 @@ |
2954 | 2995 | // Update the previousTime ( so we can know if the user-javascript |
2955 | 2996 | // changed currentTime ) |
2956 | 2997 | _this.previousTime = _this.currentTime; |
| 2998 | + |
| 2999 | + if( _this.pauseTime && _this.currentTime > _this.pauseTime ){ |
| 3000 | + _this.pause(); |
| 3001 | + _this.pauseTime = null; |
| 3002 | + } |
2957 | 3003 | |
2958 | 3004 | |
2959 | 3005 | // Check if volume was set outside of embed player function |
— | — | @@ -3110,68 +3156,8 @@ |
3111 | 3157 | $j( this ).trigger('updatePlayHeadPercent', perc); |
3112 | 3158 | }, |
3113 | 3159 | |
3114 | | - /** |
3115 | | - * Highlight a section of video on the playhead |
3116 | | - * |
3117 | | - * @param {Object} |
3118 | | - * options Provides "start" time & "end" time to highlight |
3119 | | - */ |
3120 | | - highlightPlaySection:function( options ) { |
3121 | | - mw.log( 'highlightPlaySection' ); |
3122 | | - var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
3123 | | - var dur = this.getDuration(); |
3124 | | - // set the left percet and update the slider: |
3125 | | - rel_start_sec = mw.npt2seconds( options['start'] ); |
3126 | | - // remove the startOffset if relevent: |
3127 | | - if ( this.startOffset ) |
3128 | | - rel_start_sec = rel_start_sec - this.startOffset |
3129 | 3160 | |
3130 | | - var slider_perc = 0; |
3131 | | - if ( rel_start_sec <= 0 ) { |
3132 | | - left_perc = 0; |
3133 | | - options['start'] = mw.seconds2npt( this.startOffset ); |
3134 | | - rel_start_sec = 0; |
3135 | | - this.updatePlayHead( 0 ); |
3136 | | - } else { |
3137 | | - left_perc = parseInt( ( rel_start_sec / dur ) * 100 ) ; |
3138 | | - slider_perc = ( left_perc / 100 ); |
3139 | | - } |
3140 | | - |
3141 | | - mw.log( "slider perc:" + slider_perc ); |
3142 | | - if ( ! this.isPlaying() ) { |
3143 | | - this.updatePlayHead( slider_perc ); |
3144 | | - } |
3145 | | - |
3146 | | - width_perc = parseInt( ( ( mw.npt2seconds( options['end'] ) - mw.npt2seconds( options['start'] ) ) / dur ) * 100 ) ; |
3147 | | - if ( ( width_perc + left_perc ) > 100 ) { |
3148 | | - width_perc = 100 - left_perc; |
3149 | | - } |
3150 | | - // mw.log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + |
3151 | | - // rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc); |
3152 | | - $j( '#mv_seeker_' + eid + ' .mv_highlight' ).css( { |
3153 | | - 'left' : left_perc + '%', |
3154 | | - 'width' : width_perc + '%' |
3155 | | - } ).show(); |
3156 | | - |
3157 | | - this.jump_time = options['start']; |
3158 | | - this.serverSeekTime = mw.npt2seconds( options['start'] ); |
3159 | | - // trim output to |
3160 | | - this.controlBuilder.setStatus( gM( 'mwe-embedplayer-seek_to', mw.seconds2npt( this.serverSeekTime ) ) ); |
3161 | | - mw.log( 'DO update: ' + this.jump_time ); |
3162 | | - this.updateThumbTime( rel_start_sec ); |
3163 | | - }, |
3164 | | - |
3165 | 3161 | /** |
3166 | | - * Hides the playhead highlight |
3167 | | - */ |
3168 | | - hideHighlight: function() { |
3169 | | - var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
3170 | | - $j( '#mv_seeker_' + eid + ' .mv_highlight' ).hide(); |
3171 | | - this.controlBuilder.setStatus( this.getTimeRange() ); |
3172 | | - }, |
3173 | | - |
3174 | | - |
3175 | | - /** |
3176 | 3162 | * Helper Functions for selected source |
3177 | 3163 | */ |
3178 | 3164 | |
Index: branches/MwEmbedStandAlone/remotes/mediaWiki.js |
— | — | @@ -458,8 +458,8 @@ |
459 | 459 | timeHash= '#t=' + $startTime.text(); |
460 | 460 | // if we have a start time also look for endtime |
461 | 461 | var $endTime = $j( '#' + vidId ).parent().find('.endtime'); |
462 | | - if( $endTime.lenght ){ |
463 | | - timeHash += $endTime.text(); |
| 462 | + if( $endTime.length ){ |
| 463 | + timeHash += ',' + $endTime.text(); |
464 | 464 | } |
465 | 465 | } |
466 | 466 | // Update the video source with the temporal time hash: |