Brion VIBBER has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/165478

Change subject: Work in progress: ogv.js media player for Safari/IE (2 of 3)
......................................................................

Work in progress: ogv.js media player for Safari/IE (2 of 3)

Plugin to MwEmbedPlayer for using ogv.js JavaScript or Flash playback
of Ogg Theora/Vorbis media in Safari and IE.

The actual JS and Flash libraries are in the previous commit in order
to make this commit easier to review.

This commit adds only the plugin for the desktop player and support
code that's common with the mobile player coming in the next commit.

Bug: 61823
Change-Id: Ia6b2e66864a596dbb4ba5841b9da135021f38276
---
M MwEmbedModules/EmbedPlayer/EmbedPlayer.php
M MwEmbedModules/EmbedPlayer/i18n/en.json
M MwEmbedModules/EmbedPlayer/i18n/qqq.json
A MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js
A MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvSwf.js
M MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js
M MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js
M MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js
M MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js
A resources/ext.tmh.OgvJsSupport.js
10 files changed, 524 insertions(+), 6 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/TimedMediaHandler 
refs/changes/78/165478/1

diff --git a/MwEmbedModules/EmbedPlayer/EmbedPlayer.php 
b/MwEmbedModules/EmbedPlayer/EmbedPlayer.php
index c60d41c..95efa94 100644
--- a/MwEmbedModules/EmbedPlayer/EmbedPlayer.php
+++ b/MwEmbedModules/EmbedPlayer/EmbedPlayer.php
@@ -68,6 +68,11 @@
                                'scripts'=> "resources/mw.EmbedPlayerVLCApp.js",
                                'dependencies' => array( 'mediawiki.Uri' )
                        ),
+                       "mw.EmbedPlayerOgvJs"   => array(
+                               'scripts' => 'resources/mw.EmbedPlayerOgvJs.js',
+                               'dependencies' => 'ext.tmh.OgvJsSupport',
+                       ),
+                       "mw.EmbedPlayerOgvSwf"  => array( 'scripts'=> 
"resources/mw.EmbedPlayerOgvSwf.js" ),
                        "mw.EmbedPlayerImageOverlay" => array( 'scripts'=> 
"resources/mw.EmbedPlayerImageOverlay.js" ),
 
                        "mw.EmbedPlayerVlc" => array( 'scripts'=> 
"resources/mw.EmbedPlayerVlc.js" ),
diff --git a/MwEmbedModules/EmbedPlayer/i18n/en.json 
b/MwEmbedModules/EmbedPlayer/i18n/en.json
index d3221a2..7539465 100644
--- a/MwEmbedModules/EmbedPlayer/i18n/en.json
+++ b/MwEmbedModules/EmbedPlayer/i18n/en.json
@@ -50,6 +50,8 @@
     "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM player",
     "mwe-embedplayer-ogg-player-oggPlugin": "Generic Ogg plugin",
     "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC for iOS app",
+    "mwe-embedplayer-ogg-player-ogvJsPlayer": "JavaScript Ogg player",
+    "mwe-embedplayer-ogg-player-ogvSwfPlayer": "Flash Ogg player",
     "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin",
     "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX",
     "mwe-embedplayer-ogg-player-cortado": "Java Cortado",
diff --git a/MwEmbedModules/EmbedPlayer/i18n/qqq.json 
b/MwEmbedModules/EmbedPlayer/i18n/qqq.json
index 0b17710..3e3de78 100644
--- a/MwEmbedModules/EmbedPlayer/i18n/qqq.json
+++ b/MwEmbedModules/EmbedPlayer/i18n/qqq.json
@@ -24,6 +24,8 @@
        "mwe-embedplayer-ogg-player-aacNative": "name of AAC player in 
configuration screen",
        "mwe-embedplayer-ogg-player-cortado": "{{optional}}",
        "mwe-embedplayer-ogg-player-selected": "{{Identical|Selected}}",
+       "mwe-embedplayer-ogg-player-ogvJsPlayer": "name of ogv.js Ogg 
JavaScript player in configuration screen",
+       "mwe-embedplayer-ogg-player-ogvSwfPlayer": "name of ogv.swf Ogg Flash 
player in configuration screen",
        "mwe-embedplayer-for_best_experience": "Shown when user's browser 
doesn't support playing videos. Parameters:\n* $1 - An empty <a> tag. 
Don't use this parameter.",
        "mwe-embedplayer-download-warn": "Parameters:\n* $1 - URL",
        "mwe-embedplayer-do_not_warn_again": "Standard message for 
