Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerGeneric.js |
— | — | @@ -1,9 +1,9 @@ |
2 | | -/* |
3 | | -* Simple embed object for unknown application/ogg plugin |
| 2 | +/* |
| 3 | +* Simple embed object for unknown application/ogg plugin |
4 | 4 | */ |
5 | 5 | mw.EmbedPlayerGeneric = { |
6 | 6 | // List of supported features of the generic plugin |
7 | | - supports: { |
| 7 | + supports: { |
8 | 8 | 'playHead':false, |
9 | 9 | 'pause':false, |
10 | 10 | 'stop':true, |
— | — | @@ -11,18 +11,18 @@ |
12 | 12 | 'timeDisplay':false, |
13 | 13 | 'volumeControl':false |
14 | 14 | }, |
15 | | - |
16 | | - // Instance name: |
| 15 | + |
| 16 | + // Instance name: |
17 | 17 | instanceOf:'Generic', |
18 | | - |
| 18 | + |
19 | 19 | /* |
20 | 20 | * Generic embed html |
21 | 21 | * |
22 | 22 | * @return {String} |
23 | | - * embed code for generic ogg plugin |
| 23 | + * embed code for generic ogg plugin |
24 | 24 | */ |
25 | 25 | doEmbedHTML: function() { |
26 | | - $j( this ).html( |
| 26 | + $j( this ).html( |
27 | 27 | '<object type="application/ogg" ' + |
28 | 28 | 'width="' + this.getWidth() + '" height="' + this.getHeight() + '" ' + |
29 | 29 | 'data="' + this.getSrc( this.seek_time_sec ) + '"></object>' |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayer.js |
— | — | @@ -1,200 +1,201 @@ |
2 | | -/** |
| 2 | +/** |
3 | 3 | * embedPlayer is the base class for html5 video tag javascript abstraction library |
4 | 4 | * embedPlayer include a few subclasses: |
5 | | -* |
| 5 | +* |
6 | 6 | * mediaPlayer Media player embed system ie: java, vlc or native. |
7 | | -* mediaElement Represents source media elements |
| 7 | +* mediaElement Represents source media elements |
8 | 8 | * mw.PlayerControlBuilder Handles skinning of the player controls |
9 | 9 | */ |
10 | 10 | |
| 11 | +mw.includeAllModuleMessages(); |
11 | 12 | |
12 | 13 | /* |
13 | 14 | * The default video attributes supported by embedPlayer |
14 | | -*/ |
| 15 | +*/ |
15 | 16 | mw.setDefaultConfig( 'EmbedPlayer.Attributes', { |
16 | | - /* |
17 | | - * Base html element attributes: |
18 | | - */ |
19 | | - |
20 | | - // id: Auto-populated if unset |
| 17 | + /* |
| 18 | + * Base html element attributes: |
| 19 | + */ |
| 20 | + |
| 21 | + // id: Auto-populated if unset |
21 | 22 | "id" : null, |
22 | | - |
| 23 | + |
23 | 24 | // Width: alternate to "style" to set player width |
24 | 25 | "width" : null, |
25 | | - |
| 26 | + |
26 | 27 | // Height: alternative to "style" to set player height |
27 | | - "height" : null, |
| 28 | + "height" : null, |
28 | 29 | |
29 | | - /* |
| 30 | + /* |
30 | 31 | * Base html5 video element attributes / states |
31 | | - * also see: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html |
| 32 | + * also see: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html |
32 | 33 | */ |
33 | 34 | |
34 | 35 | // Media src URI, can be relative or absolute URI |
35 | 36 | "src" : null, |
36 | | - |
| 37 | + |
37 | 38 | // Poster attribute for displaying a place holder image before loading or playing the video |
38 | | - "poster": null, |
39 | | - |
40 | | - // Autoplay if the media should start playing |
| 39 | + "poster": null, |
| 40 | + |
| 41 | + // Autoplay if the media should start playing |
41 | 42 | "autoplay" : false, |
42 | | - |
| 43 | + |
43 | 44 | // Loop attribute if the media should repeat on complete |
44 | | - "loop" : false, |
45 | | - |
| 45 | + "loop" : false, |
| 46 | + |
46 | 47 | // If the player controls should be displayed |
47 | 48 | "controls" : true, |
48 | | - |
49 | | - // Video starts "paused" |
| 49 | + |
| 50 | + // Video starts "paused" |
50 | 51 | "paused" : true, |
51 | | - |
52 | | - // ReadyState an attribute informs clients of video loading state: |
53 | | - // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate |
54 | | - "readyState" : 0, |
55 | | - |
| 52 | + |
| 53 | + // ReadyState an attribute informs clients of video loading state: |
| 54 | + // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate |
| 55 | + "readyState" : 0, |
| 56 | + |
56 | 57 | // Loading state of the video element |
57 | 58 | "networkState" : 0, |
58 | | - |
59 | | - // Current playback position |
60 | | - "currentTime" :0, |
61 | | - |
| 59 | + |
| 60 | + // Current playback position |
| 61 | + "currentTime" :0, |
| 62 | + |
62 | 63 | // Previous player set time |
63 | 64 | // Lets javascript use $j('#videoId').get(0).currentTime = newTime; |
64 | | - "previousTime" :0, |
65 | | - |
| 65 | + "previousTime" :0, |
| 66 | + |
66 | 67 | // Previous player set volume |
67 | 68 | // Lets javascript use $j('#videoId').get(0).volume = newVolume; |
68 | | - "previousVolume" : 1, |
69 | | - |
70 | | - // Initial player volume: |
| 69 | + "previousVolume" : 1, |
| 70 | + |
| 71 | + // Initial player volume: |
71 | 72 | "volume" : 0.75, |
72 | | - |
| 73 | + |
73 | 74 | // Caches the volume before a mute toggle |
74 | | - "preMuteVolume" : 0.75, |
75 | | - |
76 | | - // Media duration: Value is populated via |
| 75 | + "preMuteVolume" : 0.75, |
| 76 | + |
| 77 | + // Media duration: Value is populated via |
77 | 78 | // custom durationHint attribute or via the media file once its played |
78 | | - "duration" :null, |
79 | | - |
| 79 | + "duration" :null, |
| 80 | + |
80 | 81 | // Mute state |
81 | 82 | "muted" : false, |
82 | | - |
| 83 | + |
83 | 84 | /** |
84 | 85 | * Custom attributes for embedPlayer player: |
85 | | - * (not part of the html5 video spec) |
| 86 | + * (not part of the html5 video spec) |
86 | 87 | */ |
87 | | - |
| 88 | + |
88 | 89 | // Default video aspect ratio |
89 | 90 | 'videoAspect': '4:3', |
90 | | - |
| 91 | + |
91 | 92 | // Start time of the clip |
92 | 93 | "start" : 0, |
93 | | - |
| 94 | + |
94 | 95 | // End time of the clip |
95 | | - "end" : null, |
96 | | - |
| 96 | + "end" : null, |
| 97 | + |
97 | 98 | // A apiTitleKey for looking up subtitles, credits and related videos |
98 | 99 | "apiTitleKey" : null, |
99 | | - |
| 100 | + |
100 | 101 | // The apiProvider where to lookup the title key |
101 | 102 | "apiProvider" : null, |
102 | | - |
103 | | - // If the player controls should be overlaid |
104 | | - //( Global default via config EmbedPlayer.OverlayControls in module loader.js) |
| 103 | + |
| 104 | + // If the player controls should be overlaid |
| 105 | + //( Global default via config EmbedPlayer.OverlayControls in module loader.js) |
105 | 106 | "overlaycontrols" : true, |
106 | | - |
107 | | - // Attribute to use 'native' controls |
| 107 | + |
| 108 | + // Attribute to use 'native' controls |
108 | 109 | "usenativecontrols" : false, |
109 | | - |
| 110 | + |
110 | 111 | // If the player should include an attribution button: |
111 | 112 | 'attributionbutton' : true, |
112 | | - |
| 113 | + |
113 | 114 | // ROE url ( for xml based metadata ) |
114 | 115 | // also see: http://wiki.xiph.org/ROE |
115 | 116 | "roe" : null, |
116 | 117 | |
117 | 118 | // If serving an ogg_chop segment use this to offset the presentation time |
118 | | - // ( for some plugins that use ogg page time rather than presentation time ) |
119 | | - "startOffset" : 0, |
120 | | - |
121 | | - // Thumbnail (same as poster) |
| 119 | + // ( for some plugins that use ogg page time rather than presentation time ) |
| 120 | + "startOffset" : 0, |
| 121 | + |
| 122 | + // Thumbnail (same as poster) |
122 | 123 | "thumbnail" : null, |
123 | | - |
124 | | - // Source page for media asset ( used for linkbacks in remote embedding ) |
| 124 | + |
| 125 | + // Source page for media asset ( used for linkbacks in remote embedding ) |
125 | 126 | "linkback" : null, |
126 | | - |
| 127 | + |
127 | 128 | // If the download link should be shown |
128 | 129 | "download_link" : true, |
129 | | - |
| 130 | + |
130 | 131 | // Content type of the media |
131 | 132 | "type" : null |
132 | 133 | }); |
133 | 134 | |
134 | | -mw.setDefaultConfig( { |
| 135 | +mw.setDefaultConfig( { |
135 | 136 | // If the player controls should be overlaid on top of the video ( if supported by playback method) |
136 | | - // can be set to false per embed player via overlayControls attribute |
| 137 | + // can be set to false per embed player via overlayControls attribute |
137 | 138 | 'EmbedPlayer.OverlayControls' : true, |
138 | | - |
139 | | - 'EmbedPlayer.LibraryPage': 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library', |
140 | | - |
| 139 | + |
| 140 | + 'EmbedPlayer.LibraryPage': 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library', |
| 141 | + |
141 | 142 | // A default apiProvider ( ie where to lookup subtitles, video properties etc ) |
142 | | - // NOTE: Each player instance can also specify a specific provider |
| 143 | + // NOTE: Each player instance can also specify a specific provider |
143 | 144 | "EmbedPlayer.ApiProvider" : "local", |
144 | | - |
145 | | - // Default video size ( if no size provided ) |
| 145 | + |
| 146 | + // Default video size ( if no size provided ) |
146 | 147 | "EmbedPlayer.DefaultSize" : "400x300", |
147 | 148 | |
148 | | - // If the video player should attribute kaltura |
| 149 | + // If the video player should attribute kaltura |
149 | 150 | "EmbedPlayer.KalturaAttribution" : true, |
150 | 151 | |
151 | 152 | // The attribution button |
152 | 153 | 'EmbedPlayer.AttributionButton' :{ |
153 | 154 | 'title' : 'Kaltura html5 video library', |
154 | | - 'href' : 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library', |
155 | | - // Style icon to be applied |
156 | | - 'class' : 'kaltura-icon', |
157 | | - // An icon image url ( should be a 12x12 image or data url ) |
158 | | - 'iconurl' : false |
| 155 | + 'href' : 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library', |
| 156 | + // Style icon to be applied |
| 157 | + 'class' : 'kaltura-icon', |
| 158 | + // An icon image url ( should be a 12x12 image or data url ) |
| 159 | + 'iconurl' : false |
159 | 160 | }, |
160 | 161 | |
161 | | - |
162 | | - // Set the browser player warning flag displays warning for non optimal playback |
| 162 | + |
| 163 | + // Set the browser player warning flag displays warning for non optimal playback |
163 | 164 | "EmbedPlayer.ShowNativeWarning" : true, |
164 | | - |
165 | | - // If fullscreen is global enabled. |
| 165 | + |
| 166 | + // If fullscreen is global enabled. |
166 | 167 | "EmbedPlayer.EnableFullscreen" : true, |
167 | | - |
| 168 | + |
168 | 169 | // If mwEmbed should use the Native player controls |
169 | 170 | // this will prevent video tag rewriting and skinning |
170 | 171 | // useful for devices such as iPad / iPod that |
171 | | - // don't fully support DOM overlays or don't expose full-screen |
172 | | - // functionality to javascript |
| 172 | + // don't fully support DOM overlays or don't expose full-screen |
| 173 | + // functionality to javascript |
173 | 174 | "EmbedPlayer.NativeControls" : false, |
174 | | - |
| 175 | + |
175 | 176 | // If mwEmbed should use native controls on mobile safari |
176 | 177 | "EmbedPlayer.NativeControlsMobileSafari" : true, |
177 | | - |
178 | | - |
179 | | - // The z-index given to the player interface during full screen ( high z-index ) |
| 178 | + |
| 179 | + |
| 180 | + // The z-index given to the player interface during full screen ( high z-index ) |
180 | 181 | "EmbedPlayer.fullScreenZIndex" : 999998, |
181 | | - |
| 182 | + |
182 | 183 | // The default share embed mode ( can be "object" or "videojs" ) |
183 | 184 | // |
184 | 185 | // "object" will provide a <object tag pointing to mwEmbedFrame.php |
185 | 186 | // Object embedding should be much more compatible with sites that |
186 | 187 | // let users embed flash applets |
187 | 188 | // "videojs" will include the source javascript and video tag to |
188 | | - // rewrite the player on the remote page DOM |
| 189 | + // rewrite the player on the remote page DOM |
189 | 190 | // Video tag embedding is much more mash-up friendly but exposes |
190 | | - // the remote site to the mwEmbed javascript and can be a xss issue. |
| 191 | + // the remote site to the mwEmbed javascript and can be a xss issue. |
191 | 192 | "EmbedPlayer.ShareEmbedMode" : 'object', |
192 | | - |
| 193 | + |
193 | 194 | // Default player skin name |
194 | | - "EmbedPlayer.SkinName" : "mvpcf", |
195 | | - |
196 | | - // Number of milliseconds between interface updates |
| 195 | + "EmbedPlayer.SkinName" : "mvpcf", |
| 196 | + |
| 197 | + // Number of milliseconds between interface updates |
197 | 198 | 'EmbedPlayer.MonitorRate' : 250 |
198 | | -}); |
| 199 | +} ); |
199 | 200 | |
200 | 201 | /** |
201 | 202 | * The base source attribute checks |
— | — | @@ -203,74 +204,74 @@ |
204 | 205 | mw.setDefaultConfig( 'embedPlayerSourceAttributes', [ |
205 | 206 | // source id |
206 | 207 | 'id', |
207 | | - |
| 208 | + |
208 | 209 | // media url |
209 | 210 | 'src', |
210 | | - |
211 | | - // media codecs attribute ( if provided ) |
| 211 | + |
| 212 | + // media codecs attribute ( if provided ) |
212 | 213 | 'codecs', |
213 | | - |
214 | | - // Title string for the source asset |
| 214 | + |
| 215 | + // Title string for the source asset |
215 | 216 | 'title', |
216 | | - |
| 217 | + |
217 | 218 | // boolean if we support temporal url requests on the source media |
218 | | - 'URLTimeEncoding', |
219 | | - |
220 | | - // Media has a startOffset ( used for plugins that |
221 | | - // display ogg page time rather than presentation time |
| 219 | + 'URLTimeEncoding', |
| 220 | + |
| 221 | + // Media has a startOffset ( used for plugins that |
| 222 | + // display ogg page time rather than presentation time |
222 | 223 | 'startOffset', |
223 | | - |
| 224 | + |
224 | 225 | // A hint to the duration of the media file so that duration |
225 | 226 | // can be displayed in the player without loading the media file |
226 | 227 | 'durationHint', |
227 | | - |
| 228 | + |
228 | 229 | // Media start time |
229 | 230 | 'start', |
230 | | - |
| 231 | + |
231 | 232 | // Media end time |
232 | 233 | 'end', |
233 | | - |
| 234 | + |
234 | 235 | // If the source is the default source |
235 | 236 | 'default', |
236 | | - |
| 237 | + |
237 | 238 | // Language key used for subtitle tracks |
238 | 239 | 'srclang', |
239 | | - |
240 | | - // titleKey ( used for api lookups ) |
| 240 | + |
| 241 | + // titleKey ( used for api lookups ) |
241 | 242 | 'titleKey', |
242 | | - |
| 243 | + |
243 | 244 | // The provider type ( for what type of api query to make ) |
244 | 245 | 'provider_type', |
245 | | - |
| 246 | + |
246 | 247 | // The api url for the provider |
247 | | - 'provider_url' |
| 248 | + 'provider_url' |
248 | 249 | ] ); |
249 | 250 | |
250 | 251 | /** |
251 | | -* Adds jQuery binding for embedPlayer |
| 252 | +* Adds jQuery binding for embedPlayer |
252 | 253 | */ |
253 | 254 | ( function( $ ) { |
254 | | - |
| 255 | + |
255 | 256 | /* |
256 | 257 | * embeds all players that match the rewrite player tags config |
257 | | - * Passes off request to the embedPlayer selector: |
258 | | - * |
| 258 | + * Passes off request to the embedPlayer selector: |
| 259 | + * |
259 | 260 | * @param {Object} attributes Attributes to apply to embed players |
260 | 261 | * @param {Function} callback Function to call once embedding is done |
261 | 262 | */ |
262 | 263 | $.embedPlayers = function( attributes, callback) { |
263 | 264 | $j( mw.getConfig( 'EmbedPlayer.RewriteTags' ) ).embedPlayer( attributes, callback ); |
264 | 265 | }; |
265 | | - |
266 | | - /** |
| 266 | + |
| 267 | + /** |
267 | 268 | * Selector based embedPlayer jQuery binding |
268 | 269 | * |
269 | 270 | * Rewrites all tags via a given selector |
270 | | - * |
| 271 | + * |
271 | 272 | * @param {object=} attributes Optional embedPlayer attributes for the given video interface. |
272 | 273 | * Attributes Object can include any key value pair that would otherwise be |
273 | | - * an attribute in the html element. |
274 | | - * |
| 274 | + * an attribute in the html element. |
| 275 | + * |
275 | 276 | * also see: mw.getConfig( 'EmbedPlayer.Attributes' ) |
276 | 277 | * |
277 | 278 | * @param {Function=} callback Optional Function to be called once video interfaces are ready |
— | — | @@ -279,31 +280,31 @@ |
280 | 281 | $.fn.embedPlayer = function( attributes, callback ) { |
281 | 282 | mw.log( 'EmbedPlayer:: fn.embedPlayer' ); |
282 | 283 | var playerSelect = this.selector; |
283 | | - |
| 284 | + |
284 | 285 | // Define attributes if unset |
285 | 286 | if( !attributes ) { |
286 | 287 | attributes = {}; |
287 | 288 | } |
288 | | - |
| 289 | + |
289 | 290 | // Handle optional include of attributes argument: |
290 | 291 | if( typeof attributes == 'function' ){ |
291 | 292 | callback = attributes; |
292 | 293 | attributes = {}; |
293 | 294 | } |
294 | | - |
295 | | - $j( playerSelect ).each( function( index, playerElement) { |
296 | | - // make sure the playerElement has an id: |
| 295 | + |
| 296 | + $j( playerSelect ).each( function( index, playerElement) { |
| 297 | + // make sure the playerElement has an id: |
297 | 298 | if( $j( playerElement ).attr('id') =='' ){ |
298 | | - $j( playerElement ).attr( "id", 'mwe_v' + ( index ) ); |
| 299 | + $j( playerElement ).attr( "id", 'mwe_v' + ( index ) ); |
299 | 300 | } |
300 | | - |
301 | | - // If we are dynamically embedding on a "div" check if we can |
| 301 | + |
| 302 | + // If we are dynamically embedding on a "div" check if we can |
302 | 303 | // add a poster image behind the loader: |
303 | | - if( playerElement.nodeName.toLowerCase() == 'div' |
| 304 | + if( playerElement.nodeName.toLowerCase() == 'div' |
304 | 305 | && ( attributes.poster || $j(playerElement).attr( 'poster' ) ) ){ |
305 | | - var posterSrc = ( attributes.poster ) ? attributes.poster : $j(playerElement).attr( 'poster' ); |
| 306 | + var posterSrc = ( attributes.poster ) ? attributes.poster : $j(playerElement).attr( 'poster' ); |
306 | 307 | |
307 | | - // Set image size: |
| 308 | + // Set image size: |
308 | 309 | var width = $j( playerElement ).width(); |
309 | 310 | var height = $j( playerElement ).height(); |
310 | 311 | if( !width ){ |
— | — | @@ -312,7 +313,7 @@ |
313 | 314 | if( !height ){ |
314 | 315 | var height = ( attributes.height )? attributes.height : '100%'; |
315 | 316 | } |
316 | | - |
| 317 | + |
317 | 318 | mw.log('EmbedPlayer:: set loading background: ' + posterSrc); |
318 | 319 | $j( playerElement ).append( |
319 | 320 | $j( '<img />' ) |
— | — | @@ -322,15 +323,15 @@ |
323 | 324 | 'width' : width, |
324 | 325 | 'height' : height |
325 | 326 | }) |
326 | | - ); |
| 327 | + ); |
327 | 328 | } |
328 | 329 | }); |
329 | | - |
330 | | - // If we have not detected browser plugin embed types do that now |
| 330 | + |
| 331 | + // If we have not detected browser plugin embed types do that now |
331 | 332 | if( ! mw.EmbedTypes.players ){ |
332 | 333 | mw.EmbedTypes.init(); |
333 | | - } |
334 | | - |
| 334 | + } |
| 335 | + |
335 | 336 | // Create the Global Embed Player Manager ( if not already created ) |
336 | 337 | if( ! mw.playerManager ) { |
337 | 338 | mw.log( "EmbedPlayer::Create the player manager:" ); |
— | — | @@ -338,31 +339,31 @@ |
339 | 340 | // Run the global hooks that mw.playerManager is ready |
340 | 341 | mw.log( 'EmbedPlayer::trigger: EmbedPlayerManagerReady'); |
341 | 342 | $j( mw ).trigger( 'EmbedPlayerManagerReady' ); |
342 | | - } |
| 343 | + } |
343 | 344 | var addedToPlayerManager = false; |
344 | | - // Make sure we have user preference setup ( for setting preferences on video selection ) |
345 | | - mw.setupUserConfig( function() { |
346 | | - mw.log("EmbedPlayer:: found: " + $j( playerSelect ).length + ' players '); |
347 | | - // Add each selected element to the player manager: |
348 | | - $j( playerSelect ).each( function( index, playerElement) { |
349 | | - // Make sure the video tag was not generated by our library: |
| 345 | + // Make sure we have user preference setup ( for setting preferences on video selection ) |
| 346 | + mw.setupUserConfig( function() { |
| 347 | + mw.log("EmbedPlayer:: found: " + $j( playerSelect ).length + ' players '); |
| 348 | + // Add each selected element to the player manager: |
| 349 | + $j( playerSelect ).each( function( index, playerElement) { |
| 350 | + // Make sure the video tag was not generated by our library: |
350 | 351 | if( $j( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){ |
351 | | - $j('#loadingSpinner_' + $j( playerElement ).attr('id') ).hide(); |
352 | | - mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
| 352 | + $j('#loadingSpinner_' + $j( playerElement ).attr('id') ).hide(); |
| 353 | + mw.log( 'EmbedPlayer::$j.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); |
353 | 354 | } else { |
354 | 355 | addedToPlayerManager = true; |
355 | 356 | // Add the embedPlayer ready callback |
356 | 357 | mw.playerManager.addCallback( callback ); |
357 | 358 | // Add the player |
358 | 359 | mw.playerManager.addElement( playerElement, attributes); |
359 | | - } |
360 | | - |
| 360 | + } |
| 361 | + |
361 | 362 | } ); |
362 | | - // run the callback directly if no players were added to the playerManager |
| 363 | + // run the callback directly if no players were added to the playerManager |
363 | 364 | if( !addedToPlayerManager && callback ){ |
364 | 365 | callback(); |
365 | 366 | } |
366 | | - |
| 367 | + |
367 | 368 | }); |
368 | 369 | }; |
369 | 370 | |
— | — | @@ -371,46 +372,46 @@ |
372 | 373 | /** |
373 | 374 | * EmbedPlayerManager |
374 | 375 | * |
375 | | -* Manages calls to embed video interfaces |
| 376 | +* Manages calls to embed video interfaces |
376 | 377 | */ |
377 | 378 | var EmbedPlayerManager = function( ) { |
378 | 379 | // Create a Player Manage |
379 | 380 | return this.init( ); |
380 | 381 | }; |
381 | 382 | EmbedPlayerManager.prototype = { |
382 | | - |
| 383 | + |
383 | 384 | // Functions to run after the video interface is ready |
384 | 385 | callbackFunctions : null, |
385 | | - |
| 386 | + |
386 | 387 | playerElementQueue: [], |
387 | | - |
| 388 | + |
388 | 389 | /** |
389 | | - * Constructor initializes callbackFunctions and playerList |
| 390 | + * Constructor initializes callbackFunctions and playerList |
390 | 391 | */ |
391 | | - init: function( ) { |
| 392 | + init: function( ) { |
392 | 393 | this.callbackFunctions = []; |
393 | 394 | this.playerList = []; |
394 | 395 | }, |
395 | | - |
| 396 | + |
396 | 397 | /** |
397 | 398 | * Adds a callback to the callbackFunctions list |
398 | 399 | * the callback functions are called once the players are ready. |
399 | 400 | * |
400 | | - * @param {Function} callback Function to be called once players are ready |
| 401 | + * @param {Function} callback Function to be called once players are ready |
401 | 402 | */ |
402 | 403 | addCallback: function( callback ) { |
403 | 404 | if( typeof callback == 'function' ){ |
404 | 405 | this.callbackFunctions.push( callback ); |
405 | 406 | } |
406 | 407 | }, |
407 | | - |
| 408 | + |
408 | 409 | /** |
409 | 410 | * Get the list of players |
410 | 411 | */ |
411 | 412 | getPlayerList: function( ) { |
412 | | - return this.playerList; |
| 413 | + return this.playerList; |
413 | 414 | }, |
414 | | - |
| 415 | + |
415 | 416 | /** |
416 | 417 | * Adds an Element for the embedPlayer to rewrite |
417 | 418 | * |
— | — | @@ -418,82 +419,82 @@ |
419 | 420 | * uses mvPlayList interface on playlist elements |
420 | 421 | * |
421 | 422 | * Once a player interface is established the following chain of functions are called; |
422 | | - * |
| 423 | + * |
423 | 424 | * _this.checkPlayerSources() |
424 | 425 | * _this.checkForTimedText() |
425 | 426 | * _this.setupSourcePlayer() |
426 | 427 | * _this.inheritEmbedPlayer() |
427 | 428 | * _this.selectedPlayer.load() |
428 | 429 | * _this.showPlayer() |
429 | | - * |
430 | | - * @param {Element} playerElement DOM element to be swapped |
431 | | - * @param {Object} [Optional] attributes Extra attributes to apply to the player interface |
| 430 | + * |
| 431 | + * @param {Element} playerElement DOM element to be swapped |
| 432 | + * @param {Object} [Optional] attributes Extra attributes to apply to the player interface |
432 | 433 | */ |
433 | | - addElement: function( playerElement, attributes ) { |
| 434 | + addElement: function( playerElement, attributes ) { |
434 | 435 | var _this = this; |
435 | | - |
| 436 | + |
436 | 437 | if ( !playerElement.id || playerElement.id == '' ) { |
437 | | - // give the playerElement an id: |
438 | | - playerElement.id = 'vid' + ( this.playerList.length + 1 ); |
439 | | - } |
| 438 | + // give the playerElement an id: |
| 439 | + playerElement.id = 'vid' + ( this.playerList.length + 1 ); |
| 440 | + } |
440 | 441 | mw.log('EmbedPlayerManager: addElement:: ' + playerElement.id ); |
441 | 442 | |
442 | 443 | // Add the element id to playerList |
443 | | - this.playerList.push( playerElement.id ); |
444 | | - |
445 | | - // Check for player attributes such as skins or plugins attributes |
446 | | - // that add to the request set |
| 444 | + this.playerList.push( playerElement.id ); |
| 445 | + |
| 446 | + // Check for player attributes such as skins or plugins attributes |
| 447 | + // that add to the request set |
447 | 448 | var playerDependencyRequest = []; |
448 | | - |
| 449 | + |
449 | 450 | // merge in any custom attributes |
450 | 451 | $j.extend( playerElement, attributes ); |
451 | | - |
452 | | - // Update the list of dependent libraries for the player |
| 452 | + |
| 453 | + // Update the list of dependent libraries for the player |
453 | 454 | // ( allows extensions to add to the dependency list ) |
454 | 455 | mw.embedPlayerUpdateLibraryRequest( playerElement, playerDependencyRequest ); |
455 | | - |
| 456 | + |
456 | 457 | // Load any skins we need then swap in the interface |
457 | 458 | mw.load( playerDependencyRequest, function() { |
458 | 459 | var waitForMeta = true; |
459 | | - |
460 | | - // Be sure to "stop" the target ( sometimes firefox keeps playing the video even |
461 | | - // though its been removed from the DOM ) |
| 460 | + |
| 461 | + // Be sure to "stop" the target ( sometimes firefox keeps playing the video even |
| 462 | + // though its been removed from the DOM ) |
462 | 463 | if( playerElement.pause ){ |
463 | 464 | playerElement.pause(); |
464 | 465 | } |
465 | | - |
466 | | - |
| 466 | + |
| 467 | + |
467 | 468 | // Let extensions determine if its worthwhile to wait for metadata: |
468 | | - // We pass an object to the trigger to preserve reference values |
469 | | - var eventObject = { |
470 | | - 'playerElement' : playerElement, |
| 469 | + // We pass an object to the trigger to preserve reference values |
| 470 | + var eventObject = { |
| 471 | + 'playerElement' : playerElement, |
471 | 472 | 'waitForMeta' : waitForMeta |
472 | | - }; |
| 473 | + }; |
473 | 474 | $j( mw ).trigger( 'addElementWaitForMetaEvent', eventObject ); |
474 | | - |
475 | | - // update the waitForMeta |
| 475 | + |
| 476 | + // update the waitForMeta |
476 | 477 | waitForMeta = eventObject[ 'waitForMeta' ]; |
477 | | - |
478 | | - |
| 478 | + |
| 479 | + |
479 | 480 | // Set the wait for meta flag if unset by extension |
480 | 481 | if( waitForMeta ){ |
481 | 482 | waitForMeta = _this.waitForMetaCheck( playerElement ); |
482 | 483 | } |
483 | | - |
484 | | - var ranPlayerSwapFlag = false; |
485 | | - |
| 484 | + |
| 485 | + var ranPlayerSwapFlag = false; |
| 486 | + |
486 | 487 | // Local callback to runPlayer swap once playerElement has metadata |
487 | 488 | function runPlayerSwap() { |
488 | 489 | if( ranPlayerSwapFlag ){ |
489 | | - return ; |
| 490 | + return ; |
490 | 491 | } |
491 | | - ranPlayerSwapFlag = true; |
| 492 | + ranPlayerSwapFlag = true; |
492 | 493 | mw.log("EmbedPlayer::runPlayerSwap::" + $j( playerElement ).attr('id') ); |
493 | | - |
494 | | - var playerInterface = new mw.EmbedPlayer( playerElement , attributes); |
495 | | - var swapPlayer = _this.swapEmbedPlayerElement( playerElement, playerInterface ); |
496 | | - |
497 | | - // Copy over any data attributes from the playerElement |
| 494 | + |
| 495 | + var playerInterface = new mw.EmbedPlayer( playerElement , attributes); |
| 496 | + var swapPlayer = _this.swapEmbedPlayerElement( playerElement, playerInterface ); |
| 497 | + |
| 498 | + // Copy over any data attributes from the playerElement |
498 | 499 | if( mw.getConfig( 'EmbedPlayer.DataAttributes' ) ) { |
499 | 500 | var dataAttr = mw.getConfig( 'EmbedPlayer.DataAttributes' ); |
500 | 501 | for( var i in dataAttr ){ |
— | — | @@ -502,45 +503,45 @@ |
503 | 504 | } |
504 | 505 | } |
505 | 506 | } |
506 | | - |
| 507 | + |
507 | 508 | // Pass the id to any hook that needs to interface prior to checkPlayerSources |
508 | 509 | mw.log("EmbedPlayer::addElement :trigger " + playerInterface.id ); |
509 | 510 | $j( mw ).trigger ( 'newEmbedPlayerEvent', $j( '#' + playerInterface.id ).get(0) ); |
510 | | - |
| 511 | + |
511 | 512 | // Issue the checkPlayerSources call to the new player interface: |
512 | | - // make sure to use the element that is in the DOM: |
513 | | - $j( '#' + playerInterface.id ).get(0).checkPlayerSources(); |
| 513 | + // make sure to use the element that is in the DOM: |
| 514 | + $j( '#' + playerInterface.id ).get(0).checkPlayerSources(); |
514 | 515 | } |
515 | | - |
516 | | - if( waitForMeta ) { |
517 | | - mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + |
518 | | - $j( playerElement ).attr('height') + '), width (' + |
| 516 | + |
| 517 | + if( waitForMeta ) { |
| 518 | + mw.log('EmbedPlayer::WaitForMeta ( video missing height (' + |
| 519 | + $j( playerElement ).attr('height') + '), width (' + |
519 | 520 | $j( playerElement ).attr('width') + ') or duration: ' + |
520 | | - $j( playerElement ).attr('duration') |
| 521 | + $j( playerElement ).attr('duration') |
521 | 522 | ); |
522 | | - |
| 523 | + |
523 | 524 | playerElement.removeEventListener( "loadedmetadata", runPlayerSwap, true ); |
524 | 525 | playerElement.addEventListener( "loadedmetadata", runPlayerSwap, true ); |
525 | | - |
| 526 | + |
526 | 527 | // Time-out of 5 seconds ( maybe still playable but no timely metadata ) |
527 | 528 | setTimeout( runPlayerSwap, 5000 ); |
528 | 529 | return ; |
529 | | - } else { |
| 530 | + } else { |
530 | 531 | runPlayerSwap(); |
531 | 532 | return ; |
532 | | - } |
533 | | - }); |
| 533 | + } |
| 534 | + }); |
534 | 535 | }, |
535 | | - |
536 | | - /** |
537 | | - * Check for bogus resolutions of the media asset that has not loaded. |
538 | | - * @return |
539 | | - * true if the resolution is "likely" to be updated |
| 536 | + |
| 537 | + /** |
| 538 | + * Check for bogus resolutions of the media asset that has not loaded. |
| 539 | + * @return |
| 540 | + * true if the resolution is "likely" to be updated |
540 | 541 | * by waiting for metadata |
541 | 542 | * false if the resolution has been set via an attribute or is already loaded |
542 | | - */ |
| 543 | + */ |
543 | 544 | waitForMetaCheck: function( playerElement ){ |
544 | | - var waitForMeta = false; |
| 545 | + var waitForMeta = false; |
545 | 546 | if( !playerElement ) |
546 | 547 | return ; |
547 | 548 | // If we don't have a native player don't wait for metadata |
— | — | @@ -548,156 +549,156 @@ |
549 | 550 | !mw.EmbedTypes.players.isSupportedPlayer( 'h264Native' ) ) |
550 | 551 | { |
551 | 552 | return false; |
552 | | - } |
553 | | - |
554 | | - |
| 553 | + } |
| 554 | + |
| 555 | + |
555 | 556 | var width = $j( playerElement ).css( 'width' ); |
556 | 557 | var height = $j( playerElement ).css( 'height' ); |
557 | | - |
558 | | - // Css video defaults |
559 | | - if( $j( playerElement ).css( 'width' ) == '300px' && |
| 558 | + |
| 559 | + // Css video defaults |
| 560 | + if( $j( playerElement ).css( 'width' ) == '300px' && |
560 | 561 | $j( playerElement ).css( 'height' ) == '150px' |
561 | 562 | ){ |
562 | 563 | waitForMeta = true; |
563 | | - } else { |
564 | | - // Check if we should wait for duration: |
565 | | - if( $j( playerElement ).attr( 'duration') || |
| 564 | + } else { |
| 565 | + // Check if we should wait for duration: |
| 566 | + if( $j( playerElement ).attr( 'duration') || |
566 | 567 | $j( playerElement ).attr('durationHint') |
567 | 568 | ){ |
568 | 569 | // height, width and duration set; do not wait for meta data: |
569 | 570 | return false; |
570 | | - } else { |
| 571 | + } else { |
571 | 572 | waitForMeta = true; |
572 | 573 | } |
573 | 574 | } |
574 | | - |
| 575 | + |
575 | 576 | //Firefox ~ sometimes ~ gives -1 for unloaded media |
576 | 577 | if ( $j(playerElement).attr( 'width' ) == -1 || $j(playerElement).attr( 'height' ) == -1 ) { |
577 | | - waitForMeta = true; |
| 578 | + waitForMeta = true; |
578 | 579 | } |
579 | | - |
| 580 | + |
580 | 581 | // Google Chrome / safari gives 0 width height for unloaded media |
581 | | - if( $j(playerElement).attr( 'width' ) === 0 || |
582 | | - $j(playerElement).attr( 'height' ) === 0 |
| 582 | + if( $j(playerElement).attr( 'width' ) === 0 || |
| 583 | + $j(playerElement).attr( 'height' ) === 0 |
583 | 584 | ) { |
584 | 585 | waitForMeta = true; |
585 | 586 | } |
586 | | - |
| 587 | + |
587 | 588 | // Firefox default width height is ~sometimes~ 150 / 300 |
588 | 589 | if( this.height == 150 && this.width == 300 ){ |
589 | | - waitForMeta = true; |
590 | | - } |
591 | | - |
592 | | - // Make sure we have a src attribute or source child |
| 590 | + waitForMeta = true; |
| 591 | + } |
| 592 | + |
| 593 | + // Make sure we have a src attribute or source child |
593 | 594 | // ( i.e not a video tag to be dynamically populated or looked up from xml resource description ) |
594 | | - if( waitForMeta && |
| 595 | + if( waitForMeta && |
595 | 596 | ( |
596 | 597 | $j( playerElement ).attr('src') || |
597 | | - $j( playerElement ).find("source[src]").length !== 0 |
| 598 | + $j( playerElement ).find("source[src]").length !== 0 |
598 | 599 | ) |
599 | 600 | ) { |
600 | | - // Detect src type ( if no type set ) |
| 601 | + // Detect src type ( if no type set ) |
601 | 602 | return true; |
602 | | - } else { |
| 603 | + } else { |
603 | 604 | // playerElement is not likely to update its meta data ( no src ) |
604 | 605 | return false; |
605 | | - } |
| 606 | + } |
606 | 607 | }, |
607 | | - |
| 608 | + |
608 | 609 | /** |
609 | 610 | * swapEmbedPlayerElement |
610 | 611 | * |
611 | 612 | * Takes a video element as input and swaps it out with |
612 | 613 | * an embed player interface |
613 | 614 | * |
614 | | - * @param {Element} targetElement Element to be swapped |
| 615 | + * @param {Element} targetElement Element to be swapped |
615 | 616 | * @param {Object} playerInterface Interface to swap into the target element |
616 | 617 | */ |
617 | | - swapEmbedPlayerElement: function( targetElement, playerInterface ) { |
| 618 | + swapEmbedPlayerElement: function( targetElement, playerInterface ) { |
618 | 619 | mw.log( 'EmbedPlayer::swapEmbedPlayerElement: ' + targetElement.id ); |
619 | 620 | // Create a new element to swap the player interface into |
620 | | - var swapPlayerElement = document.createElement('div'); |
621 | | - |
| 621 | + var swapPlayerElement = document.createElement('div'); |
| 622 | + |
622 | 623 | // Get properties / methods from playerInterface |
623 | | - for ( var method in playerInterface ) { |
624 | | - if ( method != 'readyState' ) { // readyState crashes IE ( don't include ) |
| 624 | + for ( var method in playerInterface ) { |
| 625 | + if ( method != 'readyState' ) { // readyState crashes IE ( don't include ) |
625 | 626 | swapPlayerElement[ method ] = playerInterface[ method ]; |
626 | 627 | } |
627 | 628 | } |
628 | | - |
| 629 | + |
629 | 630 | // Check if we are using native controls ( should keep the video embed around ) |
630 | 631 | if( playerInterface.useNativePlayerControls() ) { |
631 | 632 | $j( targetElement ) |
632 | 633 | .attr( 'id', playerInterface.pid ) |
633 | 634 | .addClass( 'nativeEmbedPlayerPid' ) |
634 | 635 | .show() |
635 | | - .after( |
| 636 | + .after( |
636 | 637 | $j( swapPlayerElement ).css( 'display', 'none' ) |
637 | 638 | ); |
638 | 639 | } else { |
639 | 640 | $j( targetElement ).replaceWith( swapPlayerElement ); |
640 | 641 | } |
641 | | - |
642 | | - |
643 | | - // Set swapPlayerElement has height / width set and set to loading: |
644 | | - $j( swapPlayerElement ).css( { |
645 | | - 'width' : playerInterface.width + 'px', |
646 | | - 'height' : playerInterface.height + 'px' |
| 642 | + |
| 643 | + |
| 644 | + // Set swapPlayerElement has height / width set and set to loading: |
| 645 | + $j( swapPlayerElement ).css( { |
| 646 | + 'width' : playerInterface.width, |
| 647 | + 'height' : playerInterface.height |
647 | 648 | } ); |
648 | | - |
649 | | - // If we don't already have a loadSpiner add one: |
| 649 | + |
| 650 | + // If we don't already have a loadSpiner add one: |
650 | 651 | if( $j('#loadingSpinner_' + playerInterface.id ).length == 0 ){ |
651 | 652 | if( playerInterface.useNativePlayerControls() ) { |
652 | 653 | $j( targetElement ) |
653 | 654 | .getAbsoluteOverlaySpinner() |
654 | 655 | .attr('id', 'loadingSpinner_' + playerInterface.id ); |
655 | 656 | }else{ |
656 | | - $j( swapPlayerElement ).append( |
| 657 | + $j( swapPlayerElement ).append( |
657 | 658 | $j('<div />') |
658 | | - .loadingSpinner() |
| 659 | + .loadingSpinner() |
659 | 660 | ); |
660 | 661 | } |
661 | 662 | } |
662 | 663 | return swapPlayerElement; |
663 | 664 | }, |
664 | | - |
665 | | - |
| 665 | + |
| 666 | + |
666 | 667 | /** |
667 | | - * Player ready will run the global callbacks |
| 668 | + * Player ready will run the global callbacks |
668 | 669 | * once players are "ready" |
669 | | - * |
670 | | - * This enables mw.ready event to expose video tag |
671 | | - * elements as if the videotag was supported natively. |
672 | 670 | * |
| 671 | + * This enables mw.ready event to expose video tag |
| 672 | + * elements as if the videotag was supported natively. |
| 673 | + * |
673 | 674 | * @param {Object} player The EmbedPlayer object |
674 | 675 | */ |
675 | 676 | playerReady: function( player ) { |
676 | 677 | var _this = this; |
677 | | - mw.log( 'EmbedPlayer::ReadyToPlay callback player:' + player.id ); |
| 678 | + mw.log( 'EmbedPlayer::ReadyToPlay callback player:' + player.id ); |
678 | 679 | player.readyToPlay = true; |
679 | | - |
| 680 | + |
680 | 681 | // Remove the player loader spinner: |
681 | 682 | $j('#loadingSpinner_' + player.id ).remove(); |
682 | | - |
683 | | - // Run the player ready trigger |
| 683 | + |
| 684 | + // Run the player ready trigger |
684 | 685 | $j( player ).trigger( 'playerReady' ); |
685 | | - |
686 | | - var is_ready = true; |
| 686 | + |
| 687 | + var is_ready = true; |
687 | 688 | for ( var i = 0; i < this.playerList.length; i++ ) { |
688 | | - var currentPlayer = $j( '#' + this.playerList[i] ).get( 0 ); |
| 689 | + var currentPlayer = $j( '#' + this.playerList[i] ).get( 0 ); |
689 | 690 | if ( player ) { |
690 | | - // Check if the current video is ready ( or has an error out ) |
691 | | - is_ready = ( player.readyToPlay || player.loadError ) ? is_ready : false; |
| 691 | + // Check if the current video is ready ( or has an error out ) |
| 692 | + is_ready = ( player.readyToPlay || player.loadError ) ? is_ready : false; |
692 | 693 | } |
693 | 694 | } |
694 | 695 | if ( is_ready ) { |
695 | 696 | // Be sure to remove any player loader spinners |
696 | 697 | $j('.playerLoadingSpinner').remove(); |
697 | | - |
698 | | - mw.log( "EmbedPlayer::All on-page players ready run playerMannager callbacks" ); |
699 | | - // Run queued functions |
| 698 | + |
| 699 | + mw.log( "EmbedPlayer::All on-page players ready run playerManager callbacks" ); |
| 700 | + // Run queued functions |
700 | 701 | if( _this.callbackFunctions ) { |
701 | | - while ( _this.callbackFunctions.length ) { |
| 702 | + while ( _this.callbackFunctions.length ) { |
702 | 703 | _this.callbackFunctions.shift()(); |
703 | 704 | } |
704 | 705 | } |
— | — | @@ -717,70 +718,70 @@ |
718 | 719 | mediaSource.prototype = { |
719 | 720 | // MIME type of the source. |
720 | 721 | mimeType:null, |
721 | | - |
| 722 | + |
722 | 723 | // URI of the source. |
723 | 724 | uri:null, |
724 | | - |
| 725 | + |
725 | 726 | // Title of the source. |
726 | 727 | title: null, |
727 | | - |
| 728 | + |
728 | 729 | // True if the source has been marked as the default. |
729 | 730 | markedDefault: false, |
730 | | - |
731 | | - // True if the source supports url specification of offset and duration |
| 731 | + |
| 732 | + // True if the source supports url specification of offset and duration |
732 | 733 | URLTimeEncoding:false, |
733 | | - |
734 | | - // Start offset of the requested segment |
| 734 | + |
| 735 | + // Start offset of the requested segment |
735 | 736 | startOffset: 0, |
736 | | - |
737 | | - // Duration of the requested segment (0 if not known) |
| 737 | + |
| 738 | + // Duration of the requested segment (0 if not known) |
738 | 739 | duration:0, |
739 | | - |
| 740 | + |
740 | 741 | // Is the source playable |
741 | 742 | is_playable: null, |
742 | | - |
| 743 | + |
743 | 744 | // source id |
744 | 745 | id: null, |
745 | | - |
| 746 | + |
746 | 747 | // Start time in npt format |
747 | 748 | start_npt: null, |
748 | | - |
| 749 | + |
749 | 750 | // End time in npt format |
750 | 751 | end_npt: null, |
751 | | - |
752 | | - // A provider "id" to identify api request type |
| 752 | + |
| 753 | + // A provider "id" to identify api request type |
753 | 754 | provider_type : null, |
754 | 755 | |
755 | 756 | // The api url for the provider |
756 | | - provider_url : null, |
757 | | - |
| 757 | + provider_url : null, |
| 758 | + |
758 | 759 | /** |
759 | 760 | * MediaSource constructor: |
760 | 761 | */ |
761 | | - init : function( element ) { |
| 762 | + init : function( element ) { |
762 | 763 | // mw.log('EmbedPlayer::adding mediaSource: ' + element); |
763 | | - this.src = $j( element ).attr( 'src' ); |
764 | | - |
765 | | - // Set default URLTimeEncoding if we have a time url: |
766 | | - // not ideal way to discover if content is on an oggz_chop server. |
767 | | - // should check some other way. |
| 764 | + this.src = $j( element ).attr( 'src' ); |
| 765 | + |
| 766 | + // Set default URLTimeEncoding if we have a time url: |
| 767 | + // not ideal way to discover if content is on an oggz_chop server. |
| 768 | + // should check some other way. |
768 | 769 | var pUrl = mw.parseUri ( this.src ); |
769 | 770 | if ( typeof pUrl[ 'queryKey' ][ 't' ] != 'undefined' ) { |
770 | 771 | this.URLTimeEncoding = true; |
771 | 772 | } |
772 | | - |
| 773 | + |
773 | 774 | var sourceAttr = mw.getConfig( 'embedPlayerSourceAttributes' ); |
774 | | - |
| 775 | + |
775 | 776 | for ( var i = 0; i < sourceAttr.length; i++ ) { // array loop: |
776 | 777 | var attr = sourceAttr[ i ]; |
777 | 778 | var attr_value = element.getAttribute( attr ); |
778 | 779 | if ( attr_value ) { |
779 | | - this[ attr ] = attr_value; |
| 780 | + this[ attr ] = attr_value; |
780 | 781 | } |
781 | 782 | } |
782 | | - |
783 | | - |
784 | | - // Set the content type: |
| 783 | + |
| 784 | + |
| 785 | + // Set the content type: |
785 | 786 | if ( $j( element ).attr( 'type' ) ) { |
786 | 787 | this.mimeType = $j( element ).attr( 'type' ); |
787 | 788 | }else if ( $j( element ).attr( 'content-type' ) ) { |
— | — | @@ -791,41 +792,41 @@ |
792 | 793 | } else { |
793 | 794 | this.mimeType = this.detectType( this.src ); |
794 | 795 | } |
795 | | - |
| 796 | + |
796 | 797 | // Conform the mime type to ogg |
797 | 798 | if( this.mimeType == 'video/theora') { |
798 | 799 | this.mimeType = 'video/ogg'; |
799 | 800 | } |
800 | | - |
| 801 | + |
801 | 802 | if( this.mimeType == 'audio/vorbis') { |
802 | 803 | this.mimeType = 'audio/ogg'; |
803 | 804 | } |
804 | | - |
| 805 | + |
805 | 806 | // Check for parent elements ( supplies categories in "track" ) |
806 | | - if( $j( element ).parent().attr('category') ) { |
807 | | - this.category = $j( element ).parent().attr('category'); |
| 807 | + if( $j( element ).parent().attr('category') ) { |
| 808 | + this.category = $j( element ).parent().attr('category'); |
808 | 809 | } |
809 | | - |
| 810 | + |
810 | 811 | if( $j( element ).attr( 'default' ) ){ |
811 | 812 | this.markedDefault = true; |
812 | 813 | } |
813 | | - |
| 814 | + |
814 | 815 | // Get the url duration ( if applicable ) |
815 | 816 | this.getURLDuration(); |
816 | 817 | }, |
817 | | - |
| 818 | + |
818 | 819 | /** |
819 | 820 | * Update Source title via Element |
820 | 821 | * @param {Element} element Source element to update attributes from |
821 | 822 | */ |
822 | 823 | updateSource: function( element ) { |
823 | | - // for now just update the title: |
| 824 | + // for now just update the title: |
824 | 825 | if ( $j( element ).attr( "title" ) ) { |
825 | 826 | this.title = $j( element ).attr( "title" ); |
826 | 827 | } |
827 | 828 | }, |
828 | | - |
829 | | - /** |
| 829 | + |
| 830 | + /** |
830 | 831 | * Updates the src time and start & end |
831 | 832 | * @param {String} start_time: in NPT format |
832 | 833 | * @param {String} end_time: in NPT format |
— | — | @@ -835,26 +836,26 @@ |
836 | 837 | // mw.log("pre uri:" + this.src); |
837 | 838 | // if we have time we can use: |
838 | 839 | if ( this.URLTimeEncoding ) { |
839 | | - // make sure its a valid start time / end time (else set default) |
| 840 | + // make sure its a valid start time / end time (else set default) |
840 | 841 | if ( !mw.npt2seconds( start_npt ) ) { |
841 | 842 | start_npt = this.start_npt; |
842 | 843 | } |
843 | | - |
| 844 | + |
844 | 845 | if ( !mw.npt2seconds( end_npt ) ) { |
845 | 846 | end_npt = this.end_npt; |
846 | 847 | } |
847 | | - |
848 | | - this.src = mw.replaceUrlParams( this.src, { |
849 | | - 't': start_npt + '/' + end_npt |
| 848 | + |
| 849 | + this.src = mw.replaceUrlParams( this.src, { |
| 850 | + 't': start_npt + '/' + end_npt |
850 | 851 | }); |
851 | | - |
| 852 | + |
852 | 853 | // update the duration |
853 | 854 | this.getURLDuration(); |
854 | 855 | } |
855 | 856 | }, |
856 | | - |
| 857 | + |
857 | 858 | /** |
858 | | - * Sets the duration and sets the end time if unset |
| 859 | + * Sets the duration and sets the end time if unset |
859 | 860 | * @param {Float} duration: in seconds |
860 | 861 | */ |
861 | 862 | setDuration: function ( duration ) { |
— | — | @@ -863,8 +864,8 @@ |
864 | 865 | this.end_npt = mw.seconds2npt( this.startOffset + duration ); |
865 | 866 | } |
866 | 867 | }, |
867 | | - |
868 | | - /** |
| 868 | + |
| 869 | + /** |
869 | 870 | * MIME type accessors function. |
870 | 871 | * @return {String} the MIME type of the source. |
871 | 872 | */ |
— | — | @@ -875,9 +876,9 @@ |
876 | 877 | this.mimeType = this.detectType( this.src ); |
877 | 878 | return this.mimeType; |
878 | 879 | }, |
879 | | - |
| 880 | + |
880 | 881 | /** URI function. |
881 | | - * @param {Number} serverSeekTime Int: Used to adjust the URI for url based seeks) |
| 882 | + * @param {Number} serverSeekTime Int: Used to adjust the URI for url based seeks) |
882 | 883 | * @return {String} the URI of the source. |
883 | 884 | */ |
884 | 885 | getSrc : function( serverSeekTime ) { |
— | — | @@ -890,21 +891,21 @@ |
891 | 892 | } |
892 | 893 | return mw.replaceUrlParams( this.src, |
893 | 894 | { |
894 | | - 't': mw.seconds2npt( serverSeekTime ) + endvar |
895 | | - } |
896 | | - ); |
| 895 | + 't' : mw.seconds2npt( serverSeekTime ) + endvar |
| 896 | + } |
| 897 | + ); |
897 | 898 | }, |
898 | | - |
899 | | - /** |
| 899 | + |
| 900 | + /** |
900 | 901 | * Title accessor function. |
901 | 902 | * @return {String} Title of the source. |
902 | 903 | */ |
903 | | - getTitle : function() { |
| 904 | + getTitle : function() { |
904 | 905 | if( this.title ){ |
905 | 906 | return this.title; |
906 | 907 | } |
907 | | - |
908 | | - // Return a Title based on mime type: |
| 908 | + |
| 909 | + // Return a Title based on mime type: |
909 | 910 | switch( this.getMIMEType() ) { |
910 | 911 | case 'video/h264' : |
911 | 912 | return gM( 'mwe-embedplayer-video-h264' ); |
— | — | @@ -925,25 +926,25 @@ |
926 | 927 | return 'AVI video'; // FIXME: i18n |
927 | 928 | break; |
928 | 929 | } |
929 | | - |
930 | | - // Return tilte based on file name: |
| 930 | + |
| 931 | + // Return Title based on file name: |
931 | 932 | var urlParts = mw.parseUri( this.getSrc() ); |
932 | 933 | if( urlParts.file ){ |
933 | 934 | return urlParts.file; |
934 | 935 | } |
935 | | - |
| 936 | + |
936 | 937 | // Return the mime type string if not known type. |
937 | 938 | return this.mimeType; |
938 | 939 | }, |
939 | | - |
940 | | - /** |
941 | | - * |
| 940 | + |
| 941 | + /** |
| 942 | + * |
942 | 943 | * Get Duration of the media in milliseconds from the source url. |
943 | 944 | * |
944 | 945 | * Supports media_url?t=ntp_start/ntp_end url request format |
945 | 946 | */ |
946 | 947 | getURLDuration : function() { |
947 | | - // check if we have a URLTimeEncoding: |
| 948 | + // check if we have a URLTimeEncoding: |
948 | 949 | if ( this.URLTimeEncoding ) { |
949 | 950 | var annoURL = mw.parseUri( this.src ); |
950 | 951 | if ( annoURL.queryKey.t ) { |
— | — | @@ -954,7 +955,7 @@ |
955 | 956 | this.duration = mw.npt2seconds( this.end_npt ) - this.startOffset; |
956 | 957 | } else { |
957 | 958 | // look for this info as attributes |
958 | | - if ( this.startOffset ) { |
| 959 | + if ( this.startOffset ) { |
959 | 960 | this.start_npt = mw.seconds2npt( this.startOffset ); |
960 | 961 | } |
961 | 962 | if ( this.duration ) { |
— | — | @@ -963,8 +964,8 @@ |
964 | 965 | } |
965 | 966 | } |
966 | 967 | }, |
967 | | - |
968 | | - /** |
| 968 | + |
| 969 | + /** |
969 | 970 | * Attempts to detect the type of a media file based on the URI. |
970 | 971 | * @param {String} uri URI of the media file. |
971 | 972 | * @return {String} The guessed MIME type of the file. |
— | — | @@ -972,14 +973,15 @@ |
973 | 974 | detectType: function( uri ) { |
974 | 975 | // NOTE: if media is on the same server as the javascript |
975 | 976 | // we can issue a HEAD request and read the mime type of the media... |
976 | | - // ( this will detect media mime type independently of the url name) |
| 977 | + // ( this will detect media mime type independently of the url name ) |
977 | 978 | // http://www.jibbering.com/2002/4/httprequest.html |
978 | | - var end_inx = ( uri.indexOf( '?' ) != -1 ) ? uri.indexOf( '?' ) : uri.length; |
979 | | - var no_param_uri = uri.substr( 0, end_inx ); |
980 | | - switch( no_param_uri.substr( no_param_uri.lastIndexOf( '.' ), 4 ).toLowerCase() ) { |
| 979 | + var urlParts = mw.parseUri( uri ); |
| 980 | + // Get the extension from the url or from the relative name: |
| 981 | + var ext = ( urlParts.file )? urlParts.file.substr( -4 ) : uri.substr( -4 ); |
| 982 | + switch( ext.toLowerCase() ) { |
981 | 983 | case 'smil': |
982 | 984 | case '.sml': |
983 | | - return 'application/smil' |
| 985 | + return 'application/smil'; |
984 | 986 | break; |
985 | 987 | case '.m4v': |
986 | 988 | case '.mp4': |
— | — | @@ -1017,13 +1019,14 @@ |
1018 | 1020 | return 'video/mpeg'; |
1019 | 1021 | break; |
1020 | 1022 | } |
| 1023 | + mw.log( "Error: could not detect type of media src: " + uri ); |
1021 | 1024 | } |
1022 | 1025 | }; |
1023 | 1026 | |
1024 | | -/** |
| 1027 | +/** |
1025 | 1028 | * A media element corresponding to a <video> element. |
1026 | 1029 | * |
1027 | | -* It is implemented as a collection of mediaSource objects. The media sources |
| 1030 | +* It is implemented as a collection of mediaSource objects. The media sources |
1028 | 1031 | * will be initialized from the <video> element, its child <source> elements, |
1029 | 1032 | * and/or the ROE file referenced by the <video> element. |
1030 | 1033 | * @param {element} videoElement <video> element used for initialization. |
— | — | @@ -1034,48 +1037,48 @@ |
1035 | 1038 | } |
1036 | 1039 | |
1037 | 1040 | mediaElement.prototype = { |
1038 | | - |
| 1041 | + |
1039 | 1042 | // The array of mediaSource elements. |
1040 | 1043 | sources: null, |
1041 | | - |
| 1044 | + |
1042 | 1045 | // flag for ROE data being added. |
1043 | 1046 | addedROEData: false, |
1044 | | - |
1045 | | - // Selected mediaSource element. |
| 1047 | + |
| 1048 | + // Selected mediaSource element. |
1046 | 1049 | selectedSource: null, |
1047 | | - |
| 1050 | + |
1048 | 1051 | // Media element thumbnail |
1049 | 1052 | thumbnail: null, |
1050 | | - |
1051 | | - // Media element linkback |
| 1053 | + |
| 1054 | + // Media element linkback |
1052 | 1055 | linkback: null, |
1053 | 1056 | |
1054 | 1057 | /** |
1055 | 1058 | * Media Element constructor |
1056 | 1059 | * |
1057 | | - * Sets up a mediaElement from a provided top level "video" element |
| 1060 | + * Sets up a mediaElement from a provided top level "video" element |
1058 | 1061 | * adds any child sources that are found |
1059 | 1062 | * |
1060 | | - * @param {Element} videoElement Element that has src attribute or has children source elements |
| 1063 | + * @param {Element} videoElement Element that has src attribute or has children source elements |
1061 | 1064 | */ |
1062 | 1065 | init: function( videoElement ) { |
1063 | | - var _this = this; |
1064 | | - mw.log( "EmbedPlayer::mediaElement:init:" + videoElement.id ); |
1065 | | - this.sources = new Array(); |
1066 | | - |
| 1066 | + var _this = this; |
| 1067 | + mw.log( "EmbedPlayer::mediaElement:init:" + videoElement.id ); |
| 1068 | + this.sources = new Array(); |
| 1069 | + |
1067 | 1070 | // Process the videoElement as a source element: |
1068 | 1071 | if ( $j( videoElement ).attr( "src" ) ) { |
1069 | 1072 | _this.tryAddSource( videoElement ); |
1070 | 1073 | } |
1071 | | - |
| 1074 | + |
1072 | 1075 | // Process elements source children |
1073 | | - $j( videoElement ).find( 'source,track' ).each( function( ) { |
| 1076 | + $j( videoElement ).find( 'source,track' ).each( function( ) { |
1074 | 1077 | _this.tryAddSource( this ); |
1075 | | - } ); |
| 1078 | + } ); |
1076 | 1079 | }, |
1077 | | - |
1078 | | - /** |
1079 | | - * Updates the time request for all sources that have |
| 1080 | + |
| 1081 | + /** |
| 1082 | + * Updates the time request for all sources that have |
1080 | 1083 | * a standard time request argument (ie &t=start_time/end_time) |
1081 | 1084 | * |
1082 | 1085 | * @param {String} start_npt Start time in npt format |
— | — | @@ -1087,26 +1090,26 @@ |
1088 | 1091 | mediaSource.updateSrcTime( start_npt, end_npt ); |
1089 | 1092 | } ); |
1090 | 1093 | }, |
1091 | | - |
| 1094 | + |
1092 | 1095 | /** |
1093 | 1096 | * Check for Timed Text tracks |
1094 | 1097 | * @return {Boolean} True if text tracks exist, false if no text tracks are found |
1095 | 1098 | */ |
1096 | 1099 | textSourceExists: function() { |
1097 | 1100 | for ( var i = 0; i < this.sources.length; i++ ) { |
1098 | | - mw.log('EmbedPlayer::textSourceExists:'+ this.sources[i].mimeType ); |
1099 | | - if ( this.sources[i].mimeType == 'text/cmml' || |
1100 | | - this.sources[i].mimeType == 'text/x-srt' ) |
| 1101 | + mw.log('EmbedPlayer::textSourceExists:'+ this.sources[i].mimeType ); |
| 1102 | + if ( this.sources[i].mimeType == 'text/cmml' || |
| 1103 | + this.sources[i].mimeType == 'text/x-srt' ) |
1101 | 1104 | { |
1102 | 1105 | return true; |
1103 | 1106 | } |
1104 | 1107 | }; |
1105 | 1108 | return false; |
1106 | 1109 | }, |
1107 | | - |
1108 | | - /** |
| 1110 | + |
| 1111 | + /** |
1109 | 1112 | * Returns the array of mediaSources of this element. |
1110 | | - * |
| 1113 | + * |
1111 | 1114 | * @param {String} [mimeFilter] Filter criteria for set of mediaSources to return |
1112 | 1115 | * @return {Array} mediaSource elements. |
1113 | 1116 | */ |
— | — | @@ -1114,34 +1117,34 @@ |
1115 | 1118 | if ( !mimeFilter ) { |
1116 | 1119 | return this.sources; |
1117 | 1120 | } |
1118 | | - // Apply mime filter: |
| 1121 | + // Apply mime filter: |
1119 | 1122 | var source_set = new Array(); |
1120 | 1123 | for ( var i = 0; i < this.sources.length ; i++ ) { |
1121 | 1124 | if ( this.sources[i].mimeType && |
1122 | | - this.sources[i].mimeType.indexOf( mimeFilter ) != -1 ) |
| 1125 | + this.sources[i].mimeType.indexOf( mimeFilter ) != -1 ) |
1123 | 1126 | { |
1124 | 1127 | source_set.push( this.sources[i] ); |
1125 | 1128 | } |
1126 | 1129 | } |
1127 | 1130 | return source_set; |
1128 | 1131 | }, |
1129 | | - |
| 1132 | + |
1130 | 1133 | /** |
1131 | 1134 | * Selects a source by id |
1132 | | - * @param {String} source_id Id of the source to select. |
1133 | | - * @return {MediaSource} The selected mediaSource or null if not found |
| 1135 | + * @param {String} source_id Id of the source to select. |
| 1136 | + * @return {MediaSource} The selected mediaSource or null if not found |
1134 | 1137 | */ |
1135 | 1138 | getSourceById:function( source_id ) { |
1136 | 1139 | for ( var i = 0; i < this.sources.length ; i++ ) { |
1137 | | - if ( this.sources[i].id == source_id ) { |
| 1140 | + if ( this.sources[i].id == source_id ) { |
1138 | 1141 | return this.sources[i]; |
1139 | 1142 | } |
1140 | 1143 | } |
1141 | 1144 | return null; |
1142 | 1145 | }, |
1143 | | - |
1144 | | - /** |
1145 | | - * Selects a particular source for playback updating the "selectedSource" |
| 1146 | + |
| 1147 | + /** |
| 1148 | + * Selects a particular source for playback updating the "selectedSource" |
1146 | 1149 | * |
1147 | 1150 | * @param {Number} index Index of source element to set as selectedSource |
1148 | 1151 | */ |
— | — | @@ -1151,33 +1154,33 @@ |
1152 | 1155 | for ( var i = 0; i < playableSources.length; i++ ) { |
1153 | 1156 | if ( i == index ) { |
1154 | 1157 | this.selectedSource = playableSources[i]; |
1155 | | - // Update the user selected format: |
| 1158 | + // Update the user selected format: |
1156 | 1159 | mw.EmbedTypes.players.setFormatPreference( playableSources[i].mimeType ); |
1157 | 1160 | break; |
1158 | 1161 | } |
1159 | 1162 | } |
1160 | 1163 | }, |
1161 | | - |
1162 | | - /** |
| 1164 | + |
| 1165 | + /** |
1163 | 1166 | * Selects the default source via cookie preference, default marked, or by id order |
1164 | 1167 | */ |
1165 | | - autoSelectSource: function() { |
| 1168 | + autoSelectSource: function() { |
1166 | 1169 | mw.log( 'EmbedPlayer::mediaElement::autoSelectSource:' + this.id); |
1167 | 1170 | // Select the default source |
1168 | 1171 | var playableSources = this.getPlayableSources(); |
1169 | 1172 | var flash_flag = ogg_flag = false; |
1170 | | - |
| 1173 | + |
1171 | 1174 | // Set via user-preference |
1172 | 1175 | for ( var source = 0; source < playableSources.length; source++ ) { |
1173 | | - var mimeType = playableSources[source].mimeType; |
| 1176 | + var mimeType = playableSources[source].mimeType; |
1174 | 1177 | if ( mw.EmbedTypes.players.preference[ 'format_preference' ] == mimeType ) { |
1175 | 1178 | mw.log( 'Set via preference: ' + playableSources[source].mimeType ); |
1176 | 1179 | this.selectedSource = playableSources[source]; |
1177 | 1180 | return true; |
1178 | 1181 | } |
1179 | 1182 | } |
1180 | | - |
1181 | | - // Set via marked default: |
| 1183 | + |
| 1184 | + // Set via marked default: |
1182 | 1185 | for ( var source = 0; source < playableSources.length; source++ ) { |
1183 | 1186 | if ( playableSources[ source ].markedDefault ) { |
1184 | 1187 | mw.log( 'Set via marked default: ' + playableSources[source].markedDefault ); |
— | — | @@ -1185,37 +1188,37 @@ |
1186 | 1189 | return true; |
1187 | 1190 | } |
1188 | 1191 | } |
1189 | | - |
1190 | | - // Prefer native playback |
| 1192 | + |
| 1193 | + // Prefer native playback |
1191 | 1194 | for ( var source = 0; source < playableSources.length; source++ ) { |
1192 | 1195 | var mimeType = playableSources[source].mimeType; |
1193 | | - var player = mw.EmbedTypes.players.defaultPlayer( mimeType ); |
| 1196 | + var player = mw.EmbedTypes.players.defaultPlayer( mimeType ); |
1194 | 1197 | if ( player && player.library == 'Native' ) { |
1195 | 1198 | mw.log('EmbedPlayer::Set native playback'); |
1196 | 1199 | this.selectedSource = playableSources[ source ]; |
1197 | 1200 | return true; |
1198 | | - } |
| 1201 | + } |
1199 | 1202 | } |
1200 | | - |
| 1203 | + |
1201 | 1204 | // Set h264 via native or flash fallback |
1202 | 1205 | for ( var source = 0; source < playableSources.length; source++ ) { |
1203 | 1206 | var mimeType = playableSources[source].mimeType; |
1204 | | - var player = mw.EmbedTypes.players.defaultPlayer( mimeType ); |
1205 | | - if ( mimeType == 'video/h264' |
1206 | | - && player |
1207 | | - && ( |
1208 | | - player.library == 'Native' |
| 1207 | + var player = mw.EmbedTypes.players.defaultPlayer( mimeType ); |
| 1208 | + if ( mimeType == 'video/h264' |
| 1209 | + && player |
| 1210 | + && ( |
| 1211 | + player.library == 'Native' |
1209 | 1212 | || |
1210 | 1213 | player.library == 'Kplayer' |
1211 | 1214 | ) |
1212 | | - ) { |
| 1215 | + ) { |
1213 | 1216 | mw.log('Set h264 via native or flash fallback'); |
1214 | 1217 | this.selectedSource = playableSources[ source ]; |
1215 | 1218 | return true; |
1216 | 1219 | } |
1217 | 1220 | }; |
1218 | | - |
1219 | | - // Else just select first source |
| 1221 | + |
| 1222 | + // Else just select first source |
1220 | 1223 | if ( !this.selectedSource ) { |
1221 | 1224 | mw.log( 'set via first source:' + playableSources[0] ); |
1222 | 1225 | this.selectedSource = playableSources[0]; |
— | — | @@ -1224,30 +1227,30 @@ |
1225 | 1228 | // No Source found so no source selected |
1226 | 1229 | return false; |
1227 | 1230 | }, |
1228 | | - |
| 1231 | + |
1229 | 1232 | /** |
1230 | | - * check if the mime is ogg |
1231 | | - */ |
| 1233 | + * check if the mime is ogg |
| 1234 | + */ |
1232 | 1235 | isOgg: function( mimeType ){ |
1233 | | - if ( mimeType == 'video/ogg' |
1234 | | - || mimeType == 'ogg/video' |
1235 | | - || mimeType == 'video/annodex' |
| 1236 | + if ( mimeType == 'video/ogg' |
| 1237 | + || mimeType == 'ogg/video' |
| 1238 | + || mimeType == 'video/annodex' |
1236 | 1239 | || mimeType == 'application/ogg' |
1237 | 1240 | ) { |
1238 | 1241 | return true; |
1239 | 1242 | } |
1240 | 1243 | return false; |
1241 | 1244 | }, |
1242 | | - |
1243 | | - /** |
| 1245 | + |
| 1246 | + /** |
1244 | 1247 | * Returns the thumbnail URL for the media element. |
1245 | 1248 | * @returns {String} thumbnail URL |
1246 | 1249 | */ |
1247 | 1250 | getPosterSrc: function( ) { |
1248 | 1251 | return this.poster; |
1249 | 1252 | }, |
1250 | | - |
1251 | | - /** |
| 1253 | + |
| 1254 | + /** |
1252 | 1255 | * Checks whether there is a stream of a specified MIME type. |
1253 | 1256 | * @param {String} mimeType MIME type to check. |
1254 | 1257 | * @return {Boolean} true if sources include MIME false if not. |
— | — | @@ -1262,31 +1265,31 @@ |
1263 | 1266 | } |
1264 | 1267 | return false; |
1265 | 1268 | }, |
1266 | | - |
| 1269 | + |
1267 | 1270 | /** |
1268 | 1271 | * Checks if media is a playable type |
1269 | 1272 | */ |
1270 | | - isPlayableType: function( mimeType ) { |
| 1273 | + isPlayableType: function( mimeType ) { |
1271 | 1274 | if ( mw.EmbedTypes.players.defaultPlayer( mimeType ) ) { |
1272 | 1275 | return true; |
1273 | 1276 | } else { |
1274 | 1277 | return false; |
1275 | 1278 | } |
1276 | 1279 | }, |
1277 | | - |
1278 | | - /** |
| 1280 | + |
| 1281 | + /** |
1279 | 1282 | * Adds a single mediaSource using the provided element if |
1280 | | - * the element has a 'src' attribute. |
| 1283 | + * the element has a 'src' attribute. |
1281 | 1284 | * @param {Element} element <video>, <source> or <mediaSource> <text> element. |
1282 | 1285 | */ |
1283 | 1286 | tryAddSource: function( element ) { |
1284 | | - //mw.log( 'f:tryAddSource:' + $j( element ).attr( "src" ) ); |
| 1287 | + mw.log( 'f:tryAddSource:' + $j( element ).attr( "src" ) ); |
1285 | 1288 | var newSrc = $j( element ).attr( 'src' ); |
1286 | | - if ( newSrc ) { |
1287 | | - // make sure an existing element with the same src does not already exist: |
| 1289 | + if ( newSrc ) { |
| 1290 | + // make sure an existing element with the same src does not already exist: |
1288 | 1291 | for ( var i = 0; i < this.sources.length; i++ ) { |
1289 | 1292 | if ( this.sources[i].src == newSrc ) { |
1290 | | - // Source already exists update any new attr: |
| 1293 | + // Source already exists update any new attr: |
1291 | 1294 | this.sources[i].updateSource( element ); |
1292 | 1295 | return this.sources[i]; |
1293 | 1296 | } |
— | — | @@ -1294,19 +1297,19 @@ |
1295 | 1298 | } |
1296 | 1299 | // Create a new source |
1297 | 1300 | var source = new mediaSource( element ); |
1298 | | - |
1299 | | - this.sources.push( source ); |
1300 | | - //mw.log( 'tryAddSource: added source ::' + source + 'sl:' + this.sources.length ); |
| 1301 | + |
| 1302 | + this.sources.push( source ); |
| 1303 | + //mw.log( 'tryAddSource: added source ::' + source + 'sl:' + this.sources.length ); |
1301 | 1304 | return source; |
1302 | 1305 | }, |
1303 | | - |
| 1306 | + |
1304 | 1307 | /** |
1305 | 1308 | * Get playable sources |
1306 | 1309 | * |
1307 | 1310 | * @returns {Array} of playable sources |
1308 | 1311 | */ |
1309 | 1312 | getPlayableSources: function() { |
1310 | | - var playableSources = []; |
| 1313 | + var playableSources = []; |
1311 | 1314 | for ( var i = 0; i < this.sources.length; i++ ) { |
1312 | 1315 | if ( this.isPlayableType( this.sources[i].mimeType ) ) { |
1313 | 1316 | playableSources.push( this.sources[i] ); |
— | — | @@ -1316,7 +1319,7 @@ |
1317 | 1320 | }; |
1318 | 1321 | return playableSources; |
1319 | 1322 | }, |
1320 | | - |
| 1323 | + |
1321 | 1324 | /** |
1322 | 1325 | * Imports media sources from ROE data. |
1323 | 1326 | * @param roe_data ROE data. |
— | — | @@ -1324,15 +1327,15 @@ |
1325 | 1328 | addROE: function( roe_data ) { |
1326 | 1329 | mw.log( 'EmbedPlayer::mediaElement:addROE' ); |
1327 | 1330 | this.addedROEData = true; |
1328 | | - var _this = this; |
| 1331 | + var _this = this; |
1329 | 1332 | if ( roe_data ) { |
1330 | | - var $roeParsed = $j( roe_data.pay_load ); |
1331 | | - |
| 1333 | + var $roeParsed = $j( roe_data.pay_load ); |
| 1334 | + |
1332 | 1335 | // Add media sources: |
1333 | | - $roeParsed.find("mediaSource").each( function( inx, source ) { |
| 1336 | + $roeParsed.find("mediaSource").each( function( inx, source ) { |
1334 | 1337 | _this.tryAddSource( source ); |
1335 | 1338 | } ); |
1336 | | - |
| 1339 | + |
1337 | 1340 | // Set the thumbnail: |
1338 | 1341 | $roeParsed.find( 'img' ).each( function( inx, n ) { |
1339 | 1342 | if ( $j( n ).attr( "id" ) == "stream_thumb" ) { |
— | — | @@ -1340,7 +1343,7 @@ |
1341 | 1344 | _this.poster = $j( n ).attr( "src" ); |
1342 | 1345 | } |
1343 | 1346 | } ); |
1344 | | - |
| 1347 | + |
1345 | 1348 | // Set the linkback: |
1346 | 1349 | $roeParsed.find( 'link' ).each( function( inx, n ) { |
1347 | 1350 | if ( $j( n ).attr( 'id' ) == 'html_linkback' ) { |
— | — | @@ -1355,10 +1358,10 @@ |
1356 | 1359 | }; |
1357 | 1360 | |
1358 | 1361 | |
1359 | | -/** |
| 1362 | +/** |
1360 | 1363 | * Base embedPlayer object |
1361 | 1364 | * @param {Element} element, the element used for initialization. |
1362 | | -* @param {Object} customAttributes Attributes for the video interface |
| 1365 | +* @param {Object} customAttributes Attributes for the video interface |
1363 | 1366 | * that are not already element attributes |
1364 | 1367 | * @constructor |
1365 | 1368 | */ |
— | — | @@ -1367,69 +1370,69 @@ |
1368 | 1371 | }; |
1369 | 1372 | |
1370 | 1373 | mw.EmbedPlayer.prototype = { |
1371 | | - |
| 1374 | + |
1372 | 1375 | // The mediaElement object containing all mediaSource objects |
1373 | 1376 | 'mediaElement' : null, |
1374 | | - |
| 1377 | + |
1375 | 1378 | // Object that describes the supported feature set of the underling plugin / player |
1376 | 1379 | 'supports': { }, |
1377 | | - |
| 1380 | + |
1378 | 1381 | // Preview mode flag, |
1379 | | - // some plugins don't seek accurately but in preview mode we need |
| 1382 | + // some plugins don't seek accurately but in preview mode we need |
1380 | 1383 | // accurate seeks so we do tricks like hide the image until its ready |
1381 | 1384 | 'preview_mode' : false, |
1382 | | - |
1383 | | - // Ready to play |
| 1385 | + |
| 1386 | + // Ready to play |
1384 | 1387 | // NOTE: we should switch over to setting the html5 video ready state |
1385 | | - 'readyToPlay' : false, |
1386 | | - |
| 1388 | + 'readyToPlay' : false, |
| 1389 | + |
1387 | 1390 | // Stores the loading errors |
1388 | | - 'loadError' : false, |
1389 | | - |
| 1391 | + 'loadError' : false, |
| 1392 | + |
1390 | 1393 | // Thumbnail updating flag ( to avoid rewriting an thumbnail thats already being updated) |
1391 | 1394 | 'thumbnail_updating' : false, |
1392 | | - |
| 1395 | + |
1393 | 1396 | // Thumbnail display flag |
1394 | 1397 | 'thumbnail_disp' : true, |
1395 | | - |
| 1398 | + |
1396 | 1399 | // Local variable to hold CMML meeta data about the current clip |
1397 | | - // for more on CMML see: http://wiki.xiph.org/CMML |
| 1400 | + // for more on CMML see: http://wiki.xiph.org/CMML |
1398 | 1401 | 'cmmlData': null, |
1399 | | - |
| 1402 | + |
1400 | 1403 | // Stores the seek time request, Updated by the doSeek function |
1401 | 1404 | 'serverSeekTime' : 0, |
1402 | | - |
1403 | | - // If the embedPlayer is current 'seeking' |
| 1405 | + |
| 1406 | + // If the embedPlayer is current 'seeking' |
1404 | 1407 | 'seeking' : false, |
1405 | | - |
1406 | | - // Percent of the clip buffered: |
1407 | | - 'bufferedPercent' : 0, |
1408 | | - |
| 1408 | + |
| 1409 | + // Percent of the clip buffered: |
| 1410 | + 'bufferedPercent' : 0, |
| 1411 | + |
1409 | 1412 | // Holds the timer interval function |
1410 | 1413 | 'monitorTimerId' : null, |
1411 | | - |
| 1414 | + |
1412 | 1415 | // Buffer flags |
1413 | 1416 | 'bufferStartFlag' : false, |
1414 | 1417 | 'bufferEndFlag' : false, |
1415 | | - |
| 1418 | + |
1416 | 1419 | // On done playing |
1417 | 1420 | 'donePlayingCount' : 0, |
1418 | | - |
| 1421 | + |
1419 | 1422 | /** |
1420 | | - * embedPlayer constructor |
| 1423 | + * embedPlayer constructor |
1421 | 1424 | * |
1422 | 1425 | * @param {Element} element DOM element that we are building the player interface for. |
1423 | | - * @param {Object} customAttributes Attributes supplied via argument (rather than applied to the element) |
| 1426 | + * @param {Object} customAttributes Attributes supplied via argument (rather than applied to the element) |
1424 | 1427 | */ |
1425 | | - init: function( element, customAttributes ) { |
1426 | | - var _this = this; |
1427 | | - // Set customAttributes if unset: |
| 1428 | + init: function( element, customAttributes ) { |
| 1429 | + var _this = this; |
| 1430 | + // Set customAttributes if unset: |
1428 | 1431 | if ( !customAttributes ) { |
1429 | 1432 | customAttributes = { }; |
1430 | | - } |
1431 | | - |
1432 | | - var playerAttributes = mw.getConfig( 'EmbedPlayer.Attributes' ); |
1433 | | - // Setup the player Interface from supported attributes: |
| 1433 | + } |
| 1434 | + |
| 1435 | + var playerAttributes = mw.getConfig( 'EmbedPlayer.Attributes' ); |
| 1436 | + // Setup the player Interface from supported attributes: |
1434 | 1437 | for ( var attr in playerAttributes ) { |
1435 | 1438 | if ( customAttributes[ attr ] || customAttributes[ attr ] === false ) { |
1436 | 1439 | this[ attr ] = customAttributes[ attr ]; |
— | — | @@ -1446,28 +1449,30 @@ |
1447 | 1450 | // string -> boolean |
1448 | 1451 | if( this[ attr ] == "false" ) this[attr] = false; |
1449 | 1452 | if( this[ attr ] == "true" ) this[attr] = true; |
1450 | | - } |
1451 | | - |
| 1453 | + } |
| 1454 | + // |
| 1455 | + |
| 1456 | + |
1452 | 1457 | if( this.apiTitleKey ){ |
1453 | | - this.apiTitleKey = unescape( this.apiTitleKey ); |
| 1458 | + this.apiTitleKey = decodeURI( this.apiTitleKey ); |
1454 | 1459 | } |
1455 | | - |
1456 | | - // Hide "controls" if using native player controls: |
| 1460 | + |
| 1461 | + // Hide "controls" if using native player controls: |
1457 | 1462 | if( this.useNativePlayerControls() ){ |
1458 | 1463 | _this.controls = false; |
1459 | 1464 | } |
1460 | | - |
| 1465 | + |
1461 | 1466 | // Set the poster: |
1462 | 1467 | if ( $j( element ).attr( 'thumbnail' ) ) { |
1463 | 1468 | _this.poster = $j( element ).attr( 'thumbnail' ); |
1464 | | - } |
| 1469 | + } |
1465 | 1470 | if ( $j( element ).attr( 'poster' ) ) { |
1466 | 1471 | _this.poster = $j( element ).attr( 'poster' ); |
1467 | | - } |
1468 | | - |
1469 | | - // Set the skin name from the class |
| 1472 | + } |
| 1473 | + |
| 1474 | + // Set the skin name from the class |
1470 | 1475 | var sn = $j(element).attr( 'class' ); |
1471 | | - |
| 1476 | + |
1472 | 1477 | if ( sn && sn != '' ) { |
1473 | 1478 | for ( var n = 0; n < mw.validSkins.length; n++ ) { |
1474 | 1479 | if ( sn.indexOf( mw.validSkins[n].toLowerCase() ) !== -1 ) { |
— | — | @@ -1475,42 +1480,42 @@ |
1476 | 1481 | } |
1477 | 1482 | } |
1478 | 1483 | } |
1479 | | - |
1480 | | - // Set the default skin if unset: |
| 1484 | + |
| 1485 | + // Set the default skin if unset: |
1481 | 1486 | if ( !this.skinName ) { |
1482 | 1487 | this.skinName = mw.getConfig( 'EmbedPlayer.SkinName' ); |
1483 | 1488 | } |
1484 | | - |
| 1489 | + |
1485 | 1490 | if( !this.monitorRate ){ |
1486 | 1491 | this.monitorRate = mw.getConfig( 'EmbedPlayer.MonitorRate' ); |
1487 | 1492 | } |
1488 | | - |
1489 | | - // Make sure startOffset is cast as an float: |
| 1493 | + |
| 1494 | + // Make sure startOffset is cast as an float: |
1490 | 1495 | if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 ) { |
1491 | 1496 | this.startOffset = parseFloat( mw.npt2seconds( this.startOffset ) ); |
1492 | 1497 | } |
1493 | | - |
1494 | | - // Make sure offset is in float: |
| 1498 | + |
| 1499 | + // Make sure offset is in float: |
1495 | 1500 | this.startOffset = parseFloat( this.startOffset ); |
1496 | | - |
| 1501 | + |
1497 | 1502 | // Set the source duration ( if provided in the element metaData or durationHint ) |
1498 | 1503 | if ( $j( element ).attr( 'duration' ) ) { |
1499 | 1504 | _this.duration = $j( element ).attr( 'duration' ); |
1500 | 1505 | } |
1501 | | - |
| 1506 | + |
1502 | 1507 | if ( !_this.duration && $j( element ).attr( 'durationHint' ) ) { |
1503 | 1508 | _this.durationHint = $j( element ).attr( 'durationHint' ); |
1504 | 1509 | // Convert duration hint if needed: |
1505 | | - _this.duration = mw.npt2seconds( _this.durationHint ); |
1506 | | - } |
1507 | | - |
1508 | | - // Make sure duration is a float: |
| 1510 | + _this.duration = mw.npt2seconds( _this.durationHint ); |
| 1511 | + } |
| 1512 | + |
| 1513 | + // Make sure duration is a float: |
1509 | 1514 | this.duration = parseFloat( this.duration ); |
1510 | | - mw.log( 'EmbedPlayer::mediaElement:' + this.id + " duration is: " + this.duration ); |
1511 | | - |
1512 | | - // Set the player size attributes based loaded video element: |
1513 | | - this.setPlayerSize( element ); |
1514 | | - |
| 1515 | + mw.log( 'EmbedPlayer::mediaElement:' + this.id + " duration is: " + this.duration ); |
| 1516 | + |
| 1517 | + // Set the player size attributes based loaded video element: |
| 1518 | + this.setPlayerSize( element ); |
| 1519 | + |
1515 | 1520 | // Set the plugin id |
1516 | 1521 | this.pid = 'pid_' + this.id; |
1517 | 1522 | |
— | — | @@ -1520,17 +1525,17 @@ |
1521 | 1526 | //mw.log( 'innerHTML: ' + element.innerHTML ); |
1522 | 1527 | this.user_missing_plugin_html = element.innerHTML; |
1523 | 1528 | } |
1524 | | - |
1525 | | - // Add the mediaElement object with the elements sources: |
| 1529 | + |
| 1530 | + // Add the mediaElement object with the elements sources: |
1526 | 1531 | this.mediaElement = new mediaElement( element ); |
1527 | | - |
| 1532 | + |
1528 | 1533 | // Process attribute "sources" for dynamic embedding |
1529 | 1534 | if( customAttributes.sources && customAttributes.sources.length ){ |
1530 | 1535 | for( var i =0; i < customAttributes.sources.length ; i ++ ){ |
1531 | | - var customSource = customAttributes.sources[i]; |
| 1536 | + var customSource = customAttributes.sources[i]; |
1532 | 1537 | if( customSource.src ){ |
1533 | 1538 | var $source = $j('<source />') |
1534 | | - .attr( 'src', customSource.src ); |
| 1539 | + .attr( 'src', customSource.src ); |
1535 | 1540 | // xxx todo pull list of valid source attributes from mediaSource prototype |
1536 | 1541 | if( customSource.type ){ |
1537 | 1542 | $source.attr('type', customSource.type ); |
— | — | @@ -1543,85 +1548,105 @@ |
1544 | 1549 | } |
1545 | 1550 | } |
1546 | 1551 | }, |
1547 | | - |
| 1552 | + |
1548 | 1553 | /** |
1549 | | - * for plugin-players to update supported features |
| 1554 | + * for plugin-players to update supported features |
1550 | 1555 | */ |
1551 | 1556 | updateFeatureSupport: function(){ |
1552 | 1557 | return ; |
1553 | 1558 | }, |
1554 | | - |
| 1559 | + |
1555 | 1560 | /** |
1556 | 1561 | * Set the width & height from css style attribute, element attribute, or by default value |
1557 | 1562 | * if no css or attribute is provided set a callback to resize. |
1558 | | - * |
| 1563 | + * |
1559 | 1564 | * Updates this.width & this.height |
1560 | | - * |
1561 | | - * @param {Element} element Source element to grab size from |
| 1565 | + * |
| 1566 | + * @param {Element} element Source element to grab size from |
1562 | 1567 | */ |
1563 | | - setPlayerSize: function( element ) { |
1564 | | - |
1565 | | - this.height = parseInt( $j(element).css( 'height' ) ); |
1566 | | - this.width = parseInt( $j(element).css( 'width' ) ); |
1567 | | - |
1568 | | - if( !this.height && !this.width ) { |
1569 | | - this.height = parseInt( $j(element).attr( 'height' ) ); |
1570 | | - this.width = parseInt( $j(element).attr( 'width' ) ); |
1571 | | - } |
1572 | | - |
1573 | | - // Special case for audio |
1574 | | - // Firefox sets audio height to "0px" while webkit uses 32px .. force zero: |
1575 | | - if( element.tagName.toLowerCase() == 'audio' && this.height == '32' ) { |
| 1568 | + setPlayerSize: function( element ) { |
| 1569 | + |
| 1570 | + this.height = $j(element).css( 'height' ); |
| 1571 | + this.width = $j(element).css( 'width' ); |
| 1572 | + |
| 1573 | + // Set to parent size ( resize events will cause player size updates) |
| 1574 | + if( this.height.indexOf('100%') != -1 || this.width.indexOf('100%') != -1 ){ |
| 1575 | + $relativeParent = $j(element).parents().filter(function() { |
| 1576 | + // reduce to only relative position or "body" elements |
| 1577 | + return $j( this ).is( 'body' ) || $j(this).css( 'position' ) == 'relative'; |
| 1578 | + }).slice(0,1); // grab only the "first" |
| 1579 | + this.width = $relativeParent.width(); |
| 1580 | + this.height = $relativeParent.height(); |
| 1581 | + } |
| 1582 | + |
| 1583 | + // Make sure height and width are a number |
| 1584 | + this.height = parseInt( this.height ); |
| 1585 | + this.width = parseInt( this.width ); |
| 1586 | + |
| 1587 | + |
| 1588 | + |
| 1589 | + // Set via attribute if CSS is zero or NaN and we have an attribute value: |
| 1590 | + this.height = ( ( this.height==0 || isNaN( this.height ) ) |
| 1591 | + && $j(element).attr( 'height' ) ) ? |
| 1592 | + parseInt( $j(element).attr( 'height' ) ): this.height; |
| 1593 | + this.width = ( ( this.width == 0 || isNaN( this.width ) ) |
| 1594 | + && $j(element).attr( 'width' ) )? |
| 1595 | + parseInt( $j(element).attr( 'width' ) ): this.width; |
| 1596 | + |
| 1597 | + |
| 1598 | + // Special case for audio |
| 1599 | + // Firefox sets audio height to "0px" while webkit uses 32px .. force zero: |
| 1600 | + if( element.tagName.toLowerCase() == 'audio' && this.height == '32' ) { |
1576 | 1601 | this.height = 0; |
1577 | | - } |
1578 | | - |
| 1602 | + } |
| 1603 | + |
1579 | 1604 | // Use default aspect ration to get height or width ( if rewriting a non-audio player ) |
1580 | | - if( element.tagName.toLowerCase() != 'audio' && this.videoAspect ) { |
1581 | | - var aspect = this.videoAspect.split( ':' ); |
1582 | | - if( this.height && !this.width ) { |
| 1605 | + if( element.tagName.toLowerCase() != 'audio' && this.videoAspect ) { |
| 1606 | + var aspect = this.videoAspect.split( ':' ); |
| 1607 | + if( this.height && !this.width ) { |
1583 | 1608 | this.width = parseInt( this.height * ( aspect[0] / aspect[1] ) ); |
1584 | | - } |
1585 | | - if( this.width && !this.height ) { |
| 1609 | + } |
| 1610 | + if( this.width && !this.height ) { |
1586 | 1611 | var apectRatio = ( aspect[1] / aspect[0] ); |
1587 | 1612 | this.height = parseInt( this.width * ( aspect[1] / aspect[0] ) ); |
1588 | 1613 | } |
1589 | 1614 | } |
1590 | | - |
1591 | | - // On load sometimes attr is temporally -1 as we don't have video metadata yet. |
| 1615 | + |
| 1616 | + // On load sometimes attr is temporally -1 as we don't have video metadata yet. |
1592 | 1617 | // or in IE we get NaN for width height |
1593 | | - // |
1594 | | - // NOTE: browsers that do support height width should set "waitForMeta" flag in addElement |
| 1618 | + // |
| 1619 | + // NOTE: browsers that do support height width should set "waitForMeta" flag in addElement |
1595 | 1620 | if( ( isNaN( this.height ) && isNaN( this.width ) ) || |
1596 | | - ( this.height == -1 || this.width == -1 ) || |
| 1621 | + ( this.height == -1 || this.width == -1 ) || |
1597 | 1622 | // Check for firefox defaults |
1598 | | - // Note: ideally firefox would not do random guesses at css values |
| 1623 | + // Note: ideally firefox would not do random guesses at css values |
1599 | 1624 | ( (this.height == 150 || this.height == 64 ) && this.width == 300 ) |
1600 | | - ) { |
| 1625 | + ) { |
1601 | 1626 | var defaultSize = mw.getConfig( 'EmbedPlayer.DefaultSize' ).split( 'x' ); |
1602 | 1627 | this.width = defaultSize[0]; |
1603 | | - |
1604 | | - // Special height default for audio tag ( if not set ) |
| 1628 | + |
| 1629 | + // Special height default for audio tag ( if not set ) |
1605 | 1630 | if( element.tagName.toLowerCase() == 'audio' ) { |
1606 | 1631 | this.height = 0; |
1607 | 1632 | }else{ |
1608 | 1633 | this.height = defaultSize[1]; |
1609 | 1634 | } |
1610 | | - } |
1611 | | - |
| 1635 | + } |
1612 | 1636 | }, |
1613 | 1637 | /** |
1614 | 1638 | * Resize the player to a new size |
| 1639 | + * @param {object} size The width height size of the player |
1615 | 1640 | */ |
1616 | 1641 | resizePlayer: function( size , animate){ |
1617 | 1642 | mw.log("EmbedPlayer::resizePlayer:" + size.width + ' x ' + size.height ); |
1618 | 1643 | this.width = size.width; |
1619 | 1644 | this.height = size.height; |
1620 | 1645 | var playerSize = {'width' : this.width, 'height' : this.height }; |
1621 | | - // check if height needs to include interface contorls |
| 1646 | + // check if height needs to include interface controls |
1622 | 1647 | if( ! this.controlBuilder.checkOverlayControls() ){ |
1623 | 1648 | size.height = size.height + this.controlBuilder.height; |
1624 | 1649 | } |
1625 | | - |
| 1650 | + |
1626 | 1651 | if( animate ){ |
1627 | 1652 | $j(this).animate(playerSize); |
1628 | 1653 | this.$interface.animate( size ); |
— | — | @@ -1630,68 +1655,68 @@ |
1631 | 1656 | this.$interface.css( size ); |
1632 | 1657 | } |
1633 | 1658 | }, |
1634 | | - |
| 1659 | + |
1635 | 1660 | /** |
1636 | 1661 | * Get the player pixel width not including controls |
1637 | 1662 | * |
1638 | 1663 | * @return {Number} pixel height of the video |
1639 | | - */ |
| 1664 | + */ |
1640 | 1665 | getPlayerWidth: function() { |
1641 | | - return parseInt( this.width ); |
| 1666 | + return $j( this ).width(); |
1642 | 1667 | }, |
1643 | | - |
| 1668 | + |
1644 | 1669 | /** |
1645 | 1670 | * Get the player pixel height not including controls |
1646 | 1671 | * |
1647 | 1672 | * @return {Number} pixel height of the video |
1648 | 1673 | */ |
1649 | | - getPlayerHeight: function() { |
1650 | | - return parseInt( this.height ); |
| 1674 | + getPlayerHeight: function() { |
| 1675 | + return $j( this ).height(); |
1651 | 1676 | }, |
1652 | 1677 | |
1653 | 1678 | /** |
1654 | | - * Check player for sources. |
1655 | | - * If we need to get media sources form an external file |
1656 | | - * that request is issued here |
| 1679 | + * Check player for sources. |
| 1680 | + * If we need to get media sources form an external file |
| 1681 | + * that request is issued here |
1657 | 1682 | */ |
1658 | 1683 | checkPlayerSources: function() { |
1659 | 1684 | mw.log( 'EmbedPlayer::checkPlayerSources: ' + this.id ); |
1660 | 1685 | var _this = this; |
1661 | | - |
1662 | | - // Scope the end of check for player sources so it can be called in a callback |
| 1686 | + |
| 1687 | + // Scope the end of check for player sources so it can be called in a callback |
1663 | 1688 | var finishCheckPlayerSources = function(){ |
1664 | | - // Run embedPlayer sources hook |
1665 | | - mw.runTriggersCallback( _this, 'checkPlayerSourcesEvent', function(){ |
| 1689 | + // Run embedPlayer sources hook |
| 1690 | + mw.runTriggersCallback( _this, 'checkPlayerSourcesEvent', function(){ |
1666 | 1691 | _this.checkForTimedText(); |
1667 | | - }); |
| 1692 | + }); |
1668 | 1693 | }; |
1669 | | - |
| 1694 | + |
1670 | 1695 | // NOTE: Should could be moved to mediaWiki Api support module |
1671 | | - // only load from api if sources are empty: |
| 1696 | + // only load from api if sources are empty: |
1672 | 1697 | if ( _this.apiTitleKey && this.mediaElement.sources.length == 0) { |
1673 | 1698 | // Load media from external data |
1674 | | - mw.log( 'EmbedPlayer::checkPlayerSources: loading apiTitleKey:' + _this.apiTitleKey ); |
1675 | | - _this.loadSourceFromApi( function(){ |
| 1699 | + mw.log( 'EmbedPlayer::checkPlayerSources: loading apiTitleKey:' + _this.apiTitleKey ); |
| 1700 | + _this.loadSourceFromApi( function(){ |
1676 | 1701 | finishCheckPlayerSources(); |
1677 | 1702 | } ); |
1678 | 1703 | return ; |
1679 | | - } else { |
| 1704 | + } else { |
1680 | 1705 | finishCheckPlayerSources(); |
1681 | 1706 | } |
1682 | 1707 | }, |
1683 | | - |
| 1708 | + |
1684 | 1709 | /** |
1685 | 1710 | * Insert and play a video source ( useful for ads or bumper videos ) |
1686 | | - * |
| 1711 | + * |
1687 | 1712 | * Only works while video is in active play back. |
1688 | | - * Only tested with native playback atm. |
| 1713 | + * Only tested with native playback atm. |
1689 | 1714 | */ |
1690 | 1715 | insertAndPlaySource: function( source ){ |
1691 | 1716 | mw.log("Error: only native playback supports insertAndPlaySource right now"); |
1692 | 1717 | }, |
1693 | | - |
| 1718 | + |
1694 | 1719 | /** |
1695 | | - * Load Source video info from mediaWiki Api title key ( this.apiTitleKey ) |
| 1720 | + * Load Source video info from mediaWiki Api title key ( this.apiTitleKey ) |
1696 | 1721 | * @@todo move this to mediaWiki 'api' module |
1697 | 1722 | * @param {Function} callback Function called once loading is complete |
1698 | 1723 | */ |
— | — | @@ -1701,16 +1726,16 @@ |
1702 | 1727 | mw.log( 'Error no apiTitleKey'); |
1703 | 1728 | return false; |
1704 | 1729 | } |
1705 | | - |
| 1730 | + |
1706 | 1731 | // Set local apiProvider via config if not defined |
1707 | 1732 | if( !_this.apiProvider ) { |
1708 | 1733 | _this.apiProvider = mw.getConfig( 'EmbedPlayer.ApiProvider' ); |
1709 | | - } |
1710 | | - |
| 1734 | + } |
| 1735 | + |
1711 | 1736 | // Setup the request |
1712 | 1737 | var request = { |
1713 | 1738 | 'prop': 'imageinfo', |
1714 | | - // In case the user added File: or Image: to the apiKey: |
| 1739 | + // In case the user added File: or Image: to the apiKey: |
1715 | 1740 | 'titles': 'File:' + this.apiTitleKey.replace( /^(File:|Image:)/ , '' ), |
1716 | 1741 | 'iiprop': 'url|size|dimensions|metadata', |
1717 | 1742 | 'iiurlwidth': _this.width, |
— | — | @@ -1727,96 +1752,96 @@ |
1728 | 1753 | } |
1729 | 1754 | var page = data.query.pages[i]; |
1730 | 1755 | } |
1731 | | - } else { |
| 1756 | + } else { |
1732 | 1757 | callback( false ); |
1733 | 1758 | return ; |
1734 | 1759 | } |
1735 | | - // Make sure we have imageinfo: |
| 1760 | + // Make sure we have imageinfo: |
1736 | 1761 | if( ! page.imageinfo || !page.imageinfo[0] ){ |
1737 | 1762 | callback( false ); |
1738 | 1763 | return ; |
1739 | 1764 | } |
1740 | 1765 | var imageinfo = page.imageinfo[0]; |
1741 | | - |
| 1766 | + |
1742 | 1767 | // Set the poster |
1743 | 1768 | _this.poster = imageinfo.thumburl; |
1744 | | - |
| 1769 | + |
1745 | 1770 | // Add the media src |
1746 | 1771 | _this.mediaElement.tryAddSource( |
1747 | 1772 | $j('<source />') |
1748 | 1773 | .attr( 'src', imageinfo.url ) |
1749 | 1774 | .get( 0 ) |
1750 | 1775 | ); |
1751 | | - |
| 1776 | + |
1752 | 1777 | // Set the duration |
1753 | 1778 | if( imageinfo.metadata[2]['name'] == 'length' ) { |
1754 | 1779 | _this.duration = imageinfo.metadata[2]['value']; |
1755 | 1780 | } |
1756 | | - |
1757 | | - // Set the width height |
| 1781 | + |
| 1782 | + // Set the width height |
1758 | 1783 | // Make sure we have an accurate aspect ratio |
1759 | | - if( imageinfo.height != 0 && imageinfo.width != 0 ) { |
| 1784 | + if( imageinfo.height != 0 && imageinfo.width != 0 ) { |
1760 | 1785 | _this.height = parseInt( _this.width * ( imageinfo.height / imageinfo.width ) ); |
1761 | 1786 | } |
1762 | | - |
| 1787 | + |
1763 | 1788 | // Update the css for the player interface |
1764 | 1789 | $j( _this ).css( 'height', _this.height); |
1765 | | - |
| 1790 | + |
1766 | 1791 | callback(); |
1767 | 1792 | }); |
1768 | 1793 | }, |
1769 | | - |
| 1794 | + |
1770 | 1795 | /** |
1771 | 1796 | * Check if we should load the timedText interface or not. |
1772 | | - * |
| 1797 | + * |
1773 | 1798 | * Note we check for text sources outside of |
1774 | 1799 | */ |
1775 | 1800 | isTimedTextSupported: function() { |
1776 | | - // Check for timed text sources or api/ roe url |
1777 | | - if ( ( this.roe || this.apiTitleKey || |
1778 | | - this.mediaElement.textSourceExists() ) ) { |
| 1801 | + // Check for timed text sources or api/ roe url |
| 1802 | + if ( ( this.roe || this.apiTitleKey || |
| 1803 | + this.mediaElement.textSourceExists() ) ) { |
1779 | 1804 | return true; |
1780 | 1805 | } else { |
1781 | 1806 | return false; |
1782 | 1807 | } |
1783 | 1808 | }, |
1784 | | - |
| 1809 | + |
1785 | 1810 | /** |
1786 | | - * Check for timed Text support |
| 1811 | + * Check for timed Text support |
1787 | 1812 | * and load necessary libraries |
1788 | 1813 | */ |
1789 | 1814 | checkForTimedText: function( ) { |
1790 | 1815 | var _this = this; |
1791 | | - mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id + " height: " + this.height ); |
| 1816 | + mw.log( 'EmbedPlayer::checkForTimedText: ' + _this.id ); |
1792 | 1817 | // Check for timedText support |
1793 | | - if( this.isTimedTextSupported() ) { |
| 1818 | + if( this.isTimedTextSupported() ) { |
1794 | 1819 | mw.load( 'TimedText', function() { |
1795 | 1820 | $j( '#' + _this.id ).timedText(); |
1796 | 1821 | _this.setupSourcePlayer(); |
1797 | | - }); |
| 1822 | + }); |
1798 | 1823 | return ; |
1799 | 1824 | } |
1800 | 1825 | _this.setupSourcePlayer(); |
1801 | | - }, |
1802 | | - |
| 1826 | + }, |
| 1827 | + |
1803 | 1828 | /** |
1804 | 1829 | * Set up the select source player |
1805 | 1830 | * |
1806 | | - * issues autoSelectSource call |
| 1831 | + * issues autoSelectSource call |
1807 | 1832 | * |
1808 | | - * Sets load error if no source is playable |
1809 | | - */ |
| 1833 | + * Sets load error if no source is playable |
| 1834 | + */ |
1810 | 1835 | setupSourcePlayer: function() { |
1811 | 1836 | mw.log("EmbedPlayer::setupSourcePlayer: " + this.id ); |
1812 | | - // Autoseletct the media source |
| 1837 | + // Autoseletct the media source |
1813 | 1838 | this.mediaElement.autoSelectSource(); |
1814 | | - |
| 1839 | + |
1815 | 1840 | // Auto select player based on default order |
1816 | 1841 | if ( !this.mediaElement.selectedSource ) { |
1817 | | - // check for parent clip: |
| 1842 | + // check for parent clip: |
1818 | 1843 | if ( typeof this.pc != 'undefined' ) { |
1819 | | - mw.log( 'no sources, type:' + this.type + ' check for html' ); |
1820 | | - // do load player if just displaying innerHTML: |
| 1844 | + mw.log( 'no sources, type:' + this.type + ' check for html' ); |
| 1845 | + // do load player if just displaying innerHTML: |
1821 | 1846 | if ( this.pc.type == 'text/html' ) { |
1822 | 1847 | this.selectedPlayer = mw.EmbedTypes.players.defaultPlayer( 'text/html' ); |
1823 | 1848 | mw.log( 'set selected player:' + this.selectedPlayer.mimeType ); |
— | — | @@ -1825,9 +1850,9 @@ |
1826 | 1851 | } else { |
1827 | 1852 | this.selectedPlayer = mw.EmbedTypes.players.defaultPlayer( this.mediaElement.selectedSource.mimeType ); |
1828 | 1853 | } |
1829 | | - |
| 1854 | + |
1830 | 1855 | if ( this.selectedPlayer ) { |
1831 | | - // Inherit the playback system of the selected player: |
| 1856 | + // Inherit the playback system of the selected player: |
1832 | 1857 | this.inheritEmbedPlayer(); |
1833 | 1858 | } else { |
1834 | 1859 | // No source's playable |
— | — | @@ -1837,31 +1862,31 @@ |
1838 | 1863 | missingType += or + this.mediaElement.sources[i].mimeType; |
1839 | 1864 | or = ' or '; |
1840 | 1865 | } |
1841 | | - // Get from parent playlist if set: |
| 1866 | + // Get from parent playlist if set: |
1842 | 1867 | if ( this.pc ){ |
1843 | 1868 | missingType = this.pc.type; |
1844 | 1869 | } |
1845 | | - |
| 1870 | + |
1846 | 1871 | mw.log( 'No player found for given source type ' + missingType ); |
1847 | 1872 | this.showPluginMissingHTML( missingType ); |
1848 | | - |
1849 | | - // Call the global player manager to inform this video interface is "ready" for page callback to be proccessed. |
| 1873 | + |
| 1874 | + // Call the global player manager to inform this video interface is "ready" for page callback to be proccessed. |
1850 | 1875 | mw.playerManager.playerReady( this ); |
1851 | 1876 | } |
1852 | 1877 | }, |
1853 | | - |
| 1878 | + |
1854 | 1879 | /** |
1855 | 1880 | * Load and inherit methods from the selected player interface |
1856 | 1881 | * |
1857 | 1882 | * @param {Function} callback Function to be called once playback-system has been inherited |
1858 | 1883 | */ |
1859 | 1884 | inheritEmbedPlayer: function( callback ) { |
1860 | | - mw.log( "EmbedPlayer::inheritEmbedPlayer:duration is: " + this.getDuration() + ' p: ' + this.id ); |
1861 | | - |
| 1885 | + mw.log( "EmbedPlayer::inheritEmbedPlayer:duration is: " + this.getDuration() + ' p: ' + this.id ); |
| 1886 | + |
1862 | 1887 | // Clear out any non-base embedObj methods: |
1863 | 1888 | if ( this.instanceOf ) { |
1864 | 1889 | eval( 'var tmpObj = mw.EmbedPlayer' + this.instanceOf ); |
1865 | | - for ( var i in tmpObj ) { // for in loop oky for object |
| 1890 | + for ( var i in tmpObj ) { // for in loop oky for object |
1866 | 1891 | if ( this[ 'parent_' + i ] ) { |
1867 | 1892 | this[i] = this[ 'parent_' + i]; |
1868 | 1893 | } else { |
— | — | @@ -1869,342 +1894,342 @@ |
1870 | 1895 | } |
1871 | 1896 | } |
1872 | 1897 | } |
1873 | | - |
| 1898 | + |
1874 | 1899 | // Set up the new embedObj |
1875 | 1900 | mw.log( 'EmbedPlayer::inheritEmbedPlayer: embedding with ' + this.selectedPlayer.library ); |
1876 | 1901 | var _this = this; |
1877 | | - |
1878 | | - // Load the selected player |
| 1902 | + |
| 1903 | + // Load the selected player |
1879 | 1904 | this.selectedPlayer.load( function() { |
1880 | 1905 | mw.log( 'EmbedPlayer::inheritEmbedPlayer ' + _this.selectedPlayer.library + " player loaded for " + _this.id ); |
1881 | | - |
| 1906 | + |
1882 | 1907 | // Get embed library player Interface |
1883 | | - var playerInterface = mw[ 'EmbedPlayer' + _this.selectedPlayer.library ]; |
1884 | | - |
1885 | | - for ( var method in playerInterface ) { |
| 1908 | + var playerInterface = mw[ 'EmbedPlayer' + _this.selectedPlayer.library ]; |
| 1909 | + |
| 1910 | + for ( var method in playerInterface ) { |
1886 | 1911 | if ( _this[method] && !_this['parent_' + method] ) { |
1887 | 1912 | _this['parent_' + method] = _this[method]; |
1888 | 1913 | } |
1889 | 1914 | _this[ method ] = playerInterface[method]; |
1890 | | - } |
1891 | | - |
1892 | | - // Update feature support |
| 1915 | + } |
| 1916 | + |
| 1917 | + // Update feature support |
1893 | 1918 | _this.updateFeatureSupport(); |
1894 | | - |
| 1919 | + |
1895 | 1920 | _this.getDuration(); |
1896 | | - |
| 1921 | + |
1897 | 1922 | _this.showPlayer(); |
1898 | | - // Call the global player manager to inform this video interface is ready: |
| 1923 | + // Call the global player manager to inform this video interface is ready: |
1899 | 1924 | mw.playerManager.playerReady( _this ); |
1900 | | - |
| 1925 | + |
1901 | 1926 | // Run the callback if provided |
1902 | 1927 | if ( typeof callback == 'function' ){ |
1903 | 1928 | callback(); |
1904 | 1929 | } |
1905 | 1930 | } ); |
1906 | 1931 | }, |
1907 | | - |
| 1932 | + |
1908 | 1933 | /** |
1909 | 1934 | * Select a player playback system |
1910 | 1935 | * |
1911 | 1936 | * @param {Object} player Player playback system to be selected |
1912 | | - * player playback system include vlc, native, java etc. |
| 1937 | + * player playback system include vlc, native, java etc. |
1913 | 1938 | */ |
1914 | | - selectPlayer: function( player ) { |
| 1939 | + selectPlayer: function( player ) { |
1915 | 1940 | var _this = this; |
1916 | 1941 | if ( this.selectedPlayer.id != player.id ) { |
1917 | 1942 | this.selectedPlayer = player; |
1918 | 1943 | this.inheritEmbedPlayer( function(){ |
1919 | 1944 | // Hide / remove track container |
1920 | | - _this.$interface.find( '.track' ).remove(); |
| 1945 | + _this.$interface.find( '.track' ).remove(); |
1921 | 1946 | // We have to re-bind hoverIntent ( has to happen in this scope ) |
1922 | 1947 | if( _this.controls && _this.controlBuilder.checkOverlayControls() ){ |
1923 | | - _this.controlBuilder.showControlBar(); |
| 1948 | + _this.controlBuilder.showControlBar(); |
1924 | 1949 | _this.$interface.hoverIntent({ |
1925 | 1950 | 'sensitivity': 4, |
1926 | 1951 | 'timeout' : 2000, |
1927 | | - 'over' : function(){ |
| 1952 | + 'over' : function(){ |
1928 | 1953 | _this.controlBuilder.showControlBar(); |
1929 | 1954 | }, |
1930 | 1955 | 'out' : function(){ |
1931 | 1956 | _this.controlBuilder.hideControlBar(); |
1932 | 1957 | } |
1933 | | - }) |
1934 | | - } |
1935 | | - }); |
| 1958 | + }); |
| 1959 | + } |
| 1960 | + }); |
1936 | 1961 | } |
1937 | | - }, |
1938 | | - |
| 1962 | + }, |
| 1963 | + |
1939 | 1964 | /** |
1940 | | - * Get a time range from the media start and end time |
| 1965 | + * Get a time range from the media start and end time |
1941 | 1966 | * |
1942 | 1967 | * @return start_npt and end_npt time if present |
1943 | | - */ |
1944 | | - getTimeRange: function() { |
| 1968 | + */ |
| 1969 | + getTimeRange: function() { |
1945 | 1970 | var end_time = (this.controlBuilder.longTimeDisp)? '/' + mw.seconds2npt( this.getDuration() ) : ''; |
1946 | | - var default_time_range = '0:00:00' + end_time; |
| 1971 | + var default_time_range = '0:00:00' + end_time; |
1947 | 1972 | if ( !this.mediaElement ) |
1948 | 1973 | return default_time_range; |
1949 | 1974 | if ( !this.mediaElement.selectedSource ) |
1950 | 1975 | return default_time_range; |
1951 | 1976 | if ( !this.mediaElement.selectedSource.end_npt ) |
1952 | | - return default_time_range; |
| 1977 | + return default_time_range; |
1953 | 1978 | return this.mediaElement.selectedSource.start_npt + this.mediaElement.selectedSource.end_npt; |
1954 | 1979 | }, |
1955 | | - |
| 1980 | + |
1956 | 1981 | /** |
1957 | 1982 | * Get the duration of the embed player |
1958 | | - */ |
| 1983 | + */ |
1959 | 1984 | getDuration: function() { |
1960 | 1985 | return this.duration; |
1961 | | - }, |
1962 | | - |
| 1986 | + }, |
| 1987 | + |
1963 | 1988 | /** |
1964 | 1989 | * Get the player height |
1965 | 1990 | */ |
1966 | 1991 | getHeight: function() { |
1967 | 1992 | return this.height; |
1968 | 1993 | }, |
1969 | | - |
| 1994 | + |
1970 | 1995 | /** |
1971 | 1996 | * Get the player width |
1972 | 1997 | */ |
1973 | 1998 | getWidth: function(){ |
1974 | 1999 | return this.width; |
1975 | 2000 | }, |
1976 | | - |
| 2001 | + |
1977 | 2002 | /** |
1978 | | - * Check if the selected source is an audio element: |
| 2003 | + * Check if the selected source is an audio element: |
1979 | 2004 | */ |
1980 | 2005 | isAudio: function(){ |
1981 | 2006 | return ( this.mediaElement.selectedSource.mimeType.indexOf('audio/') !== -1 ); |
1982 | 2007 | }, |
1983 | | - |
| 2008 | + |
1984 | 2009 | /** |
1985 | 2010 | * Get the plugin embed html ( should be implemented by embed player interface ) |
1986 | 2011 | */ |
1987 | 2012 | doEmbedHTML: function() { |
1988 | 2013 | return 'Error: function doEmbedHTML should be implemented by embed player interface '; |
1989 | 2014 | }, |
1990 | | - |
| 2015 | + |
1991 | 2016 | /** |
1992 | 2017 | * Seek function ( should be implemented by embedPlayer interface playerNative, playerKplayer etc. ) |
1993 | 2018 | * embedPlayer doSeek only handles URL time seeks |
1994 | | - */ |
| 2019 | + */ |
1995 | 2020 | doSeek: function( percent ) { |
1996 | 2021 | var _this = this; |
1997 | | - |
| 2022 | + |
1998 | 2023 | this.seeking = true; |
1999 | 2024 | // Run the seeking hook |
2000 | 2025 | $j( this.embedPlayer ).trigger( 'onSeek' ); |
2001 | | - |
2002 | | - // See if we should do a server side seek ( player independent ) |
2003 | | - if ( this.supportsURLTimeEncoding() ) { |
| 2026 | + |
| 2027 | + // See if we should do a server side seek ( player independent ) |
| 2028 | + if ( this.supportsURLTimeEncoding() ) { |
2004 | 2029 | mw.log( 'EmbedPlayer::doSeek:: updated serverSeekTime: ' + mw.seconds2npt ( this.serverSeekTime ) ); |
2005 | 2030 | this.stop(); |
2006 | 2031 | this.didSeekJump = true; |
2007 | 2032 | // Make sure this.serverSeekTime is up-to-date: |
2008 | 2033 | this.serverSeekTime = mw.npt2seconds( this.start_npt ) + parseFloat( percent * this.getDuration() ); |
2009 | 2034 | // Update the slider |
2010 | | - this.updatePlayHead( percent ); |
2011 | | - } |
2012 | | - |
2013 | | - // Do play request in 100ms ( give the dom time to swap out the embed player ) |
2014 | | - setTimeout( function() { |
| 2035 | + this.updatePlayHead( percent ); |
| 2036 | + } |
| 2037 | + |
| 2038 | + // Do play request in 100ms ( give the dom time to swap out the embed player ) |
| 2039 | + setTimeout( function() { |
2015 | 2040 | _this.seeking = false; |
2016 | | - _this.play() |
| 2041 | + _this.play(); |
2017 | 2042 | _this.monitor(); |
2018 | 2043 | }, 100 ); |
2019 | | - |
| 2044 | + |
2020 | 2045 | // Run the onSeeking interface update |
2021 | | - // NOTE controlBuilder should really bind to html5 events rather |
2022 | | - // than explicitly calling it or inheriting stuff. |
2023 | | - this.controlBuilder.onSeek(); |
2024 | | - }, |
2025 | | - |
| 2046 | + // NOTE controlBuilder should really bind to html5 events rather |
| 2047 | + // than explicitly calling it or inheriting stuff. |
| 2048 | + this.controlBuilder.onSeek(); |
| 2049 | + }, |
| 2050 | + |
2026 | 2051 | /** |
2027 | | - * Seeks to the requested time and issues a callback when ready |
| 2052 | + * Seeks to the requested time and issues a callback when ready |
2028 | 2053 | * (should be overwritten by client that supports frame serving) |
2029 | 2054 | */ |
2030 | 2055 | setCurrentTime: function( time, callback ) { |
2031 | 2056 | mw.log( 'Error: base embed setCurrentTime can not frame serve (override via plugin)' ); |
2032 | | - }, |
2033 | | - |
| 2057 | + }, |
| 2058 | + |
2034 | 2059 | /** |
2035 | 2060 | * On clip done action. Called once a clip is done playing |
2036 | 2061 | */ |
2037 | 2062 | onClipDone: function() { |
2038 | | - mw.log( 'EmbedPlayer::onClipDone:' + this.id + ' doneCount:' + this.donePlayingCount + ' stop state:' +this.isStopped() ); |
2039 | | - var _this = this; |
2040 | | - |
2041 | | - // Only run stopped once: |
| 2063 | + mw.log( 'EmbedPlayer::onClipDone:' + this.id + ' doneCount:' + this.donePlayingCount + ' stop state:' +this.isStopped() ); |
| 2064 | + var _this = this; |
| 2065 | + |
| 2066 | + // Only run stopped once: |
2042 | 2067 | if( !this.isStopped() ){ |
2043 | | - // Stop the monitor: |
| 2068 | + // Stop the monitor: |
2044 | 2069 | this.stopMonitor(); |
2045 | | - |
| 2070 | + |
2046 | 2071 | // Show the control bar: |
2047 | | - this.controlBuilder.showControlBar(); |
2048 | | - |
| 2072 | + this.controlBuilder.showControlBar(); |
| 2073 | + |
2049 | 2074 | // Update the clip done playing count: |
2050 | 2075 | this.donePlayingCount ++; |
2051 | | - |
| 2076 | + |
2052 | 2077 | // Fire the html5 ended binding |
2053 | 2078 | var onDoneActionObject = { |
2054 | 2079 | 'runBaseControlDone' : true |
2055 | | - } |
2056 | | - |
2057 | | - // Run the ended trigger ( allow the ended object to prevent default actions ) |
| 2080 | + }; |
| 2081 | + |
| 2082 | + // Run the ended trigger ( allow the ended object to prevent default actions ) |
2058 | 2083 | mw.log("EmbedPlayer::onClipDone:Trigger ended"); |
2059 | 2084 | $j( this ).trigger( 'ended', onDoneActionObject ); |
2060 | | - |
| 2085 | + |
2061 | 2086 | if( onDoneActionObject.runBaseControlDone ){ |
2062 | | - |
| 2087 | + |
2063 | 2088 | // Check if we have the "loop" property set |
2064 | 2089 | if( this.loop ) { |
2065 | 2090 | this.stop(); |
2066 | 2091 | this.play(); |
2067 | | - return; |
| 2092 | + return; |
2068 | 2093 | } |
2069 | | - |
2070 | | - // Stop the clip (load the thumbnail etc) |
| 2094 | + |
| 2095 | + // Stop the clip (load the thumbnail etc) |
2071 | 2096 | this.stop(); |
2072 | 2097 | this.serverSeekTime = 0; |
2073 | 2098 | this.updatePlayHead( 0 ); |
2074 | | - |
2075 | | - // Make sure we are not in preview mode( no end clip actions in preview mode) |
| 2099 | + |
| 2100 | + // Make sure we are not in preview mode( no end clip actions in preview mode) |
2076 | 2101 | if ( this.preview_mode ) { |
2077 | 2102 | return ; |
2078 | | - } |
2079 | | - |
| 2103 | + } |
| 2104 | + |
2080 | 2105 | // Do the controlBuilder onClip done interface |
2081 | 2106 | this.controlBuilder.onClipDone(); |
2082 | 2107 | } |
2083 | 2108 | } |
2084 | | - |
2085 | 2109 | }, |
2086 | | - |
2087 | | - |
| 2110 | + |
| 2111 | + |
2088 | 2112 | /** |
2089 | 2113 | * Shows the video Thumbnail, updates pause state |
2090 | 2114 | */ |
2091 | 2115 | showThumbnail: function() { |
2092 | 2116 | var _this = this; |
2093 | 2117 | mw.log( 'EmbedPlayer::showThumbnail' + this.thumbnail_disp ); |
2094 | | - |
| 2118 | + |
2095 | 2119 | // Close Menu Overlay: |
2096 | 2120 | this.controlBuilder.closeMenuOverlay(); |
2097 | | - |
2098 | | - // update the thumbnail html: |
| 2121 | + |
| 2122 | + // update the thumbnail html: |
2099 | 2123 | this.updatePosterHTML(); |
2100 | | - |
| 2124 | + |
2101 | 2125 | this.paused = true; |
2102 | 2126 | this.thumbnail_disp = true; |
2103 | | - // Make sure the controlBuilder bindings are up-to-date |
| 2127 | + // Make sure the controlBuilder bindings are up-to-date |
2104 | 2128 | this.controlBuilder.addControlBindings(); |
2105 | | - |
| 2129 | + |
2106 | 2130 | // Once the thumbnail is shown run the mediaReady trigger (if not using native controls) |
2107 | 2131 | if( !this.useNativePlayerControls() ){ |
2108 | 2132 | mw.log("mediaLoaded"); |
2109 | 2133 | $j( this ).trigger( 'mediaLoaded' ); |
2110 | 2134 | } |
2111 | 2135 | }, |
2112 | | - |
| 2136 | + |
2113 | 2137 | /** |
2114 | 2138 | * Show the player |
2115 | 2139 | */ |
2116 | | - showPlayer : function () { |
2117 | | - mw.log( 'EmbedPlayer:: Show player: ' + this.id ); |
| 2140 | + showPlayer : function () { |
| 2141 | + mw.log( 'EmbedPlayer:: Show player: ' + this.id + ' interace: w:' + this.width + ' h:' + this.height); |
2118 | 2142 | var _this = this; |
2119 | | - // Set-up the local controlBuilder instance: |
2120 | | - this.controlBuilder = new mw.PlayerControlBuilder( this ); |
| 2143 | + // Set-up the local controlBuilder instance: |
| 2144 | + this.controlBuilder = new mw.PlayerControlBuilder( this ); |
2121 | 2145 | var _this = this; |
| 2146 | + |
2122 | 2147 | // Make sure we have mwplayer_interface |
2123 | 2148 | if( $j( this ).parent( '.mwplayer_interface' ).length == 0 ) { |
2124 | | - // Select "player" |
2125 | | - $j( this ) |
2126 | | - .wrap( |
| 2149 | + // Select "player" |
| 2150 | + $j( this ) |
| 2151 | + .wrap( |
2127 | 2152 | $j('<div>') |
2128 | 2153 | .addClass( 'mwplayer_interface ' + this.controlBuilder.playerClass ) |
2129 | | - .css({ |
2130 | | - 'width' : parseInt( this.width ) + 'px', |
2131 | | - 'height' : parseInt( this.height ) + 'px', |
| 2154 | + .css({ |
| 2155 | + 'width' : this.width + 'px', |
| 2156 | + 'height' : this.height + 'px', |
2132 | 2157 | 'position' : 'relative' |
2133 | 2158 | }) |
2134 | | - ) |
| 2159 | + ); |
2135 | 2160 | } |
2136 | | - |
2137 | | - //Set up local jQuery object reference to "mwplayer_interface" |
2138 | | - this.$interface = $j( this ).parent( '.mwplayer_interface' ); |
2139 | | - |
2140 | | - // Update Thumbnail for the "player" |
2141 | | - this.updatePosterHTML(); |
2142 | | - |
| 2161 | + |
| 2162 | + //Set up local jQuery object reference to "mwplayer_interface" |
| 2163 | + this.$interface = $j( this ).parent( '.mwplayer_interface' ); |
| 2164 | + |
| 2165 | + // Update Thumbnail for the "player" |
| 2166 | + this.updatePosterHTML(); |
| 2167 | + |
2143 | 2168 | // Add controls if enabled: |
2144 | | - if ( this.controls ) { |
| 2169 | + if ( this.controls ) { |
2145 | 2170 | this.controlBuilder.addControls(); |
2146 | 2171 | } else { |
2147 | | - // Need to think about this some more... |
2148 | | - // Interface is hidden if controls are "off" |
2149 | | - this.$interface.hide(); |
| 2172 | + // Need to think about this some more... |
| 2173 | + // Interface is hidden if controls are "off" |
| 2174 | + this.$interface.hide(); |
2150 | 2175 | } |
2151 | | - |
2152 | | - if ( this.autoplay ) { |
| 2176 | + |
| 2177 | + if ( this.autoplay ) { |
2153 | 2178 | mw.log( 'EmbedPlayer::showPlayer::activating autoplay' ); |
2154 | | - // Issue a non-blocking play request |
| 2179 | + // Issue a non-blocking play request |
2155 | 2180 | setTimeout(function(){ |
2156 | 2181 | _this.play(); |
2157 | | - },0) |
| 2182 | + },0); |
2158 | 2183 | } |
2159 | | - |
| 2184 | + |
2160 | 2185 | }, |
2161 | | - |
| 2186 | + |
2162 | 2187 | /** |
2163 | 2188 | * Get missing plugin html (check for user included code) |
2164 | 2189 | * @param {String} [misssingType] missing type mime |
2165 | 2190 | */ |
2166 | 2191 | showPluginMissingHTML: function( misssingType ) { |
2167 | | - // Remove the loading spinner if present: |
| 2192 | + // Remove the loading spinner if present: |
2168 | 2193 | $j('.playerLoadingSpinner').remove(); |
2169 | | - |
2170 | | - // If the native video is already displayed hide it: |
| 2194 | + |
| 2195 | + // If the native video is already displayed hide it: |
2171 | 2196 | if( $j( '#' + this.pid ).length != 0 ){ |
2172 | 2197 | $j('#loadingSpinner_' + this.id ).remove(); |
2173 | | - $j( '#' + this.pid ).hide() |
| 2198 | + $j( '#' + this.pid ).hide(); |
2174 | 2199 | } |
2175 | 2200 | if( this.mediaElement.sources.length == 0 ){ |
2176 | | - // hide the pid if present: |
| 2201 | + // Hide the pid if present: |
2177 | 2202 | $j( '#pid_' + this.id ).hide(); |
2178 | 2203 | $j( this ).show().html( |
2179 | | - $j('<span />').text( |
| 2204 | + $j('<span />').text( |
2180 | 2205 | gM('mwe-embedplayer-missing-source') |
2181 | 2206 | ) |
2182 | 2207 | ); |
2183 | 2208 | return ; |
2184 | 2209 | } |
2185 | | - var source = this.mediaElement.sources[0]; |
2186 | | - // Check if we have user defined missing html msg: |
| 2210 | + var source = this.mediaElement.sources[0]; |
| 2211 | + // Check if we have user defined missing html msg: |
2187 | 2212 | if ( this.user_missing_plugin_html ) { |
2188 | | - $j( this ).html( this.user_missing_plugin_html ); |
| 2213 | + $j( this ).html( this.user_missing_plugin_html ); |
2189 | 2214 | } else { |
2190 | | - if ( !misssingType ){ |
2191 | | - misssingType = ''; |
2192 | | - } |
2193 | | - $j( this ).html( |
2194 | | - $j('<div />').append( |
2195 | | - gM( 'mwe-embedplayer-generic_missing_plugin', misssingType ), |
2196 | | - $j( '<br />' ), |
2197 | | - $j( '<a />' ) |
2198 | | - .attr( { |
2199 | | - 'title' : gM( 'mwe-embedplayer-download_clip' ), |
2200 | | - 'href' : source.src |
2201 | | - }) |
2202 | | - .text( gM( 'mwe-embedplayer-download_clip' ) ) |
2203 | | - ) |
2204 | | - ); |
| 2215 | + if ( !misssingType ){ |
| 2216 | + misssingType = ''; |
| 2217 | + } |
| 2218 | + $j( this ).html( |
| 2219 | + $j('<div />').append( |
| 2220 | + gM( 'mwe-embedplayer-generic_missing_plugin', misssingType ), |
| 2221 | + $j( '<br />' ), |
| 2222 | + $j( '<a />' ) |
| 2223 | + .attr( { |
| 2224 | + 'title' : gM( 'mwe-embedplayer-download_clip' ), |
| 2225 | + 'href' : source.src |
| 2226 | + }) |
| 2227 | + .text( gM( 'mwe-embedplayer-download_clip' ) ) |
| 2228 | + ) |
| 2229 | + ); |
2205 | 2230 | } |
2206 | 2231 | // hide |
2207 | 2232 | }, |
2208 | | - |
| 2233 | + |
2209 | 2234 | /** |
2210 | 2235 | * Update the video time request via a time request string |
2211 | 2236 | * @param {String} time_req |
— | — | @@ -2214,23 +2239,23 @@ |
2215 | 2240 | var time_parts = time_req.split( '/' ); |
2216 | 2241 | this.updateVideoTime( time_parts[0], time_parts[1] ); |
2217 | 2242 | }, |
2218 | | - |
2219 | | - /** |
| 2243 | + |
| 2244 | + /** |
2220 | 2245 | * Update Video time from provided start_npt and end_npt values |
2221 | 2246 | * |
2222 | 2247 | * @param {String} start_npt the new start time in npt format |
2223 | | - * @pamra {String} end_npt the new end time in npt format |
| 2248 | + * @pamra {String} end_npt the new end time in npt format |
2224 | 2249 | */ |
2225 | 2250 | updateVideoTime: function( start_npt, end_npt ) { |
2226 | 2251 | // update media |
2227 | 2252 | this.mediaElement.updateSourceTimes( start_npt, end_npt ); |
2228 | | - |
| 2253 | + |
2229 | 2254 | // update mv_time |
2230 | 2255 | this.controlBuilder.setStatus( start_npt + '/' + end_npt ); |
2231 | | - |
| 2256 | + |
2232 | 2257 | // reset slider |
2233 | 2258 | this.updatePlayHead( 0 ); |
2234 | | - |
| 2259 | + |
2235 | 2260 | // reset seek_offset: |
2236 | 2261 | if ( this.mediaElement.selectedSource.URLTimeEncoding ) { |
2237 | 2262 | this.serverSeekTime = 0; |
— | — | @@ -2238,45 +2263,20 @@ |
2239 | 2264 | this.serverSeekTime = mw.npt2seconds( start_npt ); |
2240 | 2265 | } |
2241 | 2266 | }, |
2242 | | - |
| 2267 | + |
| 2268 | + |
2243 | 2269 | /** |
2244 | | - * Render a thumbnail at a given time |
2245 | | - * NOTE: Should overwrite by embed library if we can render frames natively |
2246 | | - * |
2247 | | - * @param {Object} options Options for rendered timeline thumb |
2248 | | - */ |
2249 | | - renderTimelineThumbnail: function( options ) { |
2250 | | - var my_thumb_src = this.mediaElement.getPosterSrc(); |
2251 | | - // check if our thumbnail has a time attribute: |
2252 | | - if ( my_thumb_src.indexOf( 't=' ) !== -1 ) { |
2253 | | - var time_ntp = mw.seconds2npt ( options.time + parseInt( this.startOffset ) ); |
2254 | | - my_thumb_src = mw.replaceUrlParams( my_thumb_src, { |
2255 | | - 't' : time_ntp, |
2256 | | - 'size' : options.size |
2257 | | - }); |
2258 | | - } |
2259 | | - var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : ''; |
2260 | | - return '<div class="ui-corner-all ' + thumb_class + '" src="' + my_thumb_src + '" ' + |
2261 | | - 'style="height:' + options.height + 'px;' + |
2262 | | - 'width:' + options.width + 'px" >' + |
2263 | | - '<img src="' + my_thumb_src + '" ' + |
2264 | | - 'style="height:' + options.height + 'px;' + |
2265 | | - 'width:' + options.width + 'px">' + |
2266 | | - '</div>'; |
2267 | | - }, |
2268 | | - |
2269 | | - /** |
2270 | 2270 | * Update Thumb time with npt formated time |
2271 | 2271 | * @param {String} time NPT formated time to update thumbnail |
2272 | | - */ |
| 2272 | + */ |
2273 | 2273 | updateThumbTimeNPT: function( time ) { |
2274 | 2274 | this.updateThumbTime( mw.npt2seconds( time ) - parseInt( this.startOffset ) ); |
2275 | 2275 | }, |
2276 | | - |
| 2276 | + |
2277 | 2277 | /** |
2278 | | - * Update the thumb with a new time |
| 2278 | + * Update the thumb with a new time |
2279 | 2279 | * @param {Float} floatSeconds Time to update the thumb to |
2280 | | - */ |
| 2280 | + */ |
2281 | 2281 | updateThumbTime:function( floatSeconds ) { |
2282 | 2282 | // mw.log('updateThumbTime:'+floatSeconds); |
2283 | 2283 | var _this = this; |
— | — | @@ -2285,8 +2285,8 @@ |
2286 | 2286 | } |
2287 | 2287 | if ( this.org_thum_src.indexOf( 't=' ) !== -1 ) { |
2288 | 2288 | this.last_thumb_url = mw.replaceUrlParams( this.org_thum_src, |
2289 | | - { |
2290 | | - 't' : mw.seconds2npt( floatSeconds + parseInt( this.startOffset ) ) |
| 2289 | + { |
| 2290 | + 't' : mw.seconds2npt( floatSeconds + parseInt( this.startOffset ) ) |
2291 | 2291 | } |
2292 | 2292 | ); |
2293 | 2293 | if ( !this.thumbnail_updating ) { |
— | — | @@ -2295,33 +2295,33 @@ |
2296 | 2296 | } |
2297 | 2297 | } |
2298 | 2298 | }, |
2299 | | - |
2300 | | - /** |
| 2299 | + |
| 2300 | + /** |
2301 | 2301 | * Updates the displayed thumbnail via percent of the stream |
2302 | 2302 | * @param {Float} percent Percent of duration to update thumb |
2303 | 2303 | */ |
2304 | 2304 | updateThumbPerc:function( percent ) { |
2305 | 2305 | return this.updateThumbTime( ( this.getDuration() * percent ) ); |
2306 | 2306 | }, |
2307 | | - |
| 2307 | + |
2308 | 2308 | /** |
2309 | 2309 | * Updates the thumbnail if the thumbnail is being displayed |
2310 | | - * |
| 2310 | + * |
2311 | 2311 | * @param {String} src New src of thumbnail |
2312 | | - * @param {Boolean} quick_switch |
| 2312 | + * @param {Boolean} quick_switch |
2313 | 2313 | * true switch happens instantly |
2314 | 2314 | * false / undefined animated cross fade |
2315 | 2315 | */ |
2316 | 2316 | updatePosterSrc: function( src, quick_switch ) { |
2317 | | - // make sure we don't go to the same url if we are not already updating: |
| 2317 | + // make sure we don't go to the same url if we are not already updating: |
2318 | 2318 | if ( !this.thumbnail_updating && $j( '#img_thumb_' + this.id ).attr( 'src' ) == src ) |
2319 | 2319 | return false; |
2320 | | - // if we are already updating don't issue a new update: |
| 2320 | + // if we are already updating don't issue a new update: |
2321 | 2321 | if ( this.thumbnail_updating && $j( '#new_img_thumb_' + this.id ).attr( 'src' ) == src ) |
2322 | 2322 | return false; |
2323 | | - |
| 2323 | + |
2324 | 2324 | mw.log( 'update thumb: ' + src ); |
2325 | | - |
| 2325 | + |
2326 | 2326 | if ( quick_switch ) { |
2327 | 2327 | $j( '#img_thumb_' + this.id ).attr( 'src', src ); |
2328 | 2328 | } else { |
— | — | @@ -2329,11 +2329,11 @@ |
2330 | 2330 | // if still animating remove new_img_thumb_ |
2331 | 2331 | if ( this.thumbnail_updating == true ) |
2332 | 2332 | $j( '#new_img_thumb_' + this.id ).stop().remove(); |
2333 | | - |
| 2333 | + |
2334 | 2334 | if ( this.thumbnail_disp ) { |
2335 | 2335 | mw.log( 'set to thumb:' + src ); |
2336 | 2336 | this.thumbnail_updating = true; |
2337 | | - $j( this ).append( |
| 2337 | + $j( this ).append( |
2338 | 2338 | $j('<img />') |
2339 | 2339 | .attr({ |
2340 | 2340 | 'src' : src, |
— | — | @@ -2344,17 +2344,17 @@ |
2345 | 2345 | .css( { |
2346 | 2346 | 'display' : 'none', |
2347 | 2347 | 'position' : 'absolute', |
2348 | | - 'zindex' : 2, |
| 2348 | + 'z-index' : 2, |
2349 | 2349 | 'top' : '0px', |
2350 | 2350 | 'left' : '0px' |
2351 | 2351 | }) |
2352 | 2352 | ); |
2353 | | - // mw.log('appended: new_img_thumb_'); |
| 2353 | + // mw.log('appended: new_img_thumb_'); |
2354 | 2354 | $j( '#new_img_thumb_' + this.id ).fadeIn( "slow", function() { |
2355 | 2355 | // once faded in remove org and rename new: |
2356 | 2356 | $j( '#img_thumb_' + _this.id ).remove(); |
2357 | 2357 | $j( '#new_img_thumb_' + _this.id ).attr( 'id', 'img_thumb_' + _this.id ); |
2358 | | - $j( '#img_thumb_' + _this.id ).css( 'zindex', '1' ); |
| 2358 | + $j( '#img_thumb_' + _this.id ).css( 'z-index', '1' ); |
2359 | 2359 | _this.thumbnail_updating = false; |
2360 | 2360 | // mw.log("done fadding in "+ $j('#img_thumb_'+_this.id).attr("src")); |
2361 | 2361 | |
— | — | @@ -2368,8 +2368,8 @@ |
2369 | 2369 | } |
2370 | 2370 | } |
2371 | 2371 | }, |
2372 | | - |
2373 | | - /** |
| 2372 | + |
| 2373 | + /** |
2374 | 2374 | * Returns the HTML code for the video when it is in thumbnail mode. |
2375 | 2375 | * playing, configuring the player, inline cmml display, HTML linkback, |
2376 | 2376 | * download, and embed code. |
— | — | @@ -2379,23 +2379,23 @@ |
2380 | 2380 | var thumb_html = ''; |
2381 | 2381 | var class_atr = ''; |
2382 | 2382 | var style_atr = ''; |
2383 | | - |
2384 | | - |
| 2383 | + |
| 2384 | + |
2385 | 2385 | if( this.useNativePlayerControls() ){ |
2386 | 2386 | this.showNativePlayer(); |
2387 | 2387 | return ; |
2388 | | - } |
2389 | | - |
| 2388 | + } |
| 2389 | + |
2390 | 2390 | // Set by default thumb value if not found |
2391 | | - var posterSrc = ( this.poster ) ? this.poster : |
2392 | | - mw.getConfig( 'imagesPath' ) + 'vid_default_thumb.jpg'; |
2393 | | - |
| 2391 | + var posterSrc = ( this.poster ) ? this.poster : |
| 2392 | + mw.getConfig( 'imagesPath' ) + 'vid_default_thumb.jpg'; |
| 2393 | + |
2394 | 2394 | // Poster support is not very consistent in browsers |
2395 | | - // use a jpeg poster image: |
| 2395 | + // use a jpeg poster image: |
2396 | 2396 | $j( this ).html( |
2397 | 2397 | $j( '<img />' ) |
2398 | 2398 | .css({ |
2399 | | - 'position' : 'relative', |
| 2399 | + 'position' : 'relative', |
2400 | 2400 | 'width' : '100%', |
2401 | 2401 | 'height' : '100%' |
2402 | 2402 | }) |
— | — | @@ -2405,28 +2405,28 @@ |
2406 | 2406 | }) |
2407 | 2407 | .addClass( 'playerPoster' ) |
2408 | 2408 | ); |
2409 | | - |
2410 | | - if ( this.controls |
2411 | | - && this.height > this.controlBuilder.getComponentHeight( 'playButtonLarge' ) |
| 2409 | + |
| 2410 | + if ( this.controls |
| 2411 | + && this.height > this.controlBuilder.getComponentHeight( 'playButtonLarge' ) |
2412 | 2412 | ) { |
2413 | 2413 | $j( this ).append( |
2414 | 2414 | this.controlBuilder.getComponent( 'playButtonLarge' ) |
2415 | 2415 | ); |
2416 | | - } |
| 2416 | + } |
2417 | 2417 | }, |
2418 | | - |
| 2418 | + |
2419 | 2419 | /** |
2420 | | - * Checks if native controls should be used |
| 2420 | + * Checks if native controls should be used |
2421 | 2421 | * |
2422 | | - * @param [player] Object Optional player object to check controls attribute |
| 2422 | + * @param [player] Object Optional player object to check controls attribute |
2423 | 2423 | * @returns boolean true if the mwEmbed player interface should be used |
2424 | 2424 | * false if the mwEmbed player interface should not be used |
2425 | 2425 | */ |
2426 | | - useNativePlayerControls: function() { |
| 2426 | + useNativePlayerControls: function() { |
2427 | 2427 | if( this.usenativecontrols === true ){ |
2428 | 2428 | return true; |
2429 | 2429 | } |
2430 | | - |
| 2430 | + |
2431 | 2431 | if( mw.getConfig('EmbedPlayer.NativeControls') === true ) { |
2432 | 2432 | return true; |
2433 | 2433 | } |
— | — | @@ -2434,30 +2434,30 @@ |
2435 | 2435 | mw.isMobileHTML5() |
2436 | 2436 | ){ |
2437 | 2437 | return true; |
2438 | | - } |
| 2438 | + } |
2439 | 2439 | return false; |
2440 | 2440 | }, |
2441 | | - |
2442 | | - |
| 2441 | + |
| 2442 | + |
2443 | 2443 | /** |
2444 | | - * Show the native player embed code |
| 2444 | + * Show the native player embed code |
2445 | 2445 | * |
2446 | | - * This is for cases where the main library needs to "get out of the way" |
2447 | | - * since the device only supports a limited subset of the html5 and |
| 2446 | + * This is for cases where the main library needs to "get out of the way" |
| 2447 | + * since the device only supports a limited subset of the html5 and |
2448 | 2448 | * won't work with an html javascirpt interface |
2449 | 2449 | */ |
2450 | 2450 | showNativePlayer: function(){ |
2451 | 2451 | var _this = this; |
2452 | 2452 | // Empty the player |
2453 | 2453 | $j(this).empty(); |
2454 | | - |
| 2454 | + |
2455 | 2455 | // Remove the player loader spinner if it exists |
2456 | 2456 | $j('#loadingSpinner_' + this.id ).remove(); |
2457 | | - |
2458 | | - |
| 2457 | + |
| 2458 | + |
2459 | 2459 | // Check if we need to refresh mobile safari |
2460 | | - var mobileSafariNeedsRefresh = false; |
2461 | | - |
| 2460 | + var mobileSafariNeedsRefresh = false; |
| 2461 | + |
2462 | 2462 | // Unhide the original video element if not part of a playerThemer embed |
2463 | 2463 | if( !$j( '#' + this.pid ).hasClass('PlayerThemer') ){ |
2464 | 2464 | $j( '#' + this.pid ) |
— | — | @@ -2466,27 +2466,27 @@ |
2467 | 2467 | } ) |
2468 | 2468 | .show() |
2469 | 2469 | .attr('controls', 'true'); |
2470 | | - |
| 2470 | + |
2471 | 2471 | mobileSafariNeedsRefresh = true; |
2472 | 2472 | } |
2473 | | - |
2474 | | - // iPad does not handle video tag update for attributes like "controls" |
2475 | | - // so we have to do a full replace ( if controls are not included initially ) |
| 2473 | + |
| 2474 | + // iPad does not handle video tag update for attributes like "controls" |
| 2475 | + // so we have to do a full replace ( if controls are not included initially ) |
2476 | 2476 | if( mw.isMobileHTML5() && mobileSafariNeedsRefresh ) { |
2477 | 2477 | var source = this.mediaElement.getSources( 'video/h264' )[0]; |
2478 | | - // XXX note this should be updated once mobile supports h.264 |
| 2478 | + // XXX note this should be updated once mobile supports h.264 |
2479 | 2479 | if( !source || !source.src ){ |
2480 | 2480 | mw.log( 'Warning: Your probably fakeing the iPhone userAgent ( no h.264 source )' ); |
2481 | 2481 | source = this.mediaElement.getSources( 'video/ogg' )[0]; |
2482 | 2482 | } |
2483 | | - |
| 2483 | + |
2484 | 2484 | var videoAttribues = { |
2485 | 2485 | 'id' : _this.pid, |
2486 | 2486 | 'poster': _this.poster, |
2487 | 2487 | 'src' : source.src, |
2488 | 2488 | 'controls' : 'true' |
2489 | | - } |
2490 | | - |
| 2489 | + }; |
| 2490 | + |
2491 | 2491 | if( this.loop ){ |
2492 | 2492 | videoAttribues[ 'loop' ] = 'true'; |
2493 | 2493 | } |
— | — | @@ -2494,9 +2494,9 @@ |
2495 | 2495 | 'width' : _this.width, |
2496 | 2496 | 'height' : _this.height |
2497 | 2497 | }; |
2498 | | - $j( '#' + this.pid ).replaceWith( |
2499 | | - _this.getNativePlayerHtml( videoAttribues, cssStyle ) |
2500 | | - ) |
| 2498 | + $j( '#' + this.pid ).replaceWith( |
| 2499 | + _this.getNativePlayerHtml( videoAttribues, cssStyle ) |
| 2500 | + ); |
2501 | 2501 | // Bind native events: |
2502 | 2502 | this.applyMediaElementBindings(); |
2503 | 2503 | } |
— | — | @@ -2504,14 +2504,14 @@ |
2505 | 2505 | // and only with 'native display' |
2506 | 2506 | if( mw.isAndroid2() ){ |
2507 | 2507 | $j( '#' + _this.pid ).siblings('.play-btn-large').remove(); |
2508 | | - $j( '#' + _this.pid ).after( |
2509 | | - $j('<div />') |
| 2508 | + $j( '#' + _this.pid ).after( |
| 2509 | + $j('<div />') |
2510 | 2510 | .css({ |
2511 | 2511 | 'position' : 'relative', |
2512 | 2512 | 'top' : -1 * ( .5 * _this.getPlayerHeight() ) - 52, |
2513 | 2513 | 'left' : ( .5 * _this.getPlayerWidth() ) - 75 |
2514 | 2514 | }) |
2515 | | - .attr( { |
| 2515 | + .attr( { |
2516 | 2516 | 'title' : gM( 'mwe-embedplayer-play_clip' ), |
2517 | 2517 | 'class' : "ui-state-default play-btn-large" |
2518 | 2518 | } ) |
— | — | @@ -2519,12 +2519,12 @@ |
2520 | 2520 | _this.play(); |
2521 | 2521 | // no need to hide the play button since android plays fullscreen |
2522 | 2522 | } ) |
2523 | | - ) |
2524 | | - } |
| 2523 | + ); |
| 2524 | + } |
2525 | 2525 | return ; |
2526 | 2526 | }, |
2527 | 2527 | /** |
2528 | | - * Should be set via native embed support |
| 2528 | + * Should be set via native embed support |
2529 | 2529 | */ |
2530 | 2530 | getNativePlayerHtml: function(){ |
2531 | 2531 | return $j('<div />' ) |
— | — | @@ -2532,168 +2532,160 @@ |
2533 | 2533 | .html( 'Error: Trying to get native html5 player without native support for codec' ); |
2534 | 2534 | }, |
2535 | 2535 | /** |
2536 | | - * Should be set via native embed support |
| 2536 | + * Should be set via native embed support |
2537 | 2537 | */ |
2538 | 2538 | applyMediaElementBindings: function(){ |
2539 | 2539 | return ; |
2540 | 2540 | }, |
2541 | | - |
| 2541 | + |
2542 | 2542 | /** |
2543 | 2543 | * Gets code to embed the player remotely for "share" this player links |
2544 | | - */ |
| 2544 | + */ |
2545 | 2545 | getEmbeddingHTML: function() { |
2546 | 2546 | switch( mw.getConfig( 'EmbedPlayer.ShareEmbedMode' ) ){ |
2547 | | - case 'object': |
2548 | | - return this.getShareEmbedObject() |
| 2547 | + case 'iframe': |
| 2548 | + return this.getShareIframeObject(); |
2549 | 2549 | break; |
2550 | 2550 | case 'videojs': |
2551 | 2551 | return this.getShareEmbedVideoJs(); |
2552 | 2552 | break; |
2553 | 2553 | } |
2554 | 2554 | }, |
2555 | | - |
| 2555 | + |
2556 | 2556 | /** |
2557 | 2557 | * Get the share embed object code |
2558 | | - * |
| 2558 | + * |
2559 | 2559 | * NOTE this could probably share a bit more code with getShareEmbedVideoJs |
2560 | | - */ |
2561 | | - getShareEmbedObject: function(){ |
| 2560 | + */ |
| 2561 | + getShareIframeObject: function(){ |
2562 | 2562 | var iframeUrl = mw.getMwEmbedPath() + 'mwEmbedFrame.php?'; |
2563 | | - |
| 2563 | + var params = {}; |
| 2564 | + |
2564 | 2565 | if ( this.roe ) { |
2565 | | - iframeUrl += 'roe=' + escape( this.roe ) + '&'; |
2566 | | - } else if( this.apiTitleKey ) { |
2567 | | - iframeUrl += 'apiTitleKey=' + escape( this.apiTitleKey ) + '&'; |
| 2566 | + params.roe = this.roe; |
| 2567 | + } else if( this.apiTitleKey ) { |
| 2568 | + params.apiTitleKey = this.apiTitleKey; |
2568 | 2569 | if ( this.apiProvider ) { |
2569 | | - // Commons always uses the commons api provider ( special hack should refactor ) |
| 2570 | + // Commons always uses the commons api provider ( special hack should refactor ) |
2570 | 2571 | if( mw.parseUri( document.URL ).host == 'commons.wikimedia.org'){ |
2571 | 2572 | this.apiProvider = 'commons'; |
2572 | 2573 | } |
2573 | | - iframeUrl += 'apiProvider=' + escape( this.apiProvider ) + '&'; |
| 2574 | + params.apiProvider = this.apiProvider; |
2574 | 2575 | } |
2575 | | - } else { |
| 2576 | + } else { |
2576 | 2577 | // Output all the video sources: |
2577 | 2578 | for( var i=0; i < this.mediaElement.sources.length; i++ ){ |
2578 | 2579 | var source = this.mediaElement.sources[i]; |
2579 | 2580 | if( source.src ) { |
2580 | | - iframeUrl += 'src[]=' + escape( mw.absoluteUrl( source.src ) ) + '&'; |
| 2581 | + params['src[]'] = mw.absoluteUrl( source.src ); |
2581 | 2582 | } |
2582 | 2583 | } |
2583 | 2584 | // Output the poster attr |
2584 | 2585 | if( this.poster ){ |
2585 | | - iframeUrl += 'poster=' + escape( this.poster ) + '&'; |
| 2586 | + params.poster = this.poster; |
2586 | 2587 | } |
2587 | 2588 | } |
2588 | | - |
| 2589 | + |
2589 | 2590 | // Set the skin if set to something other than default |
2590 | 2591 | if( this.skinName ){ |
2591 | | - iframeUrl += 'skin=' + escape( this.skinName ) + '&'; |
| 2592 | + params.skin = this.skinName; |
2592 | 2593 | } |
2593 | | - |
| 2594 | + |
2594 | 2595 | if( this.duration ) { |
2595 | | - iframeUrl +='durationHint=' + escape( parseFloat( this.duration ) ) + '&'; |
| 2596 | + params.durationHint = parseFloat( this.duration ); |
2596 | 2597 | } |
2597 | | - // Set width / height of iframe embed ( child iframe / object can't read parent frame size ) |
2598 | | - if( this.width || this.height ){ |
2599 | | - iframeUrl += ( this.width )? 'width=' + parseInt( this.width ) + '&' : ''; |
2600 | | - iframeUrl += ( this.height )? 'height=' +parseInt( this.height ) + '&' : ''; |
2601 | | - } |
2602 | | - |
| 2598 | + iframeUrl += $j.param( params ); |
| 2599 | + |
2603 | 2600 | // Set up embedFrame src path |
2604 | | - var embedCode = '<object data="' + mw.escapeQuotesHTML( iframeUrl ) + '" '; |
2605 | | - |
2606 | | - // Set width / height of embed object ( give extra space for controls ) |
2607 | | - if( this.width || this.height ){ |
2608 | | - embedCode += ( this.width )? 'width="' + this.width +'" ': ''; |
2609 | | - embedCode += ( this.height )? 'height="' + |
2610 | | - parseInt( this.height + this.controlBuilder.getHeight() + 2 ) + |
2611 | | - '" ': ''; |
2612 | | - } |
2613 | | - //Make sure overflow is hidden: |
2614 | | - embedCode += 'style="overflow:hidden" '; |
2615 | | - |
2616 | | - // Close up the embedCode tag: |
2617 | | - embedCode+='></object>'; |
2618 | | - |
| 2601 | + var embedCode = '<iframe src="' + mw.escapeQuotesHTML( iframeUrl ) + '" '; |
| 2602 | + |
| 2603 | + // Set width / height of embed object |
| 2604 | + embedCode += 'width="' + this.getPlayerWidth() +'" '; |
| 2605 | + embedCode += 'height="' + this.getPlayerHeight() + '" '; |
| 2606 | + embedCode += 'frameborder="0" '; |
| 2607 | + |
| 2608 | + // Close up the embedCode tag: |
| 2609 | + embedCode+='></iframe>'; |
| 2610 | + |
2619 | 2611 | // Return the embed code |
2620 | 2612 | return embedCode; |
2621 | 2613 | }, |
2622 | | - |
| 2614 | + |
2623 | 2615 | /** |
2624 | 2616 | * Get the share embed Video tag code |
2625 | | - */ |
| 2617 | + */ |
2626 | 2618 | getShareEmbedVideoJs: function(){ |
2627 | | - |
2628 | | - // Set the embed tag type: |
| 2619 | + |
| 2620 | + // Set the embed tag type: |
2629 | 2621 | var embedtag = ( this.isAudio() )? 'audio': 'video'; |
2630 | | - |
2631 | | - // Set up the mwEmbed js include: |
| 2622 | + |
| 2623 | + // Set up the mwEmbed js include: |
2632 | 2624 | var embedCode = '<script type="text/javascript" ' + |
2633 | | - 'src="' + |
2634 | | - mw.escapeQuotesHTML( |
2635 | | - mw.absoluteUrl( |
2636 | | - mw.getMwEmbedSrc() |
| 2625 | + 'src="' + |
| 2626 | + mw.escapeQuotesHTML( |
| 2627 | + mw.absoluteUrl( |
| 2628 | + mw.getMwEmbedSrc() |
2637 | 2629 | ) |
2638 | 2630 | ) + '"></script>' + |
2639 | 2631 | '<' + embedtag + ' '; |
2640 | 2632 | |
2641 | 2633 | if( this.poster ) { |
2642 | 2634 | embedCode += 'poster="' + |
2643 | | - mw.escapeQuotesHTML( mw.absoluteUrl( this.poster ) ) + |
| 2635 | + mw.escapeQuotesHTML( mw.absoluteUrl( this.poster ) ) + |
2644 | 2636 | '" '; |
2645 | 2637 | } |
2646 | | - |
| 2638 | + |
2647 | 2639 | // Set the skin if set to something other than default |
2648 | 2640 | if( this.skinName ){ |
2649 | 2641 | embedCode += 'class="' + |
2650 | | - mw.escapeQuotesHTML( this.skinName ) + |
| 2642 | + mw.escapeQuotesHTML( this.skinName ) + |
2651 | 2643 | '" '; |
2652 | 2644 | } |
2653 | | - |
| 2645 | + |
2654 | 2646 | if( this.duration ) { |
2655 | 2647 | embedCode +='durationHint="' + parseFloat( this.duration ) + '" '; |
2656 | 2648 | } |
2657 | | - |
| 2649 | + |
2658 | 2650 | if( this.width || this.height ){ |
2659 | 2651 | embedCode +='style="'; |
2660 | 2652 | embedCode += ( this.width )? 'width:' + this.width +'px;': ''; |
2661 | 2653 | embedCode += ( this.height )? 'height:' + this.height +'px;': ''; |
2662 | 2654 | embedCode += '" '; |
2663 | 2655 | } |
2664 | | - |
2665 | | - |
| 2656 | + |
| 2657 | + |
2666 | 2658 | if ( this.roe ) { |
2667 | 2659 | embedCode += 'roe="' + mw.escapeQuotesHTML( this.roe ) + '" '; |
2668 | | - } else if( this.apiTitleKey ) { |
| 2660 | + } else if( this.apiTitleKey ) { |
2669 | 2661 | embedCode += 'apiTitleKey="' + mw.escapeQuotesHTML( this.apiTitleKey ) + '" '; |
2670 | 2662 | if ( this.apiProvider ) { |
2671 | 2663 | embedCode += 'apiProvider="' + mw.escapeQuotesHTML( this.apiProvider ) + '" '; |
2672 | 2664 | } |
2673 | 2665 | // close the video tag |
2674 | 2666 | embedCode += '></video>'; |
2675 | | - |
| 2667 | + |
2676 | 2668 | } else { |
2677 | 2669 | //Close the video attr |
2678 | 2670 | embedCode += '>'; |
2679 | | - |
| 2671 | + |
2680 | 2672 | // Output all the video sources: |
2681 | 2673 | for( var i=0; i < this.mediaElement.sources.length; i++ ){ |
2682 | 2674 | var source = this.mediaElement.sources[i]; |
2683 | 2675 | if( source.src ) { |
2684 | | - embedCode +='<source src="' + |
2685 | | - mw.absoluteUrl( source.src ) + |
| 2676 | + embedCode +='<source src="' + |
| 2677 | + mw.absoluteUrl( source.src ) + |
2686 | 2678 | '" <>/source>'; |
2687 | 2679 | } |
2688 | | - } |
| 2680 | + } |
2689 | 2681 | // Close the video tag |
2690 | | - embedCode += '</video>'; |
2691 | | - } |
2692 | | - |
| 2682 | + embedCode += '</video>'; |
| 2683 | + } |
| 2684 | + |
2693 | 2685 | return embedCode; |
2694 | 2686 | }, |
2695 | | - |
| 2687 | + |
2696 | 2688 | /** |
2697 | | - * Follows a linkback. Loads the ROE xml if no linkback is found |
| 2689 | + * Follows a linkback. Loads the ROE xml if no linkback is found |
2698 | 2690 | */ |
2699 | 2691 | doLinkBack: function() { |
2700 | 2692 | if ( ! this.linkback && this.roe && this.mediaElement.addedROEData == false ) { |
— | — | @@ -2712,12 +2704,12 @@ |
2713 | 2705 | this.displayMenuOverlay( gM( 'mwe-embedplayer-could_not_find_linkback' ) ); |
2714 | 2706 | } |
2715 | 2707 | } |
2716 | | - }, |
2717 | | - |
| 2708 | + }, |
| 2709 | + |
2718 | 2710 | /** |
2719 | 2711 | * Base Embed Controls |
2720 | 2712 | */ |
2721 | | - |
| 2713 | + |
2722 | 2714 | /** |
2723 | 2715 | * The Play Action |
2724 | 2716 | * |
— | — | @@ -2725,60 +2717,61 @@ |
2726 | 2718 | * seeking =false |
2727 | 2719 | * paused = false |
2728 | 2720 | * Updates pause button |
2729 | | - * Starts the "monitor" |
| 2721 | + * Starts the "monitor" |
2730 | 2722 | */ |
2731 | 2723 | play: function() { |
2732 | | - var _this = this; |
2733 | | - mw.log( "EmbedPlayer:: play" ); |
| 2724 | + var _this = this; |
| 2725 | + // Run play hook (if we we did not bind the native player ) |
| 2726 | + if( this.paused && this.useNativePlayerControls() ){ |
| 2727 | + this.paused = false; |
| 2728 | + mw.log("trigger play event::" + !this.paused); |
| 2729 | + $j( this ).trigger( 'play' ); |
| 2730 | + } |
| 2731 | + this.paused = false; |
| 2732 | + |
| 2733 | + mw.log( "EmbedPlayer:: play" ); |
2734 | 2734 | // Hide any overlay: |
2735 | 2735 | this.controlBuilder.closeMenuOverlay(); |
2736 | | - |
| 2736 | + |
2737 | 2737 | // Check if thumbnail is being displayed and embed html |
2738 | 2738 | if ( this.thumbnail_disp ) { |
2739 | 2739 | if ( !this.selectedPlayer ) { |
2740 | | - mw.log( 'no selectedPlayer' ); |
| 2740 | + mw.log( 'no selectedPlayer' ); |
2741 | 2741 | this.showPluginMissingHTML(); |
2742 | | - return; |
| 2742 | + return; |
2743 | 2743 | } else { |
2744 | 2744 | this.thumbnail_disp = false; |
2745 | | - this.doEmbedHTML(); |
| 2745 | + this.doEmbedHTML(); |
2746 | 2746 | } |
2747 | 2747 | } else { |
2748 | | - // the plugin is already being displayed |
| 2748 | + // the plugin is already being displayed |
2749 | 2749 | this.seeking = false; |
2750 | 2750 | } |
2751 | | - |
2752 | | - // Run play hook (if we were previously in paused state ) |
2753 | | - if( this.paused ){ |
2754 | | - this.paused = false; |
2755 | | - mw.log("trigger play event::"); |
2756 | | - $j( this ).trigger( 'play' ); |
2757 | | - } |
2758 | | - |
2759 | | - |
| 2751 | + |
| 2752 | + |
2760 | 2753 | this.$interface.find('.play-btn span') |
2761 | 2754 | .removeClass( 'ui-icon-play' ) |
2762 | 2755 | .addClass( 'ui-icon-pause' ); |
2763 | | - |
| 2756 | + |
2764 | 2757 | this.$interface.find( '.play-btn' ) |
2765 | | - .unbind() |
| 2758 | + .unbind() |
2766 | 2759 | .buttonHover() |
2767 | 2760 | .click( function( ) { |
2768 | 2761 | _this.pause(); |
2769 | | - } ) |
2770 | | - .attr( 'title', gM( 'mwe-embedplayer-pause_clip' ) ); |
| 2762 | + } ) |
| 2763 | + .attr( 'title', gM( 'mwe-embedplayer-pause_clip' ) ); |
2771 | 2764 | |
2772 | 2765 | // Start the monitor if not already started |
2773 | 2766 | this.monitor(); |
2774 | | - |
2775 | | - // If we previously finished playing this clip run the "replay hook" |
2776 | | - if( this.donePlayingCount > 0 ) { |
2777 | | - mw.log("replayEvent"); |
2778 | | - $j( this ).trigger( 'replayEvent' ); |
2779 | | - } |
| 2767 | + |
| 2768 | + // If we previously finished playing this clip run the "replay hook" |
| 2769 | + if( this.donePlayingCount > 0 ) { |
| 2770 | + mw.log("replayEvent"); |
| 2771 | + $j( this ).trigger( 'replayEvent' ); |
| 2772 | + } |
2780 | 2773 | }, |
2781 | | - |
2782 | | - |
| 2774 | + |
| 2775 | + |
2783 | 2776 | /** |
2784 | 2777 | * Maps the html5 load request. There is no general way to "load" clips so |
2785 | 2778 | * underling plugin-player libs should override. |
— | — | @@ -2786,8 +2779,8 @@ |
2787 | 2780 | load: function() { |
2788 | 2781 | // should be done by child (no base way to pre-buffer video) |
2789 | 2782 | mw.log( 'baseEmbed:load call' ); |
2790 | | - }, |
2791 | | - |
| 2783 | + }, |
| 2784 | + |
2792 | 2785 | /** |
2793 | 2786 | * Base embed pause |
2794 | 2787 | * Updates the play/pause button state. |
— | — | @@ -2797,32 +2790,32 @@ |
2798 | 2791 | */ |
2799 | 2792 | pause: function( event ) { |
2800 | 2793 | var _this = this; |
2801 | | - |
2802 | | - // only trigger the pause event if not already in paused state: |
2803 | | - if( this.paused === false ){ |
| 2794 | + // Trigger the pause event if not already paused and using native controls: |
| 2795 | + if( this.paused === false && this.useNativePlayerControls() ){ |
2804 | 2796 | this.paused = true; |
2805 | | - mw.log('EmbedPlayer:trigger pause'); |
2806 | | - //$j( this ).trigger('pause' ); |
2807 | | - } |
2808 | | - |
2809 | | - // update the ctrl "paused state" |
| 2797 | + mw.log('EmbedPlayer:trigger pause:' + this.paused); |
| 2798 | + $j( this ).trigger('pause' ); |
| 2799 | + } |
| 2800 | + this.paused = true; |
| 2801 | + |
| 2802 | + // update the ctrl "paused state" |
2810 | 2803 | this.$interface.find('.play-btn span' ) |
2811 | 2804 | .removeClass( 'ui-icon-pause' ) |
2812 | 2805 | .addClass( 'ui-icon-play' ); |
2813 | | - |
| 2806 | + |
2814 | 2807 | this.$interface.find('.play-btn' ) |
2815 | 2808 | .unbind() |
2816 | 2809 | .buttonHover() |
2817 | 2810 | .click( function() { |
2818 | 2811 | _this.play(); |
2819 | 2812 | } ) |
2820 | | - .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) ); |
| 2813 | + .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) ); |
2821 | 2814 | }, |
2822 | | - |
| 2815 | + |
2823 | 2816 | /** |
2824 | | - * Base embed stop |
2825 | | - * |
2826 | | - * Updates the player to the stop state |
| 2817 | + * Base embed stop |
| 2818 | + * |
| 2819 | + * Updates the player to the stop state |
2827 | 2820 | * shows Thumbnail |
2828 | 2821 | * resets Buffer |
2829 | 2822 | * resets Playhead slider |
— | — | @@ -2830,15 +2823,15 @@ |
2831 | 2824 | */ |
2832 | 2825 | stop: function() { |
2833 | 2826 | var _this = this; |
2834 | | - mw.log( 'EmbedPlayer::stop:' + this.id ); |
2835 | | - |
| 2827 | + mw.log( 'EmbedPlayer::stop:' + this.id ); |
| 2828 | + |
2836 | 2829 | // no longer seeking: |
2837 | 2830 | this.didSeekJump = false; |
2838 | | - |
| 2831 | + |
2839 | 2832 | // Reset current time and prev time and seek offset |
2840 | | - this.currentTime = this.previousTime = this.serverSeekTime = 0; |
2841 | | - |
2842 | | - // Issue pause to update interface (only call this parent) |
| 2833 | + this.currentTime = this.previousTime = this.serverSeekTime = 0; |
| 2834 | + |
| 2835 | + // Issue pause to update interface (only call this parent) |
2843 | 2836 | if( !this.paused ){ |
2844 | 2837 | this.paused = true; |
2845 | 2838 | // update the interface |
— | — | @@ -2847,46 +2840,46 @@ |
2848 | 2841 | } else { |
2849 | 2842 | this.pause(); |
2850 | 2843 | } |
2851 | | - } |
2852 | | - |
| 2844 | + } |
| 2845 | + |
2853 | 2846 | // Rewrite the html to thumbnail disp |
2854 | 2847 | this.showThumbnail(); |
2855 | | - this.bufferedPercent = 0; // reset buffer state |
| 2848 | + this.bufferedPercent = 0; // reset buffer state |
2856 | 2849 | this.controlBuilder.setStatus( this.getTimeRange() ); |
2857 | | - |
| 2850 | + |
2858 | 2851 | // Reset the playhead |
2859 | | - mw.log("EmbedPlayer::Stop:: Reset play head") |
| 2852 | + mw.log("EmbedPlayer::Stop:: Reset play head"); |
2860 | 2853 | this.updatePlayHead( 0 ); |
2861 | | - |
2862 | | - //Bind play-btn-large play |
| 2854 | + |
| 2855 | + //Bind play-btn-large play |
2863 | 2856 | this.$interface.find( '.play-btn-large' ) |
2864 | 2857 | .unbind( 'click' ) |
2865 | 2858 | .click( function() { |
2866 | 2859 | _this.play(); |
2867 | | - } ); |
| 2860 | + } ); |
2868 | 2861 | }, |
2869 | | - |
| 2862 | + |
2870 | 2863 | /** |
2871 | 2864 | * Base Embed mute |
2872 | | - * |
| 2865 | + * |
2873 | 2866 | * Handles interface updates for toggling mute. |
2874 | 2867 | * Plug-in / player interface must handle the actual media player update |
2875 | 2868 | */ |
2876 | 2869 | toggleMute: function() { |
2877 | | - mw.log( 'f:toggleMute:: (old state:) ' + this.muted ); |
| 2870 | + mw.log( 'f:toggleMute:: (old state:) ' + this.muted ); |
2878 | 2871 | if ( this.muted ) { |
2879 | | - this.muted = false; |
2880 | | - var percent = this.preMuteVolume; |
| 2872 | + this.muted = false; |
| 2873 | + var percent = this.preMuteVolume; |
2881 | 2874 | } else { |
2882 | 2875 | this.muted = true; |
2883 | | - this.preMuteVolume = this.volume; |
| 2876 | + this.preMuteVolume = this.volume; |
2884 | 2877 | var percent = 0; |
2885 | | - } |
2886 | | - this.setVolume( percent ); |
| 2878 | + } |
| 2879 | + this.setVolume( percent ); |
2887 | 2880 | // Update the interface |
2888 | 2881 | this.setInterfaceVolume( percent ); |
2889 | 2882 | }, |
2890 | | - |
| 2883 | + |
2891 | 2884 | /** |
2892 | 2885 | * Update volume function ( called from interface updates ) |
2893 | 2886 | * @param {float} percent Percent of full volume |
— | — | @@ -2896,77 +2889,77 @@ |
2897 | 2890 | if( isNaN( percent ) ){ |
2898 | 2891 | return ; |
2899 | 2892 | } |
2900 | | - // Set the local volume attribute |
| 2893 | + // Set the local volume attribute |
2901 | 2894 | this.previousVolume = this.volume = percent; |
2902 | | - |
| 2895 | + |
2903 | 2896 | // Un-mute if setting positive volume |
2904 | 2897 | if( percent != 0 ){ |
2905 | | - this.muted = false; |
| 2898 | + this.muted = false; |
2906 | 2899 | } |
2907 | | - |
2908 | | - // Update the playerElement volume |
| 2900 | + |
| 2901 | + // Update the playerElement volume |
2909 | 2902 | this.setPlayerElementVolume( percent ); |
2910 | | - |
2911 | | - //mw.log(" setVolume:: " + percent + ' this.volume is: ' + this.volume); |
| 2903 | + |
| 2904 | + //mw.log(" setVolume:: " + percent + ' this.volume is: ' + this.volume); |
2912 | 2905 | $j( this ).trigger('volumeChanged', percent ); |
2913 | 2906 | }, |
2914 | | - |
| 2907 | + |
2915 | 2908 | /** |
2916 | 2909 | * Updates the interface volume |
2917 | 2910 | * TODO should move to controlBuilder |
2918 | 2911 | * @param {float} percent Percentage volume to update interface |
2919 | 2912 | */ |
2920 | 2913 | setInterfaceVolume: function( percent ) { |
2921 | | - if( this.supports[ 'volumeControl' ] && |
2922 | | - this.$interface.find( '.volume-slider' ).length |
| 2914 | + if( this.supports[ 'volumeControl' ] && |
| 2915 | + this.$interface.find( '.volume-slider' ).length |
2923 | 2916 | ) { |
2924 | 2917 | this.$interface.find( '.volume-slider' ).slider( 'value', percent * 100 ); |
2925 | 2918 | } |
2926 | | - }, |
2927 | | - |
| 2919 | + }, |
| 2920 | + |
2928 | 2921 | /** |
2929 | 2922 | * Abstract Update volume Method must be override by plug-in / player interface |
2930 | 2923 | */ |
2931 | 2924 | setPlayerElementVolume: function( percent ) { |
2932 | 2925 | mw.log('Error player does not support volume adjustment' ); |
2933 | 2926 | }, |
2934 | | - |
| 2927 | + |
2935 | 2928 | /** |
2936 | 2929 | * Abstract get volume Method must be override by plug-in / player interface |
2937 | | - * (if player does not override we return the abstract player value ) |
| 2930 | + * (if player does not override we return the abstract player value ) |
2938 | 2931 | */ |
2939 | 2932 | getPlayerElementVolume: function(){ |
2940 | 2933 | //mw.log(' error player does not support getting volume property' ); |
2941 | | - return this.volume; |
| 2934 | + return this.volume; |
2942 | 2935 | }, |
2943 | | - |
| 2936 | + |
2944 | 2937 | /** |
2945 | | - * Abstract get volume muted property must be overwritten by plug-in / player interface |
2946 | | - * (if player does not override we return the abstract player value ) |
| 2938 | + * Abstract get volume muted property must be overwritten by plug-in / player interface |
| 2939 | + * (if player does not override we return the abstract player value ) |
2947 | 2940 | */ |
2948 | 2941 | getPlayerElementMuted: function(){ |
2949 | 2942 | //mw.log(' error player does not support getting mute property' ); |
2950 | 2943 | return this.muted; |
2951 | 2944 | }, |
2952 | | - |
| 2945 | + |
2953 | 2946 | /** |
2954 | 2947 | * Passes a fullscreen request to the controlBuilder interface |
2955 | 2948 | */ |
2956 | 2949 | fullscreen: function() { |
2957 | | - this.controlBuilder.toggleFullscreen(); |
| 2950 | + this.controlBuilder.toggleFullscreen(); |
2958 | 2951 | }, |
2959 | | - |
| 2952 | + |
2960 | 2953 | /** |
2961 | | - * Abstract method to be run post embedding the player |
2962 | | - * Generally should be overwritten by the plug-in / player |
| 2954 | + * Abstract method to be run post embedding the player |
| 2955 | + * Generally should be overwritten by the plug-in / player |
2963 | 2956 | */ |
2964 | 2957 | postEmbedJS:function() { |
2965 | 2958 | return ; |
2966 | 2959 | }, |
2967 | | - |
| 2960 | + |
2968 | 2961 | /** |
2969 | 2962 | * Checks the player state based on thumbnail display & paused state |
2970 | | - * @return {Boolean} |
| 2963 | + * @return {Boolean} |
2971 | 2964 | * true if playing |
2972 | 2965 | * false if not playing |
2973 | 2966 | */ |
— | — | @@ -2981,34 +2974,34 @@ |
2982 | 2975 | return true; |
2983 | 2976 | } |
2984 | 2977 | }, |
2985 | | - |
| 2978 | + |
2986 | 2979 | /** |
2987 | 2980 | * Get paused state |
2988 | | - * @return {Boolean} |
| 2981 | + * @return {Boolean} |
2989 | 2982 | * true if playing |
2990 | 2983 | * false if not playing |
2991 | 2984 | */ |
2992 | 2985 | isPaused: function() { |
2993 | 2986 | return this.paused; |
2994 | 2987 | }, |
2995 | | - |
| 2988 | + |
2996 | 2989 | /** |
2997 | 2990 | * Get Stopped state |
2998 | | - * @return {Boolean} |
| 2991 | + * @return {Boolean} |
2999 | 2992 | * true if stopped |
3000 | 2993 | * false if playing |
3001 | 2994 | */ |
3002 | 2995 | isStopped: function() { |
3003 | 2996 | return this.thumbnail_disp; |
3004 | | - }, |
3005 | | - |
| 2997 | + }, |
| 2998 | + |
3006 | 2999 | // xxx temporary hack we need a better stop monitor system |
3007 | 3000 | stopMonitor: function(){ |
3008 | 3001 | this.thumbnail_disp = true; |
3009 | 3002 | }, |
3010 | | - |
| 3003 | + |
3011 | 3004 | /** |
3012 | | - * Checks if the currentTime was updated outside of |
| 3005 | + * Checks if the currentTime was updated outside of |
3013 | 3006 | * the getPlayerElementTime function |
3014 | 3007 | */ |
3015 | 3008 | checkForCurrentTimeSeek: function(){ |
— | — | @@ -3017,67 +3010,67 @@ |
3018 | 3011 | if( _this.previousTime != _this.currentTime && !this.userSlide && !this.seeking){ |
3019 | 3012 | // If the time has been updated and is in range issue a seek |
3020 | 3013 | if( _this.getDuration() && _this.currentTime <= _this.getDuration() ){ |
3021 | | - var seekPercent = _this.currentTime / _this.getDuration(); |
| 3014 | + var seekPercent = _this.currentTime / _this.getDuration(); |
3022 | 3015 | mw.log("monitor::" + _this.previousTime + ' != ' + |
3023 | 3016 | _this.currentTime + " javascript based currentTime update to " + seekPercent); |
3024 | | - this.doSeek( seekPercent ); |
| 3017 | + this.doSeek( seekPercent ); |
3025 | 3018 | } |
3026 | | - } |
| 3019 | + } |
3027 | 3020 | }, |
3028 | | - |
| 3021 | + |
3029 | 3022 | /** |
3030 | 3023 | * Monitor playback and update interface components. |
3031 | 3024 | * underling plugin objects are responsible for updating currentTime |
3032 | 3025 | */ |
3033 | 3026 | monitor: function() { |
3034 | 3027 | var _this = this; |
3035 | | - |
3036 | | - // Check for current time update outside of embed player |
3037 | | - this.checkForCurrentTimeSeek(); |
3038 | | - |
| 3028 | + |
| 3029 | + // Check for current time update outside of embed player |
| 3030 | + this.checkForCurrentTimeSeek(); |
| 3031 | + |
3039 | 3032 | // Update currentTime via embedPlayer |
3040 | | - _this.currentTime = _this.getPlayerElementTime(); |
3041 | | - |
| 3033 | + _this.currentTime = _this.getPlayerElementTime(); |
| 3034 | + |
3042 | 3035 | // Update any offsets from server seek |
3043 | 3036 | if( _this.serverSeekTime && _this.supportsURLTimeEncoding ){ |
3044 | | - _this.currentTime = _this.serverSeekTime + _this.getPlayerElementTime() |
| 3037 | + _this.currentTime = _this.serverSeekTime + _this.getPlayerElementTime(); |
3045 | 3038 | } |
3046 | 3039 | |
3047 | 3040 | // Update the previousTime ( so we can know if the user-javascript changed currentTime ) |
3048 | 3041 | _this.previousTime = _this.currentTime; |
3049 | | - |
3050 | | - |
| 3042 | + |
| 3043 | + |
3051 | 3044 | // Check if volume was set outside of embed player function |
3052 | | - //mw.log( ' this.volume: ' + _this.volume + ' prev Volume:: ' + _this.previousVolume ); |
3053 | | - if( Math.round( _this.volume * 100 ) != Math.round( _this.previousVolume * 100 ) ) { |
| 3045 | + //mw.log( ' this.volume: ' + _this.volume + ' prev Volume:: ' + _this.previousVolume ); |
| 3046 | + if( Math.round( _this.volume * 100 ) != Math.round( _this.previousVolume * 100 ) ) { |
3054 | 3047 | _this.setInterfaceVolume( _this.volume ); |
3055 | 3048 | $j( this ).trigger('volumeChanged', _this.volume ); |
3056 | 3049 | } |
3057 | | - |
3058 | | - // Update the previous volume |
3059 | | - _this.previousVolume = _this.volume; |
3060 | | - |
| 3050 | + |
| 3051 | + // Update the previous volume |
| 3052 | + _this.previousVolume = _this.volume; |
| 3053 | + |
3061 | 3054 | // Update the volume from the player element |
3062 | 3055 | _this.volume = this.getPlayerElementVolume(); |
3063 | | - |
| 3056 | + |
3064 | 3057 | // update the mute state from the player element |
3065 | 3058 | if( _this.muted != _this.getPlayerElementMuted() && ! _this.isStopped() ){ |
3066 | 3059 | mw.log( "EmbedPlayer::monitor: muted does not mach embed player" ); |
3067 | 3060 | _this.toggleMute(); |
3068 | | - // Make sure they match: |
3069 | | - _this.muted = _this.getPlayerElementMuted(); |
| 3061 | + // Make sure they match: |
| 3062 | + _this.muted = _this.getPlayerElementMuted(); |
3070 | 3063 | } |
3071 | | - |
3072 | | - //mw.log( 'Monitor:: ' + this.currentTime + ' duration: ' + ( parseInt( this.getDuration() ) + 1 ) + ' is seeking: ' + this.seeking ); |
3073 | | - if ( this.currentTime >= 0 && this.duration ) { |
| 3064 | + |
| 3065 | + //mw.log( 'Monitor:: ' + this.currentTime + ' duration: ' + ( parseInt( this.getDuration() ) + 1 ) + ' is seeking: ' + this.seeking ); |
| 3066 | + if ( this.currentTime >= 0 && this.duration ) { |
3074 | 3067 | if ( !this.userSlide && !this.seeking ) { |
3075 | | - if ( parseInt( this.startOffset ) != 0 ) { |
3076 | | - // If start offset include that calculation |
| 3068 | + if ( parseInt( this.startOffset ) != 0 ) { |
| 3069 | + // If start offset include that calculation |
3077 | 3070 | this.updatePlayHead( ( this.currentTime - this.startOffset ) / this.duration ); |
3078 | 3071 | var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( parseFloat( this.startOffset ) + parseFloat( this.duration ) ) : ''; |
3079 | 3072 | this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et ); |
3080 | | - } else { |
3081 | | - this.updatePlayHead( this.currentTime / this.duration ); |
| 3073 | + } else { |
| 3074 | + this.updatePlayHead( this.currentTime / this.duration ); |
3082 | 3075 | // Only include the end time if longTimeDisp is enabled: |
3083 | 3076 | var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( this.duration ) : ''; |
3084 | 3077 | this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et ); |
— | — | @@ -3086,11 +3079,11 @@ |
3087 | 3080 | // Check if we are "done" |
3088 | 3081 | var endPresentationTime = ( this.startOffset ) ? ( this.startOffset + this.duration ) : this.duration; |
3089 | 3082 | if ( this.currentTime >= endPresentationTime ) { |
3090 | | - mw.log( "should run clip done :: " + this.currentTime + ' > ' + endPresentationTime ); |
| 3083 | + mw.log( "should run clip done :: " + this.currentTime + ' > ' + endPresentationTime ); |
3091 | 3084 | this.onClipDone(); |
3092 | 3085 | } |
3093 | 3086 | } else { |
3094 | | - // Media lacks duration just show end time |
| 3087 | + // Media lacks duration just show end time |
3095 | 3088 | if ( this.isStopped() ) { |
3096 | 3089 | this.controlBuilder.setStatus( this.getTimeRange() ); |
3097 | 3090 | } else if ( this.isPaused() ) { |
— | — | @@ -3104,107 +3097,107 @@ |
3105 | 3098 | this.controlBuilder.setStatus( this.getTimeRange() ); |
3106 | 3099 | } |
3107 | 3100 | } |
3108 | | - |
3109 | | - // Update buffer information |
| 3101 | + |
| 3102 | + // Update buffer information |
3110 | 3103 | this.updateBufferStatus(); |
3111 | | - |
| 3104 | + |
3112 | 3105 | // run the "native" progress event on the virtual html5 object if set |
3113 | 3106 | if( this.progressEventData ) { |
3114 | 3107 | //mw.log("trigger:progress event on html5 proxy"); |
3115 | 3108 | $j( this ).trigger( 'progress', this.progressEventData ); |
3116 | 3109 | } |
3117 | | - |
3118 | | - // Call monitor at 250ms interval. ( use setInterval to avoid stacking monitor requests ) |
| 3110 | + |
| 3111 | + // Call monitor at 250ms interval. ( use setInterval to avoid stacking monitor requests ) |
3119 | 3112 | if( ! this.isStopped() ) { |
3120 | 3113 | if( !this.monitorInterval ){ |
3121 | 3114 | this.monitorInterval = setInterval( function(){ |
3122 | 3115 | if( _this.monitor ) |
3123 | 3116 | _this.monitor(); |
3124 | | - }, this.monitorRate ) |
| 3117 | + }, this.monitorRate ); |
3125 | 3118 | } |
3126 | 3119 | } else { |
3127 | | - // If stopped "stop" monitor: |
| 3120 | + // If stopped "stop" monitor: |
3128 | 3121 | clearInterval( this.monitorInterval ); |
3129 | 3122 | this.monitorInterval = 0; |
3130 | 3123 | } |
3131 | | - |
3132 | | - //mw.log('trigger:monitor:: ' + this.currentTime ); |
| 3124 | + |
| 3125 | + //mw.log('trigger:monitor:: ' + this.currentTime ); |
3133 | 3126 | $j( this ).trigger( 'monitorEvent' ); |
3134 | | - }, |
3135 | | - |
| 3127 | + }, |
| 3128 | + |
3136 | 3129 | /** |
3137 | | - * Abstract getPlayerElementTime function |
| 3130 | + * Abstract getPlayerElementTime function |
3138 | 3131 | */ |
3139 | 3132 | getPlayerElementTime: function(){ |
3140 | 3133 | mw.log("Error: getPlayerElementTime should be implemented by embed library"); |
3141 | 3134 | }, |
3142 | | - |
| 3135 | + |
3143 | 3136 | /** |
3144 | 3137 | * Update the Buffer status based on the local bufferedPercent var |
3145 | 3138 | */ |
3146 | 3139 | updateBufferStatus: function() { |
3147 | | - |
3148 | | - // Get the buffer target based for playlist vs clip |
3149 | | - $buffer = this.$interface.find( '.mw_buffer' ); |
| 3140 | + |
| 3141 | + // Get the buffer target based for playlist vs clip |
| 3142 | + $buffer = this.$interface.find( '.mw_buffer' ); |
3150 | 3143 | // Update the buffer progress bar (if available ) |
3151 | 3144 | if ( this.bufferedPercent != 0 ) { |
3152 | | - //mw.log('Update buffer css: ' + ( this.bufferedPercent * 100 ) + '% ' + $buffer.length ); |
| 3145 | + //mw.log('Update buffer css: ' + ( this.bufferedPercent * 100 ) + '% ' + $buffer.length ); |
3153 | 3146 | if ( this.bufferedPercent > 1 ){ |
3154 | 3147 | this.bufferedPercent = 1; |
3155 | 3148 | } |
3156 | | - |
| 3149 | + |
3157 | 3150 | $buffer.css({ |
3158 | 3151 | "width" : ( this.bufferedPercent * 100 ) + '%' |
3159 | 3152 | }); |
3160 | | - $j( this ).trigger( 'updateBufferPercent', this.bufferedPercent ); |
| 3153 | + $j( this ).trigger( 'updateBufferPercent', this.bufferedPercent ); |
3161 | 3154 | } else { |
3162 | 3155 | $buffer.css( "width", '0px' ); |
3163 | 3156 | } |
3164 | | - |
| 3157 | + |
3165 | 3158 | // if we have not already run the buffer start hook |
3166 | | - if( this.bufferedPercent > 0 && !this.bufferStartFlag ) { |
| 3159 | + if( this.bufferedPercent > 0 && !this.bufferStartFlag ) { |
3167 | 3160 | this.bufferStartFlag = true; |
3168 | 3161 | mw.log("bufferStart"); |
3169 | 3162 | $j( this ).trigger( 'bufferStartEvent' ); |
3170 | | - } |
3171 | | - |
| 3163 | + } |
| 3164 | + |
3172 | 3165 | // if we have not already run the buffer end hook |
3173 | 3166 | if( this.bufferedPercent == 1 && !this.bufferEndFlag){ |
3174 | | - this.bufferEndFlag = true; |
| 3167 | + this.bufferEndFlag = true; |
3175 | 3168 | $j( this ).trigger( 'bufferEndEvent' ); |
3176 | 3169 | } |
3177 | 3170 | }, |
3178 | | - |
| 3171 | + |
3179 | 3172 | /** |
3180 | 3173 | * Update the player playhead |
3181 | 3174 | * |
3182 | 3175 | * @param {Float} perc Value between 0 and 1 for position of playhead |
3183 | 3176 | */ |
3184 | | - updatePlayHead: function( perc ) { |
| 3177 | + updatePlayHead: function( perc ) { |
3185 | 3178 | $playHead = this.$interface.find( '.play_head' ); |
3186 | | - if ( this.controls && $playHead.length != 0 ) { |
| 3179 | + if ( this.controls && $playHead.length != 0 ) { |
3187 | 3180 | var val = parseInt( perc * 1000 ); |
3188 | 3181 | $playHead.slider( 'value', val ); |
3189 | 3182 | } |
3190 | 3183 | // @@todo should have 'progress' trigger the same as html5 |
3191 | 3184 | $j( this ).trigger('updatePlayHeadPercent', perc); |
3192 | 3185 | }, |
3193 | | - |
| 3186 | + |
3194 | 3187 | /** |
3195 | | - * Highlight a section of video on the playhead |
| 3188 | + * Highlight a section of video on the playhead |
3196 | 3189 | * |
3197 | 3190 | * @param {Object} options Provides "start" time & "end" time to highlight |
3198 | | - */ |
| 3191 | + */ |
3199 | 3192 | highlightPlaySection:function( options ) { |
3200 | 3193 | mw.log( 'highlightPlaySection' ); |
3201 | 3194 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
3202 | 3195 | var dur = this.getDuration(); |
3203 | | - // set the left percet and update the slider: |
| 3196 | + // set the left percet and update the slider: |
3204 | 3197 | rel_start_sec = mw.npt2seconds( options['start'] ); |
3205 | | - // remove the startOffset if relevent: |
| 3198 | + // remove the startOffset if relevent: |
3206 | 3199 | if ( this.startOffset ) |
3207 | | - rel_start_sec = rel_start_sec - this.startOffset |
3208 | | - |
| 3200 | + rel_start_sec = rel_start_sec - this.startOffset; |
| 3201 | + |
3209 | 3202 | var slider_perc = 0; |
3210 | 3203 | if ( rel_start_sec <= 0 ) { |
3211 | 3204 | left_perc = 0; |
— | — | @@ -3215,48 +3208,48 @@ |
3216 | 3209 | left_perc = parseInt( ( rel_start_sec / dur ) * 100 ) ; |
3217 | 3210 | slider_perc = ( left_perc / 100 ); |
3218 | 3211 | } |
3219 | | - |
| 3212 | + |
3220 | 3213 | mw.log( "slider perc:" + slider_perc ); |
3221 | 3214 | if ( ! this.isPlaying() ) { |
3222 | 3215 | this.updatePlayHead( slider_perc ); |
3223 | 3216 | } |
3224 | | - |
| 3217 | + |
3225 | 3218 | width_perc = parseInt( ( ( mw.npt2seconds( options['end'] ) - mw.npt2seconds( options['start'] ) ) / dur ) * 100 ) ; |
3226 | 3219 | if ( ( width_perc + left_perc ) > 100 ) { |
3227 | 3220 | width_perc = 100 - left_perc; |
3228 | 3221 | } |
3229 | | - // mw.log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc); |
| 3222 | + // mw.log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc); |
3230 | 3223 | $j( '#mv_seeker_' + eid + ' .mv_highlight' ).css( { |
3231 | 3224 | 'left' : left_perc + '%', |
3232 | 3225 | 'width' : width_perc + '%' |
3233 | 3226 | } ).show(); |
3234 | | - |
3235 | | - this.jump_time = options['start']; |
| 3227 | + |
| 3228 | + this.jump_time = options['start']; |
3236 | 3229 | this.serverSeekTime = mw.npt2seconds( options['start'] ); |
3237 | | - // trim output to |
| 3230 | + // trim output to |
3238 | 3231 | this.controlBuilder.setStatus( gM( 'mwe-embedplayer-seek_to', mw.seconds2npt( this.serverSeekTime ) ) ); |
3239 | | - mw.log( 'DO update: ' + this.jump_time ); |
| 3232 | + mw.log( 'DO update: ' + this.jump_time ); |
3240 | 3233 | this.updateThumbTime( rel_start_sec ); |
3241 | 3234 | }, |
3242 | | - |
| 3235 | + |
3243 | 3236 | /** |
3244 | 3237 | * Hides the playhead highlight |
3245 | | - */ |
| 3238 | + */ |
3246 | 3239 | hideHighlight: function() { |
3247 | 3240 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
3248 | 3241 | $j( '#mv_seeker_' + eid + ' .mv_highlight' ).hide(); |
3249 | | - this.controlBuilder.setStatus( this.getTimeRange() ); |
3250 | | - }, |
3251 | | - |
3252 | | - |
| 3242 | + this.controlBuilder.setStatus( this.getTimeRange() ); |
| 3243 | + }, |
| 3244 | + |
| 3245 | + |
3253 | 3246 | /** |
3254 | | - * Helper Functions for selected source |
| 3247 | + * Helper Functions for selected source |
3255 | 3248 | */ |
3256 | | - |
| 3249 | + |
3257 | 3250 | /** |
3258 | 3251 | * Get the current selected media source |
3259 | 3252 | * |
3260 | | - * @return src url |
| 3253 | + * @return src url |
3261 | 3254 | */ |
3262 | 3255 | getSrc: function() { |
3263 | 3256 | if( this.mediaElement.selectedSource ){ |
— | — | @@ -3264,7 +3257,7 @@ |
3265 | 3258 | } |
3266 | 3259 | return false; |
3267 | 3260 | }, |
3268 | | - |
| 3261 | + |
3269 | 3262 | /** |
3270 | 3263 | * If the selected src supports URL time encoding |
3271 | 3264 | * |
— | — | @@ -3276,7 +3269,7 @@ |
3277 | 3270 | // do head request if on the same domain |
3278 | 3271 | return this.mediaElement.selectedSource.URLTimeEncoding; |
3279 | 3272 | } |
3280 | | -} |
| 3273 | +}; |
3281 | 3274 | |
3282 | 3275 | |
3283 | 3276 | |
— | — | @@ -3285,7 +3278,7 @@ |
3286 | 3279 | * |
3287 | 3280 | * @param {String} id id used for the plugin. |
3288 | 3281 | * @param {Array} supported_types an array of supported MIME types. |
3289 | | - * @param {String} library external script containing the plugin interface code. |
| 3282 | + * @param {String} library external script containing the plugin interface code. |
3290 | 3283 | * @constructor |
3291 | 3284 | */ |
3292 | 3285 | function mediaPlayer( id, supported_types, library ) |
— | — | @@ -3300,16 +3293,16 @@ |
3301 | 3294 | mediaPlayer.prototype = { |
3302 | 3295 | // Id of the mediaPlayer |
3303 | 3296 | id:null, |
3304 | | - |
| 3297 | + |
3305 | 3298 | // Mime types supported by this player |
3306 | 3299 | supported_types:null, |
3307 | | - |
3308 | | - // Player library ie: native, vlc, java etc. |
| 3300 | + |
| 3301 | + // Player library ie: native, vlc, java etc. |
3309 | 3302 | library:null, |
3310 | | - |
| 3303 | + |
3311 | 3304 | // Flag stores the mediaPlayer load state |
3312 | 3305 | loaded:false, |
3313 | | - |
| 3306 | + |
3314 | 3307 | /** |
3315 | 3308 | * Checks support for a given MIME type |
3316 | 3309 | * |
— | — | @@ -3317,7 +3310,7 @@ |
3318 | 3311 | * @return {Boolean} |
3319 | 3312 | * true if mime type is supported |
3320 | 3313 | * false if mime type is unsupported |
3321 | | - */ |
| 3314 | + */ |
3322 | 3315 | supportsMIMEType: function( type ) { |
3323 | 3316 | for ( var i = 0; i < this.supported_types.length; i++ ) { |
3324 | 3317 | if ( this.supported_types[i] == type ) |
— | — | @@ -3325,20 +3318,20 @@ |
3326 | 3319 | } |
3327 | 3320 | return false; |
3328 | 3321 | }, |
3329 | | - |
| 3322 | + |
3330 | 3323 | /** |
3331 | 3324 | * Get the "name" of the player from a predictable msg key |
3332 | 3325 | */ |
3333 | 3326 | getName: function() { |
3334 | 3327 | return gM( 'mwe-embedplayer-ogg-player-' + this.id ); |
3335 | 3328 | }, |
3336 | | - |
| 3329 | + |
3337 | 3330 | /** |
3338 | 3331 | * Loads the player library & player skin config ( if needed ) and then calls the callback. |
3339 | 3332 | * |
3340 | 3333 | * @param {Function} callback Function to be called once player library is loaded. |
3341 | | - */ |
3342 | | - load: function( callback ) { |
| 3334 | + */ |
| 3335 | + load: function( callback ) { |
3343 | 3336 | //Load player library ( upper case the first letter of the library ) |
3344 | 3337 | mw.load( [ |
3345 | 3338 | 'mw.EmbedPlayer' + this.library.substr(0,1).toUpperCase() + this.library.substr(1) |
— | — | @@ -3346,18 +3339,18 @@ |
3347 | 3340 | callback(); |
3348 | 3341 | } ); |
3349 | 3342 | } |
3350 | | -} |
| 3343 | +}; |
3351 | 3344 | |
3352 | | -/** |
3353 | | -* players and supported mime types |
3354 | | -* In an ideal world we would query the plugin to get what mime |
| 3345 | +/** |
| 3346 | +* players and supported mime types |
| 3347 | +* In an ideal world we would query the plugin to get what mime |
3355 | 3348 | * types it supports in practice not always reliable/available |
3356 | | -* |
| 3349 | +* |
3357 | 3350 | * We can't cleanly store these values per library since player library is loaded post player detection |
3358 | | -* |
| 3351 | +* |
3359 | 3352 | */ |
3360 | 3353 | |
3361 | | -//Flash based players: |
| 3354 | +//Flash based players: |
3362 | 3355 | |
3363 | 3356 | var kplayer = new mediaPlayer('kplayer', ['video/x-flv', 'video/h264'], 'Kplayer'); |
3364 | 3357 | |
— | — | @@ -3370,13 +3363,13 @@ |
3371 | 3364 | var webmNativePlayer = new mediaPlayer( 'webmNative', ['video/webm'], 'Native' ); |
3372 | 3365 | |
3373 | 3366 | // VLC player |
3374 | | -var vlcMineList = ['video/ogg', 'audio/ogg', 'application/ogg', 'video/x-flv', 'video/mp4', 'video/h264', 'video/x-msvideo', 'video/mpeg']; |
| 3367 | +var vlcMineList = ['video/ogg', 'audio/ogg', 'application/ogg', 'video/x-flv', 'video/mp4', 'video/h264', 'video/x-msvideo', 'video/mpeg']; |
3375 | 3368 | var vlcPlayer = new mediaPlayer( 'vlc-player', vlcMineList, 'Vlc' ); |
3376 | 3369 | |
3377 | 3370 | // Generic plugin |
3378 | 3371 | var oggPluginPlayer = new mediaPlayer( 'oggPlugin', ['video/ogg', 'application/ogg'], 'Generic' ); |
3379 | 3372 | |
3380 | | -// HTML player for timed display of html content |
| 3373 | +// HTML player for timed display of html content |
3381 | 3374 | var htmlPlayer = new mediaPlayer( 'html', ['text/html', 'image/jpeg', 'image/png', 'image/svg'], 'Html' ); |
3382 | 3375 | |
3383 | 3376 | |
— | — | @@ -3393,13 +3386,13 @@ |
3394 | 3387 | { |
3395 | 3388 | // The list of players supported |
3396 | 3389 | players : null, |
3397 | | - |
| 3390 | + |
3398 | 3391 | // Store per mime-type prefrences for players |
3399 | 3392 | preference : { }, |
3400 | | - |
| 3393 | + |
3401 | 3394 | // Stores the default set of players for a given mime type |
3402 | | - defaultPlayers : { }, |
3403 | | - |
| 3395 | + defaultPlayers : { }, |
| 3396 | + |
3404 | 3397 | /** |
3405 | 3398 | * Initializartion function sets the default order for players for |
3406 | 3399 | * a given mime type |
— | — | @@ -3407,29 +3400,29 @@ |
3408 | 3401 | init: function() { |
3409 | 3402 | this.players = new Array(); |
3410 | 3403 | this.loadPreferences(); |
3411 | | - |
3412 | | - // set up default players order for each library type |
| 3404 | + |
| 3405 | + // set up default players order for each library type |
3413 | 3406 | this.defaultPlayers['video/x-flv'] = ['Kplayer', 'Vlc']; |
3414 | 3407 | this.defaultPlayers['video/h264'] = ['Native', 'Kplayer', 'Vlc']; |
3415 | | - |
| 3408 | + |
3416 | 3409 | this.defaultPlayers['video/ogg'] = ['Native', 'Vlc', 'Java', 'Generic']; |
3417 | 3410 | this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 'Java', 'Generic']; |
3418 | 3411 | this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'Java' ]; |
3419 | 3412 | this.defaultPlayers['video/mp4'] = ['Vlc']; |
3420 | 3413 | this.defaultPlayers['video/mpeg'] = ['Vlc']; |
3421 | 3414 | this.defaultPlayers['video/x-msvideo'] = ['Vlc']; |
3422 | | - |
| 3415 | + |
3423 | 3416 | this.defaultPlayers['text/html'] = ['Html']; |
3424 | 3417 | this.defaultPlayers['image/jpeg'] = ['Html']; |
3425 | 3418 | this.defaultPlayers['image/png'] = ['Html']; |
3426 | | - this.defaultPlayers['image/svg'] = ['Html']; |
3427 | | - |
| 3419 | + this.defaultPlayers['image/svg'] = ['Html']; |
| 3420 | + |
3428 | 3421 | }, |
3429 | | - |
| 3422 | + |
3430 | 3423 | /** |
3431 | 3424 | * Adds a Player to the player list |
3432 | 3425 | * |
3433 | | - * @param {Object} player Player object to be added |
| 3426 | + * @param {Object} player Player object to be added |
3434 | 3427 | */ |
3435 | 3428 | addPlayer: function( player ) { |
3436 | 3429 | for ( var i = 0; i < this.players.length; i++ ) { |
— | — | @@ -3438,12 +3431,12 @@ |
3439 | 3432 | return ; |
3440 | 3433 | } |
3441 | 3434 | } |
3442 | | - |
3443 | | - |
| 3435 | + |
| 3436 | + |
3444 | 3437 | // Add the player: |
3445 | 3438 | this.players.push( player ); |
3446 | 3439 | }, |
3447 | | - |
| 3440 | + |
3448 | 3441 | /** |
3449 | 3442 | * Checks if a player is supported by id |
3450 | 3443 | */ |
— | — | @@ -3455,17 +3448,17 @@ |
3456 | 3449 | } |
3457 | 3450 | return false; |
3458 | 3451 | }, |
3459 | | - |
| 3452 | + |
3460 | 3453 | /** |
3461 | 3454 | * get players that support a given mimeType |
3462 | 3455 | * |
3463 | 3456 | * @param {String} mimeType Mime type of player set |
3464 | | - * @return {Array} |
| 3457 | + * @return {Array} |
3465 | 3458 | * Array of players that support a the requested mime type |
3466 | 3459 | */ |
3467 | 3460 | getMIMETypePlayers: function( mimeType ) { |
3468 | 3461 | var mimePlayers = new Array(); |
3469 | | - var _this = this; |
| 3462 | + var _this = this; |
3470 | 3463 | if ( this.defaultPlayers[mimeType] ) { |
3471 | 3464 | $j.each( this.defaultPlayers[ mimeType ], function( d, lib ) { |
3472 | 3465 | var library = _this.defaultPlayers[ mimeType ][ d ]; |
— | — | @@ -3478,16 +3471,16 @@ |
3479 | 3472 | } |
3480 | 3473 | return mimePlayers; |
3481 | 3474 | }, |
3482 | | - |
| 3475 | + |
3483 | 3476 | /** |
3484 | 3477 | * Default player for a given mime type |
3485 | 3478 | * |
3486 | 3479 | * @param {String} mimeType Mime type of the requested player |
3487 | | - * @return |
| 3480 | + * @return |
3488 | 3481 | * Player for mime type |
3489 | 3482 | * null if no player found |
3490 | 3483 | */ |
3491 | | - defaultPlayer : function( mimeType ) { |
| 3484 | + defaultPlayer : function( mimeType ) { |
3492 | 3485 | //mw.log( "get defaultPlayer for " + mimeType ); |
3493 | 3486 | var mimePlayers = this.getMIMETypePlayers( mimeType ); |
3494 | 3487 | if ( mimePlayers.length > 0 ) |
— | — | @@ -3504,59 +3497,59 @@ |
3505 | 3498 | //mw.log( 'No default player found for ' + mimeType ); |
3506 | 3499 | return null; |
3507 | 3500 | }, |
3508 | | - |
| 3501 | + |
3509 | 3502 | /** |
3510 | 3503 | * Sets the format preference. |
3511 | 3504 | * |
3512 | | - * @param {String} mimeFormat Prefered format |
| 3505 | + * @param {String} mimeFormat Prefered format |
3513 | 3506 | */ |
3514 | 3507 | setFormatPreference : function ( mimeFormat ) { |
3515 | 3508 | this.preference['format_preference'] = mimeFormat; |
3516 | | - mw.setUserConfig( 'playerPref', this.preference); |
| 3509 | + mw.setUserConfig( 'playerPref', this.preference); |
3517 | 3510 | }, |
3518 | | - |
| 3511 | + |
3519 | 3512 | /** |
3520 | 3513 | * Sets the player preference |
3521 | 3514 | * |
3522 | 3515 | * @param {String} playerId Prefered player id |
3523 | 3516 | * @param {String} mimeType Mime type for the associated player stream |
3524 | 3517 | */ |
3525 | | - setPlayerPreference : function( playerId, mimeType ) { |
3526 | | - var selectedPlayer = null; |
| 3518 | + setPlayerPreference : function( playerId, mimeType ) { |
| 3519 | + var selectedPlayer = null; |
3527 | 3520 | for ( var i = 0; i < this.players.length; i++ ) { |
3528 | 3521 | if ( this.players[i].id == playerId ) { |
3529 | 3522 | selectedPlayer = this.players[i]; |
3530 | 3523 | mw.log( 'EmbedPlayer::setPlayerPreference: choosing ' + playerId + ' for ' + mimeType ); |
3531 | | - this.preference[ mimeType ] = playerId; |
| 3524 | + this.preference[ mimeType ] = playerId; |
3532 | 3525 | mw.setUserConfig( 'playerPref', this.preference ); |
3533 | 3526 | break; |
3534 | 3527 | } |
3535 | 3528 | } |
3536 | | - // Update All the player instances: |
| 3529 | + // Update All the player instances: |
3537 | 3530 | if ( selectedPlayer ) { |
3538 | | - var playerList = mw.playerManager.getPlayerList(); |
| 3531 | + var playerList = mw.playerManager.getPlayerList(); |
3539 | 3532 | for ( var i = 0; i < playerList.length; i++ ) { |
3540 | 3533 | var embed = $j( '#' + playerList[i] ).get( 0 ); |
3541 | 3534 | if ( embed.mediaElement.selectedSource && ( embed.mediaElement.selectedSource.mimeType == mimeType ) ) |
3542 | 3535 | { |
3543 | 3536 | embed.selectPlayer( selectedPlayer ); |
3544 | | - mw.log( 'EmbedPlayer::setPlayerPreference: using ' + embed.selectedPlayer.getName() + ' for ' + embed.mediaElement.selectedSource.getTitle() ); |
| 3537 | + mw.log( 'EmbedPlayer::setPlayerPreference: using ' + embed.selectedPlayer.getName() + ' for ' + embed.mediaElement.selectedSource.getTitle() ); |
3545 | 3538 | } |
3546 | 3539 | } |
3547 | 3540 | } |
3548 | 3541 | }, |
3549 | | - |
| 3542 | + |
3550 | 3543 | /** |
3551 | 3544 | * Loads the user preference settings from a cookie |
3552 | | - */ |
3553 | | - loadPreferences : function ( ) { |
| 3545 | + */ |
| 3546 | + loadPreferences : function ( ) { |
3554 | 3547 | this.preference = { }; |
3555 | 3548 | // see if we have a cookie set to a clientSupported type: |
3556 | 3549 | preferenceConfig = mw.getUserConfig( 'playerPref' ); |
3557 | 3550 | if( typeof preferenceConfig == 'object' ) { |
3558 | 3551 | this.preference = preferenceConfig; |
3559 | 3552 | } |
3560 | | - } |
| 3553 | + } |
3561 | 3554 | }; |
3562 | 3555 | |
3563 | 3556 | /** |
— | — | @@ -3568,62 +3561,62 @@ |
3569 | 3562 | |
3570 | 3563 | // List of players supported |
3571 | 3564 | players: null, |
3572 | | - |
3573 | | - // Detect flag for completion |
| 3565 | + |
| 3566 | + // Detect flag for completion |
3574 | 3567 | detect_done:false, |
3575 | | - |
| 3568 | + |
3576 | 3569 | /** |
3577 | 3570 | * Runs the detect method and update the detect_done flag |
3578 | | - * @constructor |
| 3571 | + * @constructor |
3579 | 3572 | */ |
3580 | 3573 | init: function() { |
3581 | | - // detect supported types |
| 3574 | + // detect supported types |
3582 | 3575 | this.detect(); |
3583 | 3576 | this.detect_done = true; |
3584 | 3577 | }, |
3585 | | - |
| 3578 | + |
3586 | 3579 | /** |
3587 | 3580 | * If the browsers supports a given mimetype |
3588 | | - * |
| 3581 | + * |
3589 | 3582 | * @param {String} mimeType Mime type for browser plug-in check |
3590 | 3583 | */ |
3591 | 3584 | supportedMimeType: function( mimeType ) { |
3592 | 3585 | for ( var i =0; i < navigator.plugins.length; i++ ) { |
3593 | 3586 | var plugin = navigator.plugins[i]; |
3594 | 3587 | if ( typeof plugin[ mimeType ] != "undefined" ) |
3595 | | - return true; |
| 3588 | + return true; |
3596 | 3589 | } |
3597 | 3590 | return false; |
3598 | 3591 | }, |
3599 | | - |
| 3592 | + |
3600 | 3593 | /** |
3601 | | - * Detects what plug-ins the client supports |
| 3594 | + * Detects what plug-ins the client supports |
3602 | 3595 | */ |
3603 | | - detect: function() { |
3604 | | - mw.log( "embedPlayer: running detect" ); |
3605 | | - this.players = new mediaPlayers(); |
| 3596 | + detect: function() { |
| 3597 | + mw.log( "embedPlayer: running detect" ); |
| 3598 | + this.players = new mediaPlayers(); |
3606 | 3599 | // every browser supports html rendering: |
3607 | 3600 | this.players.addPlayer( htmlPlayer ); |
3608 | 3601 | // In Mozilla, navigator.javaEnabled() only tells us about preferences, we need to |
3609 | | - // search navigator.mimeTypes to see if it's installed |
| 3602 | + // search navigator.mimeTypes to see if it's installed |
3610 | 3603 | try{ |
3611 | 3604 | var javaEnabled = navigator.javaEnabled(); |
3612 | 3605 | } catch ( e ){ |
3613 | | - |
| 3606 | + |
3614 | 3607 | } |
3615 | 3608 | // Some browsers filter out duplicate mime types, hiding some plugins |
3616 | 3609 | var uniqueMimesOnly = $j.browser.opera || $j.browser.safari; |
3617 | | - |
| 3610 | + |
3618 | 3611 | // Opera will switch off javaEnabled in preferences if java can't be found. |
3619 | 3612 | // And it doesn't register an application/x-java-applet mime type like Mozilla does. |
3620 | 3613 | if ( javaEnabled && ( navigator.appName == 'Opera' ) ) { |
3621 | 3614 | this.players.addPlayer( cortadoPlayer ); |
3622 | 3615 | } |
3623 | | - |
| 3616 | + |
3624 | 3617 | // ActiveX plugins |
3625 | 3618 | if ( $j.browser.msie ) { |
3626 | | - // check for flash |
3627 | | - if ( this.testActiveX( 'ShockwaveFlash.ShockwaveFlash' ) ) { |
| 3619 | + // check for flash |
| 3620 | + if ( this.testActiveX( 'ShockwaveFlash.ShockwaveFlash' ) ) { |
3628 | 3621 | this.players.addPlayer( kplayer ); |
3629 | 3622 | //this.players.addPlayer( flowPlayer ); |
3630 | 3623 | } |
— | — | @@ -3631,52 +3624,52 @@ |
3632 | 3625 | if ( this.testActiveX( 'VideoLAN.VLCPlugin.2' ) ) { |
3633 | 3626 | this.players.addPlayer( vlcPlayer ); |
3634 | 3627 | } |
3635 | | - |
| 3628 | + |
3636 | 3629 | // Java ActiveX |
3637 | 3630 | if ( this.testActiveX( 'JavaWebStart.isInstalled' ) ) { |
3638 | 3631 | this.players.addPlayer( cortadoPlayer ); |
3639 | 3632 | } |
3640 | | - |
3641 | | - // quicktime (currently off) |
| 3633 | + |
| 3634 | + // quicktime (currently off) |
3642 | 3635 | // if ( this.testActiveX( 'QuickTimeCheckObject.QuickTimeCheck.1' ) ) |
3643 | | - // this.players.addPlayer(quicktimeActiveXPlayer); |
| 3636 | + // this.players.addPlayer(quicktimeActiveXPlayer); |
3644 | 3637 | } |
3645 | 3638 | // <video> element |
3646 | 3639 | if ( typeof HTMLVideoElement == 'object' // Firefox, Safari |
3647 | 3640 | || typeof HTMLVideoElement == 'function' ) // Opera |
3648 | | - { |
3649 | | - // Test what codecs the native player supports: |
| 3641 | + { |
| 3642 | + // Test what codecs the native player supports: |
3650 | 3643 | try { |
3651 | 3644 | var dummyvid = document.createElement( "video" ); |
3652 | 3645 | if( dummyvid.canPlayType ) { |
3653 | 3646 | // Add the webm player |
3654 | 3647 | if( dummyvid.canPlayType('video/webm; codecs="vp8, vorbis"') ){ |
3655 | | - this.players.addPlayer( webmNativePlayer ); |
| 3648 | + this.players.addPlayer( webmNativePlayer ); |
3656 | 3649 | } |
3657 | | - |
3658 | | - // Test for h264: |
3659 | | - if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) { |
| 3650 | + |
| 3651 | + // Test for h264: |
| 3652 | + if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) { |
3660 | 3653 | this.players.addPlayer( h264NativePlayer ); |
3661 | 3654 | } |
3662 | 3655 | // For now if Android assume we support h264Native (FIXME test on real devices ) |
3663 | 3656 | if ( mw.isAndroid2() ){ |
3664 | 3657 | this.players.addPlayer( h264NativePlayer ); |
3665 | 3658 | } |
3666 | | - |
| 3659 | + |
3667 | 3660 | // Test for ogg |
3668 | | - if ( dummyvid.canPlayType( 'video/ogg; codecs="theora,vorbis"' ) ) { |
3669 | | - this.players.addPlayer( oggNativePlayer ); |
| 3661 | + if ( dummyvid.canPlayType( 'video/ogg; codecs="theora,vorbis"' ) ) { |
| 3662 | + this.players.addPlayer( oggNativePlayer ); |
3670 | 3663 | // older versions of safari do not support canPlayType, |
3671 | | - // but xiph qt registers mimetype via quicktime plugin |
3672 | | - } else if ( this.supportedMimeType( 'video/ogg' ) ) { |
| 3664 | + // but xiph qt registers mimetype via quicktime plugin |
| 3665 | + } else if ( this.supportedMimeType( 'video/ogg' ) ) { |
3673 | 3666 | this.players.addPlayer( oggNativePlayer ); |
3674 | 3667 | } |
3675 | 3668 | } |
3676 | 3669 | } catch ( e ) { |
3677 | 3670 | mw.log( 'could not run canPlayType ' + e ); |
3678 | | - } |
3679 | | - } |
3680 | | - |
| 3671 | + } |
| 3672 | + } |
| 3673 | + |
3681 | 3674 | // "navigator" plugins |
3682 | 3675 | if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) { |
3683 | 3676 | for ( var i = 0; i < navigator.mimeTypes.length; i++ ) { |
— | — | @@ -3695,17 +3688,17 @@ |
3696 | 3689 | this.players.addPlayer( vlcPlayer ); |
3697 | 3690 | continue; |
3698 | 3691 | } |
3699 | | - |
| 3692 | + |
3700 | 3693 | if ( type == 'application/x-java-applet' ) { |
3701 | 3694 | this.players.addPlayer( cortadoPlayer ); |
3702 | 3695 | continue; |
3703 | 3696 | } |
3704 | | - |
| 3697 | + |
3705 | 3698 | if ( (type == 'video/mpeg' || type=='video/x-msvideo') && |
3706 | | - pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
3707 | | - this.players.addPlayer( vlcMozillaPlayer ); |
3708 | | - } |
3709 | | - |
| 3699 | + pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
| 3700 | + this.players.addPlayer( vlcMozillaPlayer ); |
| 3701 | + } |
| 3702 | + |
3710 | 3703 | if ( type == 'application/ogg' ) { |
3711 | 3704 | if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
3712 | 3705 | this.players.addPlayer( vlcMozillaPlayer ); |
— | — | @@ -3724,35 +3717,35 @@ |
3725 | 3718 | continue; |
3726 | 3719 | } |
3727 | 3720 | } |
3728 | | - |
| 3721 | + |
3729 | 3722 | if ( type == 'application/x-shockwave-flash' ) { |
3730 | | - |
| 3723 | + |
3731 | 3724 | this.players.addPlayer( kplayer ); |
3732 | 3725 | //this.players.addPlayer( flowPlayer ); |
3733 | | - |
| 3726 | + |
3734 | 3727 | // check version to add omtk: |
3735 | 3728 | if( navigator.plugins["Shockwave Flash"] ){ |
3736 | 3729 | var flashDescription = navigator.plugins["Shockwave Flash"].description; |
3737 | 3730 | var descArray = flashDescription.split( " " ); |
3738 | 3731 | var tempArrayMajor = descArray[2].split( "." ); |
3739 | 3732 | var versionMajor = tempArrayMajor[0]; |
3740 | | - // mw.log("version of flash: " + versionMajor); |
| 3733 | + // mw.log("version of flash: " + versionMajor); |
3741 | 3734 | } |
3742 | 3735 | continue; |
3743 | 3736 | } |
3744 | 3737 | } |
3745 | 3738 | } |
3746 | | - |
3747 | | - // Allow extensions to detect and add their own "players" |
| 3739 | + |
| 3740 | + // Allow extensions to detect and add their own "players" |
3748 | 3741 | mw.log("trigger::embedPlayerUpdateMediaPlayersEvent"); |
3749 | | - $j( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , this.players ); |
3750 | | - |
| 3742 | + $j( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , this.players ); |
| 3743 | + |
3751 | 3744 | }, |
3752 | | - |
| 3745 | + |
3753 | 3746 | /** |
3754 | 3747 | * Test IE for activeX by name |
3755 | 3748 | * |
3756 | | - * @param {String} name Name of ActiveXObject to look for |
| 3749 | + * @param {String} name Name of ActiveXObject to look for |
3757 | 3750 | */ |
3758 | 3751 | testActiveX : function ( name ) { |
3759 | 3752 | mw.log("EmbedPlayer::detect: test testActiveX: " + name); |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/kskin/mw.PlayerSkinKskin.js |
— | — | @@ -4,109 +4,116 @@ |
5 | 5 | |
6 | 6 | mw.PlayerSkinKskin = { |
7 | 7 | |
8 | | - // The parent class for all kskin css: |
| 8 | + // The parent class for all kskin css: |
9 | 9 | playerClass: 'k-player', |
10 | | - |
| 10 | + |
11 | 11 | // Display time string length |
12 | 12 | longTimeDisp: false, |
13 | | - |
| 13 | + |
14 | 14 | // Default control bar height |
15 | | - height: 20, |
16 | | - |
| 15 | + height: 20, |
| 16 | + |
17 | 17 | // Volume control layout is horizontal |
18 | 18 | volume_layout: 'horizontal', |
19 | | - |
| 19 | + |
20 | 20 | // Skin "kskin" is specific for wikimedia we have an |
21 | 21 | // api Title key so the "credits" menu item can be showed. |
22 | 22 | supportedMenuItems: { |
23 | 23 | 'credits': true |
24 | 24 | }, |
25 | | - |
| 25 | + |
26 | 26 | // Extends base components with kskin specific options: |
27 | 27 | components: { |
28 | 28 | 'playButtonLarge' : { |
29 | 29 | 'h' : 55 |
30 | | - }, |
| 30 | + }, |
31 | 31 | 'options': { |
32 | 32 | 'w':50, |
33 | | - 'o':function( ctrlObj ) { |
| 33 | + 'o':function( ctrlObj ) { |
34 | 34 | return $j( '<div />' ) |
35 | | - .attr( 'title', gM( 'mwe-embedplayer-player_options' ) ) |
| 35 | + .attr( 'title', gM( 'mwe-embedplayer-player_options' ) ) |
36 | 36 | .addClass( "ui-state-default ui-corner-bl rButton k-options" ) |
37 | | - .append( |
| 37 | + .append( |
38 | 38 | $j( '<span />' ) |
39 | | - .text( gM( 'mwe-embedplayer-menu_btn' ) ) |
40 | | - ) |
| 39 | + .text( gM( 'mwe-embedplayer-menu_btn' ) ) |
| 40 | + ); |
41 | 41 | } |
42 | 42 | }, |
43 | 43 | 'volumeControl': { |
44 | 44 | 'w':40 |
45 | | - }, |
46 | | - // No attributionButton component for kSkin ( its integrated into the credits screen ) |
| 45 | + }, |
| 46 | + // No attributionButton component for kSkin ( its integrated into the credits screen ) |
47 | 47 | 'attributionButton' : false, |
48 | | - |
49 | | - // Time display: |
| 48 | + |
| 49 | + // Time display: |
50 | 50 | 'timeDisplay': { |
51 | 51 | 'w':45 |
52 | | - }, |
53 | | - |
| 52 | + }, |
| 53 | + |
54 | 54 | 'optionsMenu': { |
55 | 55 | 'w' : 0, |
56 | 56 | 'o' : function( ctrlObj ) { |
57 | | - var embedPlayer = ctrlObj.embedPlayer; |
58 | | - |
59 | | - $menuOverlay = $j( '<div />') |
| 57 | + var embedPlayer = ctrlObj.embedPlayer; |
| 58 | + |
| 59 | + $menuOverlay = $j( '<div />') |
60 | 60 | .addClass( 'overlay-win k-menu ui-widget-content' ) |
61 | 61 | .css( { |
62 | 62 | 'width' : '100%', |
63 | | - 'position': 'absolute', |
| 63 | + 'position': 'absolute', |
64 | 64 | 'top' : '0px', |
65 | 65 | 'bottom' : ( ctrlObj.getHeight() + 2 ) + 'px' |
66 | 66 | } ); |
67 | | - |
68 | | - // Setup menu offset ( if player height < getOverlayHeight ) |
69 | | - // This displays the menu outside of the player on small embeds |
70 | | - if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) { |
| 67 | + |
| 68 | + // Note safari can't display video overlays with text: |
| 69 | + // see bug https://bugs.webkit.org/show_bug.cgi?id=48379 |
| 70 | + |
| 71 | + var userAgent = navigator.userAgent.toLowerCase(); |
| 72 | + if( userAgent.indexOf('safari') != -1 ){ |
| 73 | + $menuOverlay.css('opacity', '0.9'); |
| 74 | + } |
| 75 | + // Setup menu offset ( if player height < getOverlayHeight ) |
| 76 | + // This displays the menu outside of the player on small embeds |
| 77 | + if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) { |
71 | 78 | var topPos = ( ctrlObj.checkOverlayControls() ) |
72 | | - ? embedPlayer.getPlayerHeight() |
| 79 | + ? embedPlayer.getPlayerHeight() |
73 | 80 | : embedPlayer.getPlayerHeight() + ctrlObj.getHeight(); |
74 | | - |
75 | | - $menuOverlay.css( { |
| 81 | + |
| 82 | + $menuOverlay.css( { |
76 | 83 | 'top' : topPos + 'px', |
77 | 84 | 'bottom' : null, |
78 | 85 | 'width' : ctrlObj.getOverlayWidth(), |
79 | | - 'height' : ctrlObj.getOverlayHeight() + 'px' |
| 86 | + 'height' : ctrlObj.getOverlayHeight() + 'px' |
80 | 87 | }); |
81 | | - // Special common overflow hack for thumbnail display of player |
| 88 | + // Special common overflow hack for thumbnail display of player |
82 | 89 | $j( embedPlayer ).parents( '.thumbinner' ).css( 'overflow', 'visible' ); |
83 | 90 | } |
84 | | - |
| 91 | + |
85 | 92 | $menuBar = $j( '<ul />' ) |
86 | 93 | .addClass( 'k-menu-bar' ); |
87 | | - |
| 94 | + |
88 | 95 | // dont include about player menu item ( FIXME should be moved to a init function ) |
89 | 96 | delete ctrlObj.supportedMenuItems['aboutPlayerLibrary']; |
90 | | - |
91 | | - // Output menu item containers: |
| 97 | + |
| 98 | + // Output menu item containers: |
92 | 99 | for ( var menuItem in ctrlObj.supportedMenuItems ) { |
93 | | - $menuBar.append( |
94 | | - $j( '<li />') |
| 100 | + $menuBar.append( |
| 101 | + $j( '<li />') |
95 | 102 | // Add the menu item class: |
96 | 103 | .addClass( 'k-' + menuItem + '-btn' ) |
97 | 104 | .attr( 'rel', menuItem ) |
98 | 105 | .append( |
99 | 106 | $j( '<a />' ) |
100 | | - .attr( { |
| 107 | + .attr( { |
101 | 108 | 'title' : gM( 'mwe-embedplayer-' + menuItem ), |
102 | 109 | 'href' : '#' |
103 | 110 | }) |
104 | | - ) |
| 111 | + ) |
105 | 112 | ); |
106 | 113 | } |
107 | | - |
| 114 | + |
108 | 115 | // Add the menuBar to the menuOverlay |
109 | 116 | $menuOverlay.append( $menuBar ); |
110 | | - |
| 117 | + |
111 | 118 | var $menuScreens = $j( '<div />' ) |
112 | 119 | .addClass( 'k-menu-screens' ) |
113 | 120 | .css( { |
— | — | @@ -116,86 +123,86 @@ |
117 | 124 | 'bottom' : '0px', |
118 | 125 | 'right' : '45px', |
119 | 126 | 'overflow' : 'hidden' |
120 | | - } ) |
| 127 | + } ); |
121 | 128 | for ( var menuItem in ctrlObj.supportedMenuItems ) { |
122 | 129 | $menuScreens.append( |
123 | 130 | $j( '<div />' ) |
124 | 131 | .addClass( 'menu-screen menu-' + menuItem ) |
125 | | - ); |
| 132 | + ); |
126 | 133 | } |
127 | | - |
| 134 | + |
128 | 135 | // Add the menuScreens to the menuOverlay |
129 | 136 | $menuOverlay.append( $menuScreens ); |
130 | | - |
131 | | - return $menuOverlay; |
132 | | - |
| 137 | + |
| 138 | + return $menuOverlay; |
| 139 | + |
133 | 140 | } |
134 | 141 | } |
135 | 142 | }, |
136 | | - |
| 143 | + |
137 | 144 | /** |
138 | 145 | * Get minimal width for interface overlay |
139 | 146 | */ |
140 | 147 | getOverlayWidth: function(){ |
141 | 148 | return ( this.embedPlayer.getPlayerWidth() < 200 )? 200 : this.embedPlayer.getPlayerWidth(); |
142 | | - }, |
143 | | - |
| 149 | + }, |
| 150 | + |
144 | 151 | /** |
145 | 152 | * Get minimal height for interface overlay |
146 | 153 | */ |
147 | 154 | getOverlayHeight: function(){ |
148 | 155 | return ( this.embedPlayer.getPlayerHeight() < 160 )? 160 : this.embedPlayer.getPlayerHeight(); |
149 | 156 | }, |
150 | | - |
| 157 | + |
151 | 158 | /** |
152 | 159 | * Adds the skin Control Bindings |
153 | 160 | */ |
154 | 161 | addSkinControlBindings: function() { |
155 | 162 | var embedPlayer = this.embedPlayer; |
156 | | - var _this = this; |
157 | | - |
| 163 | + var _this = this; |
| 164 | + |
158 | 165 | // Set up control bar pointer |
159 | 166 | this.$playerTarget = embedPlayer.$interface; |
160 | | - // Set the menu target: |
161 | | - |
162 | | - |
163 | | - // Options menu display: |
| 167 | + // Set the menu target: |
| 168 | + |
| 169 | + |
| 170 | + // Options menu display: |
164 | 171 | this.$playerTarget.find( '.k-options' ) |
165 | 172 | .unbind() |
166 | 173 | .click( function() { |
167 | 174 | _this.checkMenuOverlay(); |
168 | | - var $kmenu = _this.$playerTarget.find( '.k-menu' ); |
| 175 | + var $kmenu = _this.$playerTarget.find( '.k-menu' ); |
169 | 176 | if ( $kmenu.is( ':visible' ) ) { |
170 | 177 | _this.closeMenuOverlay( ); |
171 | 178 | } else { |
172 | 179 | _this.showMenuOverlay( ); |
173 | 180 | } |
174 | 181 | } ); |
175 | | - |
| 182 | + |
176 | 183 | }, |
177 | 184 | /** |
178 | | - * checks for menu overlay and runs menu bindings if unset |
179 | | - */ |
| 185 | + * checks for menu overlay and runs menu bindings if unset |
| 186 | + */ |
180 | 187 | checkMenuOverlay: function(){ |
181 | 188 | var _this = this; |
182 | 189 | var embedPlayer = this.embedPlayer; |
183 | | - if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) { |
| 190 | + if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) { |
184 | 191 | // Stop the player if it does not support overlays: |
185 | 192 | if ( !embedPlayer.supports['overlays'] ) { |
186 | 193 | embedPlayer.stop(); |
187 | 194 | } |
188 | | - |
| 195 | + |
189 | 196 | // Add the menu binding |
190 | | - _this.addMeunBinding(); |
| 197 | + _this.addMenuBinding(); |
191 | 198 | } |
192 | 199 | }, |
193 | | - |
| 200 | + |
194 | 201 | /** |
195 | 202 | * Close the menu overlay |
196 | 203 | */ |
197 | 204 | closeMenuOverlay: function( ) { |
198 | | - mw.log("PlayerSkin: close menu overlay" ); |
199 | | - |
| 205 | + mw.log("PlayerSkin: close menu overlay" ); |
| 206 | + |
200 | 207 | var $optionsMenu = this.$playerTarget.find( '.k-options' ); |
201 | 208 | var $kmenu = this.$playerTarget.find( '.k-menu' ); |
202 | 209 | $kmenu.fadeOut( "fast", function() { |
— | — | @@ -204,80 +211,80 @@ |
205 | 212 | } ); |
206 | 213 | this.$playerTarget.find( '.play-btn-large' ).fadeIn( 'fast' ); |
207 | 214 | |
208 | | - // re display the control bar if hidden: |
| 215 | + // re display the control bar if hidden: |
209 | 216 | this.showControlBar(); |
210 | | - |
211 | | - // Set close overlay menu flag: |
| 217 | + |
| 218 | + // Set close overlay menu flag: |
212 | 219 | this.displayOptionsMenuFlag = false; |
213 | 220 | }, |
214 | | - |
| 221 | + |
215 | 222 | /** |
216 | 223 | * Show the menu overlay |
217 | 224 | */ |
218 | 225 | showMenuOverlay: function( $ktxt ) { |
219 | 226 | var $optionsMenu = this.$playerTarget.find( '.k-options' ); |
220 | 227 | var $kmenu = this.$playerTarget.find( '.k-menu' ); |
221 | | - |
| 228 | + |
222 | 229 | $kmenu.fadeIn( "fast", function() { |
223 | 230 | $optionsMenu.find( 'span' ) |
224 | 231 | .text ( gM( 'mwe-embedplayer-close_btn' ) ); |
225 | 232 | } ); |
226 | 233 | this.$playerTarget.find( '.play-btn-large' ).fadeOut( 'fast' ); |
227 | | - |
| 234 | + |
228 | 235 | $j(this.embedPlayer).trigger( 'displayMenuOverlay' ); |
229 | | - |
| 236 | + |
230 | 237 | // Set the Options Menu display flag to true: |
231 | 238 | this.displayOptionsMenuFlag = true; |
232 | 239 | }, |
233 | | - |
| 240 | + |
234 | 241 | /** |
235 | 242 | * Adds binding for the options menu |
236 | 243 | * |
237 | | - * @param {Object} $tp Target video container for |
| 244 | + * @param {Object} $tp Target video container for |
238 | 245 | */ |
239 | | - addMeunBinding: function() { |
| 246 | + addMenuBinding: function() { |
240 | 247 | var _this = this; |
241 | 248 | var embedPlayer = this.embedPlayer; |
242 | 249 | // Set local player target pointer: |
243 | 250 | var $playerTarget = embedPlayer.$interface; |
244 | | - |
| 251 | + |
245 | 252 | // Check if k-menu already exists: |
246 | 253 | if ( $playerTarget.find( '.k-menu' ).length != 0 ) |
247 | 254 | return false; |
248 | | - |
249 | | - // Add options menu to top of player target children: |
| 255 | + |
| 256 | + // Add options menu to top of player target children: |
250 | 257 | $playerTarget.prepend( |
251 | | - _this.getComponent( 'optionsMenu' ) |
252 | | - ); |
253 | | - |
| 258 | + _this.getComponent( 'optionsMenu' ) |
| 259 | + ); |
| 260 | + |
254 | 261 | // By default its hidden: |
255 | 262 | $playerTarget.find( '.k-menu' ).hide(); |
256 | | - |
257 | | - // Add menu-items bindings: |
| 263 | + |
| 264 | + // Add menu-items bindings: |
258 | 265 | for ( var menuItem in _this.supportedMenuItems ) { |
259 | 266 | $playerTarget.find( '.k-' + menuItem + '-btn' ).click( function( ) { |
260 | | - |
| 267 | + |
261 | 268 | // Grab the context from the "clicked" menu item |
262 | 269 | var mk = $j( this ).attr( 'rel' ); |
263 | | - |
264 | | - // hide all menu items |
265 | | - $targetItem = $playerTarget.find( '.menu-' + mk ); |
266 | | - |
| 270 | + |
| 271 | + // hide all menu items |
| 272 | + $targetItem = $playerTarget.find( '.menu-' + mk ); |
| 273 | + |
267 | 274 | // call the function showMenuItem |
268 | 275 | _this.showMenuItem( mk ); |
269 | | - |
270 | | - // Hide the others |
| 276 | + |
| 277 | + // Hide the others |
271 | 278 | $playerTarget.find( '.menu-screen' ).hide(); |
272 | | - |
| 279 | + |
273 | 280 | // Show the target menu item: |
274 | 281 | $targetItem.fadeIn( "fast" ); |
275 | | - |
| 282 | + |
276 | 283 | // Don't follow the # link |
277 | 284 | return false; |
278 | 285 | } ); |
279 | 286 | } |
280 | 287 | }, |
281 | | - |
| 288 | + |
282 | 289 | /** |
283 | 290 | * onClipDone action |
284 | 291 | * onClipDone for k-skin (with apiTitleKey) show the "credits" screen: |
— | — | @@ -285,58 +292,58 @@ |
286 | 293 | onClipDone: function(){ |
287 | 294 | if( this.embedPlayer.apiTitleKey ){ |
288 | 295 | this.checkMenuOverlay( ); |
289 | | - this.showMenuOverlay(); |
| 296 | + this.showMenuOverlay(); |
290 | 297 | this.showMenuItem( 'credits' ); |
291 | 298 | } |
292 | 299 | }, |
293 | | - |
| 300 | + |
294 | 301 | /** |
295 | 302 | * Shows a selected menu_item |
296 | 303 | * |
297 | | - * NOTE: this should be merged with parent mw.PlayerControlBuilder optionMenuItems |
| 304 | + * NOTE: this should be merged with parent mw.PlayerControlBuilder optionMenuItems |
298 | 305 | * binding mode |
299 | | - * |
| 306 | + * |
300 | 307 | * @param {String} menu_itme Menu item key to display |
301 | 308 | */ |
302 | | - showMenuItem:function( menuItem ) { |
| 309 | + showMenuItem:function( menuItem ) { |
303 | 310 | var embedPlayer = this.embedPlayer; |
304 | | - //handle special k-skin specific display; |
| 311 | + //handle special k-skin specific display; |
305 | 312 | switch( menuItem ){ |
306 | 313 | case 'credits': |
307 | | - this.showCredits(); |
| 314 | + this.showCredits(); |
308 | 315 | break; |
309 | 316 | case 'playerSelect': |
310 | | - embedPlayer.$interface.find( '.menu-playerSelect').html( |
| 317 | + embedPlayer.$interface.find( '.menu-playerSelect').html( |
311 | 318 | this.getPlayerSelect() |
312 | | - ); |
313 | | - break; |
| 319 | + ); |
| 320 | + break; |
314 | 321 | case 'download' : |
315 | | - embedPlayer.$interface.find( '.menu-download').text( |
316 | | - gM('mwe-loading_txt' ) |
| 322 | + embedPlayer.$interface.find( '.menu-download').text( |
| 323 | + gM('mwe-loading_txt' ) |
317 | 324 | ); |
318 | 325 | // Call show download with the target to be populated |
319 | 326 | this.showDownload( |
320 | | - embedPlayer.$interface.find( '.menu-download') |
| 327 | + embedPlayer.$interface.find( '.menu-download') |
321 | 328 | ); |
322 | 329 | break; |
323 | 330 | case 'share': |
324 | 331 | embedPlayer.$interface.find( '.menu-share' ).html( |
325 | 332 | this.getShare() |
326 | 333 | ); |
327 | | - break; |
328 | | - } |
| 334 | + break; |
| 335 | + } |
329 | 336 | }, |
330 | | - |
| 337 | + |
331 | 338 | /** |
332 | 339 | * Show the credit screen ( presently specific to kaltura skin ) |
333 | | - */ |
| 340 | + */ |
334 | 341 | showCredits: function() { |
335 | | - // Set up the shortcuts: |
| 342 | + // Set up the shortcuts: |
336 | 343 | var embedPlayer = this.embedPlayer; |
337 | | - var _this = this; |
| 344 | + var _this = this; |
338 | 345 | var $target = embedPlayer.$interface.find( '.menu-credits' ); |
339 | 346 | |
340 | | - $target.empty().append( |
| 347 | + $target.empty().append( |
341 | 348 | $j('<h2 />') |
342 | 349 | .text( gM( 'mwe-embedplayer-credits' ) ), |
343 | 350 | $j('<div />') |
— | — | @@ -344,8 +351,8 @@ |
345 | 352 | .loadingSpinner() |
346 | 353 | ); |
347 | 354 | |
348 | | - if( mw.getConfig( 'EmbedPlayer.KalturaAttribution' ) == true ){ |
349 | | - $target.append( |
| 355 | + if( mw.getConfig( 'EmbedPlayer.KalturaAttribution' ) == true ){ |
| 356 | + $target.append( |
350 | 357 | $j( '<div />' ) |
351 | 358 | .addClass( 'k-attribution' ) |
352 | 359 | .attr({ |
— | — | @@ -356,95 +363,95 @@ |
357 | 364 | }) |
358 | 365 | ); |
359 | 366 | } |
360 | | - |
| 367 | + |
361 | 368 | if( !embedPlayer.apiTitleKey ){ |
362 | 369 | $target.find('.credits_box').text( |
363 | | - 'Error: no title key to grab credits with' |
| 370 | + 'Error: no title key to grab credits with' |
364 | 371 | ); |
365 | 372 | return ; |
366 | 373 | } |
367 | | - |
368 | | - _this.getCredits(); |
| 374 | + |
| 375 | + _this.getCredits(); |
369 | 376 | }, |
370 | | - |
| 377 | + |
371 | 378 | /** |
372 | 379 | * Issues a request to populate the credits box |
373 | 380 | */ |
374 | 381 | getCredits: function(){ |
375 | 382 | // Setup shortcuts: |
376 | 383 | var embedPlayer = this.embedPlayer; |
377 | | - var _this = this; |
| 384 | + var _this = this; |
378 | 385 | var $target = embedPlayer.$interface.find( '.menu-credits' ); |
379 | | - |
380 | | - var apiUrl = mw.getApiProviderURL( embedPlayer.apiProvider ); |
| 386 | + |
| 387 | + var apiUrl = mw.getApiProviderURL( embedPlayer.apiProvider ); |
381 | 388 | var fileTitle = 'File:' + embedPlayer.apiTitleKey.replace(/File:|Image:/, ''); |
382 | | - |
| 389 | + |
383 | 390 | // Get the image info |
384 | | - var request = { |
| 391 | + var request = { |
385 | 392 | 'prop' : 'imageinfo', |
386 | 393 | 'titles' : fileTitle, |
387 | | - 'iiprop' : 'url' |
| 394 | + 'iiprop' : 'url' |
388 | 395 | }; |
389 | 396 | var articleUrl = ''; |
390 | | - mw.getJSON( apiUrl, request, function( data ){ |
| 397 | + mw.getJSON( apiUrl, request, function( data ){ |
391 | 398 | if ( data.query.pages ) { |
392 | 399 | for ( var i in data.query.pages ) { |
393 | 400 | var imageProps = data.query.pages[i]; |
394 | | - // Check properties for "missing" |
395 | | - if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){ |
396 | | - // Found page |
| 401 | + // Check properties for "missing" |
| 402 | + if( imageProps.imageinfo && imageProps.imageinfo[0] && imageProps.imageinfo[0].descriptionurl ){ |
| 403 | + // Found page |
397 | 404 | $target.find( '.credits_box' ).html( |
398 | 405 | _this.doCreditLine( imageProps.imageinfo[0].descriptionurl ) |
399 | | - ); |
| 406 | + ); |
400 | 407 | }else{ |
401 | | - // missing page descriptionurl |
| 408 | + // missing page descriptionurl |
402 | 409 | $target.find( '.credits_box' ).text( |
403 | | - 'Error: title key: ' + embedPlayer.apiTitleKey + ' not found' |
404 | | - ); |
| 410 | + 'Error: title key: ' + embedPlayer.apiTitleKey + ' not found' |
| 411 | + ); |
405 | 412 | } |
406 | 413 | } |
407 | 414 | } |
408 | | - } ); |
| 415 | + } ); |
409 | 416 | }, |
410 | | - |
| 417 | + |
411 | 418 | /** |
412 | 419 | * Build a clip credit from the resource wikiText page |
413 | 420 | * |
414 | 421 | * NOTE: in the future this should parse the resource page template |
415 | | - * |
| 422 | + * |
416 | 423 | * @parm {String} wikiText Resource wiki text page contents |
417 | 424 | */ |
418 | 425 | doCreditLine: function ( articleUrl ){ |
419 | 426 | var embedPlayer = this.embedPlayer; |
420 | | - |
421 | | - // Get the title str |
422 | | - var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' '); |
423 | | - |
| 427 | + |
| 428 | + // Get the title str |
| 429 | + var titleStr = embedPlayer.apiTitleKey.replace(/_/g, ' '); |
| 430 | + |
424 | 431 | var imgWidth = ( this.getOverlayWidth() < 250 )? 45 : 90; |
425 | | - |
| 432 | + |
426 | 433 | return $j( '<div/>' ).addClass( 'creditline' ) |
427 | 434 | .append( |
428 | 435 | $j('<a/>').attr({ |
429 | 436 | 'href' : articleUrl, |
430 | | - 'title' : titleStr |
431 | | - }).html( |
| 437 | + 'title' : titleStr |
| 438 | + }).html( |
432 | 439 | $j('<img/>').attr( { |
433 | | - 'border': 0, |
434 | | - 'src' : embedPlayer.poster |
| 440 | + 'border': 0, |
| 441 | + 'src' : embedPlayer.poster |
435 | 442 | } ).css( { |
436 | 443 | 'width' : imgWidth, |
437 | 444 | 'height': parseInt( imgWidth * ( embedPlayer.height / embedPlayer.width ) ) |
438 | 445 | } ) |
439 | 446 | ) |
440 | 447 | ) |
441 | | - .append( |
442 | | - $j('<span>').html( |
443 | | - gM( 'mwe-embedplayer-credit-title' , |
| 448 | + .append( |
| 449 | + $j('<span>').html( |
| 450 | + gM( 'mwe-embedplayer-credit-title' , |
444 | 451 | // We use a div container to easialy get at the built out link |
445 | | - $j('<div>').html( |
| 452 | + $j('<div>').html( |
446 | 453 | $j('<a/>').attr({ |
447 | 454 | 'href' : articleUrl, |
448 | | - 'title' : titleStr |
| 455 | + 'title' : titleStr |
449 | 456 | }).text( titleStr ) |
450 | 457 | ).html() |
451 | 458 | ) |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mw.PlayerControlBuilder.js |
— | — | @@ -1,5 +1,5 @@ |
2 | 2 | /** |
3 | | -* Msg text is inherited from embedPlayer |
| 3 | +* Msg text is inherited from embedPlayer |
4 | 4 | */ |
5 | 5 | |
6 | 6 | ( function( mw ) { |
— | — | @@ -15,189 +15,183 @@ |
16 | 16 | * ControlsBuilder prototype: |
17 | 17 | */ |
18 | 18 | mw.PlayerControlBuilder.prototype = { |
19 | | - //Default Local values: |
20 | | - |
| 19 | + //Default Local values: |
| 20 | + |
21 | 21 | // Parent css Class name |
22 | 22 | playerClass : 'mv-player', |
23 | | - |
| 23 | + |
24 | 24 | // Long string display of time value |
25 | 25 | longTimeDisp: true, |
26 | | - |
| 26 | + |
27 | 27 | // Default volume layout is "vertical" |
28 | 28 | volume_layout : 'vertical', |
29 | | - |
| 29 | + |
30 | 30 | // Default control bar height |
31 | | - height: 31, |
32 | | - |
| 31 | + height: 31, |
| 32 | + |
33 | 33 | // Default supported components is merged with embedPlayer set of supported types |
34 | | - supportedComponets: { |
35 | | - // All playback types support options |
36 | | - 'options': true |
37 | | - }, |
38 | | - |
| 34 | + supportedComponets: { |
| 35 | + // All playback types support options |
| 36 | + 'options': true |
| 37 | + }, |
| 38 | + |
39 | 39 | // Default supported menu items is merged with skin menu items |
40 | 40 | supportedMenuItems: { |
41 | 41 | // Player Select |
42 | | - 'playerSelect' : true, |
43 | | - |
| 42 | + 'playerSelect' : true, |
| 43 | + |
44 | 44 | // Download the file menu |
45 | | - 'download' : true, |
46 | | - |
| 45 | + 'download' : true, |
| 46 | + |
47 | 47 | // Share the video menu |
48 | 48 | 'share' : true, |
49 | | - |
| 49 | + |
50 | 50 | // Player library link |
51 | 51 | 'aboutPlayerLibrary': true |
52 | | - }, |
53 | | - |
| 52 | + }, |
| 53 | + |
54 | 54 | // Flag to store the current fullscreen mode |
55 | 55 | fullscreenMode: false, |
56 | | - |
57 | | - // Flag to store if a warning binding has been added |
| 56 | + |
| 57 | + // Flag to store if a warning binding has been added |
58 | 58 | addWarningFlag: false, |
59 | | - |
60 | | - // Flag to store state of overlay on player |
61 | | - displayOptionsMenuFlag: false, |
62 | | - |
| 59 | + |
| 60 | + // Flag to store state of overlay on player |
| 61 | + displayOptionsMenuFlag: false, |
| 62 | + |
63 | 63 | /** |
64 | 64 | * Initialization Object for the control builder |
65 | 65 | * |
66 | 66 | * @param {Object} embedPlayer EmbedPlayer interface |
67 | | - */ |
| 67 | + */ |
68 | 68 | init: function( embedPlayer ) { |
69 | 69 | var _this = this; |
70 | 70 | this.embedPlayer = embedPlayer; |
71 | 71 | |
72 | 72 | // Check for skin overrides for controlBuilder |
73 | | - var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 ); |
74 | | - if ( mw['PlayerSkin' + skinClass ]) { |
75 | | - |
| 73 | + var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 ); |
| 74 | + if ( mw['PlayerSkin' + skinClass ]) { |
| 75 | + |
76 | 76 | // Clone as to not override prototype with the skin config |
77 | | - var _this = $j.extend( true, { }, this, mw['PlayerSkin' + skinClass ] ); |
| 77 | + var _this = $j.extend( true, { }, this, mw['PlayerSkin' + skinClass ] ); |
78 | 78 | return _this; |
79 | 79 | } |
80 | | - // Return the controlBuilder Object: |
| 80 | + // Return the controlBuilder Object: |
81 | 81 | return this; |
82 | 82 | }, |
83 | | - |
| 83 | + |
84 | 84 | /** |
85 | 85 | * Get the control bar height |
86 | | - * @return {Number} control bar height |
| 86 | + * @return {Number} control bar height |
87 | 87 | */ |
88 | 88 | getHeight: function(){ |
89 | 89 | return this.height; |
90 | 90 | }, |
91 | | - |
| 91 | + |
92 | 92 | /** |
93 | 93 | * Add the controls html to palyer interface |
94 | 94 | */ |
95 | 95 | addControls: function() { |
96 | 96 | // Set up local pointer to the embedPlayer |
97 | 97 | var embedPlayer = this.embedPlayer; |
98 | | - |
| 98 | + |
99 | 99 | // Set up local controlBuilder |
100 | 100 | var _this = this; |
101 | 101 | |
102 | | - // Remove any old controls & old overlays: |
| 102 | + // Remove any old controls & old overlays: |
103 | 103 | embedPlayer.$interface.find( '.control-bar,.overlay-win' ).remove(); |
104 | | - |
105 | | - // Reset flag: |
| 104 | + |
| 105 | + // Reset flag: |
106 | 106 | _this.displayOptionsMenuFlag = false; |
107 | | - |
108 | | - |
| 107 | + |
| 108 | + |
109 | 109 | // Setup the controlBar container |
110 | 110 | var $controlBar = $j('<div />') |
111 | 111 | .addClass( 'ui-state-default ui-widget-header ui-helper-clearfix control-bar' ) |
112 | | - .css( 'height', this.height ); |
113 | | - |
| 112 | + .css( 'height', this.height ); |
| 113 | + |
114 | 114 | $controlBar.css( { |
115 | 115 | 'position': 'absolute', |
116 | 116 | 'bottom' : '0px', |
117 | 117 | 'left' : '0px', |
118 | 118 | 'right' : '0px' |
119 | 119 | } ); |
120 | | - // Check for overlay controls: |
121 | | - if( _this.checkOverlayControls() ) { |
122 | | - $controlBar.hide(); |
123 | | - // Make sure the interface is correct height: |
124 | | - embedPlayer.$interface.css( { |
125 | | - 'height' : parseInt( embedPlayer.height ) |
126 | | - } ); |
127 | | - } else { |
| 120 | + // Check for overlay controls: |
| 121 | + if( ! _this.checkOverlayControls() ) { |
128 | 122 | // Add some space to interface for the control bar ( if not overlaying controls ) |
129 | 123 | embedPlayer.$interface.css( { |
130 | 124 | 'height' : parseInt( embedPlayer.height ) + parseInt( this.height ) +2 |
131 | | - } ); |
| 125 | + } ); |
132 | 126 | } |
133 | | - |
| 127 | + |
134 | 128 | // Add the controls to the interface |
135 | 129 | embedPlayer.$interface.append( $controlBar ); |
136 | | - |
| 130 | + |
137 | 131 | // Add the Controls Component |
138 | 132 | this.addControlComponents(); |
139 | | - |
| 133 | + |
140 | 134 | // Add top level Controls bindings |
141 | 135 | this.addControlBindings(); |
142 | 136 | }, |
143 | | - |
| 137 | + |
144 | 138 | /** |
145 | 139 | * Add control components as defined per this.components |
146 | | - */ |
| 140 | + */ |
147 | 141 | addControlComponents: function( ) { |
148 | | - var _this = this; |
| 142 | + var _this = this; |
149 | 143 | mw.log( 'PlayerControlsBuilder:: addControlComponents' ); |
150 | | - |
| 144 | + |
151 | 145 | // Set up local pointer to the embedPlayer |
152 | 146 | var embedPlayer = this.embedPlayer; |
153 | | - |
| 147 | + |
154 | 148 | //Set up local var to control container: |
155 | | - var $controlBar = embedPlayer.$interface.find( '.control-bar' ); |
156 | | - |
| 149 | + var $controlBar = embedPlayer.$interface.find( '.control-bar' ); |
| 150 | + |
157 | 151 | this.available_width = embedPlayer.getPlayerWidth(); |
158 | | - |
| 152 | + |
159 | 153 | // Make pointer to the embedPlayer |
160 | 154 | this.embedPlayer = embedPlayer; |
161 | | - |
| 155 | + |
162 | 156 | // Build the supportedComponets list |
163 | 157 | this.supportedComponets = $j.extend( this.supportedComponets, embedPlayer.supports ); |
164 | | - |
| 158 | + |
165 | 159 | // Check for timed text support: |
166 | 160 | if( embedPlayer.isTimedTextSupported() ){ |
167 | 161 | this.supportedComponets['timedText'] = true; |
168 | | - } |
169 | | - // Check for Attribution button |
| 162 | + } |
| 163 | + // Check for Attribution button |
170 | 164 | if( mw.getConfig( 'EmbedPlayer.AttributionButton' ) && embedPlayer.attributionbutton ){ |
171 | 165 | this.supportedComponets[ 'attributionButton' ] = true; |
172 | 166 | } |
173 | | - |
| 167 | + |
174 | 168 | // Check global fullscreen enabled flag |
175 | 169 | if( mw.getConfig( 'EmbedPlayer.EnableFullscreen' ) === false ){ |
176 | | - this.supportedComponets[ 'fullscreen'] = false; |
| 170 | + this.supportedComponets[ 'fullscreen'] = false; |
177 | 171 | } |
178 | 172 | |
179 | | - // Output components |
180 | | - for ( var component_id in this.components ) { |
181 | | - // Check for (component === false ) and skip |
182 | | - if( this.components[ component_id ] === false ){ |
| 173 | + // Output components |
| 174 | + for ( var component_id in this.components ) { |
| 175 | + // Check for (component === false ) and skip |
| 176 | + if( this.components[ component_id ] === false ){ |
183 | 177 | continue; |
184 | 178 | } |
185 | | - |
| 179 | + |
186 | 180 | // Special case with playhead skip if we have > 30px of space for it |
187 | 181 | if ( component_id == 'playHead' && this.available_width < 30 ){ |
188 | 182 | continue; |
189 | | - } |
190 | | - |
191 | | - // Skip "fullscreen" button for assets or where height is 0px ( audio ) |
192 | | - if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){ |
| 183 | + } |
| 184 | + |
| 185 | + // Skip "fullscreen" button for assets or where height is 0px ( audio ) |
| 186 | + if( component_id == 'fullscreen' && this.embedPlayer.height == 0 ){ |
193 | 187 | continue; |
194 | | - } |
195 | | - |
| 188 | + } |
| 189 | + |
196 | 190 | // Make sure the given components is supported: |
197 | 191 | if ( this.supportedComponets[ component_id ] ) { |
198 | | - if ( this.available_width > this.components[ component_id ].w ) { |
| 192 | + if ( this.available_width > this.components[ component_id ].w ) { |
199 | 193 | // Append the component |
200 | | - $controlBar.append( |
201 | | - _this.getComponent( component_id ) |
| 194 | + $controlBar.append( |
| 195 | + _this.getComponent( component_id ) |
202 | 196 | ); |
203 | 197 | this.available_width -= this.components[ component_id ].w; |
204 | 198 | } else { |
— | — | @@ -206,28 +200,28 @@ |
207 | 201 | } |
208 | 202 | } |
209 | 203 | }, |
210 | | - |
| 204 | + |
211 | 205 | /** |
212 | 206 | * Get the fullscreen player css |
213 | | - */ |
| 207 | + */ |
214 | 208 | getFullscreenPlayerCss: function() { |
215 | 209 | var embedPlayer = this.embedPlayer; |
216 | | - // Setup target height width based on max window size |
| 210 | + // Setup target height width based on max window size |
217 | 211 | var fullWidth = $j( window ).width() - 2 ; |
218 | | - var fullHeight = $j( window ).height() ; |
219 | | - |
| 212 | + var fullHeight = $j( window ).height() ; |
| 213 | + |
220 | 214 | // Set target width |
221 | 215 | var targetWidth = fullWidth; |
222 | | - var targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() ); |
223 | | - // Check if it exceeds the height constraint: |
224 | | - if( targetHeight > fullHeight ){ |
225 | | - targetHeight = fullHeight; |
226 | | - targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() ); |
| 216 | + var targetHeight = targetWidth * ( embedPlayer.getHeight() / embedPlayer.getWidth() ); |
| 217 | + // Check if it exceeds the height constraint: |
| 218 | + if( targetHeight > fullHeight ){ |
| 219 | + targetHeight = fullHeight; |
| 220 | + targetWidth = targetHeight * ( embedPlayer.getWidth() / embedPlayer.getHeight() ); |
227 | 221 | } |
228 | 222 | var offsetTop = ( targetHeight < fullHeight )? ( fullHeight- targetHeight ) / 2 : 0; |
229 | 223 | var offsetLeft = ( targetWidth < fullWidth )? ( fullWidth- targetWidth ) / 2 : 0; |
230 | | - |
231 | | - //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 ); |
| 224 | + |
| 225 | + //mw.log(" targetWidth: " + targetWidth + ' fullwidth: ' + fullWidth + ' :: ' + ( fullWidth- targetWidth ) / 2 ); |
232 | 226 | return { |
233 | 227 | 'height': targetHeight, |
234 | 228 | 'width' : targetWidth, |
— | — | @@ -235,159 +229,159 @@ |
236 | 230 | 'left': offsetLeft |
237 | 231 | }; |
238 | 232 | }, |
239 | | - |
| 233 | + |
240 | 234 | /** |
241 | 235 | * Get the fullscreen play button css |
242 | 236 | */ |
243 | | - getFullscreenPlayButtonCss: function() { |
| 237 | + getFullscreenPlayButtonCss: function() { |
244 | 238 | var pos = this.getFullscreenPlayerCss(); |
245 | 239 | return { |
246 | | - 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
| 240 | + 'left' : ( ( pos.width - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
247 | 241 | 'top' : ( ( pos.height - this.getComponentHeight( 'playButtonLarge' ) ) / 2 ) |
248 | 242 | }; |
249 | 243 | }, |
250 | | - |
| 244 | + |
251 | 245 | /** |
252 | 246 | * Get the fullscreen text css |
253 | 247 | */ |
254 | 248 | getInterfaceSizeTextCss: function() { |
255 | 249 | // Some arbitrary scale relative to window size ( 400px wide is text size 105% ) |
256 | | - var textSize = this.embedPlayer.$interface.width() / 3.8; |
257 | | - if( textSize < 95 ) textSize = 95; |
| 250 | + var textSize = this.embedPlayer.$interface.width() / 3.8; |
| 251 | + if( textSize < 95 ) textSize = 95; |
258 | 252 | if( textSize > 200 ) textSize = 200; |
259 | 253 | //mw.log(' win size is: ' + $j( window ).width() + ' ts: ' + textSize ); |
260 | 254 | return { |
261 | 255 | 'font-size' : textSize + '%' |
262 | 256 | }; |
263 | 257 | }, |
264 | | - |
| 258 | + |
265 | 259 | /** |
266 | | - * Toggles full screen by calling |
| 260 | + * Toggles full screen by calling |
267 | 261 | * doFullScreenPlayer to enable fullscreen mode |
268 | 262 | * restoreWindowPlayer to restore window mode |
269 | 263 | */ |
270 | 264 | toggleFullscreen: function() { |
271 | 265 | if( this.fullscreenMode ){ |
272 | | - this.restoreWindowPlayer(); |
273 | | - $j( this.embedPlayer ).trigger( 'closeFullScreenEvent' ); |
| 266 | + this.restoreWindowPlayer(); |
| 267 | + $j( this.embedPlayer ).trigger( 'closeFullScreenEvent' ); |
274 | 268 | }else{ |
275 | 269 | this.doFullScreenPlayer(); |
276 | | - $j( this.embedPlayer ).trigger( 'openFullScreenEvent' ); |
| 270 | + $j( this.embedPlayer ).trigger( 'openFullScreenEvent' ); |
277 | 271 | } |
278 | 272 | }, |
279 | | - |
| 273 | + |
280 | 274 | /** |
281 | | - * Do full-screen mode |
282 | | - */ |
| 275 | + * Do full-screen mode |
| 276 | + */ |
283 | 277 | doFullScreenPlayer: function() { |
284 | | - mw.log(" controlBuilder :: toggle full-screen "); |
| 278 | + mw.log(" controlBuilder :: toggle full-screen "); |
285 | 279 | // Setup pointer to control builder : |
286 | 280 | var _this = this; |
287 | | - |
288 | | - // Setup local reference to embed player: |
| 281 | + |
| 282 | + // Setup local reference to embed player: |
289 | 283 | var embedPlayer = this.embedPlayer; |
290 | | - |
291 | | - // Setup a local reference to the player interface: |
| 284 | + |
| 285 | + // Setup a local reference to the player interface: |
292 | 286 | var $interface = embedPlayer.$interface; |
293 | | - |
294 | | - |
| 287 | + |
| 288 | + |
295 | 289 | // Check fullscreen state ( if already true do nothing ) |
296 | 290 | if( this.fullscreenMode == true ){ |
297 | 291 | return ; |
298 | | - } |
299 | | - this.fullscreenMode = true; |
300 | | - |
| 292 | + } |
| 293 | + this.fullscreenMode = true; |
| 294 | + |
301 | 295 | //Remove any old mw-fullscreen-overlay |
302 | 296 | $interface.find( '.mw-fullscreen-overlay' ).remove(); |
303 | | - |
| 297 | + |
304 | 298 | // Special hack for mediawiki monobook skin search box |
305 | | - if( $j( '#p-search,#p-logo' ).length ) { |
306 | | - $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1); |
307 | | - } |
308 | | - |
| 299 | + if( $j( '#p-search,#p-logo' ).length ) { |
| 300 | + $j( '#p-search,#p-logo,#ca-nstab-project a' ).css('z-index', 1); |
| 301 | + } |
| 302 | + |
309 | 303 | // Add the css fixed fullscreen black overlay as a sibling to the video element |
310 | | - $interface.after( |
| 304 | + $interface.after( |
311 | 305 | $j( '<div />' ) |
312 | 306 | .addClass( 'mw-fullscreen-overlay' ) |
313 | 307 | // Set some arbitrary high z-index |
314 | | - .css('z-index', mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) ) |
| 308 | + .css('z-index', mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) ) |
315 | 309 | .hide() |
316 | 310 | .fadeIn("slow") |
317 | | - ); |
318 | | - |
319 | | - // Change the interface to absolute positioned: |
| 311 | + ); |
| 312 | + |
| 313 | + // Change the interface to absolute positioned: |
320 | 314 | this.windowPositionStyle = $interface.css( 'position' ); |
321 | 315 | this.windowZindex = $interface.css( 'z-index' ); |
322 | | - |
323 | | - // Get the base offset: |
| 316 | + |
| 317 | + // Get the base offset: |
324 | 318 | this.windowOffset = $interface.offset(); |
325 | 319 | this.windowOffset.top = this.windowOffset.top - $j(document).scrollTop(); |
326 | 320 | this.windowOffset.left = this.windowOffset.left - $j(document).scrollLeft(); |
327 | | - |
| 321 | + |
328 | 322 | // Change the z-index of the interface |
329 | 323 | $interface.css( { |
330 | 324 | 'position' : 'fixed', |
331 | 325 | 'z-index' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1, |
332 | 326 | 'top' : this.windowOffset.top, |
333 | 327 | 'left' : this.windowOffset.left |
334 | | - } ); |
335 | | - |
| 328 | + } ); |
| 329 | + |
336 | 330 | // Empty out the parent absolute index |
337 | | - _this.parentsAbsolute = []; |
338 | | - |
| 331 | + _this.parentsAbsolute = []; |
| 332 | + |
339 | 333 | // Hide the body scroll bar |
340 | 334 | $j('body').css( 'overflow', 'hidden' ); |
341 | | - |
342 | 335 | |
| 336 | + |
343 | 337 | var topOffset = '0px'; |
344 | 338 | var leftOffset = '0px'; |
345 | | - |
| 339 | + |
346 | 340 | //Check if we have an offsetParent |
347 | 341 | if( $interface.offsetParent().get(0).tagName.toLowerCase() != 'body' ) { |
348 | 342 | topOffset = -this.windowOffset.top + 'px'; |
349 | 343 | leftOffset = -this.windowOffset.left + 'px'; |
350 | | - } |
351 | | - |
352 | | - // Resize interface container |
353 | | - $interface.animate( { |
| 344 | + } |
| 345 | + |
| 346 | + // Resize interface container |
| 347 | + $interface.animate( { |
354 | 348 | 'top' : topOffset, |
355 | 349 | 'left' : leftOffset, |
356 | 350 | 'width' : $j( window ).width(), |
357 | | - 'height' : $j( window ).height(), |
358 | | - 'overlow' : 'hidden' |
| 351 | + 'height' : $j( window ).height(), |
| 352 | + 'overlow' : 'hidden' |
359 | 353 | }, function(){ |
360 | 354 | // Remove absolute css of the interface parents |
361 | 355 | $interface.parents().each( function() { |
362 | | - //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) ); |
363 | | - if( $j( this ).css( 'position' ) == 'absolute' ) { |
364 | | - _this.parentsAbsolute.push( $j( this ) ); |
| 356 | + //mw.log(' parent : ' + $j( this ).attr('id' ) + ' class: ' + $j( this ).attr('class') + ' pos: ' + $j( this ).css( 'position' ) ); |
| 357 | + if( $j( this ).css( 'position' ) == 'absolute' ) { |
| 358 | + _this.parentsAbsolute.push( $j( this ) ); |
365 | 359 | $j( this ).css( 'position', null ); |
366 | | - mw.log(' should update position: ' + $j( this ).css( 'position' ) ); |
| 360 | + mw.log(' should update position: ' + $j( this ).css( 'position' ) ); |
367 | 361 | } |
368 | 362 | } ); |
369 | | - |
370 | | - // Resize the timed text font size per new player width |
371 | | - $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() ); |
| 363 | + |
| 364 | + // Resize the timed text font size per new player width |
| 365 | + $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() ); |
372 | 366 | } ); |
373 | | - |
374 | | - // Set the player height width: |
| 367 | + |
| 368 | + // Set the player height width: |
375 | 369 | $j( embedPlayer ).css( { |
376 | 370 | 'position' : 'relative' |
377 | 371 | } ) |
378 | 372 | // Animate a zoom ( while keeping aspect ) |
379 | 373 | .animate( _this.getFullscreenPlayerCss() ); |
380 | | - |
381 | | - |
| 374 | + |
| 375 | + |
382 | 376 | // Reposition play-btn-large ( this is unfortunately not easy to position with 'margin': 'auto' |
383 | 377 | $interface.find('.play-btn-large').animate( _this.getFullscreenPlayButtonCss() ); |
384 | | - |
| 378 | + |
385 | 379 | // Bind mouse move in interface to hide control bar |
386 | 380 | _this.mouseMovedFlag = false; |
387 | 381 | $interface.mousemove( function(e){ |
388 | | - _this.mouseMovedFlag = true; |
| 382 | + _this.mouseMovedFlag = true; |
389 | 383 | }); |
390 | 384 | // Check every 2 seconds reset flag status: |
391 | | - function checkMovedMouse(){ |
| 385 | + function checkMovedMouse(){ |
392 | 386 | if( _this.fullscreenMode ){ |
393 | 387 | if( _this.mouseMovedFlag ){ |
394 | 388 | _this.mouseMovedFlag = false; |
— | — | @@ -398,34 +392,34 @@ |
399 | 393 | // Check for mouse movement every 250ms |
400 | 394 | _this.hideControlBar(); |
401 | 395 | setTimeout(checkMovedMouse, 250 ); |
402 | | - } |
| 396 | + } |
403 | 397 | } |
404 | 398 | }; |
405 | 399 | checkMovedMouse(); |
406 | | - |
| 400 | + |
407 | 401 | // Bind Scroll position update |
408 | | - |
| 402 | + |
409 | 403 | // Bind resize resize window to resize window |
410 | 404 | $j( window ).resize( function() { |
411 | 405 | if( _this.fullscreenMode ){ |
412 | | - // Update interface container: |
413 | | - $interface.css( { |
| 406 | + // Update interface container: |
| 407 | + $interface.css( { |
414 | 408 | 'top' : '0px', |
415 | 409 | 'left' : '0px', |
416 | 410 | 'width' : $j( window ).width(), |
417 | | - 'height' : $j( window ).height() |
| 411 | + 'height' : $j( window ).height() |
418 | 412 | } ); |
419 | 413 | // Update player size |
420 | 414 | $j( embedPlayer ).css( _this.getFullscreenPlayerCss() ); |
421 | | - |
| 415 | + |
422 | 416 | // Update play button pos |
423 | | - $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() ); |
424 | | - |
425 | | - // Update the timed text size |
| 417 | + $interface.find('.play-btn-large').css( _this.getFullscreenPlayButtonCss() ); |
| 418 | + |
| 419 | + // Update the timed text size |
426 | 420 | $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() ); |
427 | 421 | } |
428 | 422 | }); |
429 | | - |
| 423 | + |
430 | 424 | // Bind escape to restore clip resolution |
431 | 425 | $j( window ).keyup( function(event) { |
432 | 426 | // Escape check |
— | — | @@ -433,90 +427,91 @@ |
434 | 428 | _this.restoreWindowPlayer(); |
435 | 429 | } |
436 | 430 | } ); |
437 | | - }, |
438 | | - |
| 431 | + }, |
| 432 | + |
439 | 433 | /** |
440 | 434 | * Restore the window player |
441 | 435 | */ |
442 | | - restoreWindowPlayer: function() { |
| 436 | + restoreWindowPlayer: function() { |
443 | 437 | var _this = this; |
444 | 438 | var embedPlayer = this.embedPlayer; |
445 | | - |
| 439 | + |
446 | 440 | // Check fullscreen state |
447 | 441 | if( this.fullscreenMode == false ){ |
448 | | - return ; |
| 442 | + return ; |
449 | 443 | } |
450 | 444 | // Set fullscreen mode to false |
451 | 445 | this.fullscreenMode = false; |
452 | | - |
453 | | - var $interface = embedPlayer.$interface; |
454 | | - var interfaceHeight = ( _this.checkOverlayControls() ) |
455 | | - ? embedPlayer.getHeight() |
| 446 | + |
| 447 | + var $interface = embedPlayer.$interface; |
| 448 | + var interfaceHeight = ( _this.checkOverlayControls() ) |
| 449 | + ? embedPlayer.getHeight() |
456 | 450 | : embedPlayer.getHeight() + _this.getHeight(); |
457 | | - |
| 451 | + |
458 | 452 | mw.log( 'restoreWindowPlayer:: h:' + interfaceHeight + ' w:' + embedPlayer.getWidth()); |
459 | 453 | $j('.mw-fullscreen-overlay').fadeOut( 'slow' ); |
460 | | - |
461 | | - // Restore interface: |
| 454 | + |
| 455 | + // Restore interface: |
462 | 456 | $interface.animate( { |
463 | 457 | 'top' : this.windowOffset.top, |
464 | 458 | 'left' : this.windowOffset.left, |
465 | | - // height is embedPlayer height + controlBuilder height: |
| 459 | + // height is embedPlayer height + controlBuilder height: |
466 | 460 | 'height' : interfaceHeight, |
467 | | - 'width' : embedPlayer.getWidth() |
468 | | - },function(){ |
469 | | - // Restore non-absolute layout: |
| 461 | + 'width' : embedPlayer.getWidth() |
| 462 | + },function(){ |
| 463 | + // Restore non-absolute layout: |
470 | 464 | $interface.css( { |
471 | 465 | 'position' : _this.windowPositionStyle, |
472 | 466 | 'z-index' : _this.windowZindex, |
473 | 467 | 'overlow' : 'visible', |
474 | 468 | 'top' : null, |
475 | | - 'left' : null |
476 | | - } ); |
477 | | - |
478 | | - // Restore absolute layout of parents: |
479 | | - $j.each( _this.parentsAbsolute, function( na, element ){ |
| 469 | + 'left' : null |
| 470 | + } ); |
| 471 | + |
| 472 | + // Restore absolute layout of parents: |
| 473 | + $j.each( _this.parentsAbsolute, function( na, element ){ |
480 | 474 | $j( element ).css( 'position', 'absolute' ); |
481 | 475 | } ); |
482 | 476 | _this.parentsAbsolute = null; |
483 | | - |
| 477 | + |
484 | 478 | // Restore the body scroll bar |
485 | 479 | $j('body').css( 'overflow', 'auto' ); |
486 | | - |
487 | | - // Resize the timed text font size per window width |
| 480 | + |
| 481 | + // Resize the timed text font size per window width |
488 | 482 | $interface.find( '.track' ).css( _this.getInterfaceSizeTextCss() ); |
489 | | - |
| 483 | + |
490 | 484 | } ); |
491 | 485 | mw.log( 'restore embedPlayer:: ' + embedPlayer.getWidth() + ' h: ' + embedPlayer.getHeight()); |
492 | | - // Restore the player: |
| 486 | + // Restore the player: |
493 | 487 | $j( embedPlayer ).animate( { |
494 | 488 | 'top' : '0px', |
495 | 489 | 'left' : '0px', |
496 | 490 | 'width' : embedPlayer.getWidth(), |
497 | 491 | 'height' : embedPlayer.getHeight() |
498 | 492 | }); |
| 493 | + |
499 | 494 | // Restore the play button |
500 | 495 | $interface.find('.play-btn-large').animate( { |
501 | | - 'left' : ( ( embedPlayer.getPlayerWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
502 | | - 'top' : ( ( embedPlayer.getPlayerHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 ) |
| 496 | + 'left' : ( ( embedPlayer.getWidth() - this.getComponentWidth( 'playButtonLarge' ) ) / 2 ), |
| 497 | + 'top' : ( ( embedPlayer.getHeight() -this.getComponentHeight( 'playButtonLarge' ) ) / 2 ) |
503 | 498 | } ); |
504 | | - |
| 499 | + |
505 | 500 | }, |
506 | | - |
| 501 | + |
507 | 502 | /** |
508 | 503 | * Get minimal width for interface overlay |
509 | 504 | */ |
510 | 505 | getOverlayWidth: function( ) { |
511 | 506 | return ( this.embedPlayer.getPlayerWidth() < 300 )? 300 : this.embedPlayer.getPlayerWidth(); |
512 | | - }, |
513 | | - |
| 507 | + }, |
| 508 | + |
514 | 509 | /** |
515 | 510 | * Get minimal height for interface overlay |
516 | 511 | */ |
517 | 512 | getOverlayHeight: function( ) { |
518 | 513 | return ( this.embedPlayer.getPlayerHeight() < 200 )? 200 : this.embedPlayer.getPlayerHeight(); |
519 | 514 | }, |
520 | | - |
| 515 | + |
521 | 516 | /** |
522 | 517 | * addControlBindings |
523 | 518 | * Adds control hooks once controls are in the DOM |
— | — | @@ -524,28 +519,28 @@ |
525 | 520 | addControlBindings: function( ) { |
526 | 521 | // Set up local pointer to the embedPlayer |
527 | 522 | var embedPlayer = this.embedPlayer; |
528 | | - var _this = this; |
| 523 | + var _this = this; |
529 | 524 | var $interface = embedPlayer.$interface; |
530 | | - |
| 525 | + |
531 | 526 | // Remove any old interface bindings |
532 | 527 | $interface.unbind(); |
533 | | - |
534 | | - // Add hide show bindings for control overlay (if overlay is enabled ) |
| 528 | + |
| 529 | + // Add hide show bindings for control overlay (if overlay is enabled ) |
535 | 530 | if( ! _this.checkOverlayControls() ) { |
536 | | - $interface.show(); |
537 | | - } else { // hide show controls: |
| 531 | + $interface.show(); |
| 532 | + } else { // hide show controls: |
538 | 533 | //$interface.css({'background-color': 'red'}); |
539 | 534 | // Bind a startTouch to show controls |
540 | 535 | $interface.bind( 'touchstart', function() { |
541 | 536 | _this.showControlBar(); |
542 | | - // ( once the user touched the video "don't hide" ) |
543 | | - } ); |
544 | | - // Add a special absolute overlay for hover ( to keep menu displayed |
| 537 | + // ( once the user touched the video "don't hide" ) |
| 538 | + } ); |
| 539 | + // Add a special absolute overlay for hover ( to keep menu displayed |
545 | 540 | $interface.hoverIntent({ |
546 | 541 | 'sensitivity': 4, |
547 | 542 | 'timeout' : 2000, |
548 | | - 'over' : function(){ |
549 | | - // Show controls with a set timeout ( avoid fade in fade out on short mouse over ) |
| 543 | + 'over' : function(){ |
| 544 | + // Show controls with a set timeout ( avoid fade in fade out on short mouse over ) |
550 | 545 | _this.showControlBar(); |
551 | 546 | }, |
552 | 547 | 'out' : function(){ |
— | — | @@ -553,66 +548,66 @@ |
554 | 549 | } |
555 | 550 | }); |
556 | 551 | } |
557 | | - |
| 552 | + |
558 | 553 | // Add recommend firefox if we have non-native playback: |
559 | | - if ( _this.checkNativeWarning( ) ) { |
| 554 | + if ( _this.checkNativeWarning( ) ) { |
560 | 555 | _this.doWarningBindinng( |
561 | 556 | 'EmbedPlayer.ShowNativeWarning', |
562 | | - gM( 'mwe-embedplayer-for_best_experience' ) |
| 557 | + gM( 'mwe-embedplayer-for_best_experience' ) |
563 | 558 | ); |
564 | 559 | } |
565 | | - |
| 560 | + |
566 | 561 | // Do png fix for ie6 |
567 | | - if ( $j.browser.msie && $j.browser.version <= 6 ) { |
| 562 | + if ( $j.browser.msie && $j.browser.version <= 6 ) { |
568 | 563 | $j('#' + embedPlayer.id + ' .play-btn-large' ).pngFix(); |
569 | 564 | } |
570 | | - |
| 565 | + |
571 | 566 | this.doVolumeBinding(); |
572 | | - |
| 567 | + |
573 | 568 | // Check if we have any custom skin Bindings to run |
574 | 569 | if ( this.addSkinControlBindings && typeof( this.addSkinControlBindings ) == 'function' ){ |
575 | 570 | this.addSkinControlBindings(); |
576 | 571 | } |
577 | | - |
578 | | - mw.log('tirgger::addControlBindingsEvent'); |
| 572 | + |
| 573 | + mw.log('trigger::addControlBindingsEvent'); |
579 | 574 | $j( embedPlayer ).trigger( 'addControlBindingsEvent'); |
580 | 575 | }, |
581 | | - |
| 576 | + |
582 | 577 | /** |
583 | | - * Hide the control bar. |
| 578 | + * Hide the control bar. |
584 | 579 | */ |
585 | 580 | hideControlBar : function(){ |
586 | 581 | var animateDuration = 'slow'; |
587 | | - var _this = this; |
588 | | - |
| 582 | + var _this = this; |
| 583 | + |
589 | 584 | // Do not hide control bar if overlay menu item is being displayed: |
590 | | - if( _this.displayOptionsMenuFlag || |
| 585 | + if( _this.displayOptionsMenuFlag || |
591 | 586 | $j( '#timedTextMenu_' + this.embedPlayer.id ).is( ':visible' ) ) { |
592 | 587 | setTimeout( function(){ |
593 | 588 | _this.hideControlBar(); |
594 | 589 | }, 200 ); |
595 | 590 | return ; |
596 | 591 | } |
597 | | - |
598 | | - |
| 592 | + |
| 593 | + |
599 | 594 | // Hide the control bar |
600 | 595 | this.embedPlayer.$interface.find( '.control-bar') |
601 | 596 | .fadeOut( animateDuration ); |
602 | | - |
603 | | - // Move the timed text XXX this should go into timedText module |
| 597 | + |
| 598 | + // Move the timed text XXX this should go into timedText module |
604 | 599 | this.embedPlayer.$interface.find( '.track' ) |
605 | 600 | .stop() |
606 | | - .animate( { |
607 | | - 'bottom' : 10 |
| 601 | + .animate( { |
| 602 | + 'bottom' : 10 |
608 | 603 | }, 'slow' ); |
609 | | - |
| 604 | + |
610 | 605 | }, |
611 | | - |
| 606 | + |
612 | 607 | /** |
613 | 608 | * Show the control bar |
614 | 609 | */ |
615 | 610 | showControlBar: function(){ |
616 | | - var animateDuration = 'slow'; |
| 611 | + var animateDuration = 'slow'; |
617 | 612 | if(! this.embedPlayer ) |
618 | 613 | return ; |
619 | 614 | if( this.embedPlayer.getPlayerElement ){ |
— | — | @@ -621,105 +616,109 @@ |
622 | 617 | mw.log( 'PlayerControlBuilder:: ShowControlBar' ); |
623 | 618 | // Move up text track if present |
624 | 619 | this.embedPlayer.$interface.find( '.track' ) |
625 | | - .animate( |
626 | | - { |
627 | | - 'bottom' : this.getHeight() + 10 |
628 | | - }, |
| 620 | + .animate( |
| 621 | + { |
| 622 | + 'bottom' : this.getHeight() + 10 |
| 623 | + }, |
629 | 624 | animateDuration |
630 | | - ); |
631 | | - |
| 625 | + ); |
| 626 | + |
632 | 627 | // Show interface controls |
633 | 628 | this.embedPlayer.$interface.find( '.control-bar' ) |
634 | | - .fadeIn( animateDuration ); |
| 629 | + .fadeIn( animateDuration ); |
635 | 630 | }, |
636 | | - |
| 631 | + |
637 | 632 | /** |
638 | | - * Checks if the browser supports overlays and the controlsOverlay is |
| 633 | + * Checks if the browser supports overlays and the controlsOverlay is |
639 | 634 | * set to true for the player or via config |
640 | 635 | */ |
641 | 636 | checkOverlayControls: function(){ |
642 | | - //if the player "supports" overlays: |
| 637 | + |
| 638 | + //if the player "supports" overlays: |
643 | 639 | if( ! this.embedPlayer.supports['overlays'] ){ |
644 | 640 | return false; |
645 | 641 | } |
646 | | - |
| 642 | + |
647 | 643 | // If disabled via the player |
648 | 644 | if( this.embedPlayer.overlaycontrols === false ){ |
649 | 645 | return false; |
650 | | - } |
651 | | - |
| 646 | + } |
| 647 | + |
652 | 648 | // If the config is false |
653 | 649 | if( mw.getConfig( 'EmbedPlayer.OverlayControls' ) == false){ |
654 | 650 | return false; |
655 | | - } |
656 | | - |
657 | | - // don't hide controls when content "height" is 0 ( audio tags ) |
658 | | - if( this.embedPlayer.getPlayerHeight() == 0 ){ |
| 651 | + } |
| 652 | + |
| 653 | + // Don't hide controls when content "height" is 0px ( audio tags ) |
| 654 | + if( this.embedPlayer.getPlayerHeight() === 0 && |
| 655 | + $j(this.embedPlayer).css('height').indexOf('%') == -1 ){ |
659 | 656 | return false; |
660 | | - } |
| 657 | + } |
661 | 658 | if( this.embedPlayer.controls === false ){ |
662 | 659 | return false; |
663 | 660 | } |
664 | | - // Past all tests OverlayControls is true: |
665 | | - return true; |
| 661 | + // Past all tests OverlayControls is true: |
| 662 | + return true; |
666 | 663 | }, |
667 | | - |
| 664 | + |
668 | 665 | /** |
669 | | - * Check if a warning should be issued to non-native playback systems |
| 666 | + * Check if a warning should be issued to non-native playback systems |
670 | 667 | * |
671 | | - * dependent on mediaElement being setup |
672 | | - */ |
673 | | - checkNativeWarning: function( ) { |
| 668 | + * dependent on mediaElement being setup |
| 669 | + */ |
| 670 | + checkNativeWarning: function( ) { |
674 | 671 | if( mw.getConfig( 'EmbedPlayer.ShowNativeWarning' ) === false ){ |
675 | 672 | return false; |
676 | 673 | } |
677 | | - |
| 674 | + |
678 | 675 | // If the resolution is too small don't display the warning |
679 | 676 | if( this.embedPlayer.getPlayerHeight() < 199 ){ |
680 | 677 | return false; |
681 | | - } |
| 678 | + } |
682 | 679 | // See if we have we have ogg support |
683 | 680 | var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( 'video/ogg' ); |
684 | 681 | for ( var i = 0; i < supportingPlayers.length; i++ ) { |
685 | | - |
686 | | - if ( supportingPlayers[i].id == 'oggNative' |
687 | | - && |
| 682 | + |
| 683 | + if ( supportingPlayers[i].id == 'oggNative' |
| 684 | + && |
688 | 685 | // xxx google chrome has broken oggNative playback: |
689 | 686 | // http://code.google.com/p/chromium/issues/detail?id=56180 |
690 | | - ! /chrome/.test(navigator.userAgent.toLowerCase() ) |
| 687 | + ! /chrome/.test(navigator.userAgent.toLowerCase() ) |
691 | 688 | ){ |
692 | 689 | return false; |
693 | 690 | } |
694 | 691 | } |
695 | | - |
696 | | - // Check for h264 and or flash/flv source and playback support and don't show warning |
697 | | - if( |
698 | | - ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' ).length |
| 692 | + |
| 693 | + // Check for h264 and or flash/flv source and playback support and don't show warning |
| 694 | + if( |
| 695 | + ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/h264' ).length |
699 | 696 | && this.embedPlayer.mediaElement.getSources( 'video/h264' ).length ) |
700 | 697 | || |
701 | | - ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/x-flv' ).length |
702 | | - && this.embedPlayer.mediaElement.getSources( 'video/x-flv' ).length ) |
| 698 | + ( mw.EmbedTypes.players.getMIMETypePlayers( 'video/x-flv' ).length |
| 699 | + && this.embedPlayer.mediaElement.getSources( 'video/x-flv' ).length ) |
703 | 700 | ){ |
704 | 701 | // No firefox link if a h.264 or flash/flv stream is present |
705 | 702 | return false; |
706 | 703 | } |
707 | | - |
| 704 | + |
708 | 705 | // Should issue the native warning |
709 | 706 | return true; |
710 | 707 | }, |
711 | | - |
| 708 | + |
712 | 709 | /** |
713 | 710 | * Does a native warning check binding to the player on mouse over. |
714 | 711 | * @param {string} preferenceId The preference Id |
715 | | - * @param {object} warningMsg The jQuery object warning message to be displayed. |
716 | | - * |
| 712 | + * @param {object} warningMsg The jQuery object warning message to be displayed. |
| 713 | + * |
717 | 714 | */ |
718 | 715 | doWarningBindinng: function( preferenceId, warningMsg ) { |
719 | | - mw.log( 'controlBuilder: doWarningBindinng: ' + preferenceId + ' wm: ' + warningMsg); |
| 716 | + mw.log( 'controlBuilder: doWarningBindinng: ' + preferenceId + ' wm: ' + warningMsg); |
720 | 717 | // Set up local pointer to the embedPlayer |
721 | 718 | var embedPlayer = this.embedPlayer; |
722 | | - var _this = this; |
723 | | - |
| 719 | + var _this = this; |
| 720 | + |
| 721 | + // make sure the |
| 722 | + |
724 | 723 | $j( embedPlayer ).hoverIntent({ |
725 | 724 | 'timeout': 2000, |
726 | 725 | 'over': function() { |
— | — | @@ -727,12 +726,12 @@ |
728 | 727 | if( embedPlayer.isPlaying() ){ |
729 | 728 | return ; |
730 | 729 | } |
731 | | - if ( $j( '#warningOverlay_' + embedPlayer.id ).length == 0 ) { |
732 | | - |
| 730 | + if ( $j( '#warningOverlay_' + embedPlayer.id ).length == 0 ) { |
| 731 | + |
733 | 732 | $j( this ).append( |
734 | 733 | $j('<div />') |
735 | 734 | .attr( { |
736 | | - 'id': "warningOverlay_" + embedPlayer.id |
| 735 | + 'id': "warningOverlay_" + embedPlayer.id |
737 | 736 | } ) |
738 | 737 | .addClass( 'ui-state-highlight ui-corner-all' ) |
739 | 738 | .css({ |
— | — | @@ -745,64 +744,62 @@ |
746 | 745 | 'right' : '10px', |
747 | 746 | 'padding' : '4px' |
748 | 747 | }) |
749 | | - .html( warningMsg ) |
| 748 | + .html( warningMsg ) |
750 | 749 | ); |
751 | | - |
752 | | - $targetWarning = $j( '#warningOverlay_' + embedPlayer.id ); |
753 | | - |
754 | | - $targetWarning.append( |
| 750 | + |
| 751 | + $targetWarning = $j( '#warningOverlay_' + embedPlayer.id ); |
| 752 | + |
| 753 | + $targetWarning.append( |
755 | 754 | $j('<br />') |
756 | | - ); |
757 | | - |
758 | | - $targetWarning.append( |
| 755 | + ); |
| 756 | + |
| 757 | + $targetWarning.append( |
759 | 758 | $j( '<input />' ) |
760 | 759 | .attr({ |
761 | 760 | 'id' : 'ffwarn_' + embedPlayer.id, |
762 | 761 | 'type' : "checkbox", |
763 | 762 | 'name' : 'ffwarn_' + embedPlayer.id |
764 | | - }) |
| 763 | + }) |
765 | 764 | .click( function() { |
766 | | - if ( $j( this ).is( ':checked' ) ) { |
767 | | - // Set up a cookie for 7 days: |
768 | | - $j.cookie( preferenceId, false, { expires: 7 } ); |
769 | | - // Set the current instance |
770 | | - mw.setConfig( preferenceId, false ); |
771 | | - $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
772 | | - // set the local prefrence to false |
773 | | - _this.addWarningFlag = false; |
774 | | - } else { |
775 | | - mw.setConfig( preferenceId, true ); |
776 | | - $j.cookie( preferenceId, true ); |
777 | | - } |
778 | | - } ) |
| 765 | + mw.log("WarningBindinng:: set " + preferenceId + ' to hidewarning ' ); |
| 766 | + // Set up a cookie for 30 days: |
| 767 | + $j.cookie( preferenceId, 'hidewarning', { expires: 30 } ); |
| 768 | + // Set the current instance |
| 769 | + mw.setConfig( preferenceId, false ); |
| 770 | + $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
| 771 | + // set the local prefrence to false |
| 772 | + _this.addWarningFlag = false; |
| 773 | + } ) |
779 | 774 | ); |
780 | | - $targetWarning.append( |
781 | | - $j('<span />') |
| 775 | + $targetWarning.append( |
| 776 | + $j('<label />') |
782 | 777 | .text( gM( 'mwe-embedplayer-do_not_warn_again' ) ) |
| 778 | + .attr( 'for', 'ffwarn_' + embedPlayer.id ) |
783 | 779 | ); |
784 | | - } |
| 780 | + } |
785 | 781 | // Check the global config before showing the warning |
786 | | - if ( mw.getConfig( preferenceId ) === true ){ |
| 782 | + if ( mw.getConfig( preferenceId ) === true && $j.cookie( preferenceId ) != 'hidewarning' ){ |
| 783 | + mw.log("WarningBindinng:: show warning " + mw.getConfig( preferenceId ) + ' cookie: '+ $j.cookie( preferenceId ) + 'typeof:' + typeof $j.cookie( preferenceId )); |
787 | 784 | $j( '#warningOverlay_' + embedPlayer.id ).fadeIn( 'slow' ); |
788 | | - } |
| 785 | + }; |
789 | 786 | }, |
790 | | - 'out': function() { |
| 787 | + 'out': function() { |
791 | 788 | $j( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); |
792 | 789 | } |
793 | 790 | }); |
794 | 791 | }, |
795 | | - |
| 792 | + |
796 | 793 | /** |
797 | 794 | * Binds the volume controls |
798 | 795 | */ |
799 | 796 | doVolumeBinding: function( ) { |
800 | 797 | var embedPlayer = this.embedPlayer; |
801 | | - var _this = this; |
| 798 | + var _this = this; |
802 | 799 | embedPlayer.$interface.find( '.volume_control span' ).unbind().buttonHover().click( function() { |
803 | 800 | mw.log( 'Volume control toggle' ); |
804 | 801 | embedPlayer.toggleMute(); |
805 | 802 | } ); |
806 | | - |
| 803 | + |
807 | 804 | // Add vertical volume display hover |
808 | 805 | if ( this.volume_layout == 'vertical' ) { |
809 | 806 | // Default volume binding: |
— | — | @@ -828,7 +825,7 @@ |
829 | 826 | } |
830 | 827 | ); |
831 | 828 | } |
832 | | - |
| 829 | + |
833 | 830 | // Setup volume slider: |
834 | 831 | var sliderConf = { |
835 | 832 | range: "min", |
— | — | @@ -847,153 +844,153 @@ |
848 | 845 | } else { |
849 | 846 | embedPlayer.$interface.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' ); |
850 | 847 | } |
851 | | - mw.log('change::update volume:' + percent); |
| 848 | + mw.log('change::update volume:' + percent); |
852 | 849 | embedPlayer.setVolume( percent ); |
853 | 850 | } |
854 | 851 | }; |
855 | | - |
| 852 | + |
856 | 853 | if ( this.volume_layout == 'vertical' ) { |
857 | 854 | sliderConf[ 'orientation' ] = "vertical"; |
858 | 855 | } |
859 | | - |
| 856 | + |
860 | 857 | embedPlayer.$interface.find( '.volume-slider' ).slider( sliderConf ); |
861 | 858 | }, |
862 | | - |
| 859 | + |
863 | 860 | /** |
864 | 861 | * Get the options menu ul with li menu items |
865 | 862 | */ |
866 | 863 | getOptionsMenu: function( ) { |
867 | 864 | $optionsMenu = $j( '<ul />' ); |
868 | 865 | for( var i in this.optionMenuItems ){ |
869 | | - |
870 | | - // Make sure its supported in the current controlBuilder config: |
| 866 | + |
| 867 | + // Make sure its supported in the current controlBuilder config: |
871 | 868 | if( ! this.supportedMenuItems[ i ] ) { |
872 | 869 | continue; |
873 | 870 | } |
874 | | - |
| 871 | + |
875 | 872 | $optionsMenu.append( |
876 | 873 | this.optionMenuItems[i]( this ) |
877 | 874 | ); |
878 | | - } |
| 875 | + } |
879 | 876 | return $optionsMenu; |
880 | | - }, |
881 | | - |
| 877 | + }, |
| 878 | + |
882 | 879 | /** |
883 | 880 | * Allow the controlBuilder to do interface actions onDone |
884 | 881 | */ |
885 | 882 | onClipDone: function(){ |
886 | | - // Related videos could be shown here |
| 883 | + // Related videos could be shown here |
887 | 884 | }, |
888 | | - |
| 885 | + |
889 | 886 | /** |
890 | | - * The ctrl builder updates the interface on seeking |
| 887 | + * The ctrl builder updates the interface on seeking |
891 | 888 | */ |
892 | 889 | onSeek: function(){ |
893 | 890 | //mw.log( "controlBuilder:: onSeek" ); |
894 | | - // Update the interface: |
| 891 | + // Update the interface: |
895 | 892 | this.setStatus( gM( 'mwe-embedplayer-seeking' ) ); |
896 | 893 | }, |
897 | | - |
| 894 | + |
898 | 895 | /** |
899 | | - * Updates the player status that displays short text msgs and the play clock |
| 896 | + * Updates the player status that displays short text msgs and the play clock |
900 | 897 | * @param {String} value Status string value to update |
901 | 898 | */ |
902 | 899 | setStatus: function( value ) { |
903 | 900 | // update status: |
904 | 901 | this.embedPlayer.$interface.find( '.time-disp' ).text( value ); |
905 | 902 | }, |
906 | | - |
907 | | - /** |
| 903 | + |
| 904 | + /** |
908 | 905 | * Option menu items |
909 | 906 | * |
910 | 907 | * @return |
911 | | - * 'li' a li line item with click action for that menu item |
| 908 | + * 'li' a li line item with click action for that menu item |
912 | 909 | */ |
913 | | - optionMenuItems: { |
| 910 | + optionMenuItems: { |
914 | 911 | // Player select menu item |
915 | 912 | 'playerSelect': function( ctrlObj ){ |
916 | | - return $j.getLineItem( |
| 913 | + return $j.getLineItem( |
917 | 914 | gM( 'mwe-embedplayer-choose_player' ), |
918 | 915 | 'gear', |
919 | 916 | function( ) { |
920 | | - ctrlObj.displayMenuOverlay( |
| 917 | + ctrlObj.displayMenuOverlay( |
921 | 918 | ctrlObj.getPlayerSelect() |
922 | | - ); |
| 919 | + ); |
923 | 920 | } |
924 | 921 | ); |
925 | | - }, |
926 | | - |
| 922 | + }, |
| 923 | + |
927 | 924 | // Download the file menu |
928 | 925 | 'download': function( ctrlObj ) { |
929 | | - return $j.getLineItem( |
| 926 | + return $j.getLineItem( |
930 | 927 | gM( 'mwe-embedplayer-download' ), |
931 | 928 | 'disk', |
932 | 929 | function( ) { |
933 | | - ctrlObj.displayMenuOverlay( gM('mwe-loading_txt' ) ); |
| 930 | + ctrlObj.displayMenuOverlay( gM('mwe-loading_txt' ) ); |
934 | 931 | // Call show download with the target to be populated |
935 | | - ctrlObj.showDownload( |
936 | | - ctrlObj.embedPlayer.$interface.find( '.overlay-content' ) |
937 | | - ); |
| 932 | + ctrlObj.showDownload( |
| 933 | + ctrlObj.embedPlayer.$interface.find( '.overlay-content' ) |
| 934 | + ); |
938 | 935 | $j( ctrlObj.embedPlayer ).trigger( 'showDownloadEvent' ); |
939 | 936 | } |
940 | 937 | ); |
941 | | - }, |
942 | | - |
| 938 | + }, |
| 939 | + |
943 | 940 | // Share the video menu |
944 | 941 | 'share': function( ctrlObj ) { |
945 | | - return $j.getLineItem( |
| 942 | + return $j.getLineItem( |
946 | 943 | gM( 'mwe-embedplayer-share' ), |
947 | 944 | 'mail-closed', |
948 | 945 | function( ) { |
949 | | - ctrlObj.displayMenuOverlay( |
| 946 | + ctrlObj.displayMenuOverlay( |
950 | 947 | ctrlObj.getShare() |
951 | | - ); |
| 948 | + ); |
952 | 949 | $j( ctrlObj.embedPlayer ).trigger( 'showShareEvent' ); |
953 | 950 | } |
954 | 951 | ); |
955 | | - }, |
956 | | - |
| 952 | + }, |
| 953 | + |
957 | 954 | 'aboutPlayerLibrary' : function( ctrlObj ){ |
958 | | - return $j.getLineItem( |
| 955 | + return $j.getLineItem( |
959 | 956 | gM( 'mwe-embedplayer-about-library' ), |
960 | 957 | 'info', |
961 | 958 | function( ) { |
962 | | - ctrlObj.displayMenuOverlay( |
| 959 | + ctrlObj.displayMenuOverlay( |
963 | 960 | ctrlObj.aboutPlayerLibrary() |
964 | | - ); |
| 961 | + ); |
965 | 962 | $j( ctrlObj.embedPlayer ).trigger( 'aboutPlayerLibrary' ); |
966 | 963 | } |
967 | 964 | ); |
968 | 965 | } |
969 | 966 | }, |
970 | | - |
971 | | - /** |
972 | | - * Close a menu overlay |
| 967 | + |
| 968 | + /** |
| 969 | + * Close a menu overlay |
973 | 970 | */ |
974 | 971 | closeMenuOverlay: function(){ |
975 | | - var _this = this; |
| 972 | + var _this = this; |
976 | 973 | var embedPlayer = this.embedPlayer; |
977 | | - var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' ); |
978 | | - |
| 974 | + var $overlay = embedPlayer.$interface.find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' ); |
| 975 | + |
979 | 976 | this.displayOptionsMenuFlag = false; |
980 | 977 | mw.log(' closeMenuOverlay: ' + this.displayOptionsMenuFlag); |
981 | | - |
| 978 | + |
982 | 979 | $overlay.fadeOut( "slow", function() { |
983 | | - $overlay.remove(); |
| 980 | + $overlay.remove(); |
984 | 981 | } ); |
985 | | - // Show the big play button: |
| 982 | + // Show the big play button: |
986 | 983 | embedPlayer.$interface.find( '.play-btn-large' ).fadeIn( 'slow' ); |
987 | | - |
988 | | - |
| 984 | + |
| 985 | + |
989 | 986 | $j(embedPlayer).trigger( 'closeMenuOverlay' ); |
990 | | - |
| 987 | + |
991 | 988 | return false; // onclick action return false |
992 | 989 | }, |
993 | | - |
994 | | - /** |
995 | | - * Generic function to display custom HTML overlay |
| 990 | + |
| 991 | + /** |
| 992 | + * Generic function to display custom HTML overlay |
996 | 993 | * on video. |
997 | | - * |
| 994 | + * |
998 | 995 | * @param {String} overlayContent content to be displayed |
999 | 996 | */ |
1000 | 997 | displayMenuOverlay: function( overlayContent ) { |
— | — | @@ -1003,26 +1000,26 @@ |
1004 | 1001 | // set the overlay display flag to true: |
1005 | 1002 | this.displayOptionsMenuFlag = true; |
1006 | 1003 | mw.log(" set displayOptionsMenuFlag:: " + this.displayOptionsMenuFlag); |
1007 | | - |
| 1004 | + |
1008 | 1005 | if ( !this.supportedComponets[ 'overlays' ] ) { |
1009 | 1006 | embedPlayer.stop(); |
1010 | | - } |
| 1007 | + } |
1011 | 1008 | |
1012 | | - |
1013 | | - // Hide the big play button: |
1014 | | - embedPlayer.$interface.find( '.play-btn-large' ).hide(); |
1015 | | - |
1016 | | - // Check if overlay window is already present: |
| 1009 | + |
| 1010 | + // Hide the big play button: |
| 1011 | + embedPlayer.$interface.find( '.play-btn-large' ).hide(); |
| 1012 | + |
| 1013 | + // Check if overlay window is already present: |
1017 | 1014 | if ( embedPlayer.$interface.find( '.overlay-win' ).length != 0 ) { |
1018 | | - //Update the content |
| 1015 | + //Update the content |
1019 | 1016 | embedPlayer.$interface.find( '.overlay-content' ).html( |
1020 | 1017 | overlayContent |
1021 | 1018 | ); |
1022 | 1019 | return ; |
1023 | 1020 | } |
1024 | | - |
| 1021 | + |
1025 | 1022 | // Add an overlay |
1026 | | - embedPlayer.$interface.append( |
| 1023 | + embedPlayer.$interface.append( |
1027 | 1024 | $j('<div />') |
1028 | 1025 | .addClass( 'ui-widget-overlay' ) |
1029 | 1026 | .css( { |
— | — | @@ -1031,8 +1028,8 @@ |
1032 | 1029 | 'z-index' : 2 |
1033 | 1030 | } ) |
1034 | 1031 | ); |
1035 | | - |
1036 | | - // Setup the close button |
| 1032 | + |
| 1033 | + // Setup the close button |
1037 | 1034 | $closeButton = $j('<span />') |
1038 | 1035 | .addClass( 'ui-icon ui-icon-closethick' ) |
1039 | 1036 | .css({ |
— | — | @@ -1045,190 +1042,187 @@ |
1046 | 1043 | .click( function() { |
1047 | 1044 | _this.closeMenuOverlay(); |
1048 | 1045 | } ); |
1049 | | - |
| 1046 | + |
1050 | 1047 | var overlayMenuCss = { |
1051 | 1048 | 'height' : 200, |
1052 | | - 'width' : 250, |
| 1049 | + 'width' : 250, |
1053 | 1050 | 'position' : 'absolute', |
1054 | 1051 | 'left' : '10px', |
1055 | 1052 | 'top': '15px', |
1056 | 1053 | 'overflow' : 'auto', |
1057 | 1054 | 'padding' : '4px', |
1058 | 1055 | 'z-index' : 3 |
1059 | | - }; |
| 1056 | + }; |
1060 | 1057 | $overlayMenu = $j('<div />') |
1061 | 1058 | .addClass( 'overlay-win ui-state-default ui-widget-header ui-corner-all' ) |
1062 | 1059 | .css( overlayMenuCss ) |
1063 | 1060 | .append( |
1064 | 1061 | $closeButton, |
1065 | 1062 | $j('<div />') |
1066 | | - .addClass( 'overlay-content' ) |
| 1063 | + .addClass( 'overlay-content' ) |
1067 | 1064 | .append( overlayContent ) |
1068 | 1065 | ); |
1069 | | - |
1070 | | - // Clone the overlay menu css: |
| 1066 | + |
| 1067 | + // Clone the overlay menu css: |
1071 | 1068 | var shadowCss = jQuery.extend( true, {}, overlayMenuCss ); |
1072 | 1069 | shadowCss['height' ] = 210; |
1073 | 1070 | shadowCss['width' ] = 260; |
1074 | | - shadowCss[ 'z-index' ] = 2; |
| 1071 | + shadowCss[ 'z-index' ] = 2; |
1075 | 1072 | $overlayShadow = $j( '<div />' ) |
1076 | 1073 | .addClass('ui-widget-shadow ui-corner-all') |
1077 | 1074 | .css( shadowCss ); |
1078 | | - |
1079 | | - // Append the overlay menu to the player interface |
1080 | | - embedPlayer.$interface.prepend( |
| 1075 | + |
| 1076 | + // Append the overlay menu to the player interface |
| 1077 | + embedPlayer.$interface.prepend( |
1081 | 1078 | $overlayMenu, |
1082 | 1079 | $overlayShadow |
1083 | 1080 | ) |
1084 | 1081 | .find( '.overlay-win' ) |
1085 | | - .fadeIn( "slow" ); |
1086 | | - |
1087 | | - // trigger menu overlay display |
| 1082 | + .fadeIn( "slow" ); |
| 1083 | + |
| 1084 | + // trigger menu overlay display |
1088 | 1085 | $j(embedPlayer).trigger( 'displayMenuOverlay' ); |
1089 | | - |
| 1086 | + |
1090 | 1087 | return false; // onclick action return false |
1091 | | - }, |
| 1088 | + }, |
1092 | 1089 | aboutPlayerLibrary: function(){ |
1093 | 1090 | return $j( '<div />' ) |
1094 | 1091 | .append( |
1095 | 1092 | $j( '<h3 />' ) |
1096 | | - .text( |
1097 | | - gM('mwe-embedplayer-about-library') |
| 1093 | + .text( |
| 1094 | + gM('mwe-embedplayer-about-library') |
1098 | 1095 | ) |
1099 | 1096 | , |
1100 | 1097 | $j( '<span />') |
1101 | 1098 | .append( |
1102 | | - gM('mwe-embedplayer-about-library-desc', |
| 1099 | + gM('mwe-embedplayer-about-library-desc', |
1103 | 1100 | $j('<a />').attr({ |
1104 | 1101 | 'href' : mw.getConfig( 'EmbedPlayer.LibraryPage' ), |
1105 | 1102 | 'target' : '_new' |
1106 | 1103 | }) |
1107 | 1104 | ) |
1108 | | - ) |
| 1105 | + ) |
1109 | 1106 | ); |
1110 | 1107 | }, |
1111 | 1108 | /** |
1112 | 1109 | * Get the "share" interface |
1113 | | - * |
| 1110 | + * |
1114 | 1111 | * TODO share should be enabled via <embed> tag usage to be compatible |
1115 | 1112 | * with sites social networking sites that allow <embed> tags but not js |
1116 | | - * |
| 1113 | + * |
1117 | 1114 | * @param {Object} $target Target jQuery object to set share html |
1118 | 1115 | */ |
1119 | 1116 | getShare: function( ) { |
1120 | 1117 | var embedPlayer = this.embedPlayer; |
1121 | | - var embed_code = embedPlayer.getEmbeddingHTML(); |
| 1118 | + var embed_code = embedPlayer.getEmbeddingHTML(); |
1122 | 1119 | var _this = this; |
1123 | | - |
| 1120 | + |
1124 | 1121 | var $shareInterface = $j('<div />'); |
1125 | | - |
| 1122 | + |
1126 | 1123 | $shareList = $j( '<ul />' ); |
1127 | | - |
1128 | | - $shareList |
1129 | | - .append( |
| 1124 | + |
| 1125 | + $shareList |
| 1126 | + .append( |
1130 | 1127 | $j('<li />') |
1131 | | - .append( |
1132 | | - $j('<a />') |
1133 | | - .attr('href', '#') |
1134 | | - .addClass( 'active' ) |
1135 | | - .text( |
1136 | | - gM( 'mwe-embedplayer-embed_site_or_blog' ) |
1137 | | - ) |
1138 | | - ) |
1139 | | - ); |
1140 | | - |
1141 | | - $shareInterface.append( |
1142 | | - $j( '<h2 />' ) |
1143 | | - .text( gM( 'mwe-embedplayer-share_this_video' ) ) |
1144 | | - .append( |
1145 | | - $shareList |
1146 | | - ) |
1147 | | - ); |
1148 | | - |
1149 | | - $shareInterface.append( |
1150 | | - |
1151 | | - $j('<span />') |
1152 | | - .addClass( 'source_wrap' ) |
1153 | | - .html( |
1154 | | - $j( '<textarea />' ) |
1155 | | - .html( embed_code ) |
1156 | | - .click( function() { |
1157 | | - $j( this ).select(); |
1158 | | - }) |
1159 | | - ), |
1160 | | - |
1161 | | - $j('<br />'), |
1162 | | - $j('<br />'), |
1163 | | - |
1164 | | - $j('<button />') |
1165 | | - .addClass( 'ui-state-default ui-corner-all copycode' ) |
1166 | | - .text( gM( 'mwe-embedplayer-copy-code' ) ) |
1167 | | - .click(function() { |
1168 | | - $shareInterface.find( 'textarea' ).focus().select(); |
| 1128 | + .append( |
| 1129 | + $j('<a />') |
| 1130 | + .attr('href', '#') |
| 1131 | + .addClass( 'active' ) |
| 1132 | + .text( |
| 1133 | + gM( 'mwe-embedplayer-embed_site_or_blog' ) |
| 1134 | + ) |
| 1135 | + ) |
| 1136 | + ); |
| 1137 | + |
| 1138 | + $shareInterface.append( |
| 1139 | + $j( '<h2 />' ) |
| 1140 | + .text( gM( 'mwe-embedplayer-share_this_video' ) ) |
| 1141 | + .append( |
| 1142 | + $shareList |
| 1143 | + ) |
| 1144 | + ); |
| 1145 | + |
| 1146 | + $shareInterface.append( |
| 1147 | + |
| 1148 | + $j( '<textarea />' ) |
| 1149 | + .attr( 'rows', 1 ) |
| 1150 | + .html( embed_code ) |
| 1151 | + .click( function() { |
| 1152 | + $j( this ).select(); |
| 1153 | + }), |
| 1154 | + |
| 1155 | + $j('<br />'), |
| 1156 | + $j('<br />'), |
| 1157 | + |
| 1158 | + $j('<button />') |
| 1159 | + .addClass( 'ui-state-default ui-corner-all copycode' ) |
| 1160 | + .text( gM( 'mwe-embedplayer-copy-code' ) ) |
| 1161 | + .click(function() { |
| 1162 | + $shareInterface.find( 'textarea' ).focus().select(); |
1169 | 1163 | // Copy the text if supported: |
1170 | 1164 | if ( document.selection ) { |
1171 | 1165 | CopiedTxt = document.selection.createRange(); |
1172 | 1166 | CopiedTxt.execCommand( "Copy" ); |
1173 | 1167 | } |
1174 | 1168 | } ) |
1175 | | - |
| 1169 | + |
1176 | 1170 | ); |
1177 | 1171 | return $shareInterface; |
1178 | 1172 | }, |
1179 | | - |
| 1173 | + |
1180 | 1174 | /** |
1181 | 1175 | * Shows the Player Select interface |
1182 | | - * |
| 1176 | + * |
1183 | 1177 | * @param {Object} $target jQuery target for output |
1184 | 1178 | */ |
1185 | | - getPlayerSelect: function( ) { |
1186 | | - mw.log('ControlBuilder::getPlayerSelect: source:' + |
| 1179 | + getPlayerSelect: function( ) { |
| 1180 | + mw.log('ControlBuilder::getPlayerSelect: source:' + |
1187 | 1181 | this.embedPlayer.mediaElement.selectedSource.getSrc() + |
1188 | | - ' player: ' + this.embedPlayer.selectedPlayer.id ); |
1189 | | - |
| 1182 | + ' player: ' + this.embedPlayer.selectedPlayer.id ); |
| 1183 | + |
1190 | 1184 | var embedPlayer = this.embedPlayer; |
1191 | | - |
| 1185 | + |
1192 | 1186 | var _this = this; |
1193 | | - |
| 1187 | + |
1194 | 1188 | $playerSelect = $j('<div />') |
1195 | | - .append( |
| 1189 | + .append( |
1196 | 1190 | $j( '<h2 />' ) |
1197 | | - .text( gM( 'mwe-embedplayer-choose_player' ) ) |
1198 | | - ); |
| 1191 | + .text( gM( 'mwe-embedplayer-choose_player' ) ) |
| 1192 | + ); |
1199 | 1193 | |
1200 | 1194 | $j.each( embedPlayer.mediaElement.getPlayableSources(), function( sourceId, source ) { |
1201 | | - |
1202 | | - var isPlayable = (typeof mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() ) == 'object' ); |
1203 | | - var is_selected = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() ); |
1204 | | - |
1205 | | - $playerSelect.append( |
| 1195 | + |
| 1196 | + var isPlayable = (typeof mw.EmbedTypes.players.defaultPlayer( source.getMIMEType() ) == 'object' ); |
| 1197 | + var is_selected = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() ); |
| 1198 | + |
| 1199 | + $playerSelect.append( |
1206 | 1200 | $j( '<h2 />' ) |
1207 | 1201 | .text( source.getTitle() ) |
1208 | 1202 | ); |
1209 | | - |
| 1203 | + |
1210 | 1204 | if ( isPlayable ) { |
1211 | 1205 | $playerList = $j('<ul />'); |
1212 | 1206 | // output the player select code: |
1213 | | - |
| 1207 | + |
1214 | 1208 | var supportingPlayers = mw.EmbedTypes.players.getMIMETypePlayers( source.getMIMEType() ); |
1215 | 1209 | |
1216 | | - for ( var i = 0; i < supportingPlayers.length ; i++ ) { |
| 1210 | + for ( var i = 0; i < supportingPlayers.length ; i++ ) { |
1217 | 1211 | |
1218 | 1212 | // Add link to select the player if not already selected ) |
1219 | | - if( embedPlayer.selectedPlayer.id == supportingPlayers[i].id && is_selected ) { |
| 1213 | + if( embedPlayer.selectedPlayer.id == supportingPlayers[i].id && is_selected ) { |
1220 | 1214 | // Active player ( no link ) |
1221 | 1215 | $playerLine = $j( '<span />' ) |
1222 | | - .text( |
| 1216 | + .text( |
1223 | 1217 | supportingPlayers[i].getName() |
1224 | 1218 | ) |
1225 | | - .addClass( 'ui-state-highlight ui-corner-all' ); |
| 1219 | + .addClass( 'ui-state-highlight ui-corner-all' ); |
1226 | 1220 | } else { |
1227 | | - // Non active player add link to select: |
| 1221 | + // Non active player add link to select: |
1228 | 1222 | $playerLine = $j( '<a />') |
1229 | 1223 | .attr({ |
1230 | 1224 | 'href' : '#', |
1231 | 1225 | 'rel' : 'sel_source', |
1232 | | - 'id' : 'sc_' + sourceId + '_' + supportingPlayers[i].id |
| 1226 | + 'id' : 'sc_' + sourceId + '_' + supportingPlayers[i].id |
1233 | 1227 | }) |
1234 | 1228 | .addClass( 'ui-corner-all') |
1235 | 1229 | .text( supportingPlayers[i].getName() ) |
— | — | @@ -1236,26 +1230,26 @@ |
1237 | 1231 | var iparts = $j( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' ); |
1238 | 1232 | var sourceId = iparts[0]; |
1239 | 1233 | var player_id = iparts[1]; |
1240 | | - mw.log( 'source id: ' + sourceId + ' player id: ' + player_id ); |
1241 | | - |
| 1234 | + mw.log( 'source id: ' + sourceId + ' player id: ' + player_id ); |
| 1235 | + |
1242 | 1236 | embedPlayer.controlBuilder.closeMenuOverlay(); |
1243 | | - |
| 1237 | + |
1244 | 1238 | // Close fullscreen if we are in fullscreen mode |
1245 | 1239 | if( _this.fullscreenMode ){ |
1246 | 1240 | _this.restoreWindowPlayer(); |
1247 | 1241 | } |
1248 | | - |
| 1242 | + |
1249 | 1243 | embedPlayer.mediaElement.selectSource( sourceId ); |
1250 | 1244 | var playableSources = embedPlayer.mediaElement.getPlayableSources(); |
1251 | | - |
1252 | | - mw.EmbedTypes.players.setPlayerPreference( |
| 1245 | + |
| 1246 | + mw.EmbedTypes.players.setPlayerPreference( |
1253 | 1247 | player_id, |
1254 | | - playableSources[ sourceId ].getMIMEType() |
| 1248 | + playableSources[ sourceId ].getMIMEType() |
1255 | 1249 | ); |
1256 | | - |
| 1250 | + |
1257 | 1251 | // Issue a stop |
1258 | | - embedPlayer.stop(); |
1259 | | - |
| 1252 | + embedPlayer.stop(); |
| 1253 | + |
1260 | 1254 | // Don't follow the # link: |
1261 | 1255 | return false; |
1262 | 1256 | } ) |
— | — | @@ -1268,71 +1262,71 @@ |
1269 | 1263 | } |
1270 | 1264 | ); |
1271 | 1265 | } |
1272 | | - |
1273 | | - // Add the player line to the player list: |
| 1266 | + |
| 1267 | + // Add the player line to the player list: |
1274 | 1268 | $playerList.append( |
1275 | 1269 | $j( '<li />' ).append( |
1276 | 1270 | $playerLine |
1277 | 1271 | ) |
1278 | 1272 | ); |
1279 | 1273 | } |
1280 | | - |
1281 | | - // Append the player list: |
| 1274 | + |
| 1275 | + // Append the player list: |
1282 | 1276 | $playerSelect.append( $playerList ); |
1283 | | - |
| 1277 | + |
1284 | 1278 | } else { |
1285 | | - // No player available: |
1286 | | - $playerSelect.append( gM( 'mwe-embedplayer-no-player', source.getTitle() ) ); |
| 1279 | + // No player available: |
| 1280 | + $playerSelect.append( gM( 'mwe-embedplayer-no-player', source.getTitle() ) ); |
1287 | 1281 | } |
1288 | 1282 | } ); |
1289 | | - |
| 1283 | + |
1290 | 1284 | // Return the player select elements |
1291 | | - return $playerSelect; |
| 1285 | + return $playerSelect; |
1292 | 1286 | }, |
1293 | | - |
| 1287 | + |
1294 | 1288 | /** |
1295 | | - * Show the text interface library and show the text interface near the player. |
| 1289 | + * Show the text interface library and show the text interface near the player. |
1296 | 1290 | */ |
1297 | 1291 | showTextInterface: function() { |
1298 | 1292 | var _this = this; |
1299 | 1293 | var embedPlayer = this.embedPlayer; |
1300 | 1294 | var loc = embedPlayer.$interface.find( '.rButton.timed-text' ).offset(); |
1301 | | - mw.log('showTextInterface::' + embedPlayer.id + ' t' + loc.top + ' r' + loc.right); |
1302 | | - |
1303 | | - |
1304 | | - var $menu = $j( '#timedTextMenu_' + embedPlayer.id ); |
| 1295 | + mw.log('showTextInterface::' + embedPlayer.id + ' t' + loc.top + ' r' + loc.right); |
| 1296 | + |
| 1297 | + |
| 1298 | + var $menu = $j( '#timedTextMenu_' + embedPlayer.id ); |
1305 | 1299 | //This may be unnecessary .. we just need to show a spinner somewhere |
1306 | 1300 | if ( $menu.length != 0 ) { |
1307 | | - // Hide show the menu: |
| 1301 | + // Hide show the menu: |
1308 | 1302 | if( $menu.is( ':visible' ) ) { |
1309 | 1303 | $menu.hide( "fast" ); |
1310 | | - }else{ |
1311 | | - // move the menu to proper location |
| 1304 | + }else{ |
| 1305 | + // move the menu to proper location |
1312 | 1306 | $menu.show("fast"); |
1313 | | - } |
1314 | | - }else{ |
1315 | | - //Setup the menu: |
1316 | | - $j('body').append( |
1317 | | - $j('<div>') |
1318 | | - .addClass('ui-widget ui-widget-content ui-corner-all') |
1319 | | - .attr( 'id', 'timedTextMenu_' + embedPlayer.id ) |
| 1307 | + } |
| 1308 | + }else{ |
| 1309 | + //Setup the menu: |
| 1310 | + $j('body').append( |
| 1311 | + $j('<div>') |
| 1312 | + .addClass('ui-widget ui-widget-content ui-corner-all') |
| 1313 | + .attr( 'id', 'timedTextMenu_' + embedPlayer.id ) |
1320 | 1314 | .css( { |
1321 | 1315 | 'position' : 'absolute', |
1322 | 1316 | 'z-index' : 10, |
1323 | 1317 | 'height' : '180px', |
1324 | | - 'width' : '180px', |
| 1318 | + 'width' : '180px', |
1325 | 1319 | 'font-size' : '12px', |
1326 | | - 'display' : 'none' |
| 1320 | + 'display' : 'none' |
1327 | 1321 | } ) |
1328 | | - |
1329 | | - ); |
| 1322 | + |
| 1323 | + ); |
1330 | 1324 | // Load text interface ( if not already loaded ) |
1331 | | - mw.load( 'TimedText', function() { |
1332 | | - $j( '#' + embedPlayer.id ).timedText( 'showMenu', '#timedTextMenu_' + embedPlayer.id ); |
1333 | | - }); |
1334 | | - } |
| 1325 | + mw.load( 'TimedText', function() { |
| 1326 | + $j( '#' + embedPlayer.id ).timedText( 'showMenu', '#timedTextMenu_' + embedPlayer.id ); |
| 1327 | + }); |
| 1328 | + } |
1335 | 1329 | }, |
1336 | | - |
| 1330 | + |
1337 | 1331 | /** |
1338 | 1332 | * Loads sources and calls showDownloadWithSources |
1339 | 1333 | * @param {Object} $target jQuery target to output to |
— | — | @@ -1340,21 +1334,21 @@ |
1341 | 1335 | showDownload: function( $target ) { |
1342 | 1336 | var _this = this; |
1343 | 1337 | var embedPlayer = this.embedPlayer; |
1344 | | - |
1345 | | - // Load the roe if available (to populate out download options: |
| 1338 | + |
| 1339 | + // Load the roe if available (to populate out download options: |
1346 | 1340 | // mw.log('f:showDownload '+ this.roe + ' ' + this.mediaElement.addedROEData); |
1347 | 1341 | if ( embedPlayer.roe && embedPlayer.mediaElement.addedROEData == false ) { |
1348 | 1342 | $target.html( gM( 'mwe-loading_txt' ) ); |
1349 | 1343 | embedPlayer.getMvJsonUrl( this.roe, function( data ) { |
1350 | | - embedPlayer.mediaElement.addROE( data ); |
1351 | | - _this.showDownloadWithSources( $target ); |
| 1344 | + embedPlayer.mediaElement.addROE( data ); |
| 1345 | + _this.showDownloadWithSources( $target ); |
1352 | 1346 | } ); |
1353 | | - |
1354 | | - // Load additional text sources via apiTitleKey: |
| 1347 | + |
| 1348 | + // Load additional text sources via apiTitleKey: |
1355 | 1349 | // @@ todo we should move this to timedText bindings |
1356 | 1350 | } else if( embedPlayer.apiTitleKey ) { |
1357 | 1351 | // Load text interface ( if not already loaded ) |
1358 | | - mw.load( 'TimedText', function() { |
| 1352 | + mw.load( 'TimedText', function() { |
1359 | 1353 | embedPlayer.timedText.setupTextSources(function(){ |
1360 | 1354 | _this.showDownloadWithSources( $target ); |
1361 | 1355 | }); |
— | — | @@ -1363,7 +1357,7 @@ |
1364 | 1358 | _this.showDownloadWithSources( $target ); |
1365 | 1359 | } |
1366 | 1360 | }, |
1367 | | - |
| 1361 | + |
1368 | 1362 | /** |
1369 | 1363 | * Shows the download interface with sources loaded |
1370 | 1364 | * @param {Object} $target jQuery target to output to |
— | — | @@ -1374,19 +1368,19 @@ |
1375 | 1369 | var embedPlayer = this.embedPlayer; |
1376 | 1370 | // Empty the target: |
1377 | 1371 | $target.empty(); |
1378 | | - |
| 1372 | + |
1379 | 1373 | var $mediaList = $j( '<ul />' ); |
1380 | | - var $textList = $j( '<ul />' ); |
| 1374 | + var $textList = $j( '<ul />' ); |
1381 | 1375 | $j.each( embedPlayer.mediaElement.getSources(), function( index, source ) { |
1382 | | - if( source.getSrc() ) { |
1383 | | - mw.log("showDownloadWithSources:: Add src: " + source.getTitle() ); |
| 1376 | + if( source.getSrc() ) { |
| 1377 | + mw.log("showDownloadWithSources:: Add src: " + source.getTitle() ); |
1384 | 1378 | var $dl_line = $j( '<li />').append( |
1385 | | - $j('<a />') |
| 1379 | + $j('<a />') |
1386 | 1380 | .attr( 'href', source.getSrc() ) |
1387 | | - .text( source.getTitle() ) |
1388 | | - ); |
1389 | | - // Add link to correct "bucket" |
1390 | | - |
| 1381 | + .text( source.getTitle() ) |
| 1382 | + ); |
| 1383 | + // Add link to correct "bucket" |
| 1384 | + |
1391 | 1385 | //Add link to time segment: |
1392 | 1386 | if ( source.getSrc().indexOf( '?t=' ) !== -1 ) { |
1393 | 1387 | $target.append( $dl_line ); |
— | — | @@ -1397,7 +1391,7 @@ |
1398 | 1392 | // Add link to media list |
1399 | 1393 | $mediaList.append( $dl_line ); |
1400 | 1394 | } |
1401 | | - |
| 1395 | + |
1402 | 1396 | } |
1403 | 1397 | } ); |
1404 | 1398 | if( $mediaList.find('li').length != 0 ) { |
— | — | @@ -1407,17 +1401,17 @@ |
1408 | 1402 | $mediaList |
1409 | 1403 | ); |
1410 | 1404 | } |
1411 | | - |
| 1405 | + |
1412 | 1406 | if( $textList.find('li').length != 0 ) { |
1413 | 1407 | $target.append( |
1414 | 1408 | $j('<h2 />') |
1415 | 1409 | .html( gM( 'mwe-embedplayer-download_text' ) ), |
1416 | 1410 | $textList |
1417 | 1411 | ); |
1418 | | - } |
| 1412 | + } |
1419 | 1413 | }, |
1420 | | - |
1421 | | - |
| 1414 | + |
| 1415 | + |
1422 | 1416 | /** |
1423 | 1417 | * Get component |
1424 | 1418 | * |
— | — | @@ -1430,39 +1424,39 @@ |
1431 | 1425 | return false; |
1432 | 1426 | } |
1433 | 1427 | }, |
1434 | | - |
| 1428 | + |
1435 | 1429 | /** |
1436 | 1430 | * Get a component height |
1437 | | - * |
| 1431 | + * |
1438 | 1432 | * @param {String} component_id Component key to grab height |
1439 | 1433 | * @return height or false if not set |
1440 | 1434 | */ |
1441 | 1435 | getComponentHeight: function( component_id ) { |
1442 | | - if ( this.components[ component_id ] |
1443 | | - && this.components[ component_id ].h ) |
| 1436 | + if ( this.components[ component_id ] |
| 1437 | + && this.components[ component_id ].h ) |
1444 | 1438 | { |
1445 | 1439 | return this.components[ component_id ].h; |
1446 | 1440 | } |
1447 | 1441 | return false; |
1448 | 1442 | }, |
1449 | | - |
| 1443 | + |
1450 | 1444 | /** |
1451 | 1445 | * Get a component width |
1452 | 1446 | * @param {String} component_id Component key to grab width |
1453 | 1447 | * @return width or false if not set |
1454 | 1448 | */ |
1455 | 1449 | getComponentWidth: function( component_id ){ |
1456 | | - if ( this.components[ component_id ] |
1457 | | - && this.components[ component_id ].w ) |
| 1450 | + if ( this.components[ component_id ] |
| 1451 | + && this.components[ component_id ].w ) |
1458 | 1452 | { |
1459 | 1453 | return this.components[ component_id ].w; |
1460 | 1454 | } |
1461 | 1455 | return false; |
1462 | 1456 | }, |
1463 | | - |
| 1457 | + |
1464 | 1458 | /** |
1465 | 1459 | * Components Object |
1466 | | - * Take in the embedPlayer and return some html for the given component. |
| 1460 | + * Take in the embedPlayer and return some html for the given component. |
1467 | 1461 | * |
1468 | 1462 | * components can be overwritten by skin javascript |
1469 | 1463 | * |
— | — | @@ -1471,15 +1465,15 @@ |
1472 | 1466 | * 'w' The width of the component |
1473 | 1467 | * 'h' The height of the component ( if height is undefined the height of the control bar is used ) |
1474 | 1468 | */ |
1475 | | - components: { |
| 1469 | + components: { |
1476 | 1470 | /** |
1477 | 1471 | * The large play button in center of the player |
1478 | 1472 | */ |
1479 | 1473 | 'playButtonLarge': { |
1480 | 1474 | 'w' : 130, |
1481 | 1475 | 'h' : 96, |
1482 | | - 'o' : function( ctrlObj ) { |
1483 | | - |
| 1476 | + 'o' : function( ctrlObj ) { |
| 1477 | + |
1484 | 1478 | return $j( '<div/>' ) |
1485 | 1479 | .attr( { |
1486 | 1480 | 'title' : gM( 'mwe-embedplayer-play_clip' ), |
— | — | @@ -1494,31 +1488,31 @@ |
1495 | 1489 | .buttonHover().click( function() { |
1496 | 1490 | ctrlObj.embedPlayer.play(); |
1497 | 1491 | } ); |
1498 | | - } |
| 1492 | + } |
1499 | 1493 | }, |
1500 | | - |
| 1494 | + |
1501 | 1495 | /** |
1502 | 1496 | * The Attribution button ( by default this is kaltura-icon |
1503 | 1497 | */ |
1504 | 1498 | 'attributionButton' : { |
1505 | 1499 | 'w' : 28, |
1506 | | - 'o' : function( ctrlObj ){ |
| 1500 | + 'o' : function( ctrlObj ){ |
1507 | 1501 | var buttonConfig = mw.getConfig( 'EmbedPlayer.AttributionButton'); |
1508 | | - |
| 1502 | + |
1509 | 1503 | var $icon = $j('<span />') |
1510 | 1504 | .addClass( 'ui-icon' ); |
1511 | 1505 | if( buttonConfig['class'] ){ |
1512 | 1506 | $icon.addClass( buttonConfig['class'] ); |
1513 | | - } |
| 1507 | + } |
1514 | 1508 | // Check for source ( by configuration convention this is a 16x16 image |
1515 | 1509 | if( buttonConfig.iconurl ){ |
1516 | | - $icon.append( |
| 1510 | + $icon.append( |
1517 | 1511 | $j('<img />') |
1518 | 1512 | .css({'width': '16px', 'height': '16px'}) |
1519 | 1513 | .attr('src', buttonConfig.iconurl ) |
1520 | 1514 | ); |
1521 | 1515 | } |
1522 | | - |
| 1516 | + |
1523 | 1517 | return $j('<a />') |
1524 | 1518 | .attr({ |
1525 | 1519 | 'href': buttonConfig.href, |
— | — | @@ -1532,13 +1526,13 @@ |
1533 | 1527 | 'top' : '9px', |
1534 | 1528 | 'left' : '2px' |
1535 | 1529 | }) |
1536 | | - .append( |
| 1530 | + .append( |
1537 | 1531 | $icon |
1538 | 1532 | ) |
1539 | | - ); |
| 1533 | + ); |
1540 | 1534 | } |
1541 | 1535 | }, |
1542 | | - |
| 1536 | + |
1543 | 1537 | /** |
1544 | 1538 | * The options button, invokes display of the options menu |
1545 | 1539 | */ |
— | — | @@ -1546,39 +1540,39 @@ |
1547 | 1541 | 'w': 28, |
1548 | 1542 | 'o': function( ctrlObj ) { |
1549 | 1543 | return $j( '<div />' ) |
1550 | | - .attr( 'title', gM( 'mwe-embedplayer-player_options' ) ) |
| 1544 | + .attr( 'title', gM( 'mwe-embedplayer-player_options' ) ) |
1551 | 1545 | .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton options-btn' ) |
1552 | | - .append( |
| 1546 | + .append( |
1553 | 1547 | $j('<span />') |
1554 | 1548 | .addClass( 'ui-icon ui-icon-wrench' ) |
1555 | | - ) |
1556 | | - .buttonHover() |
1557 | | - // Options binding: |
| 1549 | + ) |
| 1550 | + .buttonHover() |
| 1551 | + // Options binding: |
1558 | 1552 | .menu( { |
1559 | 1553 | 'content' : ctrlObj.getOptionsMenu(), |
1560 | | - 'zindex' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1, |
| 1554 | + 'zindex' : mw.getConfig( 'EmbedPlayer.fullScreenZIndex' ) + 1, |
1561 | 1555 | 'positionOpts': { |
1562 | | - 'directionV' : 'up', |
| 1556 | + 'directionV' : 'up', |
1563 | 1557 | 'offsetY' : 30, |
1564 | 1558 | 'directionH' : 'left', |
1565 | 1559 | 'offsetX' : -28 |
1566 | | - } |
1567 | | - } ); |
| 1560 | + } |
| 1561 | + } ); |
1568 | 1562 | } |
1569 | 1563 | }, |
1570 | | - |
| 1564 | + |
1571 | 1565 | /** |
1572 | 1566 | * The fullscreen button for displaying the video fullscreen |
1573 | 1567 | */ |
1574 | 1568 | 'fullscreen': { |
1575 | 1569 | 'w': 28, |
1576 | 1570 | 'o': function( ctrlObj ) { |
1577 | | - |
1578 | | - // Setup "dobuleclick" fullscreen binding to embedPlayer |
| 1571 | + |
| 1572 | + // Setup "dobuleclick" fullscreen binding to embedPlayer |
1579 | 1573 | $j( ctrlObj.embedPlayer ).unbind("dblclick").bind("dblclick", function(){ |
1580 | | - ctrlObj.embedPlayer.fullscreen(); |
1581 | | - }); |
1582 | | - |
| 1574 | + ctrlObj.embedPlayer.fullscreen(); |
| 1575 | + }); |
| 1576 | + |
1583 | 1577 | return $j( '<div />' ) |
1584 | 1578 | .attr( 'title', gM( 'mwe-embedplayer-player_fullscreen' ) ) |
1585 | 1579 | .addClass( "ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn" ) |
— | — | @@ -1593,8 +1587,8 @@ |
1594 | 1588 | } ); |
1595 | 1589 | } |
1596 | 1590 | }, |
1597 | | - |
1598 | | - |
| 1591 | + |
| 1592 | + |
1599 | 1593 | /** |
1600 | 1594 | * The pause / play button |
1601 | 1595 | */ |
— | — | @@ -1604,18 +1598,18 @@ |
1605 | 1599 | return $j( '<div />' ) |
1606 | 1600 | .attr( 'title', gM( 'mwe-embedplayer-play_clip' ) ) |
1607 | 1601 | .addClass ( "ui-state-default ui-corner-all ui-icon_link lButton play-btn" ) |
1608 | | - .append( |
| 1602 | + .append( |
1609 | 1603 | $j( '<span />' ) |
1610 | 1604 | .addClass( "ui-icon ui-icon-play" ) |
1611 | 1605 | ) |
1612 | 1606 | // Play / pause binding |
1613 | 1607 | .buttonHover() |
1614 | 1608 | .click( function() { |
1615 | | - ctrlObj.embedPlayer.play(); |
| 1609 | + ctrlObj.embedPlayer.play(); |
1616 | 1610 | }); |
1617 | 1611 | } |
1618 | 1612 | }, |
1619 | | - |
| 1613 | + |
1620 | 1614 | /** |
1621 | 1615 | * The closed captions button |
1622 | 1616 | */ |
— | — | @@ -1625,19 +1619,19 @@ |
1626 | 1620 | return $j( '<div />' ) |
1627 | 1621 | .attr( 'title', gM( 'mwe-embedplayer-timed_text' ) ) |
1628 | 1622 | .addClass( "ui-state-default ui-corner-all ui-icon_link rButton timed-text" ) |
1629 | | - .append( |
| 1623 | + .append( |
1630 | 1624 | $j( '<span />' ) |
1631 | 1625 | .addClass( "ui-icon ui-icon-comment" ) |
1632 | 1626 | ) |
1633 | 1627 | // Captions binding: |
1634 | 1628 | .buttonHover() |
1635 | | - .click( function() { |
| 1629 | + .click( function() { |
1636 | 1630 | ctrlObj.showTextInterface(); |
1637 | | - } ); |
| 1631 | + } ); |
1638 | 1632 | } |
1639 | 1633 | }, |
1640 | | - |
1641 | | - /** |
| 1634 | + |
| 1635 | + /** |
1642 | 1636 | * The volume control interface html |
1643 | 1637 | */ |
1644 | 1638 | 'volumeControl': { |
— | — | @@ -1646,42 +1640,42 @@ |
1647 | 1641 | mw.log( 'PlayerControlBuilder::Set up volume control for: ' + ctrlObj.embedPlayer.id ); |
1648 | 1642 | $volumeOut = $j( '<span />' ); |
1649 | 1643 | if ( ctrlObj.volume_layout == 'horizontal' ) { |
1650 | | - $volumeOut.append( |
| 1644 | + $volumeOut.append( |
1651 | 1645 | $j( '<div />' ) |
1652 | 1646 | .addClass( "ui-slider ui-slider-horizontal rButton volume-slider" ) |
1653 | 1647 | ); |
1654 | 1648 | } |
1655 | | - |
| 1649 | + |
1656 | 1650 | // Add the volume control icon |
1657 | | - $volumeOut.append( |
| 1651 | + $volumeOut.append( |
1658 | 1652 | $j('<div />') |
1659 | 1653 | .attr( 'title', gM( 'mwe-embedplayer-volume_control' ) ) |
1660 | 1654 | .addClass( "ui-state-default ui-corner-all ui-icon_link rButton volume_control" ) |
1661 | | - .append( |
| 1655 | + .append( |
1662 | 1656 | $j( '<span />' ) |
1663 | 1657 | .addClass( "ui-icon ui-icon-volume-on" ) |
1664 | 1658 | ) |
1665 | | - ); |
| 1659 | + ); |
1666 | 1660 | if ( ctrlObj.volume_layout == 'vertical' ) { |
1667 | | - $volumeOut.find('.volume_control').append( |
| 1661 | + $volumeOut.find('.volume_control').append( |
1668 | 1662 | $j( '<div />' ) |
1669 | 1663 | .css( { |
1670 | | - 'position' : 'absolute', |
| 1664 | + 'position' : 'absolute', |
1671 | 1665 | 'left' : '0px' |
1672 | 1666 | }) |
1673 | 1667 | .hide() |
1674 | 1668 | .addClass( "vol_container ui-corner-all" ) |
1675 | | - .append( |
| 1669 | + .append( |
1676 | 1670 | $j( '<div />' ) |
1677 | 1671 | .addClass ( "volume-slider" ) |
1678 | 1672 | ) |
1679 | 1673 | ); |
1680 | | - } |
1681 | | - //Return the inner html |
| 1674 | + } |
| 1675 | + //Return the inner html |
1682 | 1676 | return $volumeOut.html(); |
1683 | 1677 | } |
1684 | 1678 | }, |
1685 | | - |
| 1679 | + |
1686 | 1680 | /* |
1687 | 1681 | * The time display area |
1688 | 1682 | */ |
— | — | @@ -1690,12 +1684,12 @@ |
1691 | 1685 | 'o' : function( ctrlObj ) { |
1692 | 1686 | return $j( '<div />' ) |
1693 | 1687 | .addClass( "ui-widget time-disp" ) |
1694 | | - .append( |
| 1688 | + .append( |
1695 | 1689 | ctrlObj.embedPlayer.getTimeRange() |
1696 | 1690 | ); |
1697 | 1691 | } |
1698 | 1692 | }, |
1699 | | - |
| 1693 | + |
1700 | 1694 | /** |
1701 | 1695 | * The playhead component |
1702 | 1696 | */ |
— | — | @@ -1706,11 +1700,11 @@ |
1707 | 1701 | var _this = this; |
1708 | 1702 | var $playHead = $j( '<div />' ) |
1709 | 1703 | .addClass ( "play_head" ) |
1710 | | - .css({ |
| 1704 | + .css({ |
1711 | 1705 | "position" : 'absolute', |
1712 | 1706 | "left" : '33px', |
1713 | | - "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px' |
1714 | | - }) |
| 1707 | + "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.available_width ) - 33) + 'px' |
| 1708 | + }) |
1715 | 1709 | // Playhead binding |
1716 | 1710 | .slider( { |
1717 | 1711 | range: "min", |
— | — | @@ -1728,7 +1722,7 @@ |
1729 | 1723 | slide: function( event, ui ) { |
1730 | 1724 | var perc = ui.value / 1000; |
1731 | 1725 | embedPlayer.jump_time = mw.seconds2npt( parseFloat( parseFloat( embedPlayer.getDuration() ) * perc ) + embedPlayer.start_time_sec ); |
1732 | | - // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time); |
| 1726 | + // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jump_time); |
1733 | 1727 | if ( _this.longTimeDisp ) { |
1734 | 1728 | ctrlObj.setStatus( gM( 'mwe-embedplayer-seek_to', embedPlayer.jump_time ) ); |
1735 | 1729 | } else { |
— | — | @@ -1740,12 +1734,12 @@ |
1741 | 1735 | } |
1742 | 1736 | }, |
1743 | 1737 | change:function( event, ui ) { |
1744 | | - // Only run the onChange event if done by a user slide |
| 1738 | + // Only run the onChange event if done by a user slide |
1745 | 1739 | // (otherwise it runs times it should not) |
1746 | 1740 | if ( embedPlayer.userSlide ) { |
1747 | 1741 | embedPlayer.userSlide = false; |
1748 | 1742 | embedPlayer.seeking = true; |
1749 | | - |
| 1743 | + |
1750 | 1744 | var perc = ui.value / 1000; |
1751 | 1745 | // set seek time (in case we have to do a url seek) |
1752 | 1746 | embedPlayer.seek_time_sec = mw.npt2seconds( embedPlayer.jump_time, true ); |
— | — | @@ -1755,19 +1749,19 @@ |
1756 | 1750 | } |
1757 | 1751 | } |
1758 | 1752 | } ); |
1759 | | - |
| 1753 | + |
1760 | 1754 | // Up the z-index of the default status indicator: |
1761 | 1755 | $playHead.find( '.ui-slider-handle' ).css( 'z-index', 4 ); |
1762 | 1756 | $playHead.find( '.ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 ); |
1763 | | - |
1764 | | - // Add buffer html: |
1765 | | - $playHead.append( |
| 1757 | + |
| 1758 | + // Add buffer html: |
| 1759 | + $playHead.append( |
1766 | 1760 | $j('<div />') |
1767 | 1761 | .addClass( "ui-slider-range ui-slider-range-min ui-widget-header") |
1768 | 1762 | .addClass( "ui-state-highlight ui-corner-all mw_buffer") |
1769 | 1763 | ); |
1770 | | - |
1771 | | - return $playHead; |
| 1764 | + |
| 1765 | + return $playHead; |
1772 | 1766 | } |
1773 | 1767 | } |
1774 | 1768 | } |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/skins/mvpcf/mw.style.PlayerSkinMvpcf.css |
— | — | @@ -1,5 +1,5 @@ |
2 | 2 | /** |
3 | | - * reference player skin |
| 3 | + * reference player skin |
4 | 4 | */ |
5 | 5 | |
6 | 6 | |
— | — | @@ -18,8 +18,8 @@ |
19 | 19 | height: 305px; |
20 | 20 | } |
21 | 21 | .mv-player .control-bar { |
22 | | - height: 29px; |
23 | | - z-index: 2; |
| 22 | + height: 29px; |
| 23 | + z-index: 2; |
24 | 24 | } |
25 | 25 | .mv-player .controlInnerSmall { |
26 | 26 | /* width: 430px;*/ |
— | — | @@ -55,7 +55,7 @@ |
56 | 56 | width: 22px; |
57 | 57 | height: 29px; |
58 | 58 | padding: 0 0 0 0; |
59 | | - |
| 59 | + |
60 | 60 | } |
61 | 61 | |
62 | 62 | .mv-player .vol_container{ |
— | — | @@ -72,18 +72,18 @@ |
73 | 73 | top:-77px; |
74 | 74 | } |
75 | 75 | .mv-player .vol_container .volume-slider{ |
76 | | - margin-top:5px; |
| 76 | + margin-top:5px; |
77 | 77 | height:65px; |
78 | 78 | width:10px; |
79 | 79 | margin-left: auto ; |
80 | | - margin-right: auto ; |
| 80 | + margin-right: auto ; |
81 | 81 | } |
82 | 82 | .mv-player .vol_container .ui-slider-handle{ |
83 | 83 | cursor : pointer; |
84 | 84 | width:10px; |
85 | | - height:10px; |
| 85 | + height:10px; |
86 | 86 | position:absolute; |
87 | | - left:-1px; |
| 87 | + left:-1px; |
88 | 88 | } |
89 | 89 | |
90 | 90 | .mv-player .time-disp { |
— | — | @@ -99,23 +99,23 @@ |
100 | 100 | |
101 | 101 | .mv-player .play_head{ |
102 | 102 | float: left; |
103 | | - display: inline; |
| 103 | + display: inline; |
104 | 104 | height: 10px; |
105 | 105 | margin-left:8px; |
106 | 106 | margin-top:10px; |
107 | | - position:relative; |
| 107 | + position:relative; |
108 | 108 | } |
109 | 109 | |
110 | 110 | .mv-player .play_head .ui-slider-handle{ |
111 | 111 | width:10px; |
112 | 112 | height:15px; |
113 | 113 | margin-left:-5px; |
114 | | - margin-top: -0px; |
| 114 | + margin-top: -0px; |
115 | 115 | z-index: 2; |
116 | 116 | } |
117 | 117 | |
118 | 118 | .mv-player .inOutSlider .ui-slider-handle{ |
119 | | - width:8px; |
| 119 | + width:8px; |
120 | 120 | cusror: move; |
121 | 121 | } |
122 | 122 | |
— | — | @@ -152,7 +152,7 @@ |
153 | 153 | |
154 | 154 | .mv-player .overlay-win{ |
155 | 155 | font-family : arial,sans-serif; |
156 | | - font-size : 85%; |
| 156 | + font-size : 85%; |
157 | 157 | } |
158 | 158 | .mv-player .overlay-win a{ |
159 | 159 | text-decoration: none; |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/EmbedPlayer.resources.php |
— | — | @@ -25,4 +25,4 @@ |
26 | 26 | |
27 | 27 | "mw.PlayerSkinMvpcf" => array( 'scripts'=> "skins/mvpcf/mw.PlayerSkinMvpcf.js"), |
28 | 28 | "mw.style.PlayerSkinMvpcf" => array( 'scripts'=> "skins/mvpcf/mw.style.PlayerSkinMvpcf.css"), |
29 | | -); |
\ No newline at end of file |
| 29 | +); |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerJava.js |
— | — | @@ -14,8 +14,8 @@ |
15 | 15 | |
16 | 16 | // Instance name: |
17 | 17 | instanceOf: 'Java', |
18 | | - |
19 | | - // Supported feature set of the cortado applet: |
| 18 | + |
| 19 | + // Supported feature set of the cortado applet: |
20 | 20 | supports: { |
21 | 21 | 'playHead' : true, |
22 | 22 | 'pause' : true, |
— | — | @@ -24,24 +24,24 @@ |
25 | 25 | 'timeDisplay' : true, |
26 | 26 | 'volumeControl' : false |
27 | 27 | }, |
28 | | - |
| 28 | + |
29 | 29 | /** |
30 | 30 | * Output the the embed html |
31 | 31 | */ |
32 | 32 | doEmbedHTML: function () { |
33 | 33 | var _this = this; |
34 | 34 | mw.log( "java play url:" + this.getSrc( this.seek_time_sec ) ); |
35 | | - |
36 | | - var applet_loc = this.getAppletLocation(); |
37 | | - |
| 35 | + |
| 36 | + var applet_loc = this.getAppletLocation(); |
| 37 | + |
38 | 38 | mw.log('Applet location: ' + applet_loc ); |
39 | 39 | mw.log('Play media: ' + this.getSrc() ); |
40 | | - |
| 40 | + |
41 | 41 | // load directly in the page.. |
42 | 42 | // (media must be on the same server or applet must be signed) |
43 | 43 | var appletCode = '' + |
44 | 44 | '<applet id="' + this.pid + '" code="com.fluendo.player.Cortado.class" ' + |
45 | | - 'archive="' + applet_loc + '" width="' + parseInt( this.getWidth() ) + '" ' + |
| 45 | + 'archive="' + applet_loc + '" width="' + parseInt( this.getWidth() ) + '" ' + |
46 | 46 | 'height="' + parseInt( this.getHeight() ) + '"> ' + "\n" + |
47 | 47 | '<param name="url" value="' + this.getSrc() + '" /> ' + "\n" + |
48 | 48 | '<param name="local" value="false"/>' + "\n" + |
— | — | @@ -50,19 +50,19 @@ |
51 | 51 | '<param name="showStatus" value="hide" />' + "\n" + |
52 | 52 | '<param name="audio" value="true" />' + "\n" + |
53 | 53 | '<param name="seekable" value="true" />' + "\n"; |
54 | | - |
55 | | - // Add the duration attribute if set: |
| 54 | + |
| 55 | + // Add the duration attribute if set: |
56 | 56 | if( this.getDuration() ){ |
57 | | - appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + "\n"; |
| 57 | + appletCode += '<param name="duration" value="' + parseFloat( this.getDuration() ) + '" />' + "\n"; |
58 | 58 | } |
59 | | - |
| 59 | + |
60 | 60 | appletCode += '<param name="bufferSize" value="4096" />' + "\n" + |
61 | 61 | '</applet>'; |
62 | | - |
| 62 | + |
63 | 63 | $j( this ).html( appletCode ); |
64 | | - |
| 64 | + |
65 | 65 | // Wrap it in an iframe to avoid hanging the event thread in FF 2/3 and similar |
66 | | - // NOTE: This breaks reference to the applet so disabled for now: |
| 66 | + // NOTE: This breaks reference to the applet so disabled for now: |
67 | 67 | /*if ( $j.browser.mozilla ) { |
68 | 68 | var iframe = document.createElement( 'iframe' ); |
69 | 69 | iframe.setAttribute( 'width', this.getWidth() ); |
— | — | @@ -72,103 +72,103 @@ |
73 | 73 | iframe.setAttribute( 'marginWidth', 0 ); |
74 | 74 | iframe.setAttribute( 'marginHeight', 0 ); |
75 | 75 | iframe.setAttribute( 'id', 'cframe_' + this.id ) |
76 | | - |
77 | | - // Append the iframe to the embed object: |
| 76 | + |
| 77 | + // Append the iframe to the embed object: |
78 | 78 | $j( this ).html( iframe ); |
79 | | - |
80 | | - // Write out the iframe content: |
| 79 | + |
| 80 | + // Write out the iframe content: |
81 | 81 | var newDoc = iframe.contentDocument; |
82 | 82 | newDoc.open(); |
83 | 83 | newDoc.write( '<html><body>' + appletCode + '</body></html>' ); |
84 | 84 | // spurious error in some versions of FF, no workaround known |
85 | | - newDoc.close(); |
| 85 | + newDoc.close(); |
86 | 86 | } else { |
87 | 87 | $j( this ).html( appletCode ); |
88 | | - //} |
89 | | - */ |
90 | | - |
91 | | - // Start the monitor: |
| 88 | + //} |
| 89 | + */ |
| 90 | + |
| 91 | + // Start the monitor: |
92 | 92 | _this.monitor(); |
93 | 93 | }, |
94 | | - |
| 94 | + |
95 | 95 | /** |
96 | 96 | * Get the applet location |
97 | 97 | */ |
98 | 98 | getAppletLocation: function() { |
99 | 99 | var mediaSrc = this.getSrc(); |
100 | 100 | var applet_loc = false; |
101 | | - if ( |
102 | | - !mw.isLocalDomain( mediaSrc ) |
103 | | - || |
104 | | - !mw.isLocalDomain( mw.getMwEmbedPath() |
| 101 | + if ( |
| 102 | + !mw.isLocalDomain( mediaSrc ) |
105 | 103 | || |
106 | | - mw.getConfig( 'relativeCortadoAppletPath' ) === false ) |
| 104 | + !mw.isLocalDomain( mw.getMwEmbedPath() |
| 105 | + || |
| 106 | + mw.getConfig( 'relativeCortadoAppletPath' ) === false ) |
107 | 107 | ){ |
108 | 108 | if ( window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ] ) { |
109 | | - applet_loc = window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ]; |
| 109 | + applet_loc = window.cortadoDomainLocations[ mw.parseUri( mediaSrc ).host ]; |
110 | 110 | } else { |
111 | | - applet_loc = 'http://theora.org/cortado.jar'; |
| 111 | + applet_loc = 'http://theora.org/cortado.jar'; |
112 | 112 | } |
113 | 113 | } else { |
114 | | - // Get the local relative cortado applet location: |
115 | | - applet_loc = mw.getConfig( 'relativeCortadoAppletPath' ); |
| 114 | + // Get the local relative cortado applet location: |
| 115 | + applet_loc = mw.getConfig( 'relativeCortadoAppletPath' ); |
116 | 116 | } |
117 | 117 | return applet_loc; |
118 | 118 | }, |
119 | | - |
| 119 | + |
120 | 120 | /** |
121 | 121 | * Get the embed player time |
122 | 122 | */ |
123 | 123 | getPlayerElementTime: function() { |
124 | | - this.getPlayerElement(); |
125 | | - var currentTime = 0; |
| 124 | + this.getPlayerElement(); |
| 125 | + var currentTime = 0; |
126 | 126 | if ( this.playerElement ) { |
127 | 127 | try { |
128 | | - // java reads ogg media time.. so no need to add the start or seek offset: |
129 | | - //mw.log(' ct: ' + this.playerElement.getPlayPosition() + ' ' + this.supportsURLTimeEncoding()); |
130 | | - |
131 | | - currentTime = this.playerElement.currentTime; |
132 | | - if ( this.currentTime < 0 ) { |
133 | | - mw.log( 'pp:' + this.currentTime ); |
134 | | - // Probably reached clip ( should fire ondone event instead ) |
| 128 | + // java reads ogg media time.. so no need to add the start or seek offset: |
| 129 | + //mw.log(' ct: ' + this.playerElement.getPlayPosition() + ' ' + this.supportsURLTimeEncoding()); |
| 130 | + |
| 131 | + currentTime = this.playerElement.currentTime; |
| 132 | + if ( this.currentTime < 0 ) { |
| 133 | + mw.log( 'pp:' + this.currentTime ); |
| 134 | + // Probably reached clip ( should fire ondone event instead ) |
135 | 135 | this.onClipDone(); |
136 | | - } |
| 136 | + } |
137 | 137 | } catch ( e ) { |
138 | | - mw.log( 'could not get time from jPlayer: ' + e ); |
| 138 | + mw.log( 'could not get time from jPlayer: ' + e ); |
139 | 139 | } |
140 | 140 | }else{ |
141 | 141 | mw.log(" could not find playerElement " ); |
142 | 142 | } |
143 | 143 | return currentTime; |
144 | 144 | }, |
145 | | - |
| 145 | + |
146 | 146 | /** |
147 | | - * Seek in the ogg stream |
148 | | - * ( Cortado seek does not seem to work very well ) |
| 147 | + * Seek in the ogg stream |
| 148 | + * ( Cortado seek does not seem to work very well ) |
149 | 149 | * @param {Float} percentage Percentage to seek into the stream |
150 | 150 | */ |
151 | | - doSeek: function( percentage ) { |
152 | | - mw.log( 'java:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
| 151 | + doSeek: function( percentage ) { |
| 152 | + mw.log( 'java:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
153 | 153 | this.getPlayerElement(); |
154 | | - |
| 154 | + |
155 | 155 | if ( this.supportsURLTimeEncoding() ) { |
156 | | - this.parent_doSeek( percentage ); |
| 156 | + this.parent_doSeek( percentage ); |
157 | 157 | } else if ( this.playerElement ) { |
158 | | - // do a (generally broken) local seek: |
159 | | - mw.log( "Cortado seek is not very accurate :: doSeek::" + ( percentage * parseFloat( this.getDuration() ) ) ); |
160 | | - this.playerElement.currentTime = ( percentage * parseFloat( this.getDuration() ) ); |
| 158 | + // do a (generally broken) local seek: |
| 159 | + mw.log( "Cortado seek is not very accurate :: doSeek::" + ( percentage * parseFloat( this.getDuration() ) ) ); |
| 160 | + this.playerElement.currentTime = ( percentage * parseFloat( this.getDuration() ) ); |
161 | 161 | } else { |
162 | | - this.doPlayThenSeek( percentage ); |
| 162 | + this.doPlayThenSeek( percentage ); |
163 | 163 | } |
164 | | - |
| 164 | + |
165 | 165 | // Run the onSeeking interface update |
166 | 166 | this.controlBuilder.onSeek(); |
167 | 167 | }, |
168 | | - |
| 168 | + |
169 | 169 | /** |
170 | 170 | * Issue a play request then seek to a percentage point in the stream |
171 | 171 | * @param {Float} percentage Percentage to seek into the stream |
172 | | - */ |
| 172 | + */ |
173 | 173 | doPlayThenSeek: function( percentage ) { |
174 | 174 | mw.log( 'doPlayThenSeek' ); |
175 | 175 | var _this = this; |
— | — | @@ -176,11 +176,11 @@ |
177 | 177 | var rfsCount = 0; |
178 | 178 | var readyForSeek = function() { |
179 | 179 | _this.getPlayerElement(); |
180 | | - // if we have .jre ~in theory~ we can seek (but probably not) |
| 180 | + // if we have .jre ~in theory~ we can seek (but probably not) |
181 | 181 | if ( _this.playerElement ) { |
182 | 182 | _this.doSeek( perc ); |
183 | 183 | } else { |
184 | | - // try to get player for 10 seconds: |
| 184 | + // try to get player for 10 seconds: |
185 | 185 | if ( rfsCount < 200 ) { |
186 | 186 | setTimeout( readyForSeek, 50 ); |
187 | 187 | rfsCount++; |
— | — | @@ -191,9 +191,9 @@ |
192 | 192 | } |
193 | 193 | readyForSeek(); |
194 | 194 | }, |
195 | | - |
| 195 | + |
196 | 196 | /** |
197 | | - * Update the playerElement instance with a pointer to the embed object |
| 197 | + * Update the playerElement instance with a pointer to the embed object |
198 | 198 | */ |
199 | 199 | getPlayerElement: function() { |
200 | 200 | if( !$j( '#' + this.pid ).length ) { |
— | — | @@ -202,15 +202,15 @@ |
203 | 203 | //mw.log( 'getPlayerElement::' + this.pid ); |
204 | 204 | this.playerElement = $j( '#' + this.pid ).get( 0 ); |
205 | 205 | //this.playerElement = document.applets[ 0 ]; |
206 | | - // NOTE we are currently not using the iframe embed method: |
| 206 | + // NOTE we are currently not using the iframe embed method: |
207 | 207 | //if ( $j.browser.mozilla ) { |
208 | | - // this.playerElement = $j('#cframe_' + this.id).contents().find( '#' + this.pid ); |
| 208 | + // this.playerElement = $j('#cframe_' + this.id).contents().find( '#' + this.pid ); |
209 | 209 | //} else { |
210 | 210 | // this.playerElement = $j( '#' + this.pid ).get( 0 ); |
211 | 211 | //} |
212 | 212 | return this.playerElement; |
213 | | - }, |
214 | | - |
| 213 | + }, |
| 214 | + |
215 | 215 | /** |
216 | 216 | * Issue the doPlay request to the playerElement |
217 | 217 | * calls parent_play to update interface |
— | — | @@ -226,16 +226,16 @@ |
227 | 227 | } |
228 | 228 | } |
229 | 229 | }, |
230 | | - |
| 230 | + |
231 | 231 | /** |
232 | 232 | * Pause playback |
233 | 233 | * calls parent_pause to update interface |
234 | | - */ |
| 234 | + */ |
235 | 235 | pause: function() { |
236 | 236 | this.getPlayerElement(); |
237 | 237 | // Update the interface |
238 | 238 | this.parent_pause(); |
239 | | - // Call the pause function if it exists: |
| 239 | + // Call the pause function if it exists: |
240 | 240 | if ( this.playerElement ) { |
241 | 241 | this.playerElement.pause(); |
242 | 242 | } |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerHtml.js |
— | — | @@ -1,19 +1,19 @@ |
2 | 2 | /* |
3 | 3 | * Used to embed HTML as a movie clip |
4 | 4 | * for use with mv_playlist SMIL additions |
5 | | - * |
6 | | - * NOTE: will be deprecated |
| 5 | + * |
| 6 | + * NOTE: will be deprecated |
7 | 7 | */ |
8 | 8 | var pcHtmlEmbedDefaults = { |
9 | | - // default duration of 4 seconds |
10 | | - 'dur':4 |
| 9 | + // default duration of 4 seconds |
| 10 | + 'dur':4 |
11 | 11 | } |
12 | 12 | |
13 | 13 | mw.EmbedPlayerHtml = { |
14 | | - |
15 | | - // Instance name: |
16 | | - instanceOf: 'Html', |
17 | 14 | |
| 15 | + // Instance name: |
| 16 | + instanceOf: 'Html', |
| 17 | + |
18 | 18 | // List of supported features |
19 | 19 | supports: { |
20 | 20 | 'playHead':true, |
— | — | @@ -24,27 +24,27 @@ |
25 | 25 | |
26 | 26 | 'overlays':true |
27 | 27 | }, |
28 | | - |
| 28 | + |
29 | 29 | // If the player is "ready to play" |
30 | 30 | ready_to_play:true, |
31 | | - |
| 31 | + |
32 | 32 | // Pause time used to track player time between pauses |
33 | 33 | pauseTime:0, |
34 | | - |
| 34 | + |
35 | 35 | // currentTime updated via internal clockStartTime var |
36 | 36 | currentTime:0, |
37 | | - |
| 37 | + |
38 | 38 | // StartOffset support seeking into the virtual player |
39 | 39 | startOffset:0, |
40 | | - |
| 40 | + |
41 | 41 | // The local clock used to emulate playback time |
42 | 42 | clockStartTime: 0, |
43 | | - |
| 43 | + |
44 | 44 | /** |
45 | 45 | * Play function starts the v |
46 | 46 | */ |
47 | 47 | play: function() { |
48 | | - mw.log(" parent: " + this.parent_play); |
| 48 | + mw.log(" parent: " + this.parent_play); |
49 | 49 | // call the parent |
50 | 50 | this.parent_play(); |
51 | 51 | |
— | — | @@ -55,27 +55,27 @@ |
56 | 56 | // Start up monitor: |
57 | 57 | this.monitor(); |
58 | 58 | }, |
59 | | - |
| 59 | + |
60 | 60 | /** |
61 | 61 | * Stops the playback |
62 | 62 | */ |
63 | 63 | stop:function() { |
64 | 64 | this.currentTime = 0; |
65 | | - this.pause(); |
| 65 | + this.pause(); |
66 | 66 | }, |
67 | | - |
| 67 | + |
68 | 68 | /** |
69 | | - * Preserves the pause time across for timed playback |
| 69 | + * Preserves the pause time across for timed playback |
70 | 70 | */ |
71 | 71 | pause:function() { |
72 | 72 | mw.log( 'f:pause: htmlEmbedWrapper' ); |
73 | 73 | var ct = new Date(); |
74 | 74 | this.pauseTime = this.currentTime; |
75 | 75 | mw.log( 'pause time: ' + this.pauseTime ); |
76 | | - |
| 76 | + |
77 | 77 | window.clearInterval( this.monitorTimerId ); |
78 | 78 | }, |
79 | | - |
| 79 | + |
80 | 80 | /** |
81 | 81 | * Seeks to a given percent and updates the pauseTime |
82 | 82 | * |
— | — | @@ -85,9 +85,9 @@ |
86 | 86 | this.pauseTime = perc * this.getDuration(); |
87 | 87 | this.play(); |
88 | 88 | }, |
89 | | - |
90 | | - /** |
91 | | - * Sets the current Time |
| 89 | + |
| 90 | + /** |
| 91 | + * Sets the current Time |
92 | 92 | * |
93 | 93 | * @param {Float} perc Percentage to seek into the virtual player |
94 | 94 | * @param {Function} callback Function called once time has been updated |
— | — | @@ -97,20 +97,20 @@ |
98 | 98 | if( callback ) |
99 | 99 | callback(); |
100 | 100 | }, |
101 | | - |
| 101 | + |
102 | 102 | /** |
103 | 103 | * Get the embed player time |
104 | 104 | */ |
105 | 105 | getPlayerElementTime: function() { |
106 | | - //mw.log('html:monitor: '+ this.currentTime); |
| 106 | + //mw.log('html:monitor: '+ this.currentTime); |
107 | 107 | var ct = new Date(); |
108 | | - var currentTime = ( ( ct.getTime() - this.clockStartTime ) / 1000 ) + this.pauseTime; |
| 108 | + var currentTime = ( ( ct.getTime() - this.clockStartTime ) / 1000 ) + this.pauseTime; |
109 | 109 | return currentTime; |
110 | 110 | }, |
111 | | - |
| 111 | + |
112 | 112 | /** |
113 | 113 | * Minimal media_element emulation: |
114 | | - */ |
| 114 | + */ |
115 | 115 | media_element: { |
116 | 116 | autoSelectSource:function() { |
117 | 117 | return true; |
— | — | @@ -125,55 +125,55 @@ |
126 | 126 | return false; |
127 | 127 | } |
128 | 128 | }, |
129 | | - |
130 | | - /** |
131 | | - * HtmlEmbed supports virtual instances without inheriting the embedPlayer |
| 129 | + |
| 130 | + /** |
| 131 | + * HtmlEmbed supports virtual instances without inheriting the embedPlayer |
132 | 132 | */ |
133 | 133 | inheritEmbedPlayer: function() { |
134 | 134 | return true; |
135 | 135 | }, |
136 | | - |
| 136 | + |
137 | 137 | /** |
138 | 138 | * Render out a Thumbnail representation for use in the sequencer |
139 | 139 | * |
140 | 140 | * @param {Object} options Thumbnail options |
141 | | - */ |
| 141 | + */ |
142 | 142 | renderTimelineThumbnail:function( options ) { |
143 | 143 | mw.log( "HTMLembed req w, height: " + options.width + ' ' + options.height ); |
144 | | - // generate a scaled down version _that_ we can clone if necessary |
| 144 | + // generate a scaled down version _that_ we can clone if necessary |
145 | 145 | // add a not visible container to the body: |
146 | 146 | var do_refresh = ( typeof options['refresh'] != 'undefined' ) ? true:false; |
147 | 147 | |
148 | | - var thumb_render_id = this.id + '_thumb_render_' + options.height; |
149 | | - if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) { |
150 | | - |
| 148 | + var thumb_render_id = this.id + '_thumb_render_' + options.height; |
| 149 | + if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) { |
| 150 | + |
151 | 151 | // Set the font scale down percentage: (kind of arbitrary) |
152 | 152 | var scale_perc = options.width / this.pc.pp.width; |
153 | | - |
| 153 | + |
154 | 154 | mw.log( 'scale_perc:' + options.width + ' / ' + $j( this ).width() + ' = ' + scale_perc ); |
155 | | - |
| 155 | + |
156 | 156 | // Min scale font percent of 70 (overflow is hidden) |
157 | | - var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 ); |
| 157 | + var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 ); |
158 | 158 | var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : ''; |
159 | 159 | $j( 'body' ).append( '<div id="' + thumb_render_id + '" style="display:none">' + |
160 | 160 | '<div class="' + thumb_class + '" ' + |
161 | 161 | 'style="width:' + options.width + 'px;height:' + options.height + 'px;" >' + |
162 | 162 | this.getThumbnailHTML( { |
163 | | - 'width': options.width, |
| 163 | + 'width': options.width, |
164 | 164 | 'height': options.height |
165 | 165 | } ) + |
166 | 166 | '</div>' + |
167 | 167 | '</div>' |
168 | | - ); |
169 | | - |
| 168 | + ); |
| 169 | + |
170 | 170 | // Scale down the fonts: |
171 | 171 | $j( '#' + thumb_render_id + ' *' ).filter( 'span,div,p,h,h1,h2,h3,h4,h5,h6' ).css( 'font-size', font_perc + '%' ) |
172 | | - |
| 172 | + |
173 | 173 | // Replace out links: |
174 | 174 | $j( '#' + thumb_render_id + ' a' ).each( function() { |
175 | 175 | $j( this ).replaceWith( "<span>" + $j( this ).html() + "</span>" ); |
176 | 176 | } ); |
177 | | - |
| 177 | + |
178 | 178 | // Scale images that have width or height: |
179 | 179 | $j( '#' + thumb_render_id + ' img' ).filter( '[width]' ).each( function() { |
180 | 180 | $j( this ).attr( { |
— | — | @@ -187,34 +187,34 @@ |
188 | 188 | }, |
189 | 189 | /* |
190 | 190 | * Updates the thumb time |
191 | | - * (does nothings since we display a single frame rendered html page) |
| 191 | + * (does nothings since we display a single frame rendered html page) |
192 | 192 | * |
193 | | - * @param {Float} float_time Ignored |
| 193 | + * @param {Float} float_time Ignored |
194 | 194 | */ |
195 | 195 | updateThumbTime:function( float_time ) { |
196 | 196 | return ; |
197 | 197 | }, |
198 | | - |
| 198 | + |
199 | 199 | /** |
200 | 200 | * Get the "embed" html for the html player |
201 | 201 | */ |
202 | 202 | doEmbedHTML: function() { |
203 | 203 | mw.log( 'f:html:doEmbedHTML: ' + this.id ); |
204 | | - // set up the css for our parent div: |
| 204 | + // set up the css for our parent div: |
205 | 205 | $j( this ).css( { |
206 | 206 | 'width':this.pc.pp.width, |
207 | 207 | 'height':this.pc.pp.height, |
208 | 208 | 'overflow':"hidden" |
209 | 209 | } ); |
210 | | - // @@todo support more smil animation layout stuff: |
| 210 | + // @@todo support more smil animation layout stuff: |
211 | 211 | |
212 | 212 | // wrap output in videoPlayer_ div: |
213 | 213 | $j( this ).html( this.getThumbnailHTML() ); |
214 | 214 | }, |
215 | | - |
| 215 | + |
216 | 216 | /** |
217 | 217 | * Get the ThumbnailHTML |
218 | | - * ThumbnailHTML is used for both the "paused and playing states of the htmlEmbed player |
| 218 | + * ThumbnailHTML is used for both the "paused and playing states of the htmlEmbed player |
219 | 219 | */ |
220 | 220 | getThumbnailHTML: function( opt ) { |
221 | 221 | var out = ''; |
— | — | @@ -223,7 +223,7 @@ |
224 | 224 | var height = ( opt.height ) ? opt.height:this.pc.pp.height; |
225 | 225 | var width = ( opt.width ) ? opt.width: this.pc.pp.width; |
226 | 226 | mw.log( '1req ' + opt.height + ' but got: ' + height ); |
227 | | - if ( this.pc.type == 'image/jpeg' || this.pc.type == 'image/png' ) { |
| 227 | + if ( this.pc.type == 'image/jpeg' || this.pc.type == 'image/png' ) { |
228 | 228 | mw.log( 'should put src: ' + this.pc.src ); |
229 | 229 | out = '<img style="width:' + width + 'px;height:' + height + 'px" src="' + this.pc.src + '">'; |
230 | 230 | } else { |
— | — | @@ -236,7 +236,7 @@ |
237 | 237 | $j( this ).css( 'background', '#fff'); |
238 | 238 | $j( this ).html( this.getThumbnailHTML() ); |
239 | 239 | }, |
240 | | - |
| 240 | + |
241 | 241 | /** |
242 | 242 | * re-show the Thumbnail |
243 | 243 | */ |
— | — | @@ -244,7 +244,7 @@ |
245 | 245 | mw.log( 'htmlEmbed:showThumbnail()' ); |
246 | 246 | this.getEmbedHTML(); |
247 | 247 | }, |
248 | | - |
| 248 | + |
249 | 249 | /** |
250 | 250 | * Get the media duration |
251 | 251 | */ |
— | — | @@ -254,22 +254,22 @@ |
255 | 255 | this.duration = this.pc.dur; |
256 | 256 | }else if( pcHtmlEmbedDefaults.dur ) { |
257 | 257 | this.duration = pcHtmlEmbedDefaults.dur ; |
258 | | - } |
259 | | - } |
260 | | - return this.duration; |
| 258 | + } |
| 259 | + } |
| 260 | + return this.duration; |
261 | 261 | }, |
262 | | - |
| 262 | + |
263 | 263 | /** |
264 | | - * Updates the Video time |
| 264 | + * Updates the Video time |
265 | 265 | * |
266 | 266 | * @param {String} start_npt Start time for update |
267 | | - * @param {String} end_npt End time for update |
| 267 | + * @param {String} end_npt End time for update |
268 | 268 | */ |
269 | 269 | updateVideoTime:function( start_npt, end_npt ) { |
270 | 270 | // since we don't really have timeline for html elements just take the delta and set it as the duration |
271 | 271 | this.pc.dur = mw.npt2seconds( end_ntp ) - mw.npt2seconds( start_ntp ); |
272 | 272 | }, |
273 | | - |
| 273 | + |
274 | 274 | /** |
275 | 275 | * Local implementation of swapPlayerElement |
276 | 276 | */ |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerVlc.js |
— | — | @@ -5,36 +5,36 @@ |
6 | 6 | */ |
7 | 7 | mw.EmbedPlayerVlc = { |
8 | 8 | |
9 | | - //Instance Name: |
| 9 | + //Instance Name: |
10 | 10 | instanceOf : 'Vlc', |
11 | | - |
12 | | - //What the vlc player / plug-in supports: |
13 | | - supports : { |
| 11 | + |
| 12 | + //What the vlc player / plug-in supports: |
| 13 | + supports : { |
14 | 14 | 'playHead':true, |
15 | 15 | 'pause':true, |
16 | 16 | 'stop':true, |
17 | 17 | 'fullscreen':true, |
18 | 18 | 'timeDisplay':true, |
19 | 19 | 'volumeControl':true, |
20 | | - |
| 20 | + |
21 | 21 | 'playlist_driver':true, // if the object supports playlist functions |
22 | 22 | 'overlay':false |
23 | 23 | }, |
24 | | - |
| 24 | + |
25 | 25 | // The previous state of the player instance |
26 | 26 | prevState : 0, |
27 | | - |
| 27 | + |
28 | 28 | // Counter for waiting for vlc embed to be ready |
29 | 29 | waitForVlcCount:0, |
30 | | - |
| 30 | + |
31 | 31 | // Store the current play time for vlc |
32 | 32 | vlcCurrentTime: 0, |
33 | | - |
| 33 | + |
34 | 34 | /** |
35 | 35 | * Get embed HTML |
36 | 36 | */ |
37 | 37 | doEmbedHTML: function() { |
38 | | - var _this = this; |
| 38 | + var _this = this; |
39 | 39 | $j( this ).html( |
40 | 40 | '<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' + |
41 | 41 | 'codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0" ' + |
— | — | @@ -57,21 +57,21 @@ |
58 | 58 | /* |
59 | 59 | $j( this ).html( |
60 | 60 | '<embed type="application/x-vlc-plugin" pluginspage="http://www.videolan.org" version="VideoLAN.VLCPlugin.2" '+ |
61 | | - 'width="' + this.width +'" ' + |
62 | | - 'height="' + this.height + '" ' + |
63 | | - 'id="' + this.pid + '"> ' + |
| 61 | + 'width="' + this.width +'" ' + |
| 62 | + 'height="' + this.height + '" ' + |
| 63 | + 'id="' + this.pid + '"> ' + |
64 | 64 | '</embed>' |
65 | 65 | );*/ |
66 | | - |
67 | | - |
68 | | - // give VLC 150ms to initialize before we start playback |
| 66 | + |
| 67 | + |
| 68 | + // give VLC 150ms to initialize before we start playback |
69 | 69 | // @@todo should be able to do this as an ready event |
70 | 70 | this.waitForVlcCount = 0; |
71 | 71 | setTimeout( function() { |
72 | 72 | _this.postEmbedJS(); |
73 | 73 | }, 150 ); |
74 | | - }, |
75 | | - |
| 74 | + }, |
| 75 | + |
76 | 76 | /** |
77 | 77 | * Javascript to run post vlc embedding |
78 | 78 | * Inserts the requested src to the embed instance |
— | — | @@ -79,16 +79,16 @@ |
80 | 80 | postEmbedJS: function() { |
81 | 81 | var _this = this; |
82 | 82 | // load a pointer to the vlc into the object (this.playerElement) |
83 | | - this.getPlayerElement(); |
84 | | - if ( this.playerElement && this.playerElement.playlist) { |
85 | | - // manipulate the dom object to make sure vlc has the correct size: |
| 83 | + this.getPlayerElement(); |
| 84 | + if ( this.playerElement && this.playerElement.playlist) { |
| 85 | + // manipulate the dom object to make sure vlc has the correct size: |
86 | 86 | this.playerElement.style.width = this.getWidth(); |
87 | 87 | this.playerElement.style.height = this.getHeight(); |
88 | 88 | this.playerElement.playlist.items.clear(); |
89 | | - |
90 | | - // VLC likes absolute urls: |
| 89 | + |
| 90 | + // VLC likes absolute urls: |
91 | 91 | var src = mw.absoluteUrl( this.getSrc() ) ; |
92 | | - |
| 92 | + |
93 | 93 | // @@todo if client supports seeking no need to send seek_offset to URI |
94 | 94 | mw.log( 'vlc play::' + src ); |
95 | 95 | var itemId = this.playerElement.playlist.add( src ); |
— | — | @@ -97,7 +97,7 @@ |
98 | 98 | this.playerElement.playlist.playItem( itemId ); |
99 | 99 | } else { |
100 | 100 | mw.log( "error:cannot play at the moment !" ); |
101 | | - } |
| 101 | + } |
102 | 102 | setTimeout( function() { |
103 | 103 | _this.monitor(); |
104 | 104 | }, 100 ); |
— | — | @@ -113,10 +113,10 @@ |
114 | 114 | } |
115 | 115 | } |
116 | 116 | }, |
117 | | - |
118 | | - /** |
| 117 | + |
| 118 | + /** |
119 | 119 | * Handles seek requests based on temporal media source type support |
120 | | - * |
| 120 | + * |
121 | 121 | * @param {Float} percent Seek to this percent of the stream |
122 | 122 | */ |
123 | 123 | doSeek : function( percent ) { |
— | — | @@ -136,7 +136,7 @@ |
137 | 137 | } |
138 | 138 | this.parent_monitor(); |
139 | 139 | }, |
140 | | - |
| 140 | + |
141 | 141 | /** |
142 | 142 | * Issues a play request then seeks to a given time |
143 | 143 | * |
— | — | @@ -150,11 +150,11 @@ |
151 | 151 | var readyForSeek = function() { |
152 | 152 | _this.getPlayerElement(); |
153 | 153 | var newState = _this.playerElement.input.state; |
154 | | - // if playing we are ready to do the |
| 154 | + // if playing we are ready to do the |
155 | 155 | if ( newState == 3 ) { |
156 | 156 | _this.doSeek( percent ); |
157 | 157 | } else { |
158 | | - // try to get player for 10 seconds: |
| 158 | + // try to get player for 10 seconds: |
159 | 159 | if ( rfsCount < 200 ) { |
160 | 160 | setTimeout( readyForSeek, 50 ); |
161 | 161 | rfsCount++; |
— | — | @@ -164,8 +164,8 @@ |
165 | 165 | } |
166 | 166 | } |
167 | 167 | readyForSeek(); |
168 | | - }, |
169 | | - |
| 168 | + }, |
| 169 | + |
170 | 170 | /** |
171 | 171 | * Updates the status time and player state |
172 | 172 | */ |
— | — | @@ -182,21 +182,21 @@ |
183 | 183 | var iter = this.playerElement.log.messages.iterator(); |
184 | 184 | while ( iter.hasNext ) { |
185 | 185 | var msg = iter.next(); |
186 | | - var msgtype = msg.type.toString(); |
187 | | - if ( ( msg.severity == 1 ) && ( msgtype == "input" ) ) |
188 | | - { |
189 | | - mw.log( msg.message ); |
190 | | - } |
| 186 | + var msgtype = msg.type.toString(); |
| 187 | + if ( ( msg.severity == 1 ) && ( msgtype == "input" ) ) |
| 188 | + { |
| 189 | + mw.log( msg.message ); |
| 190 | + } |
191 | 191 | } |
192 | 192 | // clear the log once finished to avoid clogging |
193 | 193 | this.playerElement.log.messages.clear(); |
194 | 194 | } |
195 | | - |
| 195 | + |
196 | 196 | var newState = this.playerElement.input.state; |
197 | 197 | if ( this.prevState != newState ) { |
198 | | - if ( newState == 0 ) |
| 198 | + if ( newState == 0 ) |
199 | 199 | { |
200 | | - // current media has stopped |
| 200 | + // current media has stopped |
201 | 201 | this.onStop(); |
202 | 202 | } |
203 | 203 | else if ( newState == 1 ) |
— | — | @@ -211,8 +211,8 @@ |
212 | 212 | } |
213 | 213 | else if ( newState == 3 ) |
214 | 214 | { |
215 | | - // current media is now playing |
216 | | - this.onPlay(); |
| 215 | + // current media is now playing |
| 216 | + this.onPlay(); |
217 | 217 | } |
218 | 218 | else if ( this.playerElement.input.state == 4 ) { |
219 | 219 | // current media is now paused |
— | — | @@ -229,10 +229,10 @@ |
230 | 230 | // update the status and check timmer via universal parent monitor |
231 | 231 | this.parent_monitor(); |
232 | 232 | }, |
233 | | - |
| 233 | + |
234 | 234 | /** |
235 | 235 | * Events: |
236 | | - * @@note: should be localized: |
| 236 | + * @@note: should be localized: |
237 | 237 | */ |
238 | 238 | onOpen: function() { |
239 | 239 | this.controlBuilder.setStatus( "Opening..." ); |
— | — | @@ -242,25 +242,25 @@ |
243 | 243 | }, |
244 | 244 | onPlay: function() { |
245 | 245 | this.onPlaying(); |
246 | | - }, |
| 246 | + }, |
247 | 247 | onPlaying: function() { |
248 | 248 | this.seeking = false; |
249 | 249 | // for now trust the duration from url over vlc input.length |
250 | 250 | if ( !this.getDuration() && this.playerElement.input.length > 0 ) |
251 | 251 | { |
252 | | - // mw.log('setting duration to ' + this.playerElement.input.length /1000); |
| 252 | + // mw.log('setting duration to ' + this.playerElement.input.length /1000); |
253 | 253 | this.duration = this.playerElement.input.length / 1000; |
254 | 254 | } |
255 | 255 | this.vlcCurrentTime = this.playerElement.input.time / 1000; |
256 | 256 | }, |
257 | | - |
| 257 | + |
258 | 258 | /** |
259 | 259 | * Get the embed player time |
260 | 260 | */ |
261 | 261 | getPlayerElementTime: function(){ |
262 | 262 | return this.vlcCurrentTime; |
263 | 263 | }, |
264 | | - |
| 264 | + |
265 | 265 | onPause: function() { |
266 | 266 | this.parent_pause(); // update the inteface if paused via native control |
267 | 267 | }, |
— | — | @@ -269,77 +269,77 @@ |
270 | 270 | if ( !this.seeking ) |
271 | 271 | this.onClipDone(); |
272 | 272 | }, |
273 | | - |
| 273 | + |
274 | 274 | /** |
275 | 275 | * Handles play requests |
276 | 276 | */ |
277 | | - play : function() { |
| 277 | + play : function() { |
278 | 278 | mw.log( 'f:vlcPlay' ); |
279 | 279 | // Update the interface |
280 | | - this.parent_play(); |
| 280 | + this.parent_play(); |
281 | 281 | if ( this.getPlayerElement() ) { |
282 | | - // plugin is already being present send play call: |
| 282 | + // plugin is already being present send play call: |
283 | 283 | // clear the message log and enable error logging |
284 | 284 | if ( this.playerElement.log ) { |
285 | 285 | this.playerElement.log.messages.clear(); |
286 | 286 | } |
287 | 287 | if ( this.playerElement.playlist && typeof this.playerElement.playlist.play == 'function') |
288 | 288 | this.playerElement.playlist.play(); |
289 | | - |
| 289 | + |
290 | 290 | if( typeof this.playerElement.play == 'function' ) |
291 | | - this.playerElement.play(); |
292 | | - |
| 291 | + this.playerElement.play(); |
| 292 | + |
293 | 293 | this.paused = false; |
294 | | - |
295 | | - // re-start the monitor: |
| 294 | + |
| 295 | + // re-start the monitor: |
296 | 296 | this.monitor(); |
297 | 297 | } |
298 | 298 | }, |
299 | | - |
| 299 | + |
300 | 300 | /** |
301 | | - * Passes the Pause request to the plugin. |
302 | | - * calls parent "pause" to update interface |
| 301 | + * Passes the Pause request to the plugin. |
| 302 | + * calls parent "pause" to update interface |
303 | 303 | */ |
304 | 304 | pause : function() { |
305 | 305 | this.parent_pause(); // update the interface if paused via native control |
306 | | - if ( this.getPlayerElement() ) { |
| 306 | + if ( this.getPlayerElement() ) { |
307 | 307 | try{ |
308 | | - this.playerElement.playlist.togglePause(); |
| 308 | + this.playerElement.playlist.togglePause(); |
309 | 309 | } catch( e ){ |
310 | 310 | mw.log("EmbedPlayerVlc could not pause video " + e); |
311 | 311 | } |
312 | 312 | } |
313 | 313 | }, |
314 | | - |
| 314 | + |
315 | 315 | /** |
316 | | - * Mutes the video |
317 | | - * calls parent "toggleMute" to update interface |
| 316 | + * Mutes the video |
| 317 | + * calls parent "toggleMute" to update interface |
318 | 318 | */ |
319 | 319 | toggleMute:function() { |
320 | 320 | this.parent_toggleMute(); |
321 | 321 | if ( this.getPlayerElement() ) |
322 | 322 | this.playerElement.audio.toggleMute(); |
323 | 323 | }, |
324 | | - |
| 324 | + |
325 | 325 | /** |
326 | 326 | * Update the player volume |
327 | 327 | * @pram {Float} percent Percent of total volume |
328 | | - */ |
| 328 | + */ |
329 | 329 | setPlayerElementVolume: function ( percent ) { |
330 | 330 | if ( this.getPlayerElement() ) { |
331 | 331 | this.playerElement.audio.volume = percent * 100; |
332 | 332 | } |
333 | 333 | }, |
334 | | - |
| 334 | + |
335 | 335 | /** |
336 | 336 | * Gets the current volume |
337 | 337 | * @return {Float} percent percent of total volume |
338 | | - */ |
339 | | - getVolumen:function() { |
| 338 | + */ |
| 339 | + getVolumen:function() { |
340 | 340 | if ( this.getPlayerElement() ) |
341 | 341 | return this.playerElement.audio.volume / 100; |
342 | 342 | }, |
343 | | - |
| 343 | + |
344 | 344 | /** |
345 | 345 | * Passes fullscreen request to plugin |
346 | 346 | */ |
— | — | @@ -352,14 +352,14 @@ |
353 | 353 | mw.log("VlcEmbed toggle fullscreen : possible error: " + e); |
354 | 354 | } |
355 | 355 | } |
356 | | - } |
| 356 | + } |
357 | 357 | }, |
358 | | - |
| 358 | + |
359 | 359 | /** |
360 | 360 | * Get the embed vlc object |
361 | | - */ |
362 | | - getPlayerElement : function() { |
| 361 | + */ |
| 362 | + getPlayerElement : function() { |
363 | 363 | this.playerElement = $j( '#' + this.pid ).get(0); |
364 | | - return this.playerElement; |
| 364 | + return this.playerElement; |
365 | 365 | } |
366 | 366 | }; |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerNative.js |
— | — | @@ -1,170 +1,180 @@ |
2 | 2 | /** |
3 | 3 | * Native embed library: |
4 | | -* |
| 4 | +* |
5 | 5 | * Enables embedPlayer support for native html5 browser playback system |
6 | 6 | */ |
7 | 7 | mw.EmbedPlayerNative = { |
8 | 8 | |
9 | 9 | //Instance Name |
10 | 10 | instanceOf: 'Native', |
11 | | - |
12 | | - // Counts the number of times we tried to access the video element |
| 11 | + |
| 12 | + // Counts the number of times we tried to access the video element |
13 | 13 | grab_try_count:0, |
14 | | - |
15 | | - // Flag to only load the video ( not play it ) |
16 | | - onlyLoadFlag:false, |
17 | | - |
18 | | - //Callback fired once video is "loaded" |
| 14 | + |
| 15 | + // Flag to only load the video ( not play it ) |
| 16 | + onlyLoadFlag:false, |
| 17 | + |
| 18 | + //Callback fired once video is "loaded" |
19 | 19 | onLoadedCallback: null, |
20 | | - |
| 20 | + |
21 | 21 | //For retrying a player embed with a distinct url |
22 | | - // NOTE: this bug workaround may no longer be applicable |
| 22 | + // NOTE: this bug workaround may no longer be applicable |
23 | 23 | urlAppend:'', |
24 | | - |
25 | | - // The previous "currentTime" to sniff seek actions |
26 | | - // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable |
| 24 | + |
| 25 | + // The previous "currentTime" to sniff seek actions |
| 26 | + // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable |
27 | 27 | prevCurrentTime: -1, |
28 | | - |
29 | | - // Store the progress event ( updated durring monitor ) |
| 28 | + |
| 29 | + // Store the progress event ( updated during monitor ) |
30 | 30 | progressEventData: null, |
31 | | - |
32 | | - // If the media loaded event has been fired |
| 31 | + |
| 32 | + // If the media loaded event has been fired |
33 | 33 | mediaLoadedFlag: null, |
34 | | - |
| 34 | + |
| 35 | + // All the native events per: |
| 36 | + // http://www.w3.org/TR/html5/video.html#mediaevents |
| 37 | + nativeEvents : [ |
| 38 | + 'loadstart', |
| 39 | + 'progress', |
| 40 | + 'suspend', |
| 41 | + 'abort', |
| 42 | + 'error', |
| 43 | + 'emptied', |
| 44 | + 'stalled', |
| 45 | + 'play', |
| 46 | + 'pause', |
| 47 | + 'loadedmetadata', |
| 48 | + 'loadeddata', |
| 49 | + 'waiting', |
| 50 | + 'playing', |
| 51 | + 'canplay', |
| 52 | + 'canplaythough', |
| 53 | + 'seeking', |
| 54 | + 'seeked', |
| 55 | + 'timeupdate', |
| 56 | + 'ended', |
| 57 | + 'ratechange', |
| 58 | + 'durationchange', |
| 59 | + 'volumechange' |
| 60 | + ], |
| 61 | + |
35 | 62 | // Native player supported feature set |
36 | 63 | supports: { |
37 | 64 | 'playHead' : true, |
38 | 65 | 'pause' : true, |
39 | 66 | 'fullscreen' : true, |
40 | 67 | 'timeDisplay' : true, |
41 | | - 'volumeControl' : true, |
| 68 | + 'volumeControl' : true, |
42 | 69 | 'overlays' : true |
43 | | - }, |
44 | | - |
45 | | - insertAndPlayingConfig : false, |
46 | | - |
47 | | - /** |
48 | | - * updates the supported features given the "type of player" |
| 70 | + }, |
| 71 | + |
| 72 | + /** |
| 73 | + * updates the supported features given the "type of player" |
49 | 74 | */ |
50 | 75 | updateFeatureSupport: function(){ |
51 | 76 | // iWhatever devices appear to have a broken |
52 | 77 | // dom overlay implementation of video atm. (hopefully iphone OS 4 fixes this ) |
53 | 78 | if( mw.isMobileHTML5() ) { |
54 | 79 | this.supports.overlays = false; |
55 | | - } |
| 80 | + } |
56 | 81 | }, |
57 | | - |
| 82 | + |
58 | 83 | /** |
59 | 84 | * Return the embed code |
60 | 85 | */ |
61 | 86 | doEmbedHTML : function () { |
62 | 87 | var _this = this; |
63 | | - |
64 | | - // Reset some play state flags: |
| 88 | + |
| 89 | + // Reset some play state flags: |
65 | 90 | _this.bufferStartFlag = false; |
66 | 91 | _this.bufferEndFlag = false; |
67 | | - |
| 92 | + |
68 | 93 | mw.log( "native play url:" + this.getSrc() + ' startOffset: ' + this.start_ntp + ' end: ' + this.end_ntp ); |
69 | | - |
| 94 | + |
70 | 95 | // Check if using native controls and already the "pid" is already in the DOM |
71 | 96 | if( this.useNativePlayerControls() && $j( '#' + this.pid ).length && |
72 | 97 | typeof $j( '#' + this.pid ).get(0).play != 'undefined' ) { |
73 | 98 | _this.postEmbedJS(); |
74 | 99 | return ; |
75 | 100 | } |
76 | | - |
| 101 | + |
77 | 102 | $j( this ).html( |
78 | 103 | _this.getNativePlayerHtml() |
79 | 104 | ); |
80 | | - |
81 | | - // Directly run postEmbedJS ( if playerElement is not available it will retry ) |
| 105 | + |
| 106 | + // Directly run postEmbedJS ( if playerElement is not available it will retry ) |
82 | 107 | _this.postEmbedJS(); |
83 | 108 | }, |
84 | | - |
| 109 | + |
85 | 110 | /** |
86 | 111 | * Get the native player embed code. |
87 | | - * |
| 112 | + * |
88 | 113 | * @param {object} playerAttribtues Attributes to be override in function call |
89 | | - * @return {object} cssSet css to apply to the player |
| 114 | + * @return {object} cssSet css to apply to the player |
90 | 115 | */ |
91 | 116 | getNativePlayerHtml: function( playerAttribtues, cssSet ){ |
92 | 117 | if( !playerAttribtues) { |
93 | 118 | playerAttribtues = {}; |
94 | 119 | } |
95 | 120 | // Update required attributes |
96 | | - if( !playerAttribtues[ 'id'] ) playerAttribtues['id'] = this.pid; |
| 121 | + if( !playerAttribtues[ 'id'] ) playerAttribtues['id'] = this.pid; |
97 | 122 | if( !playerAttribtues['src'] ) playerAttribtues['src'] = this.getSrc(); |
98 | | - |
| 123 | + |
99 | 124 | // If autoplay pass along to attribute ( needed for iPad / iPod no js autoplay support |
100 | 125 | if( this.autoplay ) { |
101 | 126 | playerAttribtues['autoplay'] = 'true'; |
102 | 127 | } |
103 | | - |
104 | | - |
| 128 | + |
| 129 | + |
105 | 130 | if( !cssSet ){ |
106 | 131 | cssSet = {}; |
107 | 132 | } |
108 | 133 | // Set default width height to 100% of parent container |
109 | 134 | if( !cssSet['width'] ) cssSet['width'] = '100%'; |
110 | 135 | if( !cssSet['height'] ) cssSet['height'] = '100%'; |
111 | | - |
| 136 | + |
112 | 137 | // Also need to set the loop param directly for iPad / iPod |
113 | 138 | if( this.loop ) { |
114 | 139 | playerAttribtues['loop'] = 'true'; |
115 | 140 | } |
116 | | - |
| 141 | + |
117 | 142 | var tagName = ( this.isAudio() ) ? 'audio' : 'video'; |
118 | | - |
| 143 | + |
119 | 144 | return $j( '<' + tagName + ' />' ) |
120 | | - // Add the special nativeEmbedPlayer to avoid any rewrites of of this video tag. |
| 145 | + // Add the special nativeEmbedPlayer to avoid any rewrites of of this video tag. |
121 | 146 | .addClass( 'nativeEmbedPlayerPid' ) |
122 | 147 | .attr( playerAttribtues ) |
123 | 148 | .css( cssSet ); |
124 | | - }, |
125 | | - |
| 149 | + }, |
| 150 | + |
126 | 151 | /** |
127 | | - * Post element javascript, binds event listeners and starts monitor |
128 | | - */ |
| 152 | + * Post element javascript, binds event listeners and starts monitor |
| 153 | + */ |
129 | 154 | postEmbedJS: function() { |
130 | 155 | var _this = this; |
131 | 156 | mw.log( "f:native:postEmbedJS:" ); |
132 | 157 | |
133 | | - // Setup local pointer: |
| 158 | + // Setup local pointer: |
134 | 159 | var vid = this.getPlayerElement(); |
135 | | - if ( typeof this.playerElement != 'undefined' ) { |
136 | | - // Apply media element bindings: |
137 | | - this.applyMediaElementBindings(); |
138 | | - |
139 | | - // Check for load flag |
140 | | - if ( this.onlyLoadFlag ) { |
141 | | - vid.pause(); |
142 | | - vid.load(); |
143 | | - } else { |
144 | | - // Issue play request |
145 | | - vid.play(); |
146 | | - } |
147 | | - |
148 | | - setTimeout( function() { |
149 | | - _this.monitor(); |
150 | | - }, 100 ); |
151 | | - |
152 | | - } else { |
153 | | - // False inserts don't seem to be as much of a problem as before: |
154 | | - mw.log( 'Could not grab vid obj trying again:' + typeof this.playerElement ); |
155 | | - this.grab_try_count++; |
156 | | - if ( this.grab_count == 20 ) { |
157 | | - mw.log( 'Could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ; |
158 | | - } else { |
159 | | - setTimeout( function() { |
160 | | - _this.postEmbedJS(); |
161 | | - }, 150 ); |
162 | | - } |
163 | | - |
| 160 | + // Apply media element bindings: |
| 161 | + this.applyMediaElementBindings(); |
| 162 | + |
| 163 | + // Check for load flag |
| 164 | + if ( this.onlyLoadFlag ) { |
| 165 | + vid.pause(); |
| 166 | + vid.load(); |
| 167 | + } else { |
| 168 | + // Issue play request |
| 169 | + vid.play(); |
164 | 170 | } |
| 171 | + |
| 172 | + setTimeout( function() { |
| 173 | + _this.monitor(); |
| 174 | + }, 100 ); |
165 | 175 | }, |
166 | | - |
| 176 | + |
167 | 177 | /** |
168 | | - * Apply media element bindings |
| 178 | + * Apply media element bindings |
169 | 179 | */ |
170 | 180 | applyMediaElementBindings: function(){ |
171 | 181 | var _this = this; |
— | — | @@ -173,46 +183,47 @@ |
174 | 184 | mw.log( " Error: applyMediaElementBindings without player elemnet"); |
175 | 185 | return ; |
176 | 186 | } |
177 | | - // Bind events to local js methods: |
178 | | - vid.addEventListener( 'canplaythrogh', function() { $j( _this ).trigger('canplaythrough'); }, true); |
| 187 | + |
| 188 | + // Bind events to local js methods: |
| 189 | + vid.addEventListener( 'canplaythrough', function() { $j( _this ).trigger('canplaythrough'); }, true); |
179 | 190 | vid.addEventListener( 'loadedmetadata', function() { _this.onloadedmetadata() }, true); |
180 | | - vid.addEventListener( 'progress', function( e ) { if( _this.onprogress ) { _this.onprogress( e ); } }, true); |
181 | | - vid.addEventListener( 'ended', function() { _this.onended() }, true); |
| 191 | + vid.addEventListener( 'progress', function( e ) { if( _this.onprogress ) { _this.onprogress( e ); } }, true); |
| 192 | + vid.addEventListener( 'ended', function() { _this.onended() }, true); |
182 | 193 | vid.addEventListener( 'seeking', function() { _this.onSeeking() }, true); |
183 | | - vid.addEventListener( 'seeked', function() { _this.onSeeked() }, true); |
184 | | - |
| 194 | + vid.addEventListener( 'seeked', function() { _this.onSeeked() }, true); |
| 195 | + |
185 | 196 | vid.addEventListener( 'pause', function() { if( _this.onPaused ) { _this.onPaused() } }, true ); |
186 | | - vid.addEventListener( 'play', function(){ _this.onPlay() }, true ); |
| 197 | + vid.addEventListener( 'play', function(){ _this.onPlay() }, true ); |
187 | 198 | vid.addEventListener( 'volumechange', function(){ _this.onVolumeChange() } , true ); |
188 | 199 | }, |
189 | | - |
| 200 | + |
190 | 201 | // basic monitor function to update buffer |
191 | 202 | monitor: function(){ |
192 | 203 | var _this = this; |
193 | 204 | var vid = _this.getPlayerElement(); |
194 | | - |
| 205 | + |
195 | 206 | // Update the bufferedPercent |
196 | | - if( vid && vid.buffered && vid.buffered.end && vid.duration ) { |
| 207 | + if( vid && vid.buffered && vid.buffered.end && vid.duration ) { |
197 | 208 | this.bufferedPercent = (vid.buffered.end(0) / vid.duration); |
198 | | - } |
| 209 | + } |
199 | 210 | _this.parent_monitor(); |
200 | 211 | }, |
201 | | - |
202 | | - |
| 212 | + |
| 213 | + |
203 | 214 | /** |
204 | | - * Issue a seeking request. |
| 215 | + * Issue a seeking request. |
205 | 216 | * |
206 | 217 | * @param {Float} percentage |
207 | 218 | */ |
208 | 219 | doSeek: function( percentage ) { |
209 | | - mw.log( 'Native::doSeek p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
| 220 | + mw.log( 'Native::doSeek p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
210 | 221 | this.seeking = true; |
211 | 222 | // Run the seeking hook |
212 | | - $j( this.embedPlayer ).trigger( 'onSeek' ); |
213 | | - |
| 223 | + $j( this.embedPlayer ).trigger( 'onSeek' ); |
| 224 | + |
214 | 225 | // Run the onSeeking interface update |
215 | 226 | this.controlBuilder.onSeek(); |
216 | | - |
| 227 | + |
217 | 228 | // @@todo check if the clip is loaded here (if so we can do a local seek) |
218 | 229 | if ( this.supportsURLTimeEncoding() ) { |
219 | 230 | // Make sure we could not do a local seek instead: |
— | — | @@ -220,18 +231,18 @@ |
221 | 232 | mw.log( "do local seek " + percentage + ' is already buffered < ' + this.bufferedPercent ); |
222 | 233 | this.doNativeSeek( percentage ); |
223 | 234 | } else { |
224 | | - // We support URLTimeEncoding call parent seek: |
| 235 | + // We support URLTimeEncoding call parent seek: |
225 | 236 | this.parent_doSeek( percentage ); |
226 | 237 | } |
227 | 238 | } else if ( this.playerElement && this.playerElement.duration ) { |
228 | | - // (could also check bufferedPercent > percentage seek (and issue oggz_chop request or not) |
| 239 | + // (could also check bufferedPercent > percentage seek (and issue oggz_chop request or not) |
229 | 240 | this.doNativeSeek( percentage ); |
230 | 241 | } else { |
231 | | - // try to do a play then seek: |
| 242 | + // try to do a play then seek: |
232 | 243 | this.doPlayThenSeek( percentage ) |
233 | 244 | } |
234 | 245 | }, |
235 | | - |
| 246 | + |
236 | 247 | /** |
237 | 248 | * Do a native seek by updating the currentTime |
238 | 249 | * @param {float} percentage Percent to seek to of full time |
— | — | @@ -240,83 +251,13 @@ |
241 | 252 | var _this = this; |
242 | 253 | mw.log( 'native::doNativeSeek::' + percentage ); |
243 | 254 | this.seeking = true; |
244 | | - this.seek_time_sec = 0; |
| 255 | + this.seek_time_sec = 0; |
245 | 256 | this.setCurrentTime( ( percentage * this.duration ) , function(){ |
246 | 257 | _this.seeking = false; |
247 | 258 | _this.monitor(); |
248 | | - }) |
| 259 | + }) |
249 | 260 | }, |
250 | | - |
251 | | - insertAndPlaySource: function( src , options ){ |
252 | | - mw.log("NativeEmbed:: insertAndPlaySource: " + src + ' insertAndPlayingConfig:' + this.insertAndPlayingConfig); |
253 | | - if(!options) |
254 | | - options = {}; |
255 | | - |
256 | | - if( options.lockUI ){ |
257 | | - this.playerElement.controls = false; |
258 | | - } |
259 | | - |
260 | | - // Make sure to capture the original source |
261 | | - if(! this.insertAndPlayingConfig ){ |
262 | | - //alert( 'setup this.insertAndPlayingConfig '); |
263 | | - this.insertAndPlayingConfig = { |
264 | | - 'src' : this.getSrc(), |
265 | | - 'time' : this.currentTime, |
266 | | - 'callback' : options.callback, |
267 | | - 'restoreControls' : options.lockUI |
268 | | - } |
269 | | - } |
270 | | - // Try to directly playback the source |
271 | | - this.switchSrc( src ); |
272 | | - |
273 | | - }, |
274 | | - restoreSourcePlayback: function( ){ |
275 | | - var _this = this; |
276 | | - mw.log( "RestoreSourcePlayback:: empty out insertAndPlayingConfig" ); |
277 | | - if( !this.insertAndPlayingConfig) { |
278 | | - mw.log("Error: called restored playback with empty insertAndPlayingConfig") |
279 | | - return; |
280 | | - } |
281 | | - this.switchSrc( this.insertAndPlayingConfig.src ); |
282 | | - //this.playerElement.play(); |
283 | | - // Remove insert and playing config flag |
284 | | - this.insertAndPlayingConfig = false; |
285 | | - |
286 | | - var time = this.insertAndPlayingConfig.time; |
287 | | - var callback = this.insertAndPlayingConfig.callback; |
288 | | - |
289 | | - // run the seek: |
290 | | - this.setCurrentTime( time ,function(){ |
291 | | - if( this.insertAndPlayingConfig.restoreControls ){ |
292 | | - this.playerElement.controls = true; |
293 | | - } |
294 | | - }); |
295 | | - // Give some time for ipad to figure out whats going on: |
296 | | - setTimeout(function(){ |
297 | | - _this.playerElement.load(); |
298 | | - _this.playerElement.play(); |
299 | | - },100); |
300 | | - |
301 | | - //alert("insertAndPlayingConfig:: " + this.insertAndPlayingConfig); |
302 | | - // Run the callback |
303 | | - if( callback ){ |
304 | | - callback(); |
305 | | - } |
306 | | - }, |
307 | | - switchSrc: function( src ){ |
308 | | - mw.log( 'switchSrc' ) |
309 | | - if( this.getPlayerElement() ){ |
310 | | - try{ |
311 | | - //this.playerElement.pause(); |
312 | | - this.playerElement.src = src; |
313 | | - this.playerElement.load(); |
314 | | - this.playerElement.play(); |
315 | | - } catch( e ){ |
316 | | - mw.log("Error: possible error in swiching source playback"); |
317 | | - } |
318 | | - } |
319 | | - }, |
320 | | - |
| 261 | + |
321 | 262 | /** |
322 | 263 | * Seek in a existing stream |
323 | 264 | * |
— | — | @@ -328,12 +269,12 @@ |
329 | 270 | this.play(); |
330 | 271 | var retryCount = 0; |
331 | 272 | var readyForSeek = function() { |
332 | | - _this.getPlayerElement(); |
| 273 | + _this.getPlayerElement(); |
333 | 274 | // If we have duration then we are ready to do the seek |
334 | 275 | if ( _this.playerElement && _this.playerElement.duration ) { |
335 | 276 | _this.doNativeSeek( percentage ); |
336 | 277 | } else { |
337 | | - // Try to get player for 40 seconds: |
| 278 | + // Try to get player for 40 seconds: |
338 | 279 | // (it would be nice if the onmetadata type callbacks where fired consistently) |
339 | 280 | if ( retryCount < 800 ) { |
340 | 281 | setTimeout( readyForSeek, 50 ); |
— | — | @@ -345,36 +286,42 @@ |
346 | 287 | } |
347 | 288 | readyForSeek(); |
348 | 289 | }, |
349 | | - |
| 290 | + |
350 | 291 | /** |
351 | 292 | * Set the current time with a callback |
352 | | - * |
| 293 | + * |
353 | 294 | * @param {Float} position Seconds to set the time to |
354 | | - * @param {Function} callback Function called once time has been set. |
| 295 | + * @param {Function} callback Function called once time has been set. |
355 | 296 | */ |
356 | | - setCurrentTime: function( time , callback, callbackCount ) { |
357 | | - var _this = this; |
| 297 | + setCurrentTime: function( time , callback, callbackCount ) { |
| 298 | + var _this = this; |
358 | 299 | if( !callbackCount ) |
359 | 300 | callbackCount = 0; |
360 | | - this.getPlayerElement(); |
| 301 | + this.getPlayerElement(); |
361 | 302 | if( _this.playerElement.readyState >= 1 ){ |
362 | 303 | if( _this.playerElement.currentTime == time ){ |
363 | 304 | callback(); |
364 | | - return; |
365 | | - } |
366 | | - var once = function( event ) { |
| 305 | + return; |
| 306 | + } |
| 307 | + var once = function( event ) { |
367 | 308 | if( callback ){ |
368 | 309 | callback(); |
369 | 310 | } |
370 | 311 | _this.playerElement.removeEventListener( 'seeked', once, false ); |
371 | | - }; |
372 | | - // Assume we will get to add the Listener before the seek is done |
| 312 | + }; |
| 313 | + // Assume we will get to add the Listener before the seek is done |
373 | 314 | _this.playerElement.addEventListener( 'seeked', once, false ); |
374 | | - _this.playerElement.currentTime = time; |
375 | | - } else { |
| 315 | + try { |
| 316 | + _this.playerElement.currentTime = time; |
| 317 | + } catch (e) { |
| 318 | + mw.log("Could not seek to this point. Unbuffered point."); |
| 319 | + callback(); |
| 320 | + return; |
| 321 | + } |
| 322 | + } else { |
376 | 323 | if( callbackCount >= 300 ){ |
377 | 324 | mw.log("Error with seek request, media never in ready state"); |
378 | | - return ; |
| 325 | + return ; |
379 | 326 | } |
380 | 327 | setTimeout( function(){ |
381 | 328 | _this.setCurrentTime( time, callback , callbackCount++); |
— | — | @@ -385,63 +332,63 @@ |
386 | 333 | /** |
387 | 334 | * Get the embed player time |
388 | 335 | */ |
389 | | - getPlayerElementTime: function() { |
390 | | - var _this = this; |
| 336 | + getPlayerElementTime: function() { |
| 337 | + var _this = this; |
391 | 338 | // Make sure we have .vid obj |
392 | | - this.getPlayerElement(); |
393 | | - |
| 339 | + this.getPlayerElement(); |
| 340 | + |
394 | 341 | if ( !this.playerElement ) { |
395 | | - mw.log( 'Error: mwEmbedPlayer::getPlayerElementTime: missing ' + this.id + ' stop monitor' ); |
| 342 | + mw.log( 'mwEmbedPlayer::getPlayerElementTime: ' + this.id + ' not in dom ( stop monitor)' ); |
396 | 343 | return false; |
397 | | - } |
398 | | - // Return the playerElement currentTime |
| 344 | + } |
| 345 | + // Return the playerElement currentTime |
399 | 346 | return this.playerElement.currentTime; |
400 | 347 | }, |
401 | | - |
| 348 | + |
402 | 349 | /** |
403 | 350 | * Get video src URI |
404 | | - * appends this.urlAppend for unique urls for re-requesting src urls on broken playback |
| 351 | + * appends this.urlAppend for unique urls for re-requesting src urls on broken playback |
405 | 352 | */ |
406 | 353 | getSrc: function() { |
407 | 354 | var src = this.parent_getSrc(); |
408 | | - if ( this.urlAppend != '' ) |
| 355 | + if ( this.urlAppend != '' ) |
409 | 356 | return src + ( ( src.indexOf( '?' ) == -1 ) ? '?':'&' ) + this.urlAppend; |
410 | 357 | return src; |
411 | | - }, |
412 | | - |
| 358 | + }, |
| 359 | + |
413 | 360 | /** |
414 | 361 | * Pause the video playback |
415 | 362 | * calls parent_pause to update the interface |
416 | 363 | */ |
417 | 364 | pause: function( ) { |
418 | | - this.getPlayerElement(); |
419 | | - this.parent_pause(); // update interface |
| 365 | + this.getPlayerElement(); |
| 366 | + this.parent_pause(); // update interface |
420 | 367 | if ( this.playerElement ) { // update player |
421 | 368 | if( !this.playerElement.paused ){ |
422 | 369 | this.playerElement.pause(); |
423 | 370 | } |
424 | 371 | } |
425 | 372 | }, |
426 | | - |
| 373 | + |
427 | 374 | /** |
428 | 375 | * Play back the video stream |
429 | 376 | * calls parent_play to update the interface |
430 | 377 | */ |
431 | 378 | play: function( ) { |
432 | | - |
433 | | - this.getPlayerElement(); |
| 379 | + |
| 380 | + this.getPlayerElement(); |
434 | 381 | this.parent_play(); // update interface |
435 | 382 | if ( this.playerElement && this.playerElement.play ) { |
436 | 383 | // issue a play request if the media is paused: |
437 | 384 | if( this.playerElement.paused ){ |
438 | 385 | this.playerElement.play(); |
439 | 386 | } |
440 | | - // re-start the monitor: |
| 387 | + // re-start the monitor: |
441 | 388 | this.monitor(); |
442 | 389 | } |
443 | 390 | }, |
444 | 391 | /** |
445 | | - * Stop the player ( end all listeners ) |
| 392 | + * Stop the player ( end all listeners ) |
446 | 393 | */ |
447 | 394 | stop:function(){ |
448 | 395 | if( this.playerElement ){ |
— | — | @@ -449,61 +396,62 @@ |
450 | 397 | } |
451 | 398 | this.parent_stop(); |
452 | 399 | }, |
453 | | - |
| 400 | + |
454 | 401 | /** |
455 | 402 | * Toggle the Mute |
456 | 403 | * calls parent_toggleMute to update the interface |
457 | | - */ |
| 404 | + */ |
458 | 405 | toggleMute: function() { |
459 | 406 | this.parent_toggleMute(); |
460 | 407 | this.getPlayerElement(); |
461 | 408 | if ( this.playerElement ) |
462 | 409 | this.playerElement.muted = this.muted; |
463 | 410 | }, |
464 | | - |
| 411 | + |
465 | 412 | /** |
466 | 413 | * Update Volume |
467 | 414 | * |
468 | 415 | * @param {Float} percentage Value between 0 and 1 to set audio volume |
469 | | - */ |
| 416 | + */ |
470 | 417 | setPlayerElementVolume : function( percentage ) { |
471 | 418 | if ( this.getPlayerElement() ) { |
472 | | - // Disable mute if positive volume |
| 419 | + // Disable mute if positive volume |
473 | 420 | if( percentage != 0 ) { |
474 | 421 | this.playerElement.muted = false; |
475 | 422 | } |
476 | 423 | this.playerElement.volume = percentage; |
477 | 424 | } |
478 | 425 | }, |
479 | | - |
| 426 | + |
480 | 427 | /** |
481 | 428 | * get Volume |
482 | 429 | * |
483 | | - * @return {Float} |
| 430 | + * @return {Float} |
484 | 431 | * Audio volume between 0 and 1. |
485 | | - */ |
486 | | - getPlayerElementVolume: function() { |
| 432 | + */ |
| 433 | + getPlayerElementVolume: function() { |
487 | 434 | if ( this.getPlayerElement() ) { |
488 | 435 | return this.playerElement.volume; |
489 | 436 | } |
490 | 437 | }, |
491 | 438 | /** |
492 | 439 | * get the native muted state |
493 | | - */ |
| 440 | + */ |
494 | 441 | getPlayerElementMuted: function(){ |
495 | 442 | if ( this.getPlayerElement() ) { |
496 | 443 | return this.playerElement.muted; |
497 | 444 | } |
498 | 445 | }, |
499 | | - |
| 446 | + |
500 | 447 | /** |
501 | 448 | * Handle volume change are handled via "monitor" as to not do too many binding triggers per seconds. |
502 | 449 | */ |
503 | 450 | onVolumeChange: function(){ |
504 | 451 | //mw.log( "native::volumechange::trigger" ); |
505 | 452 | //this.volume = this.playerElement.volume; |
| 453 | + $j( this ).trigger( 'volumechange' ); |
506 | 454 | }, |
507 | | - |
| 455 | + |
508 | 456 | /** |
509 | 457 | * Get the native media duration |
510 | 458 | */ |
— | — | @@ -512,20 +460,20 @@ |
513 | 461 | return this.playerElement.duration; |
514 | 462 | } |
515 | 463 | }, |
516 | | - |
| 464 | + |
517 | 465 | /** |
518 | 466 | * load the video stream with a callback fired once the video is "loaded" |
519 | 467 | * |
520 | 468 | * @parma {Function} callbcak Function called once video is loaded |
521 | 469 | */ |
522 | 470 | load: function( callback ) { |
523 | | - this.getPlayerElement(); |
| 471 | + this.getPlayerElement(); |
524 | 472 | if ( !this.playerElement ) { |
525 | 473 | // No vid loaded |
526 | 474 | mw.log( 'native::load() ... doEmbed' ); |
527 | 475 | this.onlyLoadFlag = true; |
528 | 476 | this.doEmbedHTML(); |
529 | | - this.onLoadedCallback = callback; |
| 477 | + this.onLoadedCallback = callback; |
530 | 478 | } else { |
531 | 479 | // Should not happen offten |
532 | 480 | this.playerElement.load(); |
— | — | @@ -533,125 +481,123 @@ |
534 | 482 | callback(); |
535 | 483 | } |
536 | 484 | }, |
537 | | - |
| 485 | + |
538 | 486 | /** |
539 | | - * Get /update the playerElement value |
540 | | - */ |
541 | | - getPlayerElement: function () { |
| 487 | + * Get /update the playerElement value |
| 488 | + */ |
| 489 | + getPlayerElement: function () { |
542 | 490 | this.playerElement = $j( '#' + this.pid ).get( 0 ); |
543 | 491 | return this.playerElement; |
544 | 492 | }, |
545 | | - |
| 493 | + |
546 | 494 | /** |
547 | | - * Bindings for the Video Element Events |
| 495 | + * Bindings for the Video Element Events |
548 | 496 | */ |
549 | | - |
| 497 | + |
550 | 498 | /** |
551 | 499 | * Local method for seeking event |
552 | | - * fired when "seeking" |
| 500 | + * fired when "seeking" |
553 | 501 | */ |
554 | | - onSeeking: function() { |
| 502 | + onSeeking: function() { |
555 | 503 | mw.log( "native:onSeeking"); |
556 | | - // Trigger the html5 seeking event |
| 504 | + // Trigger the html5 seeking event |
557 | 505 | //( if not already set from interface ) |
558 | | - if( !this.seeking ) { |
| 506 | + if( !this.seeking ) { |
559 | 507 | this.seeking = true; |
560 | 508 | // Run the seeking hook (somewhat redundant ) |
561 | 509 | $j( this ).trigger( 'onSeek' ); |
562 | | - |
| 510 | + |
563 | 511 | // Run the onSeeking interface update |
564 | | - this.controlBuilder.onSeek(); |
565 | | - |
| 512 | + this.controlBuilder.onSeek(); |
| 513 | + |
566 | 514 | // Trigger the html5 "seeking" trigger |
567 | | - mw.log("native:seeking:trigger:: " + this.seeking); |
| 515 | + mw.log("native:seeking:trigger:: " + this.seeking); |
568 | 516 | $j( this ).trigger( 'seeking' ); |
569 | 517 | } |
570 | 518 | }, |
571 | | - |
| 519 | + |
572 | 520 | /** |
573 | 521 | * Local method for seeked event |
574 | | - * fired when done seeking |
| 522 | + * fired when done seeking |
575 | 523 | */ |
576 | 524 | onSeeked: function() { |
577 | 525 | mw.log("native:onSeeked"); |
578 | | - this.seeking = false; |
| 526 | + |
579 | 527 | mw.log("native:onSeeked:trigger"); |
580 | | - // Trigger the html5 action on the parent |
581 | | - $j( this ).trigger( 'seeked' ); |
| 528 | + // Trigger the html5 action on the parent |
| 529 | + if( this.seeking && this.useNativePlayerControls() ){ |
| 530 | + this.seeking = false; |
| 531 | + $j( this ).trigger( 'seeked' ); |
| 532 | + } |
| 533 | + this.seeking = false; |
582 | 534 | }, |
583 | | - |
| 535 | + |
584 | 536 | /** |
585 | 537 | * Handle the native paused event |
586 | | - */ |
| 538 | + */ |
587 | 539 | onPaused: function(){ |
588 | 540 | mw.log( "EmbedPlayer:native: OnPaused" ); |
589 | | - this.parent_pause(); |
| 541 | + this.parent_pause(); |
590 | 542 | }, |
591 | | - |
| 543 | + |
592 | 544 | /** |
593 | | - * Handle the native play event |
| 545 | + * Handle the native play event |
594 | 546 | */ |
595 | 547 | onPlay: function(){ |
596 | | - mw.log("EmbedPlayer:native:: OnPlay"); |
597 | | - // Update the interface |
| 548 | + mw.log("EmbedPlayer:native:: OnPlay"); |
| 549 | + // Update the interface ( if paused ) |
598 | 550 | this.parent_play(); |
599 | 551 | }, |
600 | | - |
601 | | - /** |
| 552 | + |
| 553 | + /** |
602 | 554 | * Local method for metadata ready |
603 | 555 | * fired when metadata becomes available |
604 | 556 | * |
605 | | - * Used to update the media duration to |
606 | | - * accurately reflect the src duration |
| 557 | + * Used to update the media duration to |
| 558 | + * accurately reflect the src duration |
607 | 559 | */ |
608 | 560 | onloadedmetadata: function() { |
609 | 561 | this.getPlayerElement(); |
610 | | - if ( this.playerElement && ! isNaN( this.playerElement.duration ) ) { |
611 | | - mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() ); |
| 562 | + if ( this.playerElement && ! isNaN( this.playerElement.duration ) ) { |
| 563 | + mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() ); |
612 | 564 | this.duration = this.playerElement.duration; |
613 | 565 | } |
614 | | - |
| 566 | + |
615 | 567 | //Fire "onLoaded" flags if set |
616 | 568 | if( typeof this.onLoadedCallback == 'function' ) { |
617 | 569 | this.onLoadedCallback(); |
618 | 570 | } |
619 | | - |
| 571 | + |
620 | 572 | // Tigger "media loaded" |
621 | 573 | if( ! this.mediaLoadedFlag ){ |
622 | 574 | $j( this ).trigger( 'mediaLoaded' ); |
623 | 575 | this.mediaLoadedFlag = true; |
624 | 576 | } |
625 | 577 | }, |
626 | | - |
| 578 | + |
627 | 579 | /** |
628 | 580 | * Local method for progress event |
629 | 581 | * fired as the video is downloaded / buffered |
630 | 582 | * |
631 | 583 | * Used to update the bufferedPercent |
632 | 584 | */ |
633 | | - onprogress: function( e ) { |
| 585 | + onprogress: function( e ) { |
634 | 586 | if( e.loaded && e.total ) { |
635 | | - this.bufferedPercent = e.loaded / e.total; |
| 587 | + this.bufferedPercent = e.loaded / e.total; |
636 | 588 | this.progressEventData = e.loaded; |
637 | | - } |
| 589 | + } |
638 | 590 | }, |
639 | | - |
| 591 | + |
640 | 592 | /** |
641 | 593 | * Local method for progress event |
642 | 594 | * fired as the video is downloaded / buffered |
643 | 595 | * |
644 | 596 | * Used to update the bufferedPercent |
645 | | - */ |
| 597 | + */ |
646 | 598 | onended: function() { |
647 | | - var _this = this; |
648 | | - mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() + |
649 | | - ' insertAndPlayingConfig: ' + this.insertAndPlayingConfig); |
650 | | - |
651 | | - if( this.insertAndPlayingConfig ){ |
652 | | - this.restoreSourcePlayback(); |
653 | | - this.insertAndPlayingConfig = false; |
654 | | - return ; |
655 | | - } |
| 599 | + var _this = this; |
| 600 | + mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() ); |
| 601 | + |
656 | 602 | this.onClipDone(); |
657 | 603 | } |
658 | 604 | }; |
Index: trunk/extensions/TimedMediaHandler/EmbedPlayer/mw.EmbedPlayerKplayer.js |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 | // Use a relative url if the protocal is file:// |
44 | 44 | if( mw.parseUri( document.URL).protocol == 'file' ) { |
45 | 45 | playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player'; |
46 | | - flashvars.entryId = _this.getSrc(); |
| 46 | + flashvars.entryId = _this.getSrc(); |
47 | 47 | } |
48 | 48 | |
49 | 49 | flashvars.debugMode = "true"; |
— | — | @@ -92,18 +92,17 @@ |
93 | 93 | |
94 | 94 | // Direct object embed |
95 | 95 | /*$j( this ).html( |
96 | | - '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">'+ |
97 | | - '<param name="movie" value="myContent.swf" />'+ |
98 | | - '<!--[if !IE]>-->'+ |
99 | | - '<object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">'+ |
100 | | - '<!--<![endif]-->'+ |
101 | | - '<p> error with flash embed</p>' |
102 | | - '<!--[if !IE]>-->'+ |
103 | | - '</object>'+ |
104 | | - '<!--<![endif]-->'+ |
105 | | - '</object>' |
106 | | - )*/ |
107 | | - |
| 96 | + '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">'+ |
| 97 | + '<param name="movie" value="myContent.swf" />'+ |
| 98 | + '<!--[if !IE]>-->'+ |
| 99 | + '<object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">'+ |
| 100 | + '<!--<![endif]-->'+ |
| 101 | + '<p> error with flash embed</p>' |
| 102 | + '<!--[if !IE]>-->'+ |
| 103 | + '</object>'+ |
| 104 | + '<!--<![endif]-->'+ |
| 105 | + '</object>' |
| 106 | + )*/ |
108 | 107 | |
109 | 108 | setTimeout( function() { |
110 | 109 | _this.postEmbedJS(); |
— | — | @@ -217,7 +216,7 @@ |
218 | 217 | if ( this.supportsURLTimeEncoding() ){ |
219 | 218 | |
220 | 219 | // Make sure we could not do a local seek instead: |
221 | | - if ( !( percentage < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump )) { |
| 220 | + if ( !( percentage < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump )) { |
222 | 221 | // We support URLTimeEncoding call parent seek: |
223 | 222 | this.parent_doSeek( percentage ); |
224 | 223 | return; |
— | — | @@ -227,7 +226,7 @@ |
228 | 227 | if( this.playerElement ) { |
229 | 228 | var seekTime = percentage * this.getDuration(); |
230 | 229 | // Issue the seek to the flash player: |
231 | | - this.playerElement.sendNotification('doSeek', seekTime); |
| 230 | + this.playerElement.sendNotification('doSeek', seekTime); |
232 | 231 | |
233 | 232 | // Kdp is missing seek done callback |
234 | 233 | setTimeout(function() { |
— | — | @@ -262,7 +261,7 @@ |
263 | 262 | if ( _this.playerElement && _this.playerElement.sendNotification && _this.getDuration() && _this.bufferedPercent ) { |
264 | 263 | var seekTime = percentage * _this.getDuration(); |
265 | 264 | // Issue the seek to the flash player: |
266 | | - _this.playerElement.sendNotification('doSeek', seekTime); |
| 265 | + _this.playerElement.sendNotification('doSeek', seekTime); |
267 | 266 | } else { |
268 | 267 | // Try to get player for 20 seconds: |
269 | 268 | if ( getPlayerCount < 400 ) { |
— | — | @@ -297,7 +296,7 @@ |
298 | 297 | * function called by flash when the total media size changes |
299 | 298 | */ |
300 | 299 | onBytesTotalChange: function(data, id) { |
301 | | - this.bytesTotal = data.newValue ; |
| 300 | + this.bytesTotal = data.newValue ; |
302 | 301 | }, |
303 | 302 | |
304 | 303 | /** |
— | — | @@ -306,11 +305,11 @@ |
307 | 306 | onBytesDownloadedChange: function( data, id){ |
308 | 307 | mw.log( 'onBytesDownloadedChange'); |
309 | 308 | this.bytesLoaded = data.newValue; |
310 | | - this.bufferedPercent = this.bytesLoaded / this.bytesTotal; |
| 309 | + this.bufferedPercent = this.bytesLoaded / this.bytesTotal; |
311 | 310 | |
312 | 311 | // Fire the parent html5 action |
313 | 312 | $j( this ).trigger( 'progress', { |
314 | | - 'loaded' : this.bytesLoaded, |
| 313 | + 'loaded' : this.bytesLoaded, |
315 | 314 | 'total' : this.bytesTotal |
316 | 315 | } ); |
317 | 316 | }, |