Skip to content
Browse files

upgrade mejs to 2.11.0

  • Loading branch information...
1 parent 3f35a63 commit c769149505f81ccd786d37d5083c738f244a2a55 Mike Elston committed Mar 20, 2013
View
36 app/assets/javascripts/mediaelement_rails/mediaelement.js
@@ -15,7 +15,7 @@
var mejs = mejs || {};
// version number
-mejs.version = '2.10.3';
+mejs.version = '2.11.0';
// player number (for missing, same id attr)
mejs.meIndex = 0;
@@ -30,13 +30,14 @@ mejs.plugins = {
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
],
youtube: [
- {version: null, types: ['video/youtube', 'video/x-youtube']}
+ {version: null, types: ['video/youtube', 'video/x-youtube', 'audio/youtube', 'audio/x-youtube']}
],
vimeo: [
{version: null, types: ['video/vimeo', 'video/x-vimeo']}
]
};
+
/*
Utility methods
*/
@@ -148,7 +149,7 @@ mejs.Utility = {
/* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
removeSwf: function(id) {
var obj = document.getElementById(id);
- if (obj && obj.nodeName == "OBJECT") {
+ if (obj && /object|embed/i.test(obj.nodeName)) {
if (mejs.MediaFeatures.isIE) {
obj.style.display = "none";
(function(){
@@ -532,13 +533,13 @@ mejs.PluginMediaElement.prototype = {
for (j=0; j<pluginInfo.types.length; j++) {
// find plugin that can play the type
if (type == pluginInfo.types[j]) {
- return true;
+ return 'probably';
}
}
}
}
- return false;
+ return '';
},
positionFullscreenButton: function(x,y,visibleAndAbove) {
@@ -701,6 +702,7 @@ mejs.PluginMediaElement.prototype = {
remove: function() {
mejs.Utility.removeSwf(this.pluginElement.id);
+ mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
}
};
@@ -715,6 +717,11 @@ mejs.MediaPluginBridge = {
this.htmlMediaElements[id] = htmlMediaElement;
},
+ unregisterPluginElement: function (id) {
+ delete this.pluginMediaElements[id];
+ delete this.htmlMediaElements[id];
+ },
+
// when Flash/Silverlight is ready, it calls out to this method
initPlugin: function (id) {
@@ -1210,7 +1217,7 @@ mejs.HtmlMediaElementShim = {
switch (playback.method) {
case 'silverlight':
container.innerHTML =
-'<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="' + pluginid + '" name="' + pluginid + '" width="' + width + '" height="' + height + '">' +
+'<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="' + pluginid + '" name="' + pluginid + '" width="' + width + '" height="' + height + '" class="mejs-shim">' +
'<param name="initParams" value="' + initVars.join(',') + '" />' +
'<param name="windowless" value="true" />' +
'<param name="background" value="black" />' +
@@ -1227,7 +1234,7 @@ mejs.HtmlMediaElementShim = {
container.appendChild(specialIEContainer);
specialIEContainer.outerHTML =
'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
-'id="' + pluginid + '" width="' + width + '" height="' + height + '">' +
+'id="' + pluginid + '" width="' + width + '" height="' + height + '" class="mejs-shim">' +
'<param name="movie" value="' + options.pluginPath + options.flashName + '?x=' + (new Date()) + '" />' +
'<param name="flashvars" value="' + initVars.join('&amp;') + '" />' +
'<param name="quality" value="high" />' +
@@ -1252,7 +1259,8 @@ mejs.HtmlMediaElementShim = {
'src="' + options.pluginPath + options.flashName + '" ' +
'flashvars="' + initVars.join('&') + '" ' +
'width="' + width + '" ' +
-'height="' + height + '"></embed>';
+'height="' + height + '" ' +
+'class="mejs-shim"></embed>';
}
break;
@@ -1285,16 +1293,16 @@ mejs.HtmlMediaElementShim = {
pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1);
- container.innerHTML ='<iframe src="http://player.vimeo.com/video/' + pluginMediaElement.vimeoid + '?portrait=0&byline=0&title=0" width="' + width +'" height="' + height +'" frameborder="0"></iframe>';
+ container.innerHTML ='<iframe src="http://player.vimeo.com/video/' + pluginMediaElement.vimeoid + '?portrait=0&byline=0&title=0" width="' + width +'" height="' + height +'" frameborder="0" class="mejs-shim"></iframe>';
/*
container.innerHTML =
- '<object width="' + width + '" height="' + height + '">' +
+ '<object width="' + width + '" height="' + height + '" class="mejs-shim">' +
'<param name="allowfullscreen" value="true" />' +
'<param name="allowscriptaccess" value="always" />' +
'<param name="flashvars" value="api=1" />' +
'<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" />' +
- '<embed src="//vimeo.com/moogaloop.swf?api=1&amp;clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' + width + '" height="' + height + '"></embed>' +
+ '<embed src="//vimeo.com/moogaloop.swf?api=1&amp;clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' + width + '" height="' + height + '" class="mejs-shim"></embed>' +
'</object>';
*/
@@ -1478,7 +1486,7 @@ mejs.YouTubeApi = {
/*
settings.container.innerHTML =
'<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="//www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=' + settings.pluginId + '&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0" ' +
- 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; ">' +
+ 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; " class="mejs-shim">' +
'<param name="allowScriptAccess" value="always">' +
'<param name="wmode" value="transparent">' +
'</object>';
@@ -1492,7 +1500,7 @@ mejs.YouTubeApi = {
specialIEContainer = document.createElement('div');
settings.container.appendChild(specialIEContainer);
specialIEContainer.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
-'id="' + settings.pluginId + '" width="' + settings.width + '" height="' + settings.height + '">' +
+'id="' + settings.pluginId + '" width="' + settings.width + '" height="' + settings.height + '" class="mejs-shim">' +
'<param name="movie" value="' + youtubeUrl + '" />' +
'<param name="wmode" value="transparent" />' +
'<param name="allowScriptAccess" value="always" />' +
@@ -1501,7 +1509,7 @@ mejs.YouTubeApi = {
} else {
settings.container.innerHTML =
'<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="' + youtubeUrl + '" ' +
- 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; ">' +
+ 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; " class="mejs-shim">' +
'<param name="allowScriptAccess" value="always">' +
'<param name="wmode" value="transparent">' +
'</object>';
View
429 app/assets/javascripts/mediaelement_rails/mediaelementplayer.js
@@ -66,6 +66,8 @@ if (typeof jQuery != 'undefined') {
autosizeProgress : true,
// Hide controls when playing and mouse is not over the video
alwaysShowControls: false,
+ // Display the video control
+ hideVideoControlsOnLoad: false,
// Enable click video element to toggle play/pause
clickToPlayPause: true,
// force iPad's native controls
@@ -167,7 +169,7 @@ if (typeof jQuery != 'undefined') {
mejs.mepIndex = 0;
- mejs.players = [];
+ mejs.players = {};
// wraps a MediaElement object in player controls
mejs.MediaElementPlayer = function(node, o) {
@@ -199,8 +201,11 @@ if (typeof jQuery != 'undefined') {
// extend default options
t.options = $.extend({},mejs.MepDefaults,o);
+ // unique ID
+ t.id = 'mep_' + mejs.mepIndex++;
+
// add to player array (for focus events)
- mejs.players.push(t);
+ mejs.players[t.id] = t;
// start up
t.init();
@@ -252,7 +257,7 @@ if (typeof jQuery != 'undefined') {
t.media.play();
}
- } else if (mf.isAndroid && t.AndroidUseNativeControls) {
+ } else if (mf.isAndroid && t.options.AndroidUseNativeControls) {
// leave default player
@@ -263,9 +268,6 @@ if (typeof jQuery != 'undefined') {
// remove native controls
t.$media.removeAttr('controls');
- // unique ID
- t.id = 'mep_' + mejs.mepIndex++;
-
// build container
t.container =
$('<div id="' + t.id + '" class="mejs-container ' + (mejs.MediaFeatures.svg ? 'svg' : 'no-svg') + '">'+
@@ -604,7 +606,11 @@ if (typeof jQuery != 'undefined') {
}
});
}
-
+
+ if(t.options.hideVideoControlsOnLoad) {
+ t.hideControls(false);
+ }
+
// check for autoplay
if (autoplay && !t.options.alwaysShowControls) {
t.hideControls();
@@ -628,10 +634,11 @@ if (typeof jQuery != 'undefined') {
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
media.addEventListener('play', function() {
+ var playerIndex;
// go through all other players
- for (var i=0, il=mejs.players.length; i<il; i++) {
- var p = mejs.players[i];
+ for (playerIndex in mejs.players) {
+ var p = mejs.players[playerIndex];
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
p.pause();
}
@@ -688,7 +695,7 @@ if (typeof jQuery != 'undefined') {
}, 50);
// adjust controls whenever window sizes (used to be in fullscreen only)
- $(window).resize(function() {
+ t.globalBind('resize', function() {
// don't resize for fullscreen mode
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
@@ -762,17 +769,12 @@ if (typeof jQuery != 'undefined') {
t.container
.width(parentWidth)
.height(newHeight);
-
- // set native <video> or <audio>
- t.$media
- .width('100%')
- .height('100%');
-
- // set shims
- t.container.find('object, embed, iframe')
+
+ // set native <video> or <audio> and shims
+ t.$media.add(t.container.find('.mejs-shim'))
.width('100%')
.height('100%');
-
+
// if shim is ready, send the size to the embeded plugin
if (t.isVideo) {
if (t.media.setVideoSize) {
@@ -823,7 +825,8 @@ if (typeof jQuery != 'undefined') {
// find the size of all the other controls besides the rail
others.each(function() {
- if ($(this).css('position') != 'absolute') {
+ var $this = $(this);
+ if ($this.css('position') != 'absolute' && $this.is(':visible')) {
usedWidth += $(this).outerWidth(true);
}
});
@@ -988,7 +991,7 @@ if (typeof jQuery != 'undefined') {
var t = this;
// listen for key presses
- $(document).keydown(function(e) {
+ t.globalBind('keydown', function(e) {
if (player.hasFocus && player.options.enableKeyboard) {
@@ -1010,7 +1013,7 @@ if (typeof jQuery != 'undefined') {
});
// check if someone clicked outside a player region, then kill its focus
- $(document).click(function(event) {
+ t.globalBind('click', function(event) {
if ($(event.target).closest('.mejs-container').length == 0) {
player.hasFocus = false;
}
@@ -1029,7 +1032,7 @@ if (typeof jQuery != 'undefined') {
track = $(track);
t.tracks.push({
- srclang: track.attr('srclang').toLowerCase(),
+ srclang: (track.attr('srclang')) ? track.attr('srclang').toLowerCase() : '',
src: track.attr('src'),
kind: track.attr('kind'),
label: track.attr('label') || '',
@@ -1071,29 +1074,98 @@ if (typeof jQuery != 'undefined') {
this.media.setSrc(src);
},
remove: function() {
- var t = this;
+ var t = this, featureIndex, feature;
- if (t.media.pluginType === 'flash') {
- t.media.remove();
- } else if (t.media.pluginType === 'native') {
+ // invoke features cleanup
+ for (featureIndex in t.options.features) {
+ feature = t.options.features[featureIndex];
+ if (t['clean' + feature]) {
+ try {
+ t['clean' + feature](t);
+ } catch (e) {
+ // TODO: report control error
+ //throw e;
+ //console.log('error building ' + feature);
+ //console.log(e);
+ }
+ }
+ }
+
+ if (t.media.pluginType === 'native') {
t.$media.prop('controls', true);
+ } else {
+ t.media.remove();
}
// grab video and put it back in place
if (!t.isDynamic) {
- t.$node.insertBefore(t.container)
+ if (t.media.pluginType === 'native') {
+ // detach events from the video
+ // TODO: detach event listeners better than this;
+ // also detach ONLY the events attached by this plugin!
+ //t.$node.clone().insertBefore(t.container);
+ //t.$node.remove();
+ }
+ /*else*/ t.$node.insertBefore(t.container)
}
+
+ // Remove the player from the mejs.players array so that pauseOtherPlayers doesn't blow up when trying to pause a non existance flash api.
+ mejs.players.splice( $.inArray( t, mejs.players ), 1);
t.container.remove();
+ t.globalUnbind();
+ delete t.node.player;
+ delete mejs.players[t.id];
}
};
+ (function(){
+ var rwindow = /^((after|before)print|(before)?unload|hashchange|message|o(ff|n)line|page(hide|show)|popstate|resize|storage)\b/;
+
+ function splitEvents(events, id) {
+ // add player ID as an event namespace so it's easier to unbind them all later
+ var ret = {d: [], w: []};
+ $.each((events || '').split(' '), function(k, v){
+ ret[rwindow.test(v) ? 'w' : 'd'].push(v + '.' + id);
+ });
+ ret.d = ret.d.join(' ');
+ ret.w = ret.w.join(' ');
+ return ret;
+ }
+
+ mejs.MediaElementPlayer.prototype.globalBind = function(events, data, callback) {
+ var t = this;
+ events = splitEvents(events, t.id);
+ if (events.d) $(document).bind(events.d, data, callback);
+ if (events.w) $(window).bind(events.w, data, callback);
+ };
+
+ mejs.MediaElementPlayer.prototype.globalUnbind = function(events, callback) {
+ var t = this;
+ events = splitEvents(events, t.id);
+ if (events.d) $(document).unbind(events.d, callback);
+ if (events.w) $(window).unbind(events.w, callback);
+ };
+ })();
+
// turn into jQuery plugin
if (typeof jQuery != 'undefined') {
jQuery.fn.mediaelementplayer = function (options) {
- return this.each(function () {
- new mejs.MediaElementPlayer(this, options);
- });
+ if (options === false) {
+ this.each(function () {
+ var player = jQuery(this).data('mediaelementplayer');
+ if (player) {
+ player.remove();
+ }
+ jQuery(this).removeData('mediaelementplayer');
+ });
+ }
+ else {
+ this.each(function () {
+ jQuery(this).data('mediaelementplayer', new mejs.MediaElementPlayer(this, options));
+ });
+ }
+ return this;
};
}
@@ -1259,21 +1331,20 @@ if (typeof jQuery != 'undefined') {
if (e.which === 1) {
mouseIsDown = true;
handleMouseMove(e);
- $(document)
- .bind('mousemove.dur', function(e) {
- handleMouseMove(e);
- })
- .bind('mouseup.dur', function (e) {
- mouseIsDown = false;
- timefloat.hide();
- $(document).unbind('.dur');
- });
+ t.globalBind('mousemove.dur', function(e) {
+ handleMouseMove(e);
+ });
+ t.globalBind('mouseup.dur', function (e) {
+ mouseIsDown = false;
+ timefloat.hide();
+ t.globalUnbind('.dur');
+ });
return false;
}
})
.bind('mouseenter', function(e) {
mouseIsOver = true;
- $(document).bind('mousemove.dur', function(e) {
+ t.globalBind('mousemove.dur', function(e) {
handleMouseMove(e);
});
if (!mejs.MediaFeatures.hasTouch) {
@@ -1283,7 +1354,7 @@ if (typeof jQuery != 'undefined') {
.bind('mouseleave',function(e) {
mouseIsOver = false;
if (!mouseIsDown) {
- $(document).unbind('.dur');
+ t.globalUnbind('.dur');
timefloat.hide();
}
});
@@ -1349,8 +1420,8 @@ if (typeof jQuery != 'undefined') {
// update bar and handle
if (t.total && t.handle) {
var
- newWidth = t.total.width() * t.media.currentTime / t.media.duration,
- handlePos = newWidth - (t.handle.outerWidth(true) / 2);
+ newWidth = Math.round(t.total.width() * t.media.currentTime / t.media.duration),
+ handlePos = newWidth - Math.round(t.handle.outerWidth(true) / 2);
t.current.width(newWidth);
t.handle.css('left', handlePos);
@@ -1432,14 +1503,14 @@ if (typeof jQuery != 'undefined') {
}
},
- updateDuration: function() {
+ updateDuration: function() {
var t = this;
//Toggle the long video class if the video is longer than an hour.
t.container.toggleClass("mejs-long-video", t.media.duration > 3600);
- if (t.media.duration && t.durationD) {
- t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
+ if (t.durationD && (t.options.duration > 0 || t.media.duration)) {
+ t.durationD.html(mejs.Utility.secondsToTimeCode(t.options.duration > 0 ? t.options.duration : t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
}
}
});
@@ -1617,18 +1688,17 @@ if (typeof jQuery != 'undefined') {
})
.bind('mousedown', function (e) {
handleVolumeMove(e);
- $(document)
- .bind('mousemove.vol', function(e) {
- handleVolumeMove(e);
- })
- .bind('mouseup.vol', function () {
- mouseIsDown = false;
- $(document).unbind('.vol');
+ t.globalBind('mousemove.vol', function(e) {
+ handleVolumeMove(e);
+ });
+ t.globalBind('mouseup.vol', function () {
+ mouseIsDown = false;
+ t.globalUnbind('.vol');
- if (!mouseIsOver && mode == 'vertical') {
- volumeSlider.hide();
- }
- });
+ if (!mouseIsOver && mode == 'vertical') {
+ volumeSlider.hide();
+ }
+ });
mouseIsDown = true;
return false;
@@ -1656,7 +1726,12 @@ if (typeof jQuery != 'undefined') {
if (t.container.is(':visible')) {
// set initial volume
positionVolumeHandle(player.options.startVolume);
-
+
+ // mutes the media and sets the volume icon muted if the initial volume is set to 0
+ if (player.options.startVolume === 0) {
+ media.setMuted(true);
+ }
+
// shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
if (media.pluginType === 'native') {
media.setVolume(player.options.startVolume);
@@ -1696,15 +1771,7 @@ if (typeof jQuery != 'undefined') {
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
// chrome doesn't alays fire this in an iframe
- var target = null;
-
- if (mejs.MediaFeatures.hasMozNativeFullScreen) {
- target = $(document);
- } else {
- target = player.container;
- }
-
- target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
+ var func = function(e) {
if (mejs.MediaFeatures.isFullScreen()) {
player.isNativeFullScreen = true;
@@ -1716,7 +1783,13 @@ if (typeof jQuery != 'undefined') {
// make sure to put the player back into place
player.exitFullScreen();
}
- });
+ };
+
+ if (mejs.MediaFeatures.hasMozNativeFullScreen) {
+ player.globalBind(mejs.MediaFeatures.fullScreenEventName, func);
+ } else {
+ player.container.bind(mejs.MediaFeatures.fullScreenEventName, func);
+ }
}
var t = this,
@@ -1822,7 +1895,7 @@ if (typeof jQuery != 'undefined') {
left: fullScreenBtnOffset + fullScreenBtnWidth});
};
- $(document).resize(function() {
+ t.globalBind('resize', function() {
positionHoverDivs();
});
@@ -1862,7 +1935,7 @@ if (typeof jQuery != 'undefined') {
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
/*
- $(document).mousemove(function(e) {
+ t.globalBind('mousemove', function(e) {
// if the mouse is anywhere but the fullsceen button, then restore it all
if (fullscreenIsDisabled) {
@@ -1920,13 +1993,18 @@ if (typeof jQuery != 'undefined') {
player.fullscreenBtn = fullscreenBtn;
- $(document).bind('keydown',function (e) {
+ t.globalBind('keydown',function (e) {
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
player.exitFullScreen();
}
});
},
+
+ cleanfullscreen: function(player) {
+ player.exitFullScreen();
+ },
+
enterFullScreen: function() {
var t = this;
@@ -2030,7 +2108,7 @@ if (typeof jQuery != 'undefined') {
.width('100%')
.height('100%');
} else {
- t.container.find('object, embed, iframe')
+ t.container.find('.mejs-shim')
.width('100%')
.height('100%');
@@ -2111,8 +2189,17 @@ if (typeof jQuery != 'undefined') {
$.extend(mejs.MepDefaults, {
// this will automatically turn on a <track>
startLanguage: '',
+
+ tracksText: 'Captions/Subtitles',
- tracksText: 'Captions/Subtitles'
+ // option to remove the [cc] button when no <track kind="subtitles"> are present
+ hideCaptionsButtonWhenEmpty: true,
+
+ // If true and we only have one track, change captions to popup
+ toggleCaptionsButtonWhenOnlyOne: false,
+
+ // #id or .class
+ slidesSelector: ''
});
$.extend(MediaElementPlayer.prototype, {
@@ -2126,13 +2213,15 @@ if (typeof jQuery != 'undefined') {
if (player.tracks.length == 0)
return;
- var t= this, i, options = '';
+ var t = this,
+ i,
+ options = '';
player.chapters =
$('<div class="mejs-chapters mejs-layer"></div>')
.prependTo(layers).hide();
player.captions =
- $('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position"><span class="mejs-captions-text"></span></div></div>')
+ $('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position mejs-captions-position-hover"><span class="mejs-captions-text"></span></div></div>')
.prependTo(layers).hide();
player.captionsText = player.captions.find('.mejs-captions-text');
player.captionsButton =
@@ -2147,35 +2236,42 @@ if (typeof jQuery != 'undefined') {
'</ul>'+
'</div>'+
'</div>')
- .appendTo(controls)
-
- // hover
- .hover(function() {
- $(this).find('.mejs-captions-selector').css('visibility','visible');
- }, function() {
- $(this).find('.mejs-captions-selector').css('visibility','hidden');
- })
+ .appendTo(controls);
+
- // handle clicks to the language radio buttons
- .delegate('input[type=radio]','click',function() {
- lang = this.value;
+ var subtitleCount = 0;
+ for (i=0; i<player.tracks.length; i++) {
+ if (player.tracks[i].kind == 'subtitles') {
+ subtitleCount++;
+ }
+ }
- if (lang == 'none') {
- player.selectedTrack = null;
- } else {
- for (i=0; i<player.tracks.length; i++) {
- if (player.tracks[i].srclang == lang) {
- player.selectedTrack = player.tracks[i];
- player.captions.attr('lang', player.selectedTrack.srclang);
- player.displayCaptions();
- break;
- }
- }
- }
- });
- //.bind('mouseenter', function() {
- // player.captionsButton.find('.mejs-captions-selector').css('visibility','visible')
- //});
+ // if only one language then just make the button a toggle
+ if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitleCount == 1){
+ // click
+ player.captionsButton.on('click',function() {
+ if (player.selectedTrack == null) {
+ var lang = player.tracks[0].srclang;
+ } else {
+ var lang = 'none';
+ }
+ player.setTrack(lang);
+ });
+ } else {
+ // hover
+ player.captionsButton.hover(function() {
+ $(this).find('.mejs-captions-selector').css('visibility','visible');
+ }, function() {
+ $(this).find('.mejs-captions-selector').css('visibility','hidden');
+ })
+
+ // handle clicks to the language radio buttons
+ .on('click','input[type=radio]',function() {
+ lang = this.value;
+ player.setTrack(lang);
+ });
+
+ }
if (!player.options.alwaysShowControls) {
// move with controls
@@ -2208,12 +2304,22 @@ if (typeof jQuery != 'undefined') {
}
}
+ // start loading tracks
player.loadNextTrack();
media.addEventListener('timeupdate',function(e) {
player.displayCaptions();
}, false);
+
+ if (player.options.slidesSelector != '') {
+ player.slidesContainer = $(player.options.slidesSelector);
+
+ media.addEventListener('timeupdate',function(e) {
+ player.displaySlides();
+ }, false);
+
+ }
media.addEventListener('loadedmetadata', function(e) {
player.displayChapters();
@@ -2241,6 +2347,28 @@ if (typeof jQuery != 'undefined') {
player.chapters.css('visibility','hidden');
}
},
+
+ setTrack: function(lang){
+
+ var t = this,
+ i;
+
+ if (lang == 'none') {
+ t.selectedTrack = null;
+ t.captionsButton.removeClass('mejs-captions-enabled');
+ } else {
+ for (i=0; i<t.tracks.length; i++) {
+ if (t.tracks[i].srclang == lang) {
+ if (t.selectedTrack == null)
+ t.captionsButton.addClass('mejs-captions-enabled');
+ t.selectedTrack = t.tracks[i];
+ t.captions.attr('lang', t.selectedTrack.srclang);
+ t.displayCaptions();
+ break;
+ }
+ }
+ }
+ },
loadNextTrack: function() {
var t = this;
@@ -2252,6 +2380,8 @@ if (typeof jQuery != 'undefined') {
} else {
// add done?
t.isLoadingTrack = false;
+
+ t.checkForTracks();
}
},
@@ -2293,6 +2423,10 @@ if (typeof jQuery != 'undefined') {
}
}, false);
}
+
+ if (track.kind == 'slides') {
+ t.setupSlides(track);
+ }
},
error: function() {
t.loadNextTrack();
@@ -2348,6 +2482,27 @@ if (typeof jQuery != 'undefined') {
t.captionsButton.find('.mejs-captions-translations').outerHeight(true)
);
},
+
+ checkForTracks: function() {
+ var
+ t = this,
+ hasSubtitles = false;
+
+ // check if any subtitles
+ if (t.options.hideCaptionsButtonWhenEmpty) {
+ for (i=0; i<t.tracks.length; i++) {
+ if (t.tracks[i].kind == 'subtitles') {
+ hasSubtitles = true;
+ break;
+ }
+ }
+
+ if (!hasSubtitles) {
+ t.captionsButton.hide();
+ t.setControlsSize();
+ }
+ }
+ },
displayCaptions: function() {
@@ -2372,6 +2527,70 @@ if (typeof jQuery != 'undefined') {
t.captions.hide();
}
},
+
+ setupSlides: function(track) {
+ var t = this;
+
+ t.slides = track;
+ t.slides.entries.imgs = [t.slides.entries.text.length];
+ t.showSlide(0);
+
+ },
+
+ showSlide: function(index) {
+ if (typeof this.tracks == 'undefined' || typeof this.slidesContainer == 'undefined') {
+ return;
+ }
+
+ var t = this,
+ url = t.slides.entries.text[index],
+ img = t.slides.entries.imgs[index];
+
+ if (typeof img == 'undefined' || typeof img.fadeIn == 'undefined') {
+
+ t.slides.entries.imgs[index] = img = $('<img src="' + url + '">')
+ .on('load', function() {
+ img.appendTo(t.slidesContainer)
+ .hide()
+ .fadeIn()
+ .siblings(':visible')
+ .fadeOut();
+
+ });
+
+ } else {
+
+ if (!img.is(':visible') && !img.is(':animated')) {
+
+ console.log('showing existing slide');
+
+ img.fadeIn()
+ .siblings(':visible')
+ .fadeOut();
+ }
+ }
+
+ },
+
+ displaySlides: function() {
+
+ if (typeof this.slides == 'undefined')
+ return;
+
+ var
+ t = this,
+ slides = t.slides,
+ i;
+
+ for (i=0; i<slides.entries.times.length; i++) {
+ if (t.media.currentTime >= slides.entries.times[i].start && t.media.currentTime <= slides.entries.times[i].stop){
+
+ t.showSlide(i);
+
+ return; // exit out if one is visible;
+ }
+ }
+ },
displayChapters: function() {
var
@@ -2735,6 +2954,10 @@ $.extend(mejs.MepDefaults,
});
},
+
+ cleancontextmenu: function(player) {
+ player.contextMenu.remove();
+ },
isContextMenuEnabled: true,
enableContextMenu: function() {
View
BIN app/assets/plugins/mediaelement_rails/flashmediaelement.swf
Binary file not shown.

0 comments on commit c769149

Please sign in to comment.
Something went wrong with that request. Please try again.