Index: trunk/extensions/OggHandler/OggHandler.php |
— | — | @@ -17,7 +17,7 @@ |
18 | 18 | ini_get( 'include_path' ) ); |
19 | 19 | |
20 | 20 | // Bump this when updating OggPlayer.js to help update caches |
21 | | -$wgOggScriptVersion = '7'; |
| 21 | +$wgOggScriptVersion = '8'; |
22 | 22 | |
23 | 23 | $wgExtensionMessagesFiles['OggHandler'] = "$oggDir/OggHandler.i18n.php"; |
24 | 24 | $wgParserOutputHooks['OggHandler'] = array( 'OggHandler', 'outputHook' ); |
Index: trunk/extensions/OggHandler/OggPlayer.js |
— | — | @@ -4,19 +4,34 @@ |
5 | 5 | 'msie': false, |
6 | 6 | 'safari' : false, |
7 | 7 | 'opera' : false, |
| 8 | + 'mozilla': false, |
8 | 9 | |
9 | 10 | // List of players in order of preference |
10 | 11 | // Downpreffed VLC because it crashes my browser all the damn time -- TS |
11 | | - 'players': ['cortado', 'quicktime-mozilla', 'quicktime-activex', 'vlc-mozilla', 'vlc-activex', 'oggPlugin', 'videoElement'], |
| 12 | + 'players': ['cortado', 'quicktime-mozilla', 'quicktime-activex', 'vlc-mozilla', 'vlc-activex', 'totem', 'kmplayer', 'kaffeine', 'oggPlugin', 'videoElement'], |
12 | 13 | |
| 14 | + // Client support table |
13 | 15 | 'clientSupports': { 'thumbnail' : true }, |
| 16 | + |
| 17 | + // MIME type to be used to invoke a given plugin with <object> |
| 18 | + // May be changed by detect() |
| 19 | + 'mimeTypes' : { |
| 20 | + 'quicktime-mozilla': 'video/quicktime', |
| 21 | + 'quicktime-activex': 'video/quicktime', |
| 22 | + 'vlc-mozilla': 'application/x-vlc-plugin', |
| 23 | + 'oggPlugin': 'application/ogg', |
| 24 | + 'totem': 'application/ogg', |
| 25 | + 'kmplayer': 'application/ogg', |
| 26 | + 'kaffeine': 'application/ogg' |
| 27 | + }, |
| 28 | + |
14 | 29 | 'savedThumbs': {}, |
15 | 30 | 'qtTimers' : {}, |
16 | 31 | // Text for new messages, to support cached HTML invocation |
17 | | - 'defaultMsg' : { |
18 | | - 'ogg-no-xiphqt': 'You do not appear to have the XiphQT component for QuickTime. QuickTime cannot play ' + |
19 | | - 'Ogg files without this component. Please ' + |
20 | | - '<a href="http://www.mediawiki.org/wiki/Extension:OggHandler/Client_download">download XiphQT</a> or choose another player.' |
| 32 | + 'defaultMsg' : { |
| 33 | + 'ogg-player-totem': 'Totem', |
| 34 | + 'ogg-player-kmplayer': 'KMPlayer', |
| 35 | + 'ogg-player-kaffeine': 'Kaffeine' |
21 | 36 | }, |
22 | 37 | |
23 | 38 | // Configuration from MW |
— | — | @@ -44,7 +59,7 @@ |
45 | 60 | this.savedThumbs[params.id] = thumb; |
46 | 61 | } |
47 | 62 | |
48 | | - this.detect( elt ); |
| 63 | + this.detect(); |
49 | 64 | |
50 | 65 | if ( !player ) { |
51 | 66 | // See if there is a cookie specifying a preferred player |
— | — | @@ -73,7 +88,10 @@ |
74 | 89 | this.embedVideoElement( elt, params ); |
75 | 90 | break; |
76 | 91 | case 'oggPlugin': |
77 | | - this.embedOggPlugin( elt, params ); |
| 92 | + case 'kaffeine': |
| 93 | + case 'totem': |
| 94 | + case 'kmplayer': |
| 95 | + this.embedOggPlugin( elt, params, player ); |
78 | 96 | break; |
79 | 97 | case 'vlc-mozilla': |
80 | 98 | this.embedVlcPlugin( elt, params ); |
— | — | @@ -114,8 +132,12 @@ |
115 | 133 | } |
116 | 134 | }, |
117 | 135 | |
| 136 | + 'debug': function( s ) { |
| 137 | + //alert(s); |
| 138 | + }, |
| 139 | + |
118 | 140 | // Detect client capabilities |
119 | | - 'detect': function( elt ) { |
| 141 | + 'detect': function() { |
120 | 142 | if (this.detectionDone) { |
121 | 143 | return; |
122 | 144 | } |
— | — | @@ -123,16 +145,16 @@ |
124 | 146 | |
125 | 147 | // First some browser detection |
126 | 148 | this.msie = ( navigator.appName == "Microsoft Internet Explorer" ); |
| 149 | + this.mozilla = ( navigator.appName == "Netscape" ); |
127 | 150 | this.opera = ( navigator.appName == 'Opera' ); |
128 | 151 | this.safari = ( navigator.vendor && navigator.vendor.substr( 0, 5 ) == 'Apple' ); |
| 152 | + this.konqueror = ( navigator.appName == 'Konqueror' ); |
129 | 153 | |
130 | 154 | // In Mozilla, navigator.javaEnabled() only tells us about preferences, we need to |
131 | 155 | // search navigator.mimeTypes to see if it's installed |
132 | 156 | var javaEnabled = navigator.javaEnabled(); |
133 | 157 | // In Opera, navigator.javaEnabled() is all there is |
134 | 158 | var invisibleJava = this.opera; |
135 | | - // Some browsers filter out duplicate mime types, hiding some plugins |
136 | | - var uniqueMimesOnly = this.opera || this.safari; |
137 | 159 | |
138 | 160 | // Opera will switch off javaEnabled in preferences if java can't be found. |
139 | 161 | // And it doesn't register an application/x-java-applet mime type like Mozilla does. |
— | — | @@ -140,6 +162,12 @@ |
141 | 163 | this.clientSupports['cortado'] = true; |
142 | 164 | } |
143 | 165 | |
| 166 | + if ( this.konqueror ) { |
| 167 | + // Bugged as of 3.5.9 |
| 168 | + // Applet freezes shortly after starting |
| 169 | + javaEnabled = false; |
| 170 | + } |
| 171 | + |
144 | 172 | // ActiveX plugins |
145 | 173 | // VLC |
146 | 174 | if ( this.testActiveX( 'VideoLAN.VLCPlugin.2' ) ) { |
— | — | @@ -155,64 +183,119 @@ |
156 | 184 | } |
157 | 185 | |
158 | 186 | // <video> element |
159 | | - elt.innerHTML = '<video id="testvideo"></video>\n'; |
160 | | - var testvideo = document.getElementById('testvideo'); |
161 | | - if (testvideo && testvideo.play) { |
| 187 | + if ( typeof HTMLVideoElement == 'object' ) { |
162 | 188 | this.clientSupports['videoElement'] = true; |
163 | 189 | } |
164 | 190 | |
| 191 | + if (!navigator.mimeTypes || navigator.mimeTypes.length == 0) { |
| 192 | + // No Mozilla plugins, all done |
| 193 | + return; |
| 194 | + } |
| 195 | + |
165 | 196 | // Mozilla plugins |
166 | | - |
167 | | - if(navigator.mimeTypes && navigator.mimeTypes.length > 0) { |
168 | | - for ( var i = 0; i < navigator.mimeTypes.length; i++) { |
169 | | - var entry = navigator.mimeTypes[i]; |
170 | | - var type = entry.type; |
171 | | - var semicolonPos = type.indexOf( ';' ); |
172 | | - if ( semicolonPos > -1 ) { |
173 | | - type = type.substr( 0, semicolonPos ); |
| 197 | + var typesByPlayer = {}; |
| 198 | + var playersByType = {}; |
| 199 | + var numPlayersByType = {}; |
| 200 | + var player; |
| 201 | + var i; |
| 202 | + for ( i = 0; i < navigator.mimeTypes.length; i++) { |
| 203 | + var entry = navigator.mimeTypes[i]; |
| 204 | + var type = entry.type; |
| 205 | + var semicolonPos = type.indexOf( ';' ); |
| 206 | + if ( semicolonPos > -1 ) { |
| 207 | + type = type.substr( 0, semicolonPos ); |
| 208 | + } |
| 209 | + |
| 210 | + var plugin = entry.enabledPlugin; |
| 211 | + // In case it is null or undefined |
| 212 | + var pluginName = plugin && plugin.name ? plugin.name : ''; |
| 213 | + var pluginFilename = plugin && plugin.filename ? plugin.filename : ''; |
| 214 | + player = ''; |
| 215 | + |
| 216 | + if ( javaEnabled && type == 'application/x-java-applet' ) { |
| 217 | + // We use <applet> so we don't have to worry about unique types |
| 218 | + this.clientSupports['cortado'] = true; |
| 219 | + // But it could conflict with another plugin |
| 220 | + // Set player='' to avoid double registration of cortado |
| 221 | + player = ''; |
| 222 | + } else if ( pluginFilename.indexOf( 'libtotem' ) > -1 ) { |
| 223 | + // Totem |
| 224 | + player = 'totem'; |
| 225 | + } else if ( pluginFilename.indexOf( 'libkmplayerpart' ) > -1 ) { |
| 226 | + // KMPlayer is fussy about what type you give it |
| 227 | + if ( pluginName == 'Windows Media Player Plugin' |
| 228 | + || pluginName == 'QuickTime Plug-in' ) |
| 229 | + { |
| 230 | + player = 'kmplayer'; |
174 | 231 | } |
| 232 | + } else if ( pluginFilename.indexOf( 'kaffeineplugin' ) > -1 ) { |
| 233 | + // Kaffeine |
| 234 | + player = 'kaffeine'; |
| 235 | + } else if ( pluginName.indexOf( 'QuickTime Plug-in' ) > -1 ) { |
| 236 | + // Note: Totem and KMPlayer also use this pluginName, which is |
| 237 | + // why we check for them first |
| 238 | + player = 'quicktime-mozilla'; |
| 239 | + } else if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
| 240 | + player = 'vlc-mozilla'; |
| 241 | + } else if ( type == 'application/ogg' ) { |
| 242 | + player = 'oggPlugin'; |
| 243 | + } |
175 | 244 | |
176 | | - var plugin = entry.enabledPlugin; |
177 | | - // In case it is null or undefined |
178 | | - var pluginName = plugin && plugin.name ? plugin.name : ''; |
179 | | - var pluginFilename = plugin && plugin.filename ? plugin.filename : ''; |
180 | | - |
181 | | - if ( javaEnabled && type == 'application/x-java-applet' ) { |
182 | | - this.clientSupports['cortado'] = true; |
183 | | - continue; |
| 245 | + if ( this.konqueror && player == 'vlc-mozilla' ) { |
| 246 | + // In Konqueror 3.5.9, VLC is not scriptable, has no controls, and crashes the browser |
| 247 | + player = ''; |
| 248 | + } |
| 249 | + |
| 250 | + // Update some hashtables to track unique type assignment |
| 251 | + // Slightly complicated because players can and do conflict with themselves |
| 252 | + if ( !( player in typesByPlayer ) ) { |
| 253 | + typesByPlayer[player] = {}; |
| 254 | + } |
| 255 | + typesByPlayer[player][type] = true; |
| 256 | + if ( !( type in playersByType ) ) { |
| 257 | + playersByType[type] = {}; |
| 258 | + numPlayersByType[type] = 0; |
| 259 | + } |
| 260 | + if ( !( player in playersByType[type] ) ) { |
| 261 | + playersByType[type][player] = true; |
| 262 | + numPlayersByType[type]++; |
| 263 | + } |
| 264 | + } |
| 265 | + |
| 266 | + // Determine a unique MIME type for each player found |
| 267 | + for ( i = 0; i < this.players.length; i++ ) { |
| 268 | + player = this.players[i]; |
| 269 | + if ( !( player in typesByPlayer ) ) { |
| 270 | + continue; |
| 271 | + } |
| 272 | + // Is the default OK? |
| 273 | + var defaultType = this.mimeTypes[player]; |
| 274 | + if ( defaultType in numPlayersByType |
| 275 | + && numPlayersByType[defaultType] == 1 |
| 276 | + && defaultType in typesByPlayer[player] ) |
| 277 | + { |
| 278 | + // Yes, use it |
| 279 | + this.debug( player + " -> " + defaultType ); |
| 280 | + this.clientSupports[player] = true; |
| 281 | + continue; |
| 282 | + } |
| 283 | + // Search for a unique type |
| 284 | + for ( var type in typesByPlayer[player] ) { |
| 285 | + if ( numPlayersByType[type] == 1 ) { |
| 286 | + // Found a unique type |
| 287 | + this.mimeTypes[player] = type; |
| 288 | + this.clientSupports[player] = true; |
| 289 | + this.debug( player + " => " + type ); |
| 290 | + break; |
184 | 291 | } |
185 | | - if ( type == 'application/ogg' ) { |
186 | | - if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
187 | | - this.clientSupports['vlc-mozilla'] = true; |
188 | | - } else if ( pluginName.indexOf( 'QuickTime' ) > -1 ) { |
189 | | - this.clientSupports['quicktime-mozilla'] = true; |
190 | | - } else { |
191 | | - this.clientSupports['oggPlugin'] = true; |
192 | | - } |
193 | | - continue; |
194 | | - } else if ( uniqueMimesOnly ) { |
195 | | - // Could cause false positives if codecs are missing... |
196 | | - if ( type == 'application/x-vlc-player' ) { |
197 | | - this.clientSupports['vlc-mozilla'] = true; |
198 | | - continue; |
199 | | - } else if ( type == 'video/quicktime' ) { |
200 | | - this.clientSupports['quicktime-mozilla'] = true; |
201 | | - continue; |
202 | | - } |
| 292 | + } |
| 293 | + if ( !(player in this.clientSupports ) ) { |
| 294 | + if ( typesByPlayer[player].length > 0 ) { |
| 295 | + this.debug( "No unique MIME type for " + player ); |
| 296 | + } else { |
| 297 | + this.debug( "No types for player " + player ); |
203 | 298 | } |
204 | | - |
205 | | - if ( type == 'video/quicktime' ) { |
206 | | - if ( pluginFilename.indexOf( 'libtotem' ) > -1 ) { |
207 | | - // Totem plugin on *nix... |
208 | | - // Will in fact play oggs, but we'll have a native |
209 | | - // plugin alongside it. Skip the entry. |
210 | | - } else { |
211 | | - this.clientSupports['quicktime-mozilla'] = true; |
212 | | - continue; |
213 | | - } |
214 | | - } |
215 | 299 | } |
216 | | - |
217 | 300 | } |
218 | 301 | }, |
219 | 302 | |
— | — | @@ -321,13 +404,13 @@ |
322 | 405 | if ( player == selectedPlayer ) { |
323 | 406 | var strong = document.createElement( 'strong' ); |
324 | 407 | strong.appendChild( document.createTextNode( |
325 | | - this.msg[playerMsg] + ' ' + this.msg['ogg-player-selected'] ) ); |
| 408 | + this.getMsg(playerMsg) + ' ' + this.msg['ogg-player-selected'] ) ); |
326 | 409 | li.appendChild( strong ); |
327 | 410 | } else { |
328 | 411 | a = document.createElement( 'a' ); |
329 | 412 | a.href = 'javascript:void("' + player + '")'; |
330 | 413 | a.onclick = this.makePlayerFunction( player, params ); |
331 | | - a.appendChild( document.createTextNode( this.msg[playerMsg] ) ); |
| 414 | + a.appendChild( document.createTextNode( this.getMsg(playerMsg) ) ); |
332 | 415 | li.appendChild( a ); |
333 | 416 | } |
334 | 417 | ul.appendChild( li ); |
— | — | @@ -443,11 +526,11 @@ |
444 | 527 | } |
445 | 528 | }, |
446 | 529 | |
447 | | - 'embedOggPlugin': function ( elt, params ) { |
| 530 | + 'embedOggPlugin': function ( elt, params, player ) { |
448 | 531 | var id = elt.id + "_obj"; |
449 | 532 | elt.innerHTML += |
450 | 533 | "<div><object id=" + this.hq( id ) + |
451 | | - " type='application/ogg'" + |
| 534 | + " type='" + this.mimeTypes[player] + "'" + |
452 | 535 | " width=" + this.hq( params.width ) + |
453 | 536 | " height=" + this.hq( params.height + this.controlsHeightGuess ) + |
454 | 537 | " data=" + this.hq( params.videoUrl ) + "></object></div>"; |
— | — | @@ -457,7 +540,7 @@ |
458 | 541 | var id = elt.id + "_obj"; |
459 | 542 | elt.innerHTML += |
460 | 543 | "<div><object id=" + this.hq( id ) + |
461 | | - " type='application/x-vlc-plugin'" + |
| 544 | + " type='" + this.mimeTypes['vlc-mozilla'] + "'" + |
462 | 545 | " width=" + this.hq( params.width ) + |
463 | 546 | " height=" + this.hq( params.height ) + |
464 | 547 | " data=" + this.hq( params.videoUrl ) + "></object></div>"; |
— | — | @@ -522,12 +605,13 @@ |
523 | 606 | ' <param name="autoPlay" value="true"/>' + |
524 | 607 | ' <param name="showStatus" value="show"/>' + |
525 | 608 | ' <param name="showSpeaker" value="false"/>' + |
| 609 | + ' <param name="debug" value="4"/>' + |
526 | 610 | ' <param name="statusHeight" value="' + statusHeight + '"/>' + |
527 | 611 | '</applet>'; |
528 | 612 | |
529 | 613 | // Wrap it in an iframe to avoid hanging the rendering thread in FF 2.0 and similar |
530 | | - // Doesn't work in Safari/Mac |
531 | | - if ( !this.msie && !this.safari ) { |
| 614 | + // Doesn't work in MSIE or Safari/Mac or Opera 9.5 |
| 615 | + if ( this.mozilla ) { |
532 | 616 | var iframeHtml = '<html><body>' + html + '</body></html>'; |
533 | 617 | var iframeJs = 'parent.wgOggPlayer.writeApplet(self, "' + iframeHtml.replace( /"/g, '\\"' ) + '");'; |
534 | 618 | var iframeUrl = 'javascript:' + encodeURIComponent( iframeJs ); |
— | — | @@ -542,7 +626,7 @@ |
543 | 627 | |
544 | 628 | 'writeApplet' : function ( win, html ) { |
545 | 629 | win.document.write( html ); |
546 | | - win.stop(); |
| 630 | + if ( win.stop ) win.stop(); |
547 | 631 | // Disable autoplay on back button |
548 | 632 | this_ = this; |
549 | 633 | win.setTimeout( |
— | — | @@ -563,7 +647,7 @@ |
564 | 648 | |
565 | 649 | elt.innerHTML += |
566 | 650 | "<div><object id=" + this.hq( id ) + |
567 | | - " type='video/quicktime'" + |
| 651 | + " type='" + this.mimeTypes[player] + "'" + |
568 | 652 | " width=" + this.hq( params.width ) + |
569 | 653 | " height=" + this.hq( params.height + controllerHeight ) + |
570 | 654 | |
Index: trunk/extensions/OggHandler/OggHandler_body.php |
— | — | @@ -390,7 +390,7 @@ |
391 | 391 | } |
392 | 392 | |
393 | 393 | function setHeaders( $out ) { |
394 | | - global $wgOggScriptVersion, $wgCortadoJarFile; |
| 394 | + global $wgOggScriptVersion, $wgCortadoJarFile, $wgServer; |
395 | 395 | if ( $out->hasHeadItem( 'OggHandler' ) ) { |
396 | 396 | return; |
397 | 397 | } |
— | — | @@ -400,6 +400,7 @@ |
401 | 401 | $msgNames = array( 'ogg-play', 'ogg-pause', 'ogg-stop', 'ogg-no-player', |
402 | 402 | 'ogg-player-videoElement', 'ogg-player-oggPlugin', 'ogg-player-cortado', 'ogg-player-vlc-mozilla', |
403 | 403 | 'ogg-player-vlc-activex', 'ogg-player-quicktime-mozilla', 'ogg-player-quicktime-activex', |
| 404 | + 'ogg-player-totem', 'ogg-player-kaffeine', 'ogg-player-kmplayer', |
404 | 405 | 'ogg-player-thumbnail', 'ogg-player-selected', 'ogg-use-player', 'ogg-more', 'ogg-download', |
405 | 406 | 'ogg-desc-link', 'ogg-dismiss', 'ogg-player-soundthumb', 'ogg-no-xiphqt' ); |
406 | 407 | $msgValues = array_map( 'wfMsg', $msgNames ); |
— | — | @@ -408,7 +409,7 @@ |
409 | 410 | $scriptPath = self::getMyScriptPath(); |
410 | 411 | if( substr( $cortadoUrl, 0, 1 ) != '/' |
411 | 412 | && substr( $cortadoUrl, 0, 4 ) != 'http' ) { |
412 | | - $cortadoUrl = "$scriptPath/$cortadoUrl"; |
| 413 | + $cortadoUrl = "$wgServer$scriptPath/$cortadoUrl"; |
413 | 414 | } |
414 | 415 | $encCortadoUrl = Xml::encodeJsVar( $cortadoUrl ); |
415 | 416 | $encExtPathUrl = Xml::encodeJsVar( $scriptPath ); |
Index: trunk/extensions/OggHandler/OggHandler.i18n.php |
— | — | @@ -31,13 +31,16 @@ |
32 | 32 | QuickTime cannot play Ogg files without this component. |
33 | 33 | Please <a href="http://www.mediawiki.org/wiki/Extension:OggHandler/Client_download">download XiphQT</a> or choose another player.', |
34 | 34 | |
35 | | - 'ogg-player-videoElement' => '<video> element', |
36 | | - 'ogg-player-oggPlugin' => 'Ogg plugin', |
| 35 | + 'ogg-player-videoElement' => 'Native browser support', |
| 36 | + 'ogg-player-oggPlugin' => 'Browser plugin', |
37 | 37 | 'ogg-player-cortado' => 'Cortado (Java)', # only translate this message to other languages if you have to change it |
38 | 38 | 'ogg-player-vlc-mozilla' => 'VLC', # only translate this message to other languages if you have to change it |
39 | 39 | 'ogg-player-vlc-activex' => 'VLC (ActiveX)', # only translate this message to other languages if you have to change it |
40 | 40 | 'ogg-player-quicktime-mozilla' => 'QuickTime', # only translate this message to other languages if you have to change it |
41 | 41 | 'ogg-player-quicktime-activex' => 'QuickTime (ActiveX)', # only translate this message to other languages if you have to change it |
| 42 | + 'ogg-player-totem' => 'Totem', # only translate this message to other languages if you have to change it |
| 43 | + 'ogg-player-kmplayer' => 'KMPlayer', # only translate this message to other languages if you have to change it |
| 44 | + 'ogg-player-kaffeine' => 'Kaffeine', # only translate this message to other languages if you have to change it |
42 | 45 | 'ogg-player-thumbnail' => 'Still image only', |
43 | 46 | 'ogg-player-soundthumb' => 'No player', |
44 | 47 | 'ogg-player-selected' => '(selected)', |