disabling\nfuture identical warnings messages",
diff --git a/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js 
b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js
new file mode 100644
index 0000000..d2ef1b6
--- /dev/null
+++ b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js
@@ -0,0 +1,171 @@
+( function( mw, $ ) { "use strict";
+
+mw.EmbedPlayerOgvJs = {
+
+       // Instance name:
+       instanceOf: 'OgvJs',
+
+       // Supported feature set of the cortado applet:
+       supports: {
+               'playHead' : false, // seeking not supported yet
+               'pause' : true,
+               'stop' : true,
+               'fullscreen' : false,
+               'sourceSwitch': true, // todo
+               'timeDisplay' : true,
+               'volumeControl' : false,
+               'overlays': true
+       },
+
+       /**
+       * Output the the embed html
+       */
+       embedPlayerHTML: function (optionalCallback) {
+       
+               $( this ).text( '... loading ...' );
+
+               if (mw.isIOS()) {
+                       this._initializeAudioForiOS();
+               }
+               var _this = this;
+               _this._loadOgvJs( function() {
+                       var options = {
+                               webGL: true, // auto-detect accelerated YUV 
conversion
+                               base: _this._ogvJsBase() // where to find the 
Flash shims for IE
+                       };
+                       if (_this._iOSAudioContext) {
+                               options.audioContext = _this._iOSAudioContext;
+                       }
+                       var player = new OgvJsPlayer(options);
+                       player.id = _this.pid;
+                       player.width = parseInt( _this.getWidth() );
+                       player.height = parseInt( _this.getHeight() );
+                       player.src = _this.getSrc();
+                       if ( _this.getDuration() ) {
+                               player.durationHint = parseFloat( 
_this.getDuration() );
+                       }
+                       $( _this ).empty().append( player );
+                       player.play();
+               
+                       // Start the monitor:
+                       _this.monitor();
+
+                       if ( optionalCallback ) {
+                               optionalCallback();
+                       }
+               });
+       },
+       
+       _iOSAudioContext: undefined,
+       
+       _initializeAudioForiOS: function() {
+               // iOS Safari Web Audio API must be initialized from an input 
event handler
+               // This is a temporary (?) hack while we load OgvJsPlayer 
support code async
+               if ( this._iOSAudioContext ) {
+                       return;
+               }
+               this._iOSAudioContext = mw.OgvJsSupport.initAudioContext();
+       },
+
+       _loadOgvJs: function( callback ) {
+               if ( typeof OgvJsPlayer === 'undefined' ) {
+                       $.ajax({
+                               dataType: 'script',
+                               cache: true,
+                               url: this._findOgvJs()
+                       }).done(function() {
+                               callback();
+                       });
+               } else {
+                       callback();
+               }
+       },
+       
+       _ogvJsBase: function() {
+               return mw.getEmbedPlayerPath() + '/binPlayers/ogv.js';
+       },
+       
+       _findOgvJs: function() {
+               var url = this._ogvJsBase() + '/ogvjs.js?version=0.1.5';
+               return url;
+       },
+
+       /**
+       * Get the embed player time
+       */
+       getPlayerElementTime: function() {
+               this.getPlayerElement();
+               var currentTime = 0;
+               if ( this.playerElement ) {
+                       currentTime = this.playerElement.currentTime;
+                               try {
+                                       currentTime = 
this.playerElement.currentTime;
+                               } catch ( e ) {
+                                       mw.log( 'EmbedPlayerOgvJs:: Could not 
get time from jPlayer: ' + e );
+                               }
+               }else{
+                       mw.log("EmbedPlayerOgvJs:: Could not find playerElement 
" );
+               }
+               return currentTime;
+       },
+
+       /**
+       * Update the playerElement instance with a pointer to the embed object
+       */
+       getPlayerElement: function() {
+               if( !$( '#' + this.pid ).length ) {
+                       return false;
+               };
+               this.playerElement = $( '#' + this.pid ).get( 0 );
+               return this.playerElement;
+       },
+
+       /**
+       * Issue the doPlay request to the playerElement
+       *       calls parent_play to update interface
+       */
+       play: function() {
+               this.getPlayerElement();
+               this.parent_play();
+               if ( this.playerElement ) {
+                       try{
+                               this.playerElement.play();
+                       }catch( e ){
+                               mw.log("EmbedPlayerOgvJs::Could not issue play 
request");
+                       }
+               }
+       },
+
+       /**
+       * Pause playback
+       *       calls parent_pause to update interface
+       */
+       pause: function() {
+               this.getPlayerElement();
+               // Update the interface
+               this.parent_pause();
+               // Call the pause function if it exists:
+               if ( this.playerElement ) {
+                       try{
+                               this.playerElement.pause();
+                       }catch( e ){
+                               mw.log("EmbedPlayerOgvJs::Could not issue pause 
request");
+                       }
+               }
+       },
+
+       playerSwitchSource: function( source, switchCallback, doneCallback ){
+               var _this = this;
+               var src = source.getSrc();
+               var vid = this.getPlayerElement();
+               vid.stop();
+               
+               switchCallback();
+               
+               // Currently have to tear down the player and make a new one
+               this.embedPlayerHTML( doneCallback );
+       }
+
+};
+
+} )( window.mediaWiki, window.jQuery );
diff --git a/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvSwf.js 
b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvSwf.js
new file mode 100644
index 0000000..afbdd42
--- /dev/null
+++ b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvSwf.js
@@ -0,0 +1,175 @@
+( function( mw, $ ) { "use strict";
+
+mw.EmbedPlayerOgvSwf = {
+
+       // Instance name:
+       instanceOf: 'OgvSwf',
+
+       // Supported feature set of the cortado applet:
+       supports: {
+               'playHead' : false, // seeking not supported yet
+               'pause' : true,
+               'stop' : true,
+               'fullscreen' : false, // todo
+               'sourceSwitch': true,
+               'timeDisplay' : true,
+               'volumeControl' : false,
+               'overlays': (function() {
+                       if (navigator.userAgent.indexOf('Trident') != -1) {
+                               // IE of some version
+                               if (navigator.userAgent.indexOf('MSIE') == -1) {
+                                       // IE 11 drops the 'MSIE' token, and is 
known
+                                       // to handle the overlay case correctly.
+                                       return true;
+                               } else if (navigator.userAgent.indexOf('MSIE 
10.') !== -1) {
+                                       // IE 10 still has MSIE token, but is 
known
+                                       // to handle the overlay case correctly.
+                               } else {
+                                       // IE 9 doesn't handle overlay case 
well;
+                                       // at least it doesn't pass mouse events
+                                       // so once the control bar disappears we
+                                       // never get it back.
+                                       return false;
+                               }
+                       }
+
+                       // Who knows? Might work!
+                       return true;
+               })()
+       },
+
+       /**
+       * Output the the embed html
+       */
+       embedPlayerHTML: function () {
+       
+               $( this ).text( '... loading ...' );
+
+               var _this = this;
+               _this._loadOgvSwf( function() {
+                       var player = new OgvSwfPlayer({
+                               base: _this._OgvSwfBase() // where to find the 
Flash .swf files
+                       });
+                       player.id = _this.pid;
+                       player.width = parseInt( _this.getWidth() );
+                       player.height = parseInt( _this.getHeight() );
+                       if (!_this.supports.overlays) {
+                               // Squish to leave space for fixed control bar 
on IE 9
+                               player.height -= 
_this.controlBuilder.getHeight();
+                       }
+                       player.src = _this.getSrc();
+                       if ( _this.getDuration() ) {
+                               player.durationHint = parseFloat( 
_this.getDuration() );
+                       }
+                       $( _this ).empty().append( player );
+                       player.play();
+               
+                       // Start the monitor:
+                       _this.monitor();
+               });
+       },
+       
+       _loadOgvSwf: function( callback ) {
+               if ( typeof OgvSwfPlayer === 'undefined' ) {
+                       $.ajax({
+                               dataType: 'script',
+                               cache: true,
+                               url: this._findOgvSwf()
+                       }).done(function() {
+                               callback();
+                       });
+               } else {
+                       callback();
+               }
+       },
+       
+       _OgvSwfBase: function() {
+               return mw.getEmbedPlayerPath() + '/binPlayers/ogv.js';
+       },
+       
+       _findOgvSwf: function() {
+               var url = this._OgvSwfBase() + '/ogvswf.js?version=0.1.2';
+               return url;
+       },
+
+       /**
+       * Get the embed player time
+       */
+       getPlayerElementTime: function() {
+               this.getPlayerElement();
+               var currentTime = 0;
+               if ( this.playerElement ) {
+                       currentTime = this.playerElement.currentTime;
+                               try {
+                                       currentTime = 
this.playerElement.currentTime;
+                               } catch ( e ) {
+                                       mw.log( 'EmbedPlayerOgvSwf:: Could not 
get time from jPlayer: ' + e );
+                               }
+               }else{
+                       mw.log("EmbedPlayerOgvSwf:: Could not find 
playerElement " );
+               }
+               return currentTime;
+       },
+
+       /**
+       * Update the playerElement instance with a pointer to the embed object
+       */
+       getPlayerElement: function() {
+               if( !$( '#' + this.pid ).length ) {
+                       return false;
+               };
+               this.playerElement = $( '#' + this.pid ).get( 0 );
+               return this.playerElement;
+       },
+
+       /**
+       * Issue the doPlay request to the playerElement
+       *       calls parent_play to update interface
+       */
+       play: function() {
+               this.getPlayerElement();
+               this.parent_play();
+               if ( this.playerElement ) {
+                       try{
+                               this.playerElement.play();
+                       }catch( e ){
+                               mw.log("EmbedPlayerOgvSwf::Could not issue play 
request");
+                       }
+               }
+       },
+
+       /**
+       * Pause playback
+       *       calls parent_pause to update interface
+       */
+       pause: function() {
+               this.getPlayerElement();
+               // Update the interface
+               this.parent_pause();
+               // Call the pause function if it exists:
+               if ( this.playerElement ) {
+                       try{
+                               this.playerElement.pause();
+                       }catch( e ){
+                               mw.log("EmbedPlayerOgvSwf::Could not issue 
pause request");
+                       }
+               }
+       },
+
+       playerSwitchSource: function( source, switchCallback, doneCallback ){
+               var _this = this;
+               var src = source.getSrc();
+               var vid = this.getPlayerElement();
+               if (!this.paused) {
+                       vid.pause();
+               }
+
+               switchCallback();
+
+               // Currently have to tear down the player and make a new one
+               this.embedPlayerHTML( doneCallback );
+       }
+
+};
+
+} )( window.mediaWiki, window.jQuery );
diff --git a/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js 
b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js
index 3749f80..6ee8ccf 100644
--- a/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js
+++ b/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js
@@ -89,6 +89,25 @@
        'video/webm; codecs="vp8, vorbis"',
 ], 'VLCApp' );
 
+var ogvJsPlayer = new mw.MediaPlayer( 'ogvJsPlayer', [
+       'video/ogg',
+       'video/ogg; codecs="theora"',
+       'video/ogg; codecs="theora, vorbis"',
+       'audio/ogg',
+       'audio/ogg; codecs="vorbis"',
+       'audio/ogg; codecs="opus"',
+       'application/ogg'
+], 'OgvJs' );
+
+var ogvSwfPlayer = new mw.MediaPlayer( 'ogvSwfPlayer', [
+       'video/ogg',
+       'video/ogg; codecs="theora"',
+       'video/ogg; codecs="theora, vorbis"',
+       'audio/ogg',
+       'audio/ogg; codecs="vorbis"',
+       'application/ogg'
+], 'OgvSwf' );
+
 // Generic plugin
 //var oggPluginPlayer = new mw.MediaPlayer( 'oggPlugin', ['video/ogg', 
'application/ogg'], 'Generic' );
 
@@ -314,6 +333,48 @@
                if ( mw.isIOS() ) {
                        this.mediaPlayers.addPlayer( vlcAppPlayer );
                }
+
+               // ogv.js / ogv.swf detection
+               var hasTypedArrays = ( window.Uint32Array ),
+                       hasWebAudio = ( window.AudioContext || 
window.webkitAudioContext );
+
+               // don't use mw.supportsFlash() as it's hardcoded to false
+               // we want to use Flash for free codecs here!
+               var reallyHasFlash = false;
+               if ( $.client.profile().name === 'msie' ) {
+                       reallyHasFlash = this.testActiveX( 
'ShockwaveFlash.ShockwaveFlash' );
+               } else {
+                       // check plugins...
+               }
+
+               if ( hasTypedArrays && hasWebAudio ) {
+                       // ogv.js emscripten version
+                       //
+                       // Works great in Safari, as fast or faster than Flash.
+                       //
+                       // Current Firefox, Chrome, Opera all work great, but 
use
+                       // native playback by default of course!
+                       //
+                       // Works in IE 10/11 but requires a Flash audio shim and
+                       // doesn't perform quite as well as the pure-Flash build
+                       // on slower machines. Currently disabled for this case,
+                       // but future versions of IE with Web Audio should start
+                       // working one hopes.
+                       //
+                       this.mediaPlayers.addPlayer( ogvJsPlayer );
+               }
+               if ( reallyHasFlash ) {
+                       // ogv.swf crossbridge version
+                       //
+                       // Currently used for IE 9/10/11. Older IE browsers 
might work,
+                       // but IE 8 doesn't seem to run the base player code.
+                       //
+                       // Other browsers without Web Audio might work, but are 
currently
+                       // not detected.
+                       //
+                       this.mediaPlayers.addPlayer( ogvSwfPlayer );
+               }
+
                // Allow extensions to detect and add their own "players"
                
mw.log("EmbedPlayer::trigger:embedPlayerUpdateMediaPlayersEvent");
                $( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , 
this.mediaPlayers );
diff --git a/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js 
b/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js
index 02a9d9a..ca878bb 100644
--- a/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js
+++ b/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js
@@ -255,10 +255,11 @@
 
                // Prefer native playback ( and prefer WebM over ogg and h.264 )
                var namedSourceSet = {};
+               var useBogoSlow = false; // use benchmark only for 
ogv.js/ogv.swf
                $.each( playableSources, function(inx, source ){
                        var mimeType = source.mimeType;
                        var player = 
mw.EmbedTypes.getMediaPlayers().defaultPlayer( mimeType );
-                       if ( player && player.library == 'Native'       ) {
+                       if ( player && ( player.library == 'Native' || 
player.library == 'OgvJs' || player.library == 'OgvSwf' ) ) {
                                switch( player.id       ){
                                        case 'mp3Native':
                                                var shortName = 'mp3';
@@ -267,6 +268,11 @@
                                                var shortName = 'aac';
                                                break;
                                        case 'oggNative':
+                                               var shortName = 'ogg';
+                                               break;
+                                       case 'ogvJsPlayer':
+                                       case 'ogvSwfPlayer':
+                                               useBogoSlow = true;
                                                var shortName = 'ogg';
                                                break;
                                        case 'webmNative':
@@ -309,9 +315,69 @@
                                        // select based on size:
                                        // Set via embed resolution closest to 
relative to display size
                                        var minSizeDelta = null;
+
+                                       // unless we're really slow...
+                                       // @fixme move most of this to ogv.js 
embed code
+                                       // @fixme avoid rerunning benchmark all 
the time, but don't get
+                                       // weirdly stuck at slow speed by 
mistake if opened in debug mode
+                                       var bench = function() {
+                                               var timer;
+                                               if (window.performance && 
window.performance.now) {
+                                                       timer = function() {
+                                                               return 
window.performance.now();
+                                                       }
+                                               } else {
+                                                       timer = function() {
+                                                               return 
Date.now();
+                                                       }
+                                               }
+
+                                               var ops = 0;
+                                               var fibonacci = function(n) {
+                                                       ops++;
+                                                       if (n < 2) {
+                                                               return n;
+                                                       } else {
+                                                               return 
fibonacci(n - 2) + fibonacci(n - 1);
+                                                       }
+                                               };
+
+                                               var start = timer();
+                                               var result = fibonacci(30);
+                                               var delta = timer() - start;
+                                               var bogoSpeed = (ops / delta);
+
+                                               // 2012 Retina MacBook Pro 
(Safari 7)  ~150,000
+                                               // 2009 Dell T5500         (IE 
11)     ~100,000
+                                               // iPad Air                (iOS 
7)      ~65,000
+                                               // 2010 MBP / OS X 10.9    
(Safari 7)   ~62,500
+                                               // 2010 MBP / Win7 VM      (IE 
11)      ~50,000+-
+                                               //   ^ these play 360p ok
+                                               // ----------- line of moderate 
doom ----------
+                                               //   v these play 160p ok
+                                               // iPad Mini non-Retina    (iOS 
8 beta) ~25,000
+                                               // Dell Inspiron Duo       (IE 
11)      ~25,000
+                                               // Surface RT              (IE 
11)      ~18,000
+                                               // iPod Touch 5th-gen      (iOS 
8 beta) ~16,000
+                                               // ------------ line of total 
doom ------------
+                                               //   v these play only audio, 
if that
+                                               // iPod 4th-gen            (iOS 
6.1)     ~6,750
+                                               // iPhone 3Gs              (iOS 
6.1)     ~4,500
+                                               var bogoSpeedCutoff = 50000;
+
+                                               
mw.log('MediaElement::autoSelectSource::bench: ' + bogoSpeed + ' ops per ms 
bogo test (' + ops + ' / '  + delta + ')');
+                                               return (bogoSpeed < 
bogoSpeedCutoff);
+                                       };
+                                       var isBogoSlow = (useBogoSlow ? bench() 
: false);
+
                                        if( this.parentEmbedId ){
                                                var displayWidth = $('#' + 
this.parentEmbedId).width();
                                                $.each( namedSourceSet[ codec 
], function(inx, source ){
+                                                       if ( isBogoSlow && 
source.height > 240 ) {
+                                                               // On iOS or 
slow Windows devices, large videos decoded in JavaScript are a bad idea!
+                                                               // continue
+                                                               return true;
+                                                       }
                                                        if( source.width && 
displayWidth ){
                                                                var sizeDelta = 
 Math.abs( source.width - displayWidth );
                                                                
mw.log('MediaElement::autoSelectSource: size delta : ' + sizeDelta + ' for s:' 
+ source.width );
diff --git a/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js 
b/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js
index 19e7fde..6f1af43 100644
--- a/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js
+++ b/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js
@@ -33,10 +33,10 @@
 
                this.defaultPlayers['application/vnd.apple.mpegurl'] = 
['Native'];
 
-               this.defaultPlayers['video/ogg'] = ['Native', 'Vlc', 'Java', 
'Generic', 'VLCApp'];
+               this.defaultPlayers['video/ogg'] = ['Native', 'Vlc', 'OgvJs', 
'OgvSwf', 'Java', 'Generic', 'VLCApp'];
                this.defaultPlayers['video/webm'] = ['Native', 'Vlc', 'VLCApp'];
-               this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 
'Java', 'Generic', 'VLCApp'];
-               this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'Java', 
'VLCApp'];
+               this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 
'OgvJs', 'OgvSwf','Java', 'Generic', 'VLCApp'];
+               this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'OgvJs', 
'OgvSwf', 'Java', 'VLCApp'];
                this.defaultPlayers['audio/mpeg']= ['Native', 'Kplayer'];
                this.defaultPlayers['audio/mp3']= ['Native', 'Kplayer'];
                this.defaultPlayers['audio/mp4']= ['Native'];
diff --git 
a/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js 
b/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js
index 98602da..ee48a3a 100644
--- a/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js
+++ b/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js
@@ -2214,12 +2214,17 @@
                                })
                        );
                }
