Update MediaElement.js to 2.11.0.

Props wonderboymusic
see #24015


git-svn-id: http://core.svn.wordpress.org/trunk@23958 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Ryan Boren 2013-04-10 22:38:30 +00:00
parent 3bcdb3fa1a
commit 338c2afd86
5 changed files with 1118 additions and 764 deletions

View File

@ -8,14 +8,14 @@
* Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3 * Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3
* *
* Copyright 2010-2012, John Dyer (http://j.hn) * Copyright 2010-2012, John Dyer (http://j.hn)
* Dual licensed under the MIT or GPL Version 2 licenses. * License: MIT
* *
*/ */
// Namespace // Namespace
var mejs = mejs || {}; var mejs = mejs || {};
// version number // version number
mejs.version = '2.10.1'; mejs.version = '2.11.0';
// player number (for missing, same id attr) // player number (for missing, same id attr)
mejs.meIndex = 0; mejs.meIndex = 0;
@ -30,13 +30,14 @@ mejs.plugins = {
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!) //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
], ],
youtube: [ youtube: [
{version: null, types: ['video/youtube', 'video/x-youtube']} {version: null, types: ['video/youtube', 'video/x-youtube', 'audio/youtube', 'audio/x-youtube']}
], ],
vimeo: [ vimeo: [
{version: null, types: ['video/vimeo', 'video/x-vimeo']} {version: null, types: ['video/vimeo', 'video/x-vimeo']}
] ]
}; };
/* /*
Utility methods 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 */ /* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
removeSwf: function(id) { removeSwf: function(id) {
var obj = document.getElementById(id); var obj = document.getElementById(id);
if (obj && obj.nodeName == "OBJECT") { if (obj && /object|embed/i.test(obj.nodeName)) {
if (mejs.MediaFeatures.isIE) { if (mejs.MediaFeatures.isIE) {
obj.style.display = "none"; obj.style.display = "none";
(function(){ (function(){
@ -377,7 +378,6 @@ mejs.MediaFeatures = {
}; };
mejs.MediaFeatures.init(); mejs.MediaFeatures.init();
/* /*
extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below) extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below)
*/ */
@ -442,6 +442,7 @@ mejs.PluginMediaElement = function (pluginid, pluginType, mediaUrl) {
this.pluginType = pluginType; this.pluginType = pluginType;
this.src = mediaUrl; this.src = mediaUrl;
this.events = {}; this.events = {};
this.attributes = {};
}; };
// JavaScript values and ExternalInterface methods that match HTML5 video properties methods // JavaScript values and ExternalInterface methods that match HTML5 video properties methods
@ -532,13 +533,13 @@ mejs.PluginMediaElement.prototype = {
for (j=0; j<pluginInfo.types.length; j++) { for (j=0; j<pluginInfo.types.length; j++) {
// find plugin that can play the type // find plugin that can play the type
if (type == pluginInfo.types[j]) { if (type == pluginInfo.types[j]) {
return true; return 'probably';
} }
} }
} }
} }
return false; return '';
}, },
positionFullscreenButton: function(x,y,visibleAndAbove) { positionFullscreenButton: function(x,y,visibleAndAbove) {
@ -683,7 +684,6 @@ mejs.PluginMediaElement.prototype = {
// end: fake events // end: fake events
// fake DOM attribute methods // fake DOM attribute methods
attributes: {},
hasAttribute: function(name){ hasAttribute: function(name){
return (name in this.attributes); return (name in this.attributes);
}, },
@ -702,6 +702,7 @@ mejs.PluginMediaElement.prototype = {
remove: function() { remove: function() {
mejs.Utility.removeSwf(this.pluginElement.id); mejs.Utility.removeSwf(this.pluginElement.id);
mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
} }
}; };
@ -716,6 +717,11 @@ mejs.MediaPluginBridge = {
this.htmlMediaElements[id] = htmlMediaElement; 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 // when Flash/Silverlight is ready, it calls out to this method
initPlugin: function (id) { initPlugin: function (id) {
@ -1211,7 +1217,7 @@ mejs.HtmlMediaElementShim = {
switch (playback.method) { switch (playback.method) {
case 'silverlight': case 'silverlight':
container.innerHTML = 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="initParams" value="' + initVars.join(',') + '" />' +
'<param name="windowless" value="true" />' + '<param name="windowless" value="true" />' +
'<param name="background" value="black" />' + '<param name="background" value="black" />' +
@ -1228,7 +1234,7 @@ mejs.HtmlMediaElementShim = {
container.appendChild(specialIEContainer); container.appendChild(specialIEContainer);
specialIEContainer.outerHTML = specialIEContainer.outerHTML =
'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' + '<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="movie" value="' + options.pluginPath + options.flashName + '?x=' + (new Date()) + '" />' +
'<param name="flashvars" value="' + initVars.join('&amp;') + '" />' + '<param name="flashvars" value="' + initVars.join('&amp;') + '" />' +
'<param name="quality" value="high" />' + '<param name="quality" value="high" />' +
@ -1253,7 +1259,8 @@ mejs.HtmlMediaElementShim = {
'src="' + options.pluginPath + options.flashName + '" ' + 'src="' + options.pluginPath + options.flashName + '" ' +
'flashvars="' + initVars.join('&') + '" ' + 'flashvars="' + initVars.join('&') + '" ' +
'width="' + width + '" ' + 'width="' + width + '" ' +
'height="' + height + '"></embed>'; 'height="' + height + '" ' +
'class="mejs-shim"></embed>';
} }
break; break;
@ -1286,16 +1293,16 @@ mejs.HtmlMediaElementShim = {
pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1); 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 = container.innerHTML =
'<object width="' + width + '" height="' + height + '">' + '<object width="' + width + '" height="' + height + '" class="mejs-shim">' +
'<param name="allowfullscreen" value="true" />' + '<param name="allowfullscreen" value="true" />' +
'<param name="allowscriptaccess" value="always" />' + '<param name="allowscriptaccess" value="always" />' +
'<param name="flashvars" value="api=1" />' + '<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" />' + '<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>'; '</object>';
*/ */
@ -1479,7 +1486,7 @@ mejs.YouTubeApi = {
/* /*
settings.container.innerHTML = 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" ' + '<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="allowScriptAccess" value="always">' +
'<param name="wmode" value="transparent">' + '<param name="wmode" value="transparent">' +
'</object>'; '</object>';
@ -1493,7 +1500,7 @@ mejs.YouTubeApi = {
specialIEContainer = document.createElement('div'); specialIEContainer = document.createElement('div');
settings.container.appendChild(specialIEContainer); settings.container.appendChild(specialIEContainer);
specialIEContainer.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' + 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="movie" value="' + youtubeUrl + '" />' +
'<param name="wmode" value="transparent" />' + '<param name="wmode" value="transparent" />' +
'<param name="allowScriptAccess" value="always" />' + '<param name="allowScriptAccess" value="always" />' +
@ -1502,7 +1509,7 @@ mejs.YouTubeApi = {
} else { } else {
settings.container.innerHTML = settings.container.innerHTML =
'<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="' + youtubeUrl + '" ' + '<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="allowScriptAccess" value="always">' +
'<param name="wmode" value="transparent">' + '<param name="wmode" value="transparent">' +
'</object>'; '</object>';
@ -1524,7 +1531,7 @@ mejs.YouTubeApi = {
// load the youtube video // load the youtube video
player.cueVideoById(settings.videoId); player.cueVideoById(settings.videoId);
var callbackName = settings.containerId + '_callback' var callbackName = settings.containerId + '_callback';
window[callbackName] = function(e) { window[callbackName] = function(e) {
mejs.YouTubeApi.handleStateChange(e, player, pluginMediaElement); mejs.YouTubeApi.handleStateChange(e, player, pluginMediaElement);
@ -1814,7 +1821,7 @@ window.MediaElement = mejs.MediaElement;
* using jQuery and MediaElement.js (HTML5 Flash/Silverlight wrapper) * using jQuery and MediaElement.js (HTML5 Flash/Silverlight wrapper)
* *
* Copyright 2010-2012, John Dyer (http://j.hn/) * Copyright 2010-2012, John Dyer (http://j.hn/)
* Dual licensed under the MIT or GPL Version 2 licenses. * License: MIT
* *
*/ */
if (typeof jQuery != 'undefined') { if (typeof jQuery != 'undefined') {
@ -1858,6 +1865,8 @@ if (typeof jQuery != 'undefined') {
startVolume: 0.8, startVolume: 0.8,
// useful for <audio> player loops // useful for <audio> player loops
loop: false, loop: false,
// rewind to beginning when media ends
autoRewind: true,
// resize to media dimensions // resize to media dimensions
enableAutosize: true, enableAutosize: true,
// forces the hour marker (##:00:00) // forces the hour marker (##:00:00)
@ -1872,6 +1881,10 @@ if (typeof jQuery != 'undefined') {
autosizeProgress : true, autosizeProgress : true,
// Hide controls when playing and mouse is not over the video // Hide controls when playing and mouse is not over the video
alwaysShowControls: false, alwaysShowControls: false,
// Display the video control
hideVideoControlsOnLoad: false,
// Enable click video element to toggle play/pause
clickToPlayPause: true,
// force iPad's native controls // force iPad's native controls
iPadUseNativeControls: false, iPadUseNativeControls: false,
// force iPhone's native controls // force iPhone's native controls
@ -1971,7 +1984,7 @@ if (typeof jQuery != 'undefined') {
mejs.mepIndex = 0; mejs.mepIndex = 0;
mejs.players = []; mejs.players = {};
// wraps a MediaElement object in player controls // wraps a MediaElement object in player controls
mejs.MediaElementPlayer = function(node, o) { mejs.MediaElementPlayer = function(node, o) {
@ -2003,8 +2016,11 @@ if (typeof jQuery != 'undefined') {
// extend default options // extend default options
t.options = $.extend({},mejs.MepDefaults,o); t.options = $.extend({},mejs.MepDefaults,o);
// unique ID
t.id = 'mep_' + mejs.mepIndex++;
// add to player array (for focus events) // add to player array (for focus events)
mejs.players.push(t); mejs.players[t.id] = t;
// start up // start up
t.init(); t.init();
@ -2056,7 +2072,7 @@ if (typeof jQuery != 'undefined') {
t.media.play(); t.media.play();
} }
} else if (mf.isAndroid && t.AndroidUseNativeControls) { } else if (mf.isAndroid && t.options.AndroidUseNativeControls) {
// leave default player // leave default player
@ -2067,9 +2083,6 @@ if (typeof jQuery != 'undefined') {
// remove native controls // remove native controls
t.$media.removeAttr('controls'); t.$media.removeAttr('controls');
// unique ID
t.id = 'mep_' + mejs.mepIndex++;
// build container // build container
t.container = t.container =
$('<div id="' + t.id + '" class="mejs-container ' + (mejs.MediaFeatures.svg ? 'svg' : 'no-svg') + '">'+ $('<div id="' + t.id + '" class="mejs-container ' + (mejs.MediaFeatures.svg ? 'svg' : 'no-svg') + '">'+
@ -2160,6 +2173,9 @@ if (typeof jQuery != 'undefined') {
// create MediaElement shim // create MediaElement shim
mejs.MediaElement(t.$media[0], meOptions); mejs.MediaElement(t.$media[0], meOptions);
// controls are shown when loaded
t.container.trigger('controlsshown');
}, },
showControls: function(doAnimation) { showControls: function(doAnimation) {
@ -2173,7 +2189,10 @@ if (typeof jQuery != 'undefined') {
if (doAnimation) { if (doAnimation) {
t.controls t.controls
.css('visibility','visible') .css('visibility','visible')
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;}); .stop(true, true).fadeIn(200, function() {
t.controlsAreVisible = true;
t.container.trigger('controlsshown');
});
// any additional controls people might add and want to hide // any additional controls people might add and want to hide
t.container.find('.mejs-control') t.container.find('.mejs-control')
@ -2191,6 +2210,7 @@ if (typeof jQuery != 'undefined') {
.css('display','block'); .css('display','block');
t.controlsAreVisible = true; t.controlsAreVisible = true;
t.container.trigger('controlsshown');
} }
t.setControlsSize(); t.setControlsSize();
@ -2213,6 +2233,7 @@ if (typeof jQuery != 'undefined') {
.css('display','block'); .css('display','block');
t.controlsAreVisible = false; t.controlsAreVisible = false;
t.container.trigger('controlshidden');
}); });
// any additional controls people might add and want to hide // any additional controls people might add and want to hide
@ -2234,6 +2255,7 @@ if (typeof jQuery != 'undefined') {
.css('display','block'); .css('display','block');
t.controlsAreVisible = false; t.controlsAreVisible = false;
t.container.trigger('controlshidden');
} }
}, },
@ -2360,11 +2382,13 @@ if (typeof jQuery != 'undefined') {
} else { } else {
// click to play/pause // click to play/pause
t.media.addEventListener('click', function() { t.media.addEventListener('click', function() {
if (t.options.clickToPlayPause) {
if (t.media.paused) { if (t.media.paused) {
t.media.play(); t.media.play();
} else { } else {
t.media.pause(); t.media.pause();
} }
}
}); });
// show/hide controls // show/hide controls
@ -2398,6 +2422,10 @@ if (typeof jQuery != 'undefined') {
}); });
} }
if(t.options.hideVideoControlsOnLoad) {
t.hideControls(false);
}
// check for autoplay // check for autoplay
if (autoplay && !t.options.alwaysShowControls) { if (autoplay && !t.options.alwaysShowControls) {
t.hideControls(); t.hideControls();
@ -2421,10 +2449,11 @@ if (typeof jQuery != 'undefined') {
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them) // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
media.addEventListener('play', function() { media.addEventListener('play', function() {
var playerIndex;
// go through all other players // go through all other players
for (var i=0, il=mejs.players.length; i<il; i++) { for (playerIndex in mejs.players) {
var p = mejs.players[i]; var p = mejs.players[playerIndex];
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) { if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
p.pause(); p.pause();
} }
@ -2437,11 +2466,13 @@ if (typeof jQuery != 'undefined') {
// ended for all // ended for all
t.media.addEventListener('ended', function (e) { t.media.addEventListener('ended', function (e) {
if(t.options.autoRewind) {
try{ try{
t.media.setCurrentTime(0); t.media.setCurrentTime(0);
} catch (exp) { } catch (exp) {
} }
}
t.media.pause(); t.media.pause();
if (t.setProgressRail) if (t.setProgressRail)
@ -2479,7 +2510,7 @@ if (typeof jQuery != 'undefined') {
}, 50); }, 50);
// adjust controls whenever window sizes (used to be in fullscreen only) // adjust controls whenever window sizes (used to be in fullscreen only)
$(window).resize(function() { t.globalBind('resize', function() {
// don't resize for fullscreen mode // don't resize for fullscreen mode
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) { if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
@ -2541,26 +2572,21 @@ if (typeof jQuery != 'undefined') {
nativeWidth = t.isVideo ? ((t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth) : t.options.defaultAudioWidth, nativeWidth = t.isVideo ? ((t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth) : t.options.defaultAudioWidth,
nativeHeight = t.isVideo ? ((t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight) : t.options.defaultAudioHeight, nativeHeight = t.isVideo ? ((t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight) : t.options.defaultAudioHeight,
parentWidth = t.container.parent().closest(':visible').width(), parentWidth = t.container.parent().closest(':visible').width(),
newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10); newHeight = t.isVideo || !t.options.autosizeProgress ? parseInt(parentWidth * nativeHeight/nativeWidth, 10) : nativeHeight;
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) { if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
parentWidth = $(window).width(); parentWidth = $(window).width();
newHeight = $(window).height(); newHeight = $(window).height();
} }
if ( newHeight != 0 ) { if ( newHeight != 0 && parentWidth != 0 ) {
// set outer container size // set outer container size
t.container t.container
.width(parentWidth) .width(parentWidth)
.height(newHeight); .height(newHeight);
// set native <video> or <audio> // set native <video> or <audio> and shims
t.$media t.$media.add(t.container.find('.mejs-shim'))
.width('100%')
.height('100%');
// set shims
t.container.find('object, embed, iframe')
.width('100%') .width('100%')
.height('100%'); .height('100%');
@ -2614,7 +2640,8 @@ if (typeof jQuery != 'undefined') {
// find the size of all the other controls besides the rail // find the size of all the other controls besides the rail
others.each(function() { others.each(function() {
if ($(this).css('position') != 'absolute') { var $this = $(this);
if ($this.css('position') != 'absolute' && $this.is(':visible')) {
usedWidth += $(this).outerWidth(true); usedWidth += $(this).outerWidth(true);
} }
}); });
@ -2673,6 +2700,7 @@ if (typeof jQuery != 'undefined') {
}, },
buildoverlays: function(player, controls, layers, media) { buildoverlays: function(player, controls, layers, media) {
var t = this;
if (!player.isVideo) if (!player.isVideo)
return; return;
@ -2696,10 +2724,12 @@ if (typeof jQuery != 'undefined') {
'</div>') '</div>')
.appendTo(layers) .appendTo(layers)
.click(function() { .click(function() {
if (t.options.clickToPlayPause) {
if (media.paused) { if (media.paused) {
media.play(); media.play();
} else { } else {
media.pause(); media.pause();
}
} }
}); });
@ -2776,7 +2806,7 @@ if (typeof jQuery != 'undefined') {
var t = this; var t = this;
// listen for key presses // listen for key presses
$(document).keydown(function(e) { t.globalBind('keydown', function(e) {
if (player.hasFocus && player.options.enableKeyboard) { if (player.hasFocus && player.options.enableKeyboard) {
@ -2798,7 +2828,7 @@ if (typeof jQuery != 'undefined') {
}); });
// check if someone clicked outside a player region, then kill its focus // 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) { if ($(event.target).closest('.mejs-container').length == 0) {
player.hasFocus = false; player.hasFocus = false;
} }
@ -2817,7 +2847,7 @@ if (typeof jQuery != 'undefined') {
track = $(track); track = $(track);
t.tracks.push({ t.tracks.push({
srclang: track.attr('srclang').toLowerCase(), srclang: (track.attr('srclang')) ? track.attr('srclang').toLowerCase() : '',
src: track.attr('src'), src: track.attr('src'),
kind: track.attr('kind'), kind: track.attr('kind'),
label: track.attr('label') || '', label: track.attr('label') || '',
@ -2859,29 +2889,98 @@ if (typeof jQuery != 'undefined') {
this.media.setSrc(src); this.media.setSrc(src);
}, },
remove: function() { remove: function() {
var t = this; var t = this, featureIndex, feature;
if (t.media.pluginType === 'flash') { // invoke features cleanup
t.media.remove(); for (featureIndex in t.options.features) {
} else if (t.media.pluginType === 'native') { 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); t.$media.prop('controls', true);
} else {
t.media.remove();
} }
// grab video and put it back in place // grab video and put it back in place
if (!t.isDynamic) { 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.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 // turn into jQuery plugin
if (typeof jQuery != 'undefined') { if (typeof jQuery != 'undefined') {
jQuery.fn.mediaelementplayer = function (options) { jQuery.fn.mediaelementplayer = function (options) {
return this.each(function () { if (options === false) {
new mejs.MediaElementPlayer(this, options); 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;
}; };
} }
@ -3009,15 +3108,22 @@ if (typeof jQuery != 'undefined') {
width = total.outerWidth(true), width = total.outerWidth(true),
percentage = 0, percentage = 0,
newTime = 0, newTime = 0,
pos = 0;
if (media.duration) {
if (x < offset.left) {
x = offset.left;
} else if (x > width + offset.left) {
x = width + offset.left;
}
pos = x - offset.left; pos = x - offset.left;
percentage = (pos / width);
if (x > offset.left && x <= width + offset.left && media.duration) {
percentage = ((x - offset.left) / width);
newTime = (percentage <= 0.02) ? 0 : percentage * media.duration; newTime = (percentage <= 0.02) ? 0 : percentage * media.duration;
// seek to where the mouse is // seek to where the mouse is
if (mouseIsDown) { if (mouseIsDown && newTime !== media.currentTime) {
media.setCurrentTime(newTime); media.setCurrentTime(newTime);
} }
@ -3040,21 +3146,20 @@ if (typeof jQuery != 'undefined') {
if (e.which === 1) { if (e.which === 1) {
mouseIsDown = true; mouseIsDown = true;
handleMouseMove(e); handleMouseMove(e);
$(document) t.globalBind('mousemove.dur', function(e) {
.bind('mousemove.dur', function(e) {
handleMouseMove(e); handleMouseMove(e);
}) });
.bind('mouseup.dur', function (e) { t.globalBind('mouseup.dur', function (e) {
mouseIsDown = false; mouseIsDown = false;
timefloat.hide(); timefloat.hide();
$(document).unbind('.dur'); t.globalUnbind('.dur');
}); });
return false; return false;
} }
}) })
.bind('mouseenter', function(e) { .bind('mouseenter', function(e) {
mouseIsOver = true; mouseIsOver = true;
$(document).bind('mousemove.dur', function(e) { t.globalBind('mousemove.dur', function(e) {
handleMouseMove(e); handleMouseMove(e);
}); });
if (!mejs.MediaFeatures.hasTouch) { if (!mejs.MediaFeatures.hasTouch) {
@ -3064,7 +3169,7 @@ if (typeof jQuery != 'undefined') {
.bind('mouseleave',function(e) { .bind('mouseleave',function(e) {
mouseIsOver = false; mouseIsOver = false;
if (!mouseIsDown) { if (!mouseIsDown) {
$(document).unbind('.dur'); t.globalUnbind('.dur');
timefloat.hide(); timefloat.hide();
} }
}); });
@ -3130,8 +3235,8 @@ if (typeof jQuery != 'undefined') {
// update bar and handle // update bar and handle
if (t.total && t.handle) { if (t.total && t.handle) {
var var
newWidth = t.total.width() * t.media.currentTime / t.media.duration, newWidth = Math.round(t.total.width() * t.media.currentTime / t.media.duration),
handlePos = newWidth - (t.handle.outerWidth(true) / 2); handlePos = newWidth - Math.round(t.handle.outerWidth(true) / 2);
t.current.width(newWidth); t.current.width(newWidth);
t.handle.css('left', handlePos); t.handle.css('left', handlePos);
@ -3141,6 +3246,7 @@ if (typeof jQuery != 'undefined') {
} }
}); });
})(mejs.$); })(mejs.$);
(function($) { (function($) {
// options // options
@ -3215,8 +3321,11 @@ if (typeof jQuery != 'undefined') {
updateDuration: function() { updateDuration: function() {
var t = this; var t = this;
if (t.media.duration && t.durationD) { //Toggle the long video class if the video is longer than an hour.
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25)); t.container.toggleClass("mejs-long-video", t.media.duration > 3600);
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));
} }
} }
}); });
@ -3394,13 +3503,12 @@ if (typeof jQuery != 'undefined') {
}) })
.bind('mousedown', function (e) { .bind('mousedown', function (e) {
handleVolumeMove(e); handleVolumeMove(e);
$(document) t.globalBind('mousemove.vol', function(e) {
.bind('mousemove.vol', function(e) {
handleVolumeMove(e); handleVolumeMove(e);
}) });
.bind('mouseup.vol', function () { t.globalBind('mouseup.vol', function () {
mouseIsDown = false; mouseIsDown = false;
$(document).unbind('.vol'); t.globalUnbind('.vol');
if (!mouseIsOver && mode == 'vertical') { if (!mouseIsOver && mode == 'vertical') {
volumeSlider.hide(); volumeSlider.hide();
@ -3434,6 +3542,11 @@ if (typeof jQuery != 'undefined') {
// set initial volume // set initial volume
positionVolumeHandle(player.options.startVolume); 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 // shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
if (media.pluginType === 'native') { if (media.pluginType === 'native') {
media.setVolume(player.options.startVolume); media.setVolume(player.options.startVolume);
@ -3473,15 +3586,7 @@ if (typeof jQuery != 'undefined') {
if (mejs.MediaFeatures.hasTrueNativeFullScreen) { if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
// chrome doesn't alays fire this in an iframe // chrome doesn't alays fire this in an iframe
var target = null; var func = function(e) {
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
target = $(document);
} else {
target = player.container;
}
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
if (mejs.MediaFeatures.isFullScreen()) { if (mejs.MediaFeatures.isFullScreen()) {
player.isNativeFullScreen = true; player.isNativeFullScreen = true;
@ -3493,7 +3598,13 @@ if (typeof jQuery != 'undefined') {
// make sure to put the player back into place // make sure to put the player back into place
player.exitFullScreen(); player.exitFullScreen();
} }
}); };
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
player.globalBind(mejs.MediaFeatures.fullScreenEventName, func);
} else {
player.container.bind(mejs.MediaFeatures.fullScreenEventName, func);
}
} }
var t = this, var t = this,
@ -3599,7 +3710,7 @@ if (typeof jQuery != 'undefined') {
left: fullScreenBtnOffset + fullScreenBtnWidth}); left: fullScreenBtnOffset + fullScreenBtnWidth});
}; };
$(document).resize(function() { t.globalBind('resize', function() {
positionHoverDivs(); positionHoverDivs();
}); });
@ -3639,7 +3750,7 @@ if (typeof jQuery != 'undefined') {
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events // 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 // 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 the mouse is anywhere but the fullsceen button, then restore it all
if (fullscreenIsDisabled) { if (fullscreenIsDisabled) {
@ -3697,13 +3808,18 @@ if (typeof jQuery != 'undefined') {
player.fullscreenBtn = fullscreenBtn; 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) { if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
player.exitFullScreen(); player.exitFullScreen();
} }
}); });
}, },
cleanfullscreen: function(player) {
player.exitFullScreen();
},
enterFullScreen: function() { enterFullScreen: function() {
var t = this; var t = this;
@ -3807,7 +3923,7 @@ if (typeof jQuery != 'undefined') {
.width('100%') .width('100%')
.height('100%'); .height('100%');
} else { } else {
t.container.find('object, embed, iframe') t.container.find('.mejs-shim')
.width('100%') .width('100%')
.height('100%'); .height('100%');
@ -3889,7 +4005,16 @@ if (typeof jQuery != 'undefined') {
// this will automatically turn on a <track> // this will automatically turn on a <track>
startLanguage: '', 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, { $.extend(MediaElementPlayer.prototype, {
@ -3903,13 +4028,15 @@ if (typeof jQuery != 'undefined') {
if (player.tracks.length == 0) if (player.tracks.length == 0)
return; return;
var t= this, i, options = ''; var t = this,
i,
options = '';
player.chapters = player.chapters =
$('<div class="mejs-chapters mejs-layer"></div>') $('<div class="mejs-chapters mejs-layer"></div>')
.prependTo(layers).hide(); .prependTo(layers).hide();
player.captions = 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(); .prependTo(layers).hide();
player.captionsText = player.captions.find('.mejs-captions-text'); player.captionsText = player.captions.find('.mejs-captions-text');
player.captionsButton = player.captionsButton =
@ -3924,45 +4051,52 @@ if (typeof jQuery != 'undefined') {
'</ul>'+ '</ul>'+
'</div>'+ '</div>'+
'</div>') '</div>')
.appendTo(controls) .appendTo(controls);
var subtitleCount = 0;
for (i=0; i<player.tracks.length; i++) {
if (player.tracks[i].kind == 'subtitles') {
subtitleCount++;
}
}
// 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 // hover
.hover(function() { player.captionsButton.hover(function() {
$(this).find('.mejs-captions-selector').css('visibility','visible'); $(this).find('.mejs-captions-selector').css('visibility','visible');
}, function() { }, function() {
$(this).find('.mejs-captions-selector').css('visibility','hidden'); $(this).find('.mejs-captions-selector').css('visibility','hidden');
}) })
// handle clicks to the language radio buttons // handle clicks to the language radio buttons
.delegate('input[type=radio]','click',function() { .on('click','input[type=radio]',function() {
lang = this.value; lang = this.value;
player.setTrack(lang);
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 (!player.options.alwaysShowControls) { if (!player.options.alwaysShowControls) {
// move with controls // move with controls
player.container player.container
.bind('mouseenter', function () { .bind('controlsshown', function () {
// push captions above controls // push captions above controls
player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover'); player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');
}) })
.bind('mouseleave', function () { .bind('controlshidden', function () {
if (!media.paused) { if (!media.paused) {
// move back to normal place // move back to normal place
player.container.find('.mejs-captions-position').removeClass('mejs-captions-position-hover'); player.container.find('.mejs-captions-position').removeClass('mejs-captions-position-hover');
@ -3985,6 +4119,7 @@ if (typeof jQuery != 'undefined') {
} }
} }
// start loading tracks
player.loadNextTrack(); player.loadNextTrack();
@ -3992,6 +4127,15 @@ if (typeof jQuery != 'undefined') {
player.displayCaptions(); player.displayCaptions();
}, false); }, false);
if (player.options.slidesSelector != '') {
player.slidesContainer = $(player.options.slidesSelector);
media.addEventListener('timeupdate',function(e) {
player.displaySlides();
}, false);
}
media.addEventListener('loadedmetadata', function(e) { media.addEventListener('loadedmetadata', function(e) {
player.displayChapters(); player.displayChapters();
}, false); }, false);
@ -4019,6 +4163,28 @@ if (typeof jQuery != 'undefined') {
} }
}, },
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() { loadNextTrack: function() {
var t = this; var t = this;
@ -4029,6 +4195,8 @@ if (typeof jQuery != 'undefined') {
} else { } else {
// add done? // add done?
t.isLoadingTrack = false; t.isLoadingTrack = false;
t.checkForTracks();
} }
}, },
@ -4070,6 +4238,10 @@ if (typeof jQuery != 'undefined') {
} }
}, false); }, false);
} }
if (track.kind == 'slides') {
t.setupSlides(track);
}
}, },
error: function() { error: function() {
t.loadNextTrack(); t.loadNextTrack();
@ -4126,6 +4298,27 @@ if (typeof jQuery != 'undefined') {
); );
}, },
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() { displayCaptions: function() {
if (typeof this.tracks == 'undefined') if (typeof this.tracks == 'undefined')
@ -4150,6 +4343,70 @@ if (typeof jQuery != 'undefined') {
} }
}, },
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() { displayChapters: function() {
var var
t = this, t = this,
@ -4513,6 +4770,10 @@ $.extend(mejs.MepDefaults,
}); });
}, },
cleancontextmenu: function(player) {
player.contextMenu.remove();
},
isContextMenuEnabled: true, isContextMenuEnabled: true,
enableContextMenu: function() { enableContextMenu: function() {
this.isContextMenuEnabled = true; this.isContextMenuEnabled = true;

File diff suppressed because one or more lines are too long

View File

@ -321,6 +321,7 @@
text-align: center; text-align: center;
left: 0; left: 0;
} }
.mejs-controls .mejs-time-rail .mejs-time-float-corner { .mejs-controls .mejs-time-rail .mejs-time-float-corner {
position: absolute; position: absolute;
display: block; display: block;
@ -334,9 +335,19 @@
border-radius: 0; border-radius: 0;
top: 15px; top: 15px;
left: 13px; left: 13px;
} }
.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float {
width: 48px;
}
.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-current {
width: 44px;
}
.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-corner {
left: 18px;
}

File diff suppressed because one or more lines are too long