+               var addedSources = {};
                $.each( this.embedPlayer.mediaElement.getPlayableSources(), 
function( sourceIndex, source ) {
                        // Output the player select code:
                        var supportingPlayers = 
mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( source.getMIMEType() );
                        for ( var i = 0; i < supportingPlayers.length ; i++ ) {
-                               if( supportingPlayers[i].library == 'Native' ){
-                                       addToSourceMenu( source );
+                               var lib = supportingPlayers[i].library;
+                               if( lib === 'Native' || lib === 'OgvJs' || lib 
=== 'OgvSwf' ){ // @fixme use supports.sourceSwitch ... if preloaded?
+                                       if ( !( source.getSrc() in addedSources 
) ) {
+                                               addedSources[source.getSrc()] = 
true;
+                                               addToSourceMenu( source );
+                                       }
                                }
                        }
                });
diff --git a/resources/ext.tmh.OgvJsSupport.js 
b/resources/ext.tmh.OgvJsSupport.js
new file mode 100644
index 0000000..a65db29
--- /dev/null
+++ b/resources/ext.tmh.OgvJsSupport.js
@@ -0,0 +1,31 @@
+( function( $, mw ) {
+
+       mw.OgvJsSupport = {
+               /**
+                * Return a stub audio context
+                */
+               initAudioContext: function() {
+                       var AudioContext = window.AudioContext || 
window.webkitAudioContext;
+                       if (AudioContext) {
+                               var context = new AudioContext(),
+                                       node;
+                               if (context.createScriptProcessor) {
+                                       node = 
context.createScriptProcessor(1024, 0, 2);
+                               } else if (context.createJavaScriptNode) {
+                                       node = 
context.createJavaScriptNode(1024, 0, 2);
+                               } else {
+                                       throw new Error("Bad version of web 
audio API?");
+                               }
+
+                               // Don't actually run any audio, just start & 
stop the node
+                               node.connect(context.destination);
+                               node.disconnect();
+                               
+                               return context;
+                       } else {
+                               return null;
+                       }
+               }
+       }
+
+} )( jQuery, mw );

-- 
To view, visit https://gerrit.wikimedia.org/r/165478
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia6b2e66864a596dbb4ba5841b9da135021f38276
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/TimedMediaHandler
Gerrit-Branch: master
Gerrit-Owner: Brion VIBBER <br...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to