Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/apps.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Reschke <lukas@statuscode.ch>2013-04-12 03:15:38 +0400
committerLukas Reschke <lukas@statuscode.ch>2013-04-12 03:16:31 +0400
commitcd0961af906749f19024fa4dcf1cea41d3c74696 (patch)
tree3cbdb47a665543d7635ac7680b7f919438e70265 /files_videoviewer
parentf36644a53740b56b152bf3475a86df13520d7402 (diff)
Bump MediaElement.js to version 2.11.1
Diffstat (limited to 'files_videoviewer')
-rwxr-xr-x[-rw-r--r--]files_videoviewer/js/flashmediaelement.swfbin27775 -> 28648 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/js/mediaelement-and-player.js613
-rwxr-xr-x[-rw-r--r--]files_videoviewer/js/mediaelement-and-player.min.js201
-rwxr-xr-xfiles_videoviewer/mediaelement/src/Builder.py1
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/compiler.jarbin3939454 -> 3939454 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/background.pngbin166 -> 166 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/bigplay.fw.pngbin79426 -> 79426 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/bigplay.pngbin3001 -> 3001 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/bigplay.svg0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls-ted.pngbin1559 -> 1559 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls-wmp-bg.pngbin1960 -> 1960 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls-wmp.pngbin5511 -> 5511 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls.fw.pngbin80753 -> 80753 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls.pngbin1892 -> 1892 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/controls.svg0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/loading.gifbin6224 -> 6224 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/mediaelementplayer.css0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/css/mejs-skins.css0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/FlashMediaElement.as2
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/FlashMediaElement.flabin26095 -> 26182 bytes
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/HtmlMediaEvent.as0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/htmlelements/AudioElement.as2
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/htmlelements/IMediaElement.as0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as2
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/flash/htmlelements/YouTubeElement.as404
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/jeesh-extras.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/jeesh.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-featuredetection.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-header.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-i18n-locale-de.js0
-rwxr-xr-xfiles_videoviewer/mediaelement/src/js/me-i18n-locale-zh.js26
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-i18n.js5
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-mediaelements.js5
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-namespace.js6
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-plugindetector.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-shim.js36
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/me-utility.js9
-rwxr-xr-xfiles_videoviewer/mediaelement/src/js/mep-feature-ads-vast.js243
-rwxr-xr-xfiles_videoviewer/mediaelement/src/js/mep-feature-ads.js312
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-backlight.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js4
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-endedhtml.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js109
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-googleanalytics.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-loop.js4
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-playlist.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-playpause.js4
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-postroll.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-progress.js25
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-sourcechooser.js2
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-speed.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-stop.js4
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-time.js6
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-tracks.js208
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-visualcontrols.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-feature-volume.js32
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-header.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-library.js0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/js/mep-player.js139
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/App.xaml0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/App.xaml.cs0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/MainPage.xaml0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/MainPage.xaml.cs0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/Properties/AppManifest.xml0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/Properties/AssemblyInfo.cs0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj.user0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.sln0
-rwxr-xr-x[-rw-r--r--]files_videoviewer/mediaelement/src/yuicompressor-2.4.2.jarbin851219 -> 851219 bytes
69 files changed, 1967 insertions, 437 deletions
diff --git a/files_videoviewer/js/flashmediaelement.swf b/files_videoviewer/js/flashmediaelement.swf
index 4e5c2cbf7..d2464bfe2 100644..100755
--- a/files_videoviewer/js/flashmediaelement.swf
+++ b/files_videoviewer/js/flashmediaelement.swf
Binary files differ
diff --git a/files_videoviewer/js/mediaelement-and-player.js b/files_videoviewer/js/mediaelement-and-player.js
index 2d88f4e47..96da675df 100644..100755
--- a/files_videoviewer/js/mediaelement-and-player.js
+++ b/files_videoviewer/js/mediaelement-and-player.js
@@ -15,7 +15,7 @@
var mejs = mejs || {};
// version number
-mejs.version = '2.10.3';
+mejs.version = '2.11.1';
// player number (for missing, same id attr)
mejs.meIndex = 0;
@@ -30,7 +30,7 @@ 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']}
@@ -58,6 +58,7 @@ mejs.Utility = {
j,
path = '',
name = '',
+ pos,
script,
scripts = document.getElementsByTagName('script'),
il = scripts.length,
@@ -67,8 +68,9 @@ mejs.Utility = {
script = scripts[i].src;
for (j = 0; j < jl; j++) {
name = scriptNames[j];
- if (script.indexOf(name) > -1) {
- path = script.substring(0, script.indexOf(name));
+ pos = script.indexOf(name);
+ if (pos > -1 && pos == script.length - name.length) {
+ path = script.substring(0, pos);
break;
}
}
@@ -148,7 +150,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 +534,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 +703,7 @@ mejs.PluginMediaElement.prototype = {
remove: function() {
mejs.Utility.removeSwf(this.pluginElement.id);
+ mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
}
};
@@ -715,6 +718,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) {
@@ -803,6 +811,10 @@ mejs.MediaElementDefaults = {
flashStreamer: '',
// turns on the smoothing filter in Flash
enablePluginSmoothing: false,
+ // enabled pseudo-streaming (seek) on .mp4 files
+ enablePseudoStreaming: false,
+ // start query parameter sent to server for pseudo-streaming
+ pseudoStreamingStartQueryParam: 'start',
// name of silverlight file
silverlightName: 'silverlightmediaelement.xap',
// default if the <video width> is not specified
@@ -1068,7 +1080,7 @@ mejs.HtmlMediaElementShim = {
getTypeFromFile: function(url) {
url = url.split('?')[0];
- var ext = url.substring(url.lastIndexOf('.') + 1);
+ var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return (/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext);
},
@@ -1185,7 +1197,8 @@ mejs.HtmlMediaElementShim = {
'startvolume=' + options.startVolume,
'timerrate=' + options.timerRate,
'flashstreamer=' + options.flashStreamer,
- 'height=' + height];
+ 'height=' + height,
+ 'pseudostreamstart=' + options.pseudoStreamingStartQueryParam];
if (playback.url !== null) {
if (playback.method == 'flash') {
@@ -1200,6 +1213,9 @@ mejs.HtmlMediaElementShim = {
if (options.enablePluginSmoothing) {
initVars.push('smoothing=true');
}
+ if (options.enablePseudoStreaming) {
+ initVars.push('pseudostreaming=true');
+ }
if (controls) {
initVars.push('controls=true'); // shows controls in the plugin if desired
}
@@ -1210,7 +1226,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 +1243,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 +1268,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 +1302,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 +1495,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 +1509,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 +1518,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>';
@@ -1622,12 +1639,11 @@ window.MediaElement = mejs.MediaElement;
* me-i18n-locale.js
*
* @params
- * - $ - zepto || jQuery ..
* - context - document, iframe ..
* - exports - CommonJS, window ..
*
*/
-;(function($, context, exports, undefined) {
+;(function(context, exports, undefined) {
"use strict";
var i18n = {
"locale": {
@@ -1777,7 +1793,8 @@ window.MediaElement = mejs.MediaElement;
// end i18n
exports.i18n = i18n;
-}(jQuery, document, mejs));
+}(document, mejs));
+
/*!
* This is a i18n.locale language object.
*
@@ -1804,6 +1821,33 @@ window.MediaElement = mejs.MediaElement;
};
}(mejs.i18n.locale.strings));
+/*!
+ * This is a i18n.locale language object.
+ *
+ *<de> Traditional chinese translation by Tim Latz, latz.tim@gmail.com
+ *
+ * @author
+ * Tim Latz (latz.tim@gmail.com)
+ *
+ * @see
+ * me-i18n.js
+ *
+ * @params
+ * - exports - CommonJS, window ..
+ */
+;(function(exports, undefined) {
+
+ "use strict";
+
+ exports.zh = {
+ "Fullscreen" : "全螢幕",
+ "Go Fullscreen" : "全屏模式",
+ "Turn off Fullscreen" : "退出全屏模式",
+ "Close" : "關閉"
+ };
+
+}(mejs.i18n.locale.strings));
+
/*!
* MediaElementPlayer
@@ -1873,6 +1917,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
@@ -1974,7 +2020,7 @@ if (typeof jQuery != 'undefined') {
mejs.mepIndex = 0;
- mejs.players = [];
+ mejs.players = {};
// wraps a MediaElement object in player controls
mejs.MediaElementPlayer = function(node, o) {
@@ -2006,8 +2052,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();
@@ -2059,7 +2108,7 @@ if (typeof jQuery != 'undefined') {
t.media.play();
}
- } else if (mf.isAndroid && t.AndroidUseNativeControls) {
+ } else if (mf.isAndroid && t.options.AndroidUseNativeControls) {
// leave default player
@@ -2070,9 +2119,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') + '">'+
@@ -2164,8 +2210,10 @@ if (typeof jQuery != 'undefined') {
// create MediaElement shim
mejs.MediaElement(t.$media[0], meOptions);
- // controls are shown when loaded
- t.container.trigger('controlsshown');
+ if (typeof(t.container) != 'undefined'){
+ // controls are shown when loaded
+ t.container.trigger('controlsshown');
+ }
},
showControls: function(doAnimation) {
@@ -2411,7 +2459,11 @@ if (typeof jQuery != 'undefined') {
}
});
}
-
+
+ if(t.options.hideVideoControlsOnLoad) {
+ t.hideControls(false);
+ }
+
// check for autoplay
if (autoplay && !t.options.alwaysShowControls) {
t.hideControls();
@@ -2435,10 +2487,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();
}
@@ -2495,7 +2548,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)) ) {
@@ -2569,17 +2622,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) {
@@ -2630,7 +2678,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);
}
});
@@ -2795,7 +2844,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) {
@@ -2817,7 +2866,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;
}
@@ -2836,7 +2885,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') || '',
@@ -2878,29 +2927,97 @@ 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 object so that pauseOtherPlayers doesn't blow up when trying to pause a non existance flash api.
+ delete mejs.players[t.id];
t.container.remove();
+ t.globalUnbind();
+ delete t.node.player;
}
};
+ (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;
};
}
@@ -2927,7 +3044,7 @@ if (typeof jQuery != 'undefined') {
t = this,
play =
$('<div class="mejs-button mejs-playpause-button mejs-play" >' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.playpauseText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.playpauseText + '" aria-label="' + t.options.playpauseText + '"></button>' +
'</div>')
.appendTo(controls)
.click(function(e) {
@@ -2960,6 +3077,7 @@ if (typeof jQuery != 'undefined') {
});
})(mejs.$);
+
(function($) {
$.extend(mejs.MepDefaults, {
@@ -2972,7 +3090,7 @@ if (typeof jQuery != 'undefined') {
var t = this,
stop =
$('<div class="mejs-button mejs-stop-button mejs-stop">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '" aria-label="' + t.options.stopText + '"></button>' +
'</div>')
.appendTo(controls)
.click(function() {
@@ -2993,6 +3111,7 @@ if (typeof jQuery != 'undefined') {
});
})(mejs.$);
+
(function($) {
// progress/loaded bar
$.extend(MediaElementPlayer.prototype, {
@@ -3066,21 +3185,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) {
@@ -3090,7 +3208,7 @@ if (typeof jQuery != 'undefined') {
.bind('mouseleave',function(e) {
mouseIsOver = false;
if (!mouseIsDown) {
- $(document).unbind('.dur');
+ t.globalUnbind('.dur');
timefloat.hide();
}
});
@@ -3156,8 +3274,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);
@@ -3239,14 +3357,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));
}
}
});
@@ -3275,7 +3393,7 @@ if (typeof jQuery != 'undefined') {
// horizontal version
$('<div class="mejs-button mejs-volume-button mejs-mute">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '" aria-label="' + t.options.muteText + '"></button>'+
'</div>' +
'<div class="mejs-horizontal-volume-slider">'+ // outer background
'<div class="mejs-horizontal-volume-total"></div>'+ // line background
@@ -3287,7 +3405,7 @@ if (typeof jQuery != 'undefined') {
// vertical version
$('<div class="mejs-button mejs-volume-button mejs-mute">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '" aria-label="' + t.options.muteText + '"></button>'+
'<div class="mejs-volume-slider">'+ // outer background
'<div class="mejs-volume-total"></div>'+ // line background
'<div class="mejs-volume-current"></div>'+ // current volume
@@ -3424,18 +3542,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;
@@ -3463,7 +3580,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);
@@ -3503,15 +3625,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;
@@ -3523,7 +3637,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,
@@ -3532,7 +3652,7 @@ if (typeof jQuery != 'undefined') {
container = player.container,
fullscreenBtn =
$('<div class="mejs-button mejs-fullscreen-button">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '" aria-label="' + t.options.fullscreenText + '"></button>' +
'</div>')
.appendTo(controls);
@@ -3586,9 +3706,9 @@ if (typeof jQuery != 'undefined') {
restoreControls = function() {
if (fullscreenIsDisabled) {
// hide the hovers
- videoHoverDiv.hide();
- controlsLeftHoverDiv.hide();
- controlsRightHoverDiv.hide();
+ for (var i in hoverDivs) {
+ hoverDivs[i].hide();
+ }
// restore the control bar
fullscreenBtn.css('pointer-events', '');
@@ -3598,41 +3718,54 @@ if (typeof jQuery != 'undefined') {
fullscreenIsDisabled = false;
}
},
- videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
- controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
- controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
+ hoverDivs = {},
+ hoverDivNames = ['top', 'left', 'right', 'bottom'],
+ i, len,
positionHoverDivs = function() {
- var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
- videoHoverDiv.css(style);
- controlsLeftHoverDiv.css(style);
- controlsRightHoverDiv.css(style);
+ var fullScreenBtnOffsetLeft = fullscreenBtn.offset().left - t.container.offset().left,
+ fullScreenBtnOffsetTop = fullscreenBtn.offset().top - t.container.offset().top,
+ fullScreenBtnWidth = fullscreenBtn.outerWidth(true),
+ fullScreenBtnHeight = fullscreenBtn.outerHeight(true),
+ containerWidth = t.container.width(),
+ containerHeight = t.container.height();
+
+ for (i in hoverDivs) {
+ hoverDivs[i].css({position: 'absolute', top: 0, left: 0}); //, backgroundColor: '#f00'});
+ }
// over video, but not controls
- videoHoverDiv
- .width( t.container.width() )
- .height( t.container.height() - t.controls.height() );
+ hoverDivs['top']
+ .width( containerWidth )
+ .height( fullScreenBtnOffsetTop );
// over controls, but not the fullscreen button
- var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
- fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
-
- controlsLeftHoverDiv
- .width( fullScreenBtnOffset )
- .height( t.controls.height() )
- .css({top: t.container.height() - t.controls.height()});
+ hoverDivs['left']
+ .width( fullScreenBtnOffsetLeft )
+ .height( fullScreenBtnHeight )
+ .css({top: fullScreenBtnOffsetTop});
// after the fullscreen button
- controlsRightHoverDiv
- .width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
- .height( t.controls.height() )
- .css({top: t.container.height() - t.controls.height(),
- left: fullScreenBtnOffset + fullScreenBtnWidth});
+ hoverDivs['right']
+ .width( containerWidth - fullScreenBtnOffsetLeft - fullScreenBtnWidth )
+ .height( fullScreenBtnHeight )
+ .css({top: fullScreenBtnOffsetTop,
+ left: fullScreenBtnOffsetLeft + fullScreenBtnWidth});
+
+ // under the fullscreen button
+ hoverDivs['bottom']
+ .width( containerWidth )
+ .height( containerHeight - fullScreenBtnHeight - fullScreenBtnOffsetTop )
+ .css({top: fullScreenBtnOffsetTop + fullScreenBtnHeight});
};
- $(document).resize(function() {
+ t.globalBind('resize', function() {
positionHoverDivs();
});
+ for (i = 0, len = hoverDivNames.length; i < len; i += 1) {
+ hoverDivs[hoverDivNames[i]] = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls).hide();
+ }
+
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
fullscreenBtn
.mouseover(function() {
@@ -3650,9 +3783,9 @@ if (typeof jQuery != 'undefined') {
t.controls.css('pointer-events', 'none');
// show the divs that will restore things
- videoHoverDiv.show();
- controlsRightHoverDiv.show();
- controlsLeftHoverDiv.show();
+ for (i in hoverDivs) {
+ hoverDivs[i].show();
+ }
positionHoverDivs();
fullscreenIsDisabled = true;
@@ -3669,7 +3802,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) {
@@ -3727,13 +3860,20 @@ 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();
+ },
+
+ containerSizeTimeout: null,
+
enterFullScreen: function() {
var t = this;
@@ -3826,7 +3966,7 @@ if (typeof jQuery != 'undefined') {
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
// Actually, it seems to be needed for IE8, too
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
- setTimeout(function() {
+ t.containerSizeTimeout = setTimeout(function() {
t.container.css({width: '100%', height: '100%'});
t.setControlsSize();
}, 500);
@@ -3837,7 +3977,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%');
@@ -3864,6 +4004,9 @@ if (typeof jQuery != 'undefined') {
var t = this;
+ // Prevent container from attempting to stretch a second time
+ clearTimeout(t.containerSizeTimeout);
+
// firefox can't adjust plugins
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
t.media.setFullscreen(false);
@@ -3918,8 +4061,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, {
@@ -3927,24 +4079,23 @@ if (typeof jQuery != 'undefined') {
hasChapters: false,
buildtracks: function(player, controls, layers, media) {
- if (!player.isVideo)
- return;
-
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 =
$('<div class="mejs-button mejs-captions-button">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.tracksText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.tracksText + '" aria-label="' + t.options.tracksText + '"></button>'+
'<div class="mejs-captions-selector">'+
'<ul>'+
'<li>'+
@@ -3954,35 +4105,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
@@ -4015,12 +4173,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();
@@ -4048,6 +4216,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;
@@ -4059,6 +4249,8 @@ if (typeof jQuery != 'undefined') {
} else {
// add done?
t.isLoadingTrack = false;
+
+ t.checkForTracks();
}
},
@@ -4100,6 +4292,10 @@ if (typeof jQuery != 'undefined') {
}
}, false);
}
+
+ if (track.kind == 'slides') {
+ t.setupSlides(track);
+ }
},
error: function() {
t.loadNextTrack();
@@ -4155,6 +4351,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() {
@@ -4179,6 +4396,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
@@ -4542,6 +4823,10 @@ $.extend(mejs.MepDefaults,
});
},
+
+ cleancontextmenu: function(player) {
+ player.contextMenu.remove();
+ },
isContextMenuEnabled: true,
enableContextMenu: function() {
diff --git a/files_videoviewer/js/mediaelement-and-player.min.js b/files_videoviewer/js/mediaelement-and-player.min.js
index 4e1074b4b..6bf5667c6 100644..100755
--- a/files_videoviewer/js/mediaelement-and-player.min.js
+++ b/files_videoviewer/js/mediaelement-and-player.min.js
@@ -10,11 +10,12 @@
* Copyright 2010-2012, John Dyer (http://j.hn)
* License: MIT
*
-*/var mejs=mejs||{};mejs.version="2.10.3";mejs.meIndex=0;
-mejs.plugins={silverlight:[{version:[3,0],types:["video/mp4","video/m4v","video/mov","video/wmv","audio/wma","audio/m4a","audio/mp3","audio/wav","audio/mpeg"]}],flash:[{version:[9,0,124],types:["video/mp4","video/m4v","video/mov","video/flv","video/rtmp","video/x-flv","audio/flv","audio/x-flv","audio/mp3","audio/m4a","audio/mpeg","video/youtube","video/x-youtube"]}],youtube:[{version:null,types:["video/youtube","video/x-youtube"]}],vimeo:[{version:null,types:["video/vimeo","video/x-vimeo"]}]};
-mejs.Utility={encodeUrl:function(a){return encodeURIComponent(a)},escapeHTML:function(a){return a.toString().split("&").join("&amp;").split("<").join("&lt;").split('"').join("&quot;")},absolutizeUrl:function(a){var b=document.createElement("div");b.innerHTML='<a href="'+this.escapeHTML(a)+'">x</a>';return b.firstChild.href},getScriptPath:function(a){for(var b=0,c,d="",e="",g,f=document.getElementsByTagName("script"),h=f.length,l=a.length;b<h;b++){g=f[b].src;for(c=0;c<l;c++){e=a[c];if(g.indexOf(e)>
--1){d=g.substring(0,g.indexOf(e));break}}if(d!=="")break}return d},secondsToTimeCode:function(a,b,c,d){if(typeof c=="undefined")c=false;else if(typeof d=="undefined")d=25;var e=Math.floor(a/3600)%24,g=Math.floor(a/60)%60,f=Math.floor(a%60);a=Math.floor((a%1*d).toFixed(3));return(b||e>0?(e<10?"0"+e:e)+":":"")+(g<10?"0"+g:g)+":"+(f<10?"0"+f:f)+(c?":"+(a<10?"0"+a:a):"")},timeCodeToSeconds:function(a,b,c,d){if(typeof c=="undefined")c=false;else if(typeof d=="undefined")d=25;a=a.split(":");b=parseInt(a[0],
-10);var e=parseInt(a[1],10),g=parseInt(a[2],10),f=0,h=0;if(c)f=parseInt(a[3])/d;return h=b*3600+e*60+g+f},convertSMPTEtoSeconds:function(a){if(typeof a!="string")return false;a=a.replace(",",".");var b=0,c=a.indexOf(".")!=-1?a.split(".")[1].length:0,d=1;a=a.split(":").reverse();for(var e=0;e<a.length;e++){d=1;if(e>0)d=Math.pow(60,e);b+=Number(a[e])*d}return Number(b.toFixed(c))},removeSwf:function(a){var b=document.getElementById(a);if(b&&b.nodeName=="OBJECT")if(mejs.MediaFeatures.isIE){b.style.display=
+*/var mejs=mejs||{};mejs.version="2.11.1";mejs.meIndex=0;
+mejs.plugins={silverlight:[{version:[3,0],types:["video/mp4","video/m4v","video/mov","video/wmv","audio/wma","audio/m4a","audio/mp3","audio/wav","audio/mpeg"]}],flash:[{version:[9,0,124],types:["video/mp4","video/m4v","video/mov","video/flv","video/rtmp","video/x-flv","audio/flv","audio/x-flv","audio/mp3","audio/m4a","audio/mpeg","video/youtube","video/x-youtube"]}],youtube:[{version:null,types:["video/youtube","video/x-youtube","audio/youtube","audio/x-youtube"]}],vimeo:[{version:null,types:["video/vimeo",
+"video/x-vimeo"]}]};
+mejs.Utility={encodeUrl:function(a){return encodeURIComponent(a)},escapeHTML:function(a){return a.toString().split("&").join("&amp;").split("<").join("&lt;").split('"').join("&quot;")},absolutizeUrl:function(a){var b=document.createElement("div");b.innerHTML='<a href="'+this.escapeHTML(a)+'">x</a>';return b.firstChild.href},getScriptPath:function(a){for(var b=0,c,d="",e="",g,f,h=document.getElementsByTagName("script"),l=h.length,j=a.length;b<l;b++){f=h[b].src;for(c=0;c<j;c++){e=a[c];g=f.indexOf(e);
+if(g>-1&&g==f.length-e.length){d=f.substring(0,g);break}}if(d!=="")break}return d},secondsToTimeCode:function(a,b,c,d){if(typeof c=="undefined")c=false;else if(typeof d=="undefined")d=25;var e=Math.floor(a/3600)%24,g=Math.floor(a/60)%60,f=Math.floor(a%60);a=Math.floor((a%1*d).toFixed(3));return(b||e>0?(e<10?"0"+e:e)+":":"")+(g<10?"0"+g:g)+":"+(f<10?"0"+f:f)+(c?":"+(a<10?"0"+a:a):"")},timeCodeToSeconds:function(a,b,c,d){if(typeof c=="undefined")c=false;else if(typeof d=="undefined")d=25;a=a.split(":");
+b=parseInt(a[0],10);var e=parseInt(a[1],10),g=parseInt(a[2],10),f=0,h=0;if(c)f=parseInt(a[3])/d;return h=b*3600+e*60+g+f},convertSMPTEtoSeconds:function(a){if(typeof a!="string")return false;a=a.replace(",",".");var b=0,c=a.indexOf(".")!=-1?a.split(".")[1].length:0,d=1;a=a.split(":").reverse();for(var e=0;e<a.length;e++){d=1;if(e>0)d=Math.pow(60,e);b+=Number(a[e])*d}return Number(b.toFixed(c))},removeSwf:function(a){var b=document.getElementById(a);if(b&&/object|embed/i.test(b.nodeName))if(mejs.MediaFeatures.isIE){b.style.display=
"none";(function(){b.readyState==4?mejs.Utility.removeObjectInIE(a):setTimeout(arguments.callee,10)})()}else b.parentNode.removeChild(b)},removeObjectInIE:function(a){if(a=document.getElementById(a)){for(var b in a)if(typeof a[b]=="function")a[b]=null;a.parentNode.removeChild(a)}}};
mejs.PluginDetector={hasPluginVersion:function(a,b){var c=this.plugins[a];b[1]=b[1]||0;b[2]=b[2]||0;return c[0]>b[0]||c[0]==b[0]&&c[1]>b[1]||c[0]==b[0]&&c[1]==b[1]&&c[2]>=b[2]?true:false},nav:window.navigator,ua:window.navigator.userAgent.toLowerCase(),plugins:[],addPlugin:function(a,b,c,d,e){this.plugins[a]=this.detectPlugin(b,c,d,e)},detectPlugin:function(a,b,c,d){var e=[0,0,0],g;if(typeof this.nav.plugins!="undefined"&&typeof this.nav.plugins[a]=="object"){if((c=this.nav.plugins[a].description)&&
!(typeof this.nav.mimeTypes!="undefined"&&this.nav.mimeTypes[b]&&!this.nav.mimeTypes[b].enabledPlugin)){e=c.replace(a,"").replace(/^\s+/,"").replace(/\sr/gi,".").split(".");for(a=0;a<e.length;a++)e[a]=parseInt(e[a].match(/\d+/),10)}}else if(typeof window.ActiveXObject!="undefined")try{if(g=new ActiveXObject(c))e=d(g)}catch(f){}return e}};
@@ -27,41 +28,41 @@ else if(e.webkitRequestFullScreen)return b.webkitIsFullScreen};a.requestFullScre
mejs.HtmlMediaElement={pluginType:"native",isFullScreen:false,setCurrentTime:function(a){this.currentTime=a},setMuted:function(a){this.muted=a},setVolume:function(a){this.volume=a},stop:function(){this.pause()},setSrc:function(a){for(var b=this.getElementsByTagName("source");b.length>0;)this.removeChild(b[0]);if(typeof a=="string")this.src=a;else{var c;for(b=0;b<a.length;b++){c=a[b];if(this.canPlayType(c.type)){this.src=c.src;break}}}},setVideoSize:function(a,b){this.width=a;this.height=b}};
mejs.PluginMediaElement=function(a,b,c){this.id=a;this.pluginType=b;this.src=c;this.events={};this.attributes={}};
mejs.PluginMediaElement.prototype={pluginElement:null,pluginType:"",isFullScreen:false,playbackRate:-1,defaultPlaybackRate:-1,seekable:[],played:[],paused:true,ended:false,seeking:false,duration:0,error:null,tagName:"",muted:false,volume:1,currentTime:0,play:function(){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.playVideo():this.pluginApi.playMedia();this.paused=false}},load:function(){if(this.pluginApi!=null){this.pluginType!="youtube"&&this.pluginApi.loadMedia();this.paused=
-false}},pause:function(){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.pauseVideo():this.pluginApi.pauseMedia();this.paused=true}},stop:function(){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.stopVideo():this.pluginApi.stopMedia();this.paused=true}},canPlayType:function(a){var b,c,d,e=mejs.plugins[this.pluginType];for(b=0;b<e.length;b++){d=e[b];if(mejs.PluginDetector.hasPluginVersion(this.pluginType,d.version))for(c=0;c<d.types.length;c++)if(a==d.types[c])return true}return false},
+false}},pause:function(){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.pauseVideo():this.pluginApi.pauseMedia();this.paused=true}},stop:function(){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.stopVideo():this.pluginApi.stopMedia();this.paused=true}},canPlayType:function(a){var b,c,d,e=mejs.plugins[this.pluginType];for(b=0;b<e.length;b++){d=e[b];if(mejs.PluginDetector.hasPluginVersion(this.pluginType,d.version))for(c=0;c<d.types.length;c++)if(a==d.types[c])return"probably"}return""},
positionFullscreenButton:function(a,b,c){this.pluginApi!=null&&this.pluginApi.positionFullscreenButton&&this.pluginApi.positionFullscreenButton(a,b,c)},hideFullscreenButton:function(){this.pluginApi!=null&&this.pluginApi.hideFullscreenButton&&this.pluginApi.hideFullscreenButton()},setSrc:function(a){if(typeof a=="string"){this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(a));this.src=mejs.Utility.absolutizeUrl(a)}else{var b,c;for(b=0;b<a.length;b++){c=a[b];if(this.canPlayType(c.type)){this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(c.src));
this.src=mejs.Utility.absolutizeUrl(a);break}}}},setCurrentTime:function(a){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.seekTo(a):this.pluginApi.setCurrentTime(a);this.currentTime=a}},setVolume:function(a){if(this.pluginApi!=null){this.pluginType=="youtube"?this.pluginApi.setVolume(a*100):this.pluginApi.setVolume(a);this.volume=a}},setMuted:function(a){if(this.pluginApi!=null){if(this.pluginType=="youtube"){a?this.pluginApi.mute():this.pluginApi.unMute();this.muted=a;this.dispatchEvent("volumechange")}else this.pluginApi.setMuted(a);
this.muted=a}},setVideoSize:function(a,b){if(this.pluginElement.style){this.pluginElement.style.width=a+"px";this.pluginElement.style.height=b+"px"}this.pluginApi!=null&&this.pluginApi.setVideoSize&&this.pluginApi.setVideoSize(a,b)},setFullscreen:function(a){this.pluginApi!=null&&this.pluginApi.setFullscreen&&this.pluginApi.setFullscreen(a)},enterFullScreen:function(){this.pluginApi!=null&&this.pluginApi.setFullscreen&&this.setFullscreen(true)},exitFullScreen:function(){this.pluginApi!=null&&this.pluginApi.setFullscreen&&
this.setFullscreen(false)},addEventListener:function(a,b){this.events[a]=this.events[a]||[];this.events[a].push(b)},removeEventListener:function(a,b){if(!a){this.events={};return true}var c=this.events[a];if(!c)return true;if(!b){this.events[a]=[];return true}for(i=0;i<c.length;i++)if(c[i]===b){this.events[a].splice(i,1);return true}return false},dispatchEvent:function(a){var b,c,d=this.events[a];if(d){c=Array.prototype.slice.call(arguments,1);for(b=0;b<d.length;b++)d[b].apply(null,c)}},hasAttribute:function(a){return a in
-this.attributes},removeAttribute:function(a){delete this.attributes[a]},getAttribute:function(a){if(this.hasAttribute(a))return this.attributes[a];return""},setAttribute:function(a,b){this.attributes[a]=b},remove:function(){mejs.Utility.removeSwf(this.pluginElement.id)}};
-mejs.MediaPluginBridge={pluginMediaElements:{},htmlMediaElements:{},registerPluginElement:function(a,b,c){this.pluginMediaElements[a]=b;this.htmlMediaElements[a]=c},initPlugin:function(a){var b=this.pluginMediaElements[a],c=this.htmlMediaElements[a];if(b){switch(b.pluginType){case "flash":b.pluginElement=b.pluginApi=document.getElementById(a);break;case "silverlight":b.pluginElement=document.getElementById(b.id);b.pluginApi=b.pluginElement.Content.MediaElementJS}b.pluginApi!=null&&b.success&&b.success(b,
-c)}},fireEvent:function(a,b,c){var d,e;a=this.pluginMediaElements[a];b={type:b,target:a};for(d in c){a[d]=c[d];b[d]=c[d]}e=c.bufferedTime||0;b.target.buffered=b.buffered={start:function(){return 0},end:function(){return e},length:1};a.dispatchEvent(b.type,b)}};
-mejs.MediaElementDefaults={mode:"auto",plugins:["flash","silverlight","youtube","vimeo"],enablePluginDebug:false,type:"",pluginPath:mejs.Utility.getScriptPath(["mediaelement.js","mediaelement.min.js","mediaelement-and-player.js","mediaelement-and-player.min.js"]),flashName:"flashmediaelement.swf",flashStreamer:"",enablePluginSmoothing:false,silverlightName:"silverlightmediaelement.xap",defaultVideoWidth:480,defaultVideoHeight:270,pluginWidth:-1,pluginHeight:-1,pluginVars:[],timerRate:250,startVolume:0.8,
-success:function(){},error:function(){}};mejs.MediaElement=function(a,b){return mejs.HtmlMediaElementShim.create(a,b)};
+this.attributes},removeAttribute:function(a){delete this.attributes[a]},getAttribute:function(a){if(this.hasAttribute(a))return this.attributes[a];return""},setAttribute:function(a,b){this.attributes[a]=b},remove:function(){mejs.Utility.removeSwf(this.pluginElement.id);mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id)}};
+mejs.MediaPluginBridge={pluginMediaElements:{},htmlMediaElements:{},registerPluginElement:function(a,b,c){this.pluginMediaElements[a]=b;this.htmlMediaElements[a]=c},unregisterPluginElement:function(a){delete this.pluginMediaElements[a];delete this.htmlMediaElements[a]},initPlugin:function(a){var b=this.pluginMediaElements[a],c=this.htmlMediaElements[a];if(b){switch(b.pluginType){case "flash":b.pluginElement=b.pluginApi=document.getElementById(a);break;case "silverlight":b.pluginElement=document.getElementById(b.id);
+b.pluginApi=b.pluginElement.Content.MediaElementJS}b.pluginApi!=null&&b.success&&b.success(b,c)}},fireEvent:function(a,b,c){var d,e;a=this.pluginMediaElements[a];b={type:b,target:a};for(d in c){a[d]=c[d];b[d]=c[d]}e=c.bufferedTime||0;b.target.buffered=b.buffered={start:function(){return 0},end:function(){return e},length:1};a.dispatchEvent(b.type,b)}};
+mejs.MediaElementDefaults={mode:"auto",plugins:["flash","silverlight","youtube","vimeo"],enablePluginDebug:false,type:"",pluginPath:mejs.Utility.getScriptPath(["mediaelement.js","mediaelement.min.js","mediaelement-and-player.js","mediaelement-and-player.min.js"]),flashName:"flashmediaelement.swf",flashStreamer:"",enablePluginSmoothing:false,enablePseudoStreaming:false,pseudoStreamingStartQueryParam:"start",silverlightName:"silverlightmediaelement.xap",defaultVideoWidth:480,defaultVideoHeight:270,
+pluginWidth:-1,pluginHeight:-1,pluginVars:[],timerRate:250,startVolume:0.8,success:function(){},error:function(){}};mejs.MediaElement=function(a,b){return mejs.HtmlMediaElementShim.create(a,b)};
mejs.HtmlMediaElementShim={create:function(a,b){var c=mejs.MediaElementDefaults,d=typeof a=="string"?document.getElementById(a):a,e=d.tagName.toLowerCase(),g=e==="audio"||e==="video",f=g?d.getAttribute("src"):d.getAttribute("href");e=d.getAttribute("poster");var h=d.getAttribute("autoplay"),l=d.getAttribute("preload"),j=d.getAttribute("controls"),k;for(k in b)c[k]=b[k];f=typeof f=="undefined"||f===null||f==""?null:f;e=typeof e=="undefined"||e===null?"":e;l=typeof l=="undefined"||l===null||l==="false"?
"none":l;h=!(typeof h=="undefined"||h===null||h==="false");j=!(typeof j=="undefined"||j===null||j==="false");k=this.determinePlayback(d,c,mejs.MediaFeatures.supportsMediaTag,g,f);k.url=k.url!==null?mejs.Utility.absolutizeUrl(k.url):"";if(k.method=="native"){if(mejs.MediaFeatures.isBustedAndroid){d.src=k.url;d.addEventListener("click",function(){d.play()},false)}return this.updateNative(k,c,h,l)}else if(k.method!=="")return this.createPlugin(k,c,e,h,l,j);else{this.createErrorMessage(k,c,e);return this}},
determinePlayback:function(a,b,c,d,e){var g=[],f,h,l,j={method:"",url:"",htmlMediaElement:a,isVideo:a.tagName.toLowerCase()!="audio"},k;if(typeof b.type!="undefined"&&b.type!=="")if(typeof b.type=="string")g.push({type:b.type,url:e});else for(f=0;f<b.type.length;f++)g.push({type:b.type[f],url:e});else if(e!==null){l=this.formatType(e,a.getAttribute("type"));g.push({type:l,url:e})}else for(f=0;f<a.childNodes.length;f++){h=a.childNodes[f];if(h.nodeType==1&&h.tagName.toLowerCase()=="source"){e=h.getAttribute("src");
l=this.formatType(e,h.getAttribute("type"));h=h.getAttribute("media");if(!h||!window.matchMedia||window.matchMedia&&window.matchMedia(h).matches)g.push({type:l,url:e})}}if(!d&&g.length>0&&g[0].url!==null&&this.getTypeFromFile(g[0].url).indexOf("audio")>-1)j.isVideo=false;if(mejs.MediaFeatures.isBustedAndroid)a.canPlayType=function(m){return m.match(/video\/(mp4|m4v)/gi)!==null?"maybe":""};if(c&&(b.mode==="auto"||b.mode==="auto_plugin"||b.mode==="native")){if(!d){f=document.createElement(j.isVideo?
"video":"audio");a.parentNode.insertBefore(f,a);a.style.display="none";j.htmlMediaElement=a=f}for(f=0;f<g.length;f++)if(a.canPlayType(g[f].type).replace(/no/,"")!==""||a.canPlayType(g[f].type.replace(/mp3/,"mpeg")).replace(/no/,"")!==""){j.method="native";j.url=g[f].url;break}if(j.method==="native"){if(j.url!==null)a.src=j.url;if(b.mode!=="auto_plugin")return j}}if(b.mode==="auto"||b.mode==="auto_plugin"||b.mode==="shim")for(f=0;f<g.length;f++){l=g[f].type;for(a=0;a<b.plugins.length;a++){e=b.plugins[a];
h=mejs.plugins[e];for(c=0;c<h.length;c++){k=h[c];if(k.version==null||mejs.PluginDetector.hasPluginVersion(e,k.version))for(d=0;d<k.types.length;d++)if(l==k.types[d]){j.method=e;j.url=g[f].url;return j}}}}if(b.mode==="auto_plugin"&&j.method==="native")return j;if(j.method===""&&g.length>0)j.url=g[0].url;return j},formatType:function(a,b){return a&&!b?this.getTypeFromFile(a):b&&~b.indexOf(";")?b.substr(0,b.indexOf(";")):b},getTypeFromFile:function(a){a=a.split("?")[0];a=a.substring(a.lastIndexOf(".")+
-1);return(/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(a)?"video":"audio")+"/"+this.getTypeFromExtension(a)},getTypeFromExtension:function(a){switch(a){case "mp4":case "m4v":return"mp4";case "webm":case "webma":case "webmv":return"webm";case "ogg":case "oga":case "ogv":return"ogg";default:return a}},createErrorMessage:function(a,b,c){var d=a.htmlMediaElement,e=document.createElement("div");e.className="me-cannotplay";try{e.style.width=d.width+"px";e.style.height=d.height+"px"}catch(g){}e.innerHTML=
+1).toLowerCase();return(/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(a)?"video":"audio")+"/"+this.getTypeFromExtension(a)},getTypeFromExtension:function(a){switch(a){case "mp4":case "m4v":return"mp4";case "webm":case "webma":case "webmv":return"webm";case "ogg":case "oga":case "ogv":return"ogg";default:return a}},createErrorMessage:function(a,b,c){var d=a.htmlMediaElement,e=document.createElement("div");e.className="me-cannotplay";try{e.style.width=d.width+"px";e.style.height=d.height+"px"}catch(g){}e.innerHTML=
c!==""?'<a href="'+a.url+'"><img src="'+c+'" width="100%" height="100%" /></a>':'<a href="'+a.url+'"><span>'+mejs.i18n.t("Download File")+"</span></a>";d.parentNode.insertBefore(e,d);d.style.display="none";b.error(d)},createPlugin:function(a,b,c,d,e,g){c=a.htmlMediaElement;var f=1,h=1,l="me_"+a.method+"_"+mejs.meIndex++,j=new mejs.PluginMediaElement(l,a.method,a.url),k=document.createElement("div"),m;j.tagName=c.tagName;for(m=0;m<c.attributes.length;m++){var n=c.attributes[m];n.specified==true&&j.setAttribute(n.name,
n.value)}for(m=c.parentNode;m!==null&&m.tagName.toLowerCase()!="body";){if(m.parentNode.tagName.toLowerCase()=="p"){m.parentNode.parentNode.insertBefore(m,m.parentNode);break}m=m.parentNode}if(a.isVideo){f=b.videoWidth>0?b.videoWidth:c.getAttribute("width")!==null?c.getAttribute("width"):b.defaultVideoWidth;h=b.videoHeight>0?b.videoHeight:c.getAttribute("height")!==null?c.getAttribute("height"):b.defaultVideoHeight;f=mejs.Utility.encodeUrl(f);h=mejs.Utility.encodeUrl(h)}else if(b.enablePluginDebug){f=
-320;h=240}j.success=b.success;mejs.MediaPluginBridge.registerPluginElement(l,j,c);k.className="me-plugin";k.id=l+"_container";a.isVideo?c.parentNode.insertBefore(k,c):document.body.insertBefore(k,document.body.childNodes[0]);d=["id="+l,"isvideo="+(a.isVideo?"true":"false"),"autoplay="+(d?"true":"false"),"preload="+e,"width="+f,"startvolume="+b.startVolume,"timerrate="+b.timerRate,"flashstreamer="+b.flashStreamer,"height="+h];if(a.url!==null)a.method=="flash"?d.push("file="+mejs.Utility.encodeUrl(a.url)):
-d.push("file="+a.url);b.enablePluginDebug&&d.push("debug=true");b.enablePluginSmoothing&&d.push("smoothing=true");g&&d.push("controls=true");if(b.pluginVars)d=d.concat(b.pluginVars);switch(a.method){case "silverlight":k.innerHTML='<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="'+l+'" name="'+l+'" width="'+f+'" height="'+h+'"><param name="initParams" value="'+d.join(",")+'" /><param name="windowless" value="true" /><param name="background" value="black" /><param name="minRuntimeVersion" value="3.0.0.0" /><param name="autoUpgrade" value="true" /><param name="source" value="'+
-b.pluginPath+b.silverlightName+'" /></object>';break;case "flash":if(mejs.MediaFeatures.isIE){a=document.createElement("div");k.appendChild(a);a.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="'+l+'" width="'+f+'" height="'+h+'"><param name="movie" value="'+b.pluginPath+b.flashName+"?x="+new Date+'" /><param name="flashvars" value="'+d.join("&amp;")+'" /><param name="quality" value="high" /><param name="bgcolor" value="#000000" /><param name="wmode" value="transparent" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /></object>'}else k.innerHTML=
-'<embed id="'+l+'" name="'+l+'" play="true" loop="false" quality="high" bgcolor="#000000" wmode="transparent" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="//www.macromedia.com/go/getflashplayer" src="'+b.pluginPath+b.flashName+'" flashvars="'+d.join("&")+'" width="'+f+'" height="'+h+'"></embed>';break;case "youtube":b=a.url.substr(a.url.lastIndexOf("=")+1);youtubeSettings={container:k,containerId:k.id,pluginMediaElement:j,pluginId:l,videoId:b,
-height:h,width:f};mejs.PluginDetector.hasPluginVersion("flash",[10,0,0])?mejs.YouTubeApi.createFlash(youtubeSettings):mejs.YouTubeApi.enqueueIframe(youtubeSettings);break;case "vimeo":j.vimeoid=a.url.substr(a.url.lastIndexOf("/")+1);k.innerHTML='<iframe src="http://player.vimeo.com/video/'+j.vimeoid+'?portrait=0&byline=0&title=0" width="'+f+'" height="'+h+'" frameborder="0"></iframe>'}c.style.display="none";return j},updateNative:function(a,b){var c=a.htmlMediaElement,d;for(d in mejs.HtmlMediaElement)c[d]=
-mejs.HtmlMediaElement[d];b.success(c,c);return c}};
+320;h=240}j.success=b.success;mejs.MediaPluginBridge.registerPluginElement(l,j,c);k.className="me-plugin";k.id=l+"_container";a.isVideo?c.parentNode.insertBefore(k,c):document.body.insertBefore(k,document.body.childNodes[0]);d=["id="+l,"isvideo="+(a.isVideo?"true":"false"),"autoplay="+(d?"true":"false"),"preload="+e,"width="+f,"startvolume="+b.startVolume,"timerrate="+b.timerRate,"flashstreamer="+b.flashStreamer,"height="+h,"pseudostreamstart="+b.pseudoStreamingStartQueryParam];if(a.url!==null)a.method==
+"flash"?d.push("file="+mejs.Utility.encodeUrl(a.url)):d.push("file="+a.url);b.enablePluginDebug&&d.push("debug=true");b.enablePluginSmoothing&&d.push("smoothing=true");b.enablePseudoStreaming&&d.push("pseudostreaming=true");g&&d.push("controls=true");if(b.pluginVars)d=d.concat(b.pluginVars);switch(a.method){case "silverlight":k.innerHTML='<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="'+l+'" name="'+l+'" width="'+f+'" height="'+h+'" class="mejs-shim"><param name="initParams" value="'+
+d.join(",")+'" /><param name="windowless" value="true" /><param name="background" value="black" /><param name="minRuntimeVersion" value="3.0.0.0" /><param name="autoUpgrade" value="true" /><param name="source" value="'+b.pluginPath+b.silverlightName+'" /></object>';break;case "flash":if(mejs.MediaFeatures.isIE){a=document.createElement("div");k.appendChild(a);a.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="'+
+l+'" width="'+f+'" height="'+h+'" class="mejs-shim"><param name="movie" value="'+b.pluginPath+b.flashName+"?x="+new Date+'" /><param name="flashvars" value="'+d.join("&amp;")+'" /><param name="quality" value="high" /><param name="bgcolor" value="#000000" /><param name="wmode" value="transparent" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /></object>'}else k.innerHTML='<embed id="'+l+'" name="'+l+'" play="true" loop="false" quality="high" bgcolor="#000000" wmode="transparent" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="//www.macromedia.com/go/getflashplayer" src="'+
+b.pluginPath+b.flashName+'" flashvars="'+d.join("&")+'" width="'+f+'" height="'+h+'" class="mejs-shim"></embed>';break;case "youtube":b=a.url.substr(a.url.lastIndexOf("=")+1);youtubeSettings={container:k,containerId:k.id,pluginMediaElement:j,pluginId:l,videoId:b,height:h,width:f};mejs.PluginDetector.hasPluginVersion("flash",[10,0,0])?mejs.YouTubeApi.createFlash(youtubeSettings):mejs.YouTubeApi.enqueueIframe(youtubeSettings);break;case "vimeo":j.vimeoid=a.url.substr(a.url.lastIndexOf("/")+1);k.innerHTML=
+'<iframe src="http://player.vimeo.com/video/'+j.vimeoid+'?portrait=0&byline=0&title=0" width="'+f+'" height="'+h+'" frameborder="0" class="mejs-shim"></iframe>'}c.style.display="none";return j},updateNative:function(a,b){var c=a.htmlMediaElement,d;for(d in mejs.HtmlMediaElement)c[d]=mejs.HtmlMediaElement[d];b.success(c,c);return c}};
mejs.YouTubeApi={isIframeStarted:false,isIframeLoaded:false,loadIframeApi:function(){if(!this.isIframeStarted){var a=document.createElement("script");a.src="http://www.youtube.com/player_api";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b);this.isIframeStarted=true}},iframeQueue:[],enqueueIframe:function(a){if(this.isLoaded)this.createIframe(a);else{this.loadIframeApi();this.iframeQueue.push(a)}},createIframe:function(a){var b=a.pluginMediaElement,c=new YT.Player(a.containerId,
{height:a.height,width:a.width,videoId:a.videoId,playerVars:{controls:0},events:{onReady:function(){a.pluginMediaElement.pluginApi=c;mejs.MediaPluginBridge.initPlugin(a.pluginId);setInterval(function(){mejs.YouTubeApi.createEvent(c,b,"timeupdate")},250)},onStateChange:function(d){mejs.YouTubeApi.handleStateChange(d.data,c,b)}}})},createEvent:function(a,b,c){c={type:c,target:b};if(a&&a.getDuration){b.currentTime=c.currentTime=a.getCurrentTime();b.duration=c.duration=a.getDuration();c.paused=b.paused;
c.ended=b.ended;c.muted=a.isMuted();c.volume=a.getVolume()/100;c.bytesTotal=a.getVideoBytesTotal();c.bufferedBytes=a.getVideoBytesLoaded();var d=c.bufferedBytes/c.bytesTotal*c.duration;c.target.buffered=c.buffered={start:function(){return 0},end:function(){return d},length:1}}b.dispatchEvent(c.type,c)},iFrameReady:function(){for(this.isIframeLoaded=this.isLoaded=true;this.iframeQueue.length>0;)this.createIframe(this.iframeQueue.pop())},flashPlayers:{},createFlash:function(a){this.flashPlayers[a.pluginId]=
-a;var b,c="http://www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid="+a.pluginId+"&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0";if(mejs.MediaFeatures.isIE){b=document.createElement("div");a.container.appendChild(b);b.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="'+a.pluginId+'" width="'+a.width+'" height="'+a.height+'"><param name="movie" value="'+c+'" /><param name="wmode" value="transparent" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /></object>'}else a.container.innerHTML=
-'<object type="application/x-shockwave-flash" id="'+a.pluginId+'" data="'+c+'" width="'+a.width+'" height="'+a.height+'" style="visibility: visible; "><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"></object>'},flashReady:function(a){var b=this.flashPlayers[a],c=document.getElementById(a),d=b.pluginMediaElement;d.pluginApi=d.pluginElement=c;mejs.MediaPluginBridge.initPlugin(a);c.cueVideoById(b.videoId);a=b.containerId+"_callback";window[a]=function(e){mejs.YouTubeApi.handleStateChange(e,
-c,d)};c.addEventListener("onStateChange",a);setInterval(function(){mejs.YouTubeApi.createEvent(c,d,"timeupdate")},250)},handleStateChange:function(a,b,c){switch(a){case -1:c.paused=true;c.ended=true;mejs.YouTubeApi.createEvent(b,c,"loadedmetadata");break;case 0:c.paused=false;c.ended=true;mejs.YouTubeApi.createEvent(b,c,"ended");break;case 1:c.paused=false;c.ended=false;mejs.YouTubeApi.createEvent(b,c,"play");mejs.YouTubeApi.createEvent(b,c,"playing");break;case 2:c.paused=true;c.ended=false;mejs.YouTubeApi.createEvent(b,
-c,"pause");break;case 3:mejs.YouTubeApi.createEvent(b,c,"progress")}}};function onYouTubePlayerAPIReady(){mejs.YouTubeApi.iFrameReady()}function onYouTubePlayerReady(a){mejs.YouTubeApi.flashReady(a)}window.mejs=mejs;window.MediaElement=mejs.MediaElement;
-(function(a,b,c){var d={locale:{strings:{}},methods:{}};d.locale.getLanguage=function(){return{language:navigator.language}};d.locale.INIT_LANGUAGE=d.locale.getLanguage();d.methods.checkPlain=function(e){var g,f,h={"&":"&amp;",'"':"&quot;","<":"&lt;",">":"&gt;"};e=String(e);for(g in h)if(h.hasOwnProperty(g)){f=RegExp(g,"g");e=e.replace(f,h[g])}return e};d.methods.formatString=function(e,g){for(var f in g){switch(f.charAt(0)){case "@":g[f]=d.methods.checkPlain(g[f]);break;case "!":break;default:g[f]=
-'<em class="placeholder">'+d.methods.checkPlain(g[f])+"</em>"}e=e.replace(f,g[f])}return e};d.methods.t=function(e,g,f){if(d.locale.strings&&d.locale.strings[f.context]&&d.locale.strings[f.context][e])e=d.locale.strings[f.context][e];if(g)e=d.methods.formatString(e,g);return e};d.t=function(e,g,f){if(typeof e==="string"&&e.length>0){var h=d.locale.getLanguage();f=f||{context:h.language};return d.methods.t(e,g,f)}else throw{name:"InvalidArgumentException",message:"First argument is either not a string or empty."};
-};c.i18n=d})(jQuery,document,mejs);(function(a){a.de={Fullscreen:"Vollbild","Go Fullscreen":"Vollbild an","Turn off Fullscreen":"Vollbild aus",Close:"Schlie\u00dfen"}})(mejs.i18n.locale.strings);
+a;var b,c="http://www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid="+a.pluginId+"&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0";if(mejs.MediaFeatures.isIE){b=document.createElement("div");a.container.appendChild(b);b.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="'+a.pluginId+'" width="'+a.width+'" height="'+a.height+'" class="mejs-shim"><param name="movie" value="'+
+c+'" /><param name="wmode" value="transparent" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /></object>'}else a.container.innerHTML='<object type="application/x-shockwave-flash" id="'+a.pluginId+'" data="'+c+'" width="'+a.width+'" height="'+a.height+'" style="visibility: visible; " class="mejs-shim"><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"></object>'},flashReady:function(a){var b=this.flashPlayers[a],c=
+document.getElementById(a),d=b.pluginMediaElement;d.pluginApi=d.pluginElement=c;mejs.MediaPluginBridge.initPlugin(a);c.cueVideoById(b.videoId);a=b.containerId+"_callback";window[a]=function(e){mejs.YouTubeApi.handleStateChange(e,c,d)};c.addEventListener("onStateChange",a);setInterval(function(){mejs.YouTubeApi.createEvent(c,d,"timeupdate")},250)},handleStateChange:function(a,b,c){switch(a){case -1:c.paused=true;c.ended=true;mejs.YouTubeApi.createEvent(b,c,"loadedmetadata");break;case 0:c.paused=false;
+c.ended=true;mejs.YouTubeApi.createEvent(b,c,"ended");break;case 1:c.paused=false;c.ended=false;mejs.YouTubeApi.createEvent(b,c,"play");mejs.YouTubeApi.createEvent(b,c,"playing");break;case 2:c.paused=true;c.ended=false;mejs.YouTubeApi.createEvent(b,c,"pause");break;case 3:mejs.YouTubeApi.createEvent(b,c,"progress")}}};function onYouTubePlayerAPIReady(){mejs.YouTubeApi.iFrameReady()}function onYouTubePlayerReady(a){mejs.YouTubeApi.flashReady(a)}window.mejs=mejs;window.MediaElement=mejs.MediaElement;
+(function(a,b){var c={locale:{strings:{}},methods:{}};c.locale.getLanguage=function(){return{language:navigator.language}};c.locale.INIT_LANGUAGE=c.locale.getLanguage();c.methods.checkPlain=function(d){var e,g,f={"&":"&amp;",'"':"&quot;","<":"&lt;",">":"&gt;"};d=String(d);for(e in f)if(f.hasOwnProperty(e)){g=RegExp(e,"g");d=d.replace(g,f[e])}return d};c.methods.formatString=function(d,e){for(var g in e){switch(g.charAt(0)){case "@":e[g]=c.methods.checkPlain(e[g]);break;case "!":break;default:e[g]=
+'<em class="placeholder">'+c.methods.checkPlain(e[g])+"</em>"}d=d.replace(g,e[g])}return d};c.methods.t=function(d,e,g){if(c.locale.strings&&c.locale.strings[g.context]&&c.locale.strings[g.context][d])d=c.locale.strings[g.context][d];if(e)d=c.methods.formatString(d,e);return d};c.t=function(d,e,g){if(typeof d==="string"&&d.length>0){var f=c.locale.getLanguage();g=g||{context:f.language};return c.methods.t(d,e,g)}else throw{name:"InvalidArgumentException",message:"First argument is either not a string or empty."};
+};b.i18n=c})(document,mejs);(function(a){a.de={Fullscreen:"Vollbild","Go Fullscreen":"Vollbild an","Turn off Fullscreen":"Vollbild aus",Close:"Schlie\u00dfen"}})(mejs.i18n.locale.strings);(function(a){a.zh={Fullscreen:"\u5168\u87a2\u5e55","Go Fullscreen":"\u5168\u5c4f\u6a21\u5f0f","Turn off Fullscreen":"\u9000\u51fa\u5168\u5c4f\u6a21\u5f0f",Close:"\u95dc\u9589"}})(mejs.i18n.locale.strings);
/*!
* MediaElementPlayer
@@ -74,87 +75,93 @@ c,"pause");break;case 3:mejs.YouTubeApi.createEvent(b,c,"progress")}}};function
* License: MIT
*
*/if(typeof jQuery!="undefined")mejs.$=jQuery;else if(typeof ender!="undefined")mejs.$=ender;
-(function(f){mejs.MepDefaults={poster:"",defaultVideoWidth:480,defaultVideoHeight:270,videoWidth:-1,videoHeight:-1,defaultAudioWidth:400,defaultAudioHeight:30,defaultSeekBackwardInterval:function(a){return a.duration*0.05},defaultSeekForwardInterval:function(a){return a.duration*0.05},audioWidth:-1,audioHeight:-1,startVolume:0.8,loop:false,autoRewind:true,enableAutosize:true,alwaysShowHours:false,showTimecodeFrameCount:false,framesPerSecond:25,autosizeProgress:true,alwaysShowControls:false,clickToPlayPause:true,
-iPadUseNativeControls:false,iPhoneUseNativeControls:false,AndroidUseNativeControls:false,features:["playpause","current","progress","duration","tracks","volume","fullscreen"],isVideo:true,enableKeyboard:true,pauseOtherPlayers:true,keyActions:[{keys:[32,179],action:function(a,b){b.paused||b.ended?b.play():b.pause()}},{keys:[38],action:function(a,b){b.setVolume(Math.min(b.volume+0.1,1))}},{keys:[40],action:function(a,b){b.setVolume(Math.max(b.volume-0.1,0))}},{keys:[37,227],action:function(a,b){if(!isNaN(b.duration)&&
-b.duration>0){if(a.isVideo){a.showControls();a.startControlsTimer()}var c=Math.max(b.currentTime-a.options.defaultSeekBackwardInterval(b),0);b.setCurrentTime(c)}}},{keys:[39,228],action:function(a,b){if(!isNaN(b.duration)&&b.duration>0){if(a.isVideo){a.showControls();a.startControlsTimer()}var c=Math.min(b.currentTime+a.options.defaultSeekForwardInterval(b),b.duration);b.setCurrentTime(c)}}},{keys:[70],action:function(a){if(typeof a.enterFullScreen!="undefined")a.isFullScreen?a.exitFullScreen():a.enterFullScreen()}}]};
-mejs.mepIndex=0;mejs.players=[];mejs.MediaElementPlayer=function(a,b){if(!(this instanceof mejs.MediaElementPlayer))return new mejs.MediaElementPlayer(a,b);this.$media=this.$node=f(a);this.node=this.media=this.$media[0];if(typeof this.node.player!="undefined")return this.node.player;else this.node.player=this;if(typeof b=="undefined")b=this.$node.data("mejsoptions");this.options=f.extend({},mejs.MepDefaults,b);mejs.players.push(this);this.init();return this};mejs.MediaElementPlayer.prototype={hasFocus:false,
-controlsAreVisible:true,init:function(){var a=this,b=mejs.MediaFeatures,c=f.extend(true,{},a.options,{success:function(e,g){a.meReady(e,g)},error:function(e){a.handleError(e)}}),d=a.media.tagName.toLowerCase();a.isDynamic=d!=="audio"&&d!=="video";a.isVideo=a.isDynamic?a.options.isVideo:d!=="audio"&&a.options.isVideo;if(b.isiPad&&a.options.iPadUseNativeControls||b.isiPhone&&a.options.iPhoneUseNativeControls){a.$media.attr("controls","controls");if(b.isiPad&&a.media.getAttribute("autoplay")!==null){a.media.load();
-a.media.play()}}else if(!(b.isAndroid&&a.AndroidUseNativeControls)){a.$media.removeAttr("controls");a.id="mep_"+mejs.mepIndex++;a.container=f('<div id="'+a.id+'" class="mejs-container '+(mejs.MediaFeatures.svg?"svg":"no-svg")+'"><div class="mejs-inner"><div class="mejs-mediaelement"></div><div class="mejs-layers"></div><div class="mejs-controls"></div><div class="mejs-clear"></div></div></div>').addClass(a.$media[0].className).insertBefore(a.$media);a.container.addClass((b.isAndroid?"mejs-android ":
-"")+(b.isiOS?"mejs-ios ":"")+(b.isiPad?"mejs-ipad ":"")+(b.isiPhone?"mejs-iphone ":"")+(a.isVideo?"mejs-video ":"mejs-audio "));if(b.isiOS){b=a.$media.clone();a.container.find(".mejs-mediaelement").append(b);a.$media.remove();a.$node=a.$media=b;a.node=a.media=b[0]}else a.container.find(".mejs-mediaelement").append(a.$media);a.controls=a.container.find(".mejs-controls");a.layers=a.container.find(".mejs-layers");b=a.isVideo?"video":"audio";d=b.substring(0,1).toUpperCase()+b.substring(1);a.width=a.options[b+
-"Width"]>0||a.options[b+"Width"].toString().indexOf("%")>-1?a.options[b+"Width"]:a.media.style.width!==""&&a.media.style.width!==null?a.media.style.width:a.media.getAttribute("width")!==null?a.$media.attr("width"):a.options["default"+d+"Width"];a.height=a.options[b+"Height"]>0||a.options[b+"Height"].toString().indexOf("%")>-1?a.options[b+"Height"]:a.media.style.height!==""&&a.media.style.height!==null?a.media.style.height:a.$media[0].getAttribute("height")!==null?a.$media.attr("height"):a.options["default"+
-d+"Height"];a.setPlayerSize(a.width,a.height);c.pluginWidth=a.height;c.pluginHeight=a.width}mejs.MediaElement(a.$media[0],c);a.container.trigger("controlsshown")},showControls:function(a){var b=this;a=typeof a=="undefined"||a;if(!b.controlsAreVisible){if(a){b.controls.css("visibility","visible").stop(true,true).fadeIn(200,function(){b.controlsAreVisible=true;b.container.trigger("controlsshown")});b.container.find(".mejs-control").css("visibility","visible").stop(true,true).fadeIn(200,function(){b.controlsAreVisible=
-true})}else{b.controls.css("visibility","visible").css("display","block");b.container.find(".mejs-control").css("visibility","visible").css("display","block");b.controlsAreVisible=true;b.container.trigger("controlsshown")}b.setControlsSize()}},hideControls:function(a){var b=this;a=typeof a=="undefined"||a;if(b.controlsAreVisible)if(a){b.controls.stop(true,true).fadeOut(200,function(){f(this).css("visibility","hidden").css("display","block");b.controlsAreVisible=false;b.container.trigger("controlshidden")});
-b.container.find(".mejs-control").stop(true,true).fadeOut(200,function(){f(this).css("visibility","hidden").css("display","block")})}else{b.controls.css("visibility","hidden").css("display","block");b.container.find(".mejs-control").css("visibility","hidden").css("display","block");b.controlsAreVisible=false;b.container.trigger("controlshidden")}},controlsTimer:null,startControlsTimer:function(a){var b=this;a=typeof a!="undefined"?a:1500;b.killControlsTimer("start");b.controlsTimer=setTimeout(function(){b.hideControls();
-b.killControlsTimer("hide")},a)},killControlsTimer:function(){if(this.controlsTimer!==null){clearTimeout(this.controlsTimer);delete this.controlsTimer;this.controlsTimer=null}},controlsEnabled:true,disableControls:function(){this.killControlsTimer();this.hideControls(false);this.controlsEnabled=false},enableControls:function(){this.showControls(false);this.controlsEnabled=true},meReady:function(a,b){var c=this,d=mejs.MediaFeatures,e=b.getAttribute("autoplay");e=!(typeof e=="undefined"||e===null||
-e==="false");var g;if(!c.created){c.created=true;c.media=a;c.domNode=b;if(!(d.isAndroid&&c.options.AndroidUseNativeControls)&&!(d.isiPad&&c.options.iPadUseNativeControls)&&!(d.isiPhone&&c.options.iPhoneUseNativeControls)){c.buildposter(c,c.controls,c.layers,c.media);c.buildkeyboard(c,c.controls,c.layers,c.media);c.buildoverlays(c,c.controls,c.layers,c.media);c.findTracks();for(g in c.options.features){d=c.options.features[g];if(c["build"+d])try{c["build"+d](c,c.controls,c.layers,c.media)}catch(k){}}c.container.trigger("controlsready");
-c.setPlayerSize(c.width,c.height);c.setControlsSize();if(c.isVideo){if(mejs.MediaFeatures.hasTouch)c.$media.bind("touchstart",function(){if(c.controlsAreVisible)c.hideControls(false);else c.controlsEnabled&&c.showControls(false)});else{c.media.addEventListener("click",function(){if(c.options.clickToPlayPause)c.media.paused?c.media.play():c.media.pause()});c.container.bind("mouseenter mouseover",function(){if(c.controlsEnabled)if(!c.options.alwaysShowControls){c.killControlsTimer("enter");c.showControls();
-c.startControlsTimer(2500)}}).bind("mousemove",function(){if(c.controlsEnabled){c.controlsAreVisible||c.showControls();c.options.alwaysShowControls||c.startControlsTimer(2500)}}).bind("mouseleave",function(){c.controlsEnabled&&!c.media.paused&&!c.options.alwaysShowControls&&c.startControlsTimer(1E3)})}e&&!c.options.alwaysShowControls&&c.hideControls();c.options.enableAutosize&&c.media.addEventListener("loadedmetadata",function(h){if(c.options.videoHeight<=0&&c.domNode.getAttribute("height")===null&&
-!isNaN(h.target.videoHeight)){c.setPlayerSize(h.target.videoWidth,h.target.videoHeight);c.setControlsSize();c.media.setVideoSize(h.target.videoWidth,h.target.videoHeight)}},false)}a.addEventListener("play",function(){for(var h=0,o=mejs.players.length;h<o;h++){var n=mejs.players[h];n.id!=c.id&&c.options.pauseOtherPlayers&&!n.paused&&!n.ended&&n.pause();n.hasFocus=false}c.hasFocus=true},false);c.media.addEventListener("ended",function(){if(c.options.autoRewind)try{c.media.setCurrentTime(0)}catch(h){}c.media.pause();
-c.setProgressRail&&c.setProgressRail();c.setCurrentRail&&c.setCurrentRail();if(c.options.loop)c.media.play();else!c.options.alwaysShowControls&&c.controlsEnabled&&c.showControls()},false);c.media.addEventListener("loadedmetadata",function(){c.updateDuration&&c.updateDuration();c.updateCurrent&&c.updateCurrent();if(!c.isFullScreen){c.setPlayerSize(c.width,c.height);c.setControlsSize()}},false);setTimeout(function(){c.setPlayerSize(c.width,c.height);c.setControlsSize()},50);f(window).resize(function(){c.isFullScreen||
-mejs.MediaFeatures.hasTrueNativeFullScreen&&document.webkitIsFullScreen||c.setPlayerSize(c.width,c.height);c.setControlsSize()});c.media.pluginType=="youtube"&&c.container.find(".mejs-overlay-play").hide()}if(e&&a.pluginType=="native"){a.load();a.play()}if(c.options.success)typeof c.options.success=="string"?window[c.options.success](c.media,c.domNode,c):c.options.success(c.media,c.domNode,c)}},handleError:function(a){this.controls.hide();this.options.error&&this.options.error(a)},setPlayerSize:function(a,
-b){if(typeof a!="undefined")this.width=a;if(typeof b!="undefined")this.height=b;if(this.height.toString().indexOf("%")>0||this.$node.css("max-width")==="100%"||this.$node[0].currentStyle&&this.$node[0].currentStyle.maxWidth==="100%"){var c=this.isVideo?this.media.videoWidth&&this.media.videoWidth>0?this.media.videoWidth:this.options.defaultVideoWidth:this.options.defaultAudioWidth,d=this.isVideo?this.media.videoHeight&&this.media.videoHeight>0?this.media.videoHeight:this.options.defaultVideoHeight:
-this.options.defaultAudioHeight,e=this.container.parent().closest(":visible").width();c=this.isVideo||!this.options.autosizeProgress?parseInt(e*d/c,10):d;if(this.container.parent()[0].tagName.toLowerCase()==="body"){e=f(window).width();c=f(window).height()}if(c!=0&&e!=0){this.container.width(e).height(c);this.$media.width("100%").height("100%");this.container.find("object, embed, iframe").width("100%").height("100%");this.isVideo&&this.media.setVideoSize&&this.media.setVideoSize(e,c);this.layers.children(".mejs-layer").width("100%").height("100%")}}else{this.container.width(this.width).height(this.height);
-this.layers.children(".mejs-layer").width(this.width).height(this.height)}},setControlsSize:function(){var a=0,b=0,c=this.controls.find(".mejs-time-rail"),d=this.controls.find(".mejs-time-total");this.controls.find(".mejs-time-current");this.controls.find(".mejs-time-loaded");var e=c.siblings();if(this.options&&!this.options.autosizeProgress)b=parseInt(c.css("width"));if(b===0||!b){e.each(function(){if(f(this).css("position")!="absolute")a+=f(this).outerWidth(true)});b=this.controls.width()-a-(c.outerWidth(true)-
-c.width())}c.width(b);d.width(b-(d.outerWidth(true)-d.width()));this.setProgressRail&&this.setProgressRail();this.setCurrentRail&&this.setCurrentRail()},buildposter:function(a,b,c,d){var e=f('<div class="mejs-poster mejs-layer"></div>').appendTo(c);b=a.$media.attr("poster");if(a.options.poster!=="")b=a.options.poster;b!==""&&b!=null?this.setPoster(b):e.hide();d.addEventListener("play",function(){e.hide()},false)},setPoster:function(a){var b=this.container.find(".mejs-poster"),c=b.find("img");if(c.length==
-0)c=f('<img width="100%" height="100%" />').appendTo(b);c.attr("src",a)},buildoverlays:function(a,b,c,d){var e=this;if(a.isVideo){var g=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-loading"><span></span></div></div>').hide().appendTo(c),k=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-error"></div></div>').hide().appendTo(c),h=f('<div class="mejs-overlay mejs-layer mejs-overlay-play"><div class="mejs-overlay-button"></div></div>').appendTo(c).click(function(){if(e.options.clickToPlayPause)d.paused?
-d.play():d.pause()});d.addEventListener("play",function(){h.hide();g.hide();b.find(".mejs-time-buffering").hide();k.hide()},false);d.addEventListener("playing",function(){h.hide();g.hide();b.find(".mejs-time-buffering").hide();k.hide()},false);d.addEventListener("seeking",function(){g.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("seeked",function(){g.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("pause",function(){mejs.MediaFeatures.isiPhone||h.show()},
-false);d.addEventListener("waiting",function(){g.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("loadeddata",function(){g.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("canplay",function(){g.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("error",function(){g.hide();b.find(".mejs-time-buffering").hide();k.show();k.find("mejs-overlay-error").html("Error loading this resource")},false)}},buildkeyboard:function(a,b,c,d){f(document).keydown(function(e){if(a.hasFocus&&
-a.options.enableKeyboard)for(var g=0,k=a.options.keyActions.length;g<k;g++)for(var h=a.options.keyActions[g],o=0,n=h.keys.length;o<n;o++)if(e.keyCode==h.keys[o]){e.preventDefault();h.action(a,d,e.keyCode);return false}return true});f(document).click(function(e){if(f(e.target).closest(".mejs-container").length==0)a.hasFocus=false})},findTracks:function(){var a=this,b=a.$media.find("track");a.tracks=[];b.each(function(c,d){d=f(d);a.tracks.push({srclang:d.attr("srclang").toLowerCase(),src:d.attr("src"),
-kind:d.attr("kind"),label:d.attr("label")||"",entries:[],isLoaded:false})})},changeSkin:function(a){this.container[0].className="mejs-container "+a;this.setPlayerSize(this.width,this.height);this.setControlsSize()},play:function(){this.media.play()},pause:function(){this.media.pause()},load:function(){this.media.load()},setMuted:function(a){this.media.setMuted(a)},setCurrentTime:function(a){this.media.setCurrentTime(a)},getCurrentTime:function(){return this.media.currentTime},setVolume:function(a){this.media.setVolume(a)},
-getVolume:function(){return this.media.volume},setSrc:function(a){this.media.setSrc(a)},remove:function(){if(this.media.pluginType==="flash")this.media.remove();else this.media.pluginType==="native"&&this.$media.prop("controls",true);this.isDynamic||this.$node.insertBefore(this.container);this.container.remove()}};if(typeof jQuery!="undefined")jQuery.fn.mediaelementplayer=function(a){return this.each(function(){new mejs.MediaElementPlayer(this,a)})};f(document).ready(function(){f(".mejs-player").mediaelementplayer()});
-window.MediaElementPlayer=mejs.MediaElementPlayer})(mejs.$);
-(function(f){f.extend(mejs.MepDefaults,{playpauseText:"Play/Pause"});f.extend(MediaElementPlayer.prototype,{buildplaypause:function(a,b,c,d){var e=f('<div class="mejs-button mejs-playpause-button mejs-play" ><button type="button" aria-controls="'+this.id+'" title="'+this.options.playpauseText+'"></button></div>').appendTo(b).click(function(g){g.preventDefault();d.paused?d.play():d.pause();return false});d.addEventListener("play",function(){e.removeClass("mejs-play").addClass("mejs-pause")},false);
-d.addEventListener("playing",function(){e.removeClass("mejs-play").addClass("mejs-pause")},false);d.addEventListener("pause",function(){e.removeClass("mejs-pause").addClass("mejs-play")},false);d.addEventListener("paused",function(){e.removeClass("mejs-pause").addClass("mejs-play")},false)}})})(mejs.$);
-(function(f){f.extend(mejs.MepDefaults,{stopText:"Stop"});f.extend(MediaElementPlayer.prototype,{buildstop:function(a,b,c,d){f('<div class="mejs-button mejs-stop-button mejs-stop"><button type="button" aria-controls="'+this.id+'" title="'+this.options.stopText+'"></button></div>').appendTo(b).click(function(){d.paused||d.pause();if(d.currentTime>0){d.setCurrentTime(0);d.pause();b.find(".mejs-time-current").width("0px");b.find(".mejs-time-handle").css("left","0px");b.find(".mejs-time-float-current").html(mejs.Utility.secondsToTimeCode(0));
-b.find(".mejs-currenttime").html(mejs.Utility.secondsToTimeCode(0));c.find(".mejs-poster").show()}})}})})(mejs.$);
+(function(f){mejs.MepDefaults={poster:"",defaultVideoWidth:480,defaultVideoHeight:270,videoWidth:-1,videoHeight:-1,defaultAudioWidth:400,defaultAudioHeight:30,defaultSeekBackwardInterval:function(a){return a.duration*0.05},defaultSeekForwardInterval:function(a){return a.duration*0.05},audioWidth:-1,audioHeight:-1,startVolume:0.8,loop:false,autoRewind:true,enableAutosize:true,alwaysShowHours:false,showTimecodeFrameCount:false,framesPerSecond:25,autosizeProgress:true,alwaysShowControls:false,hideVideoControlsOnLoad:false,
+clickToPlayPause:true,iPadUseNativeControls:false,iPhoneUseNativeControls:false,AndroidUseNativeControls:false,features:["playpause","current","progress","duration","tracks","volume","fullscreen"],isVideo:true,enableKeyboard:true,pauseOtherPlayers:true,keyActions:[{keys:[32,179],action:function(a,b){b.paused||b.ended?b.play():b.pause()}},{keys:[38],action:function(a,b){b.setVolume(Math.min(b.volume+0.1,1))}},{keys:[40],action:function(a,b){b.setVolume(Math.max(b.volume-0.1,0))}},{keys:[37,227],action:function(a,
+b){if(!isNaN(b.duration)&&b.duration>0){if(a.isVideo){a.showControls();a.startControlsTimer()}var c=Math.max(b.currentTime-a.options.defaultSeekBackwardInterval(b),0);b.setCurrentTime(c)}}},{keys:[39,228],action:function(a,b){if(!isNaN(b.duration)&&b.duration>0){if(a.isVideo){a.showControls();a.startControlsTimer()}var c=Math.min(b.currentTime+a.options.defaultSeekForwardInterval(b),b.duration);b.setCurrentTime(c)}}},{keys:[70],action:function(a){if(typeof a.enterFullScreen!="undefined")a.isFullScreen?
+a.exitFullScreen():a.enterFullScreen()}}]};mejs.mepIndex=0;mejs.players={};mejs.MediaElementPlayer=function(a,b){if(!(this instanceof mejs.MediaElementPlayer))return new mejs.MediaElementPlayer(a,b);this.$media=this.$node=f(a);this.node=this.media=this.$media[0];if(typeof this.node.player!="undefined")return this.node.player;else this.node.player=this;if(typeof b=="undefined")b=this.$node.data("mejsoptions");this.options=f.extend({},mejs.MepDefaults,b);this.id="mep_"+mejs.mepIndex++;mejs.players[this.id]=
+this;this.init();return this};mejs.MediaElementPlayer.prototype={hasFocus:false,controlsAreVisible:true,init:function(){var a=this,b=mejs.MediaFeatures,c=f.extend(true,{},a.options,{success:function(e,g){a.meReady(e,g)},error:function(e){a.handleError(e)}}),d=a.media.tagName.toLowerCase();a.isDynamic=d!=="audio"&&d!=="video";a.isVideo=a.isDynamic?a.options.isVideo:d!=="audio"&&a.options.isVideo;if(b.isiPad&&a.options.iPadUseNativeControls||b.isiPhone&&a.options.iPhoneUseNativeControls){a.$media.attr("controls",
+"controls");if(b.isiPad&&a.media.getAttribute("autoplay")!==null){a.media.load();a.media.play()}}else if(!(b.isAndroid&&a.options.AndroidUseNativeControls)){a.$media.removeAttr("controls");a.container=f('<div id="'+a.id+'" class="mejs-container '+(mejs.MediaFeatures.svg?"svg":"no-svg")+'"><div class="mejs-inner"><div class="mejs-mediaelement"></div><div class="mejs-layers"></div><div class="mejs-controls"></div><div class="mejs-clear"></div></div></div>').addClass(a.$media[0].className).insertBefore(a.$media);
+a.container.addClass((b.isAndroid?"mejs-android ":"")+(b.isiOS?"mejs-ios ":"")+(b.isiPad?"mejs-ipad ":"")+(b.isiPhone?"mejs-iphone ":"")+(a.isVideo?"mejs-video ":"mejs-audio "));if(b.isiOS){b=a.$media.clone();a.container.find(".mejs-mediaelement").append(b);a.$media.remove();a.$node=a.$media=b;a.node=a.media=b[0]}else a.container.find(".mejs-mediaelement").append(a.$media);a.controls=a.container.find(".mejs-controls");a.layers=a.container.find(".mejs-layers");b=a.isVideo?"video":"audio";d=b.substring(0,
+1).toUpperCase()+b.substring(1);a.width=a.options[b+"Width"]>0||a.options[b+"Width"].toString().indexOf("%")>-1?a.options[b+"Width"]:a.media.style.width!==""&&a.media.style.width!==null?a.media.style.width:a.media.getAttribute("width")!==null?a.$media.attr("width"):a.options["default"+d+"Width"];a.height=a.options[b+"Height"]>0||a.options[b+"Height"].toString().indexOf("%")>-1?a.options[b+"Height"]:a.media.style.height!==""&&a.media.style.height!==null?a.media.style.height:a.$media[0].getAttribute("height")!==
+null?a.$media.attr("height"):a.options["default"+d+"Height"];a.setPlayerSize(a.width,a.height);c.pluginWidth=a.height;c.pluginHeight=a.width}mejs.MediaElement(a.$media[0],c);typeof a.container!="undefined"&&a.container.trigger("controlsshown")},showControls:function(a){var b=this;a=typeof a=="undefined"||a;if(!b.controlsAreVisible){if(a){b.controls.css("visibility","visible").stop(true,true).fadeIn(200,function(){b.controlsAreVisible=true;b.container.trigger("controlsshown")});b.container.find(".mejs-control").css("visibility",
+"visible").stop(true,true).fadeIn(200,function(){b.controlsAreVisible=true})}else{b.controls.css("visibility","visible").css("display","block");b.container.find(".mejs-control").css("visibility","visible").css("display","block");b.controlsAreVisible=true;b.container.trigger("controlsshown")}b.setControlsSize()}},hideControls:function(a){var b=this;a=typeof a=="undefined"||a;if(b.controlsAreVisible)if(a){b.controls.stop(true,true).fadeOut(200,function(){f(this).css("visibility","hidden").css("display",
+"block");b.controlsAreVisible=false;b.container.trigger("controlshidden")});b.container.find(".mejs-control").stop(true,true).fadeOut(200,function(){f(this).css("visibility","hidden").css("display","block")})}else{b.controls.css("visibility","hidden").css("display","block");b.container.find(".mejs-control").css("visibility","hidden").css("display","block");b.controlsAreVisible=false;b.container.trigger("controlshidden")}},controlsTimer:null,startControlsTimer:function(a){var b=this;a=typeof a!="undefined"?
+a:1500;b.killControlsTimer("start");b.controlsTimer=setTimeout(function(){b.hideControls();b.killControlsTimer("hide")},a)},killControlsTimer:function(){if(this.controlsTimer!==null){clearTimeout(this.controlsTimer);delete this.controlsTimer;this.controlsTimer=null}},controlsEnabled:true,disableControls:function(){this.killControlsTimer();this.hideControls(false);this.controlsEnabled=false},enableControls:function(){this.showControls(false);this.controlsEnabled=true},meReady:function(a,b){var c=this,
+d=mejs.MediaFeatures,e=b.getAttribute("autoplay");e=!(typeof e=="undefined"||e===null||e==="false");var g;if(!c.created){c.created=true;c.media=a;c.domNode=b;if(!(d.isAndroid&&c.options.AndroidUseNativeControls)&&!(d.isiPad&&c.options.iPadUseNativeControls)&&!(d.isiPhone&&c.options.iPhoneUseNativeControls)){c.buildposter(c,c.controls,c.layers,c.media);c.buildkeyboard(c,c.controls,c.layers,c.media);c.buildoverlays(c,c.controls,c.layers,c.media);c.findTracks();for(g in c.options.features){d=c.options.features[g];
+if(c["build"+d])try{c["build"+d](c,c.controls,c.layers,c.media)}catch(k){}}c.container.trigger("controlsready");c.setPlayerSize(c.width,c.height);c.setControlsSize();if(c.isVideo){if(mejs.MediaFeatures.hasTouch)c.$media.bind("touchstart",function(){if(c.controlsAreVisible)c.hideControls(false);else c.controlsEnabled&&c.showControls(false)});else{c.media.addEventListener("click",function(){if(c.options.clickToPlayPause)c.media.paused?c.media.play():c.media.pause()});c.container.bind("mouseenter mouseover",
+function(){if(c.controlsEnabled)if(!c.options.alwaysShowControls){c.killControlsTimer("enter");c.showControls();c.startControlsTimer(2500)}}).bind("mousemove",function(){if(c.controlsEnabled){c.controlsAreVisible||c.showControls();c.options.alwaysShowControls||c.startControlsTimer(2500)}}).bind("mouseleave",function(){c.controlsEnabled&&!c.media.paused&&!c.options.alwaysShowControls&&c.startControlsTimer(1E3)})}c.options.hideVideoControlsOnLoad&&c.hideControls(false);e&&!c.options.alwaysShowControls&&
+c.hideControls();c.options.enableAutosize&&c.media.addEventListener("loadedmetadata",function(j){if(c.options.videoHeight<=0&&c.domNode.getAttribute("height")===null&&!isNaN(j.target.videoHeight)){c.setPlayerSize(j.target.videoWidth,j.target.videoHeight);c.setControlsSize();c.media.setVideoSize(j.target.videoWidth,j.target.videoHeight)}},false)}a.addEventListener("play",function(){for(var j in mejs.players){var l=mejs.players[j];l.id!=c.id&&c.options.pauseOtherPlayers&&!l.paused&&!l.ended&&l.pause();
+l.hasFocus=false}c.hasFocus=true},false);c.media.addEventListener("ended",function(){if(c.options.autoRewind)try{c.media.setCurrentTime(0)}catch(j){}c.media.pause();c.setProgressRail&&c.setProgressRail();c.setCurrentRail&&c.setCurrentRail();if(c.options.loop)c.media.play();else!c.options.alwaysShowControls&&c.controlsEnabled&&c.showControls()},false);c.media.addEventListener("loadedmetadata",function(){c.updateDuration&&c.updateDuration();c.updateCurrent&&c.updateCurrent();if(!c.isFullScreen){c.setPlayerSize(c.width,
+c.height);c.setControlsSize()}},false);setTimeout(function(){c.setPlayerSize(c.width,c.height);c.setControlsSize()},50);c.globalBind("resize",function(){c.isFullScreen||mejs.MediaFeatures.hasTrueNativeFullScreen&&document.webkitIsFullScreen||c.setPlayerSize(c.width,c.height);c.setControlsSize()});c.media.pluginType=="youtube"&&c.container.find(".mejs-overlay-play").hide()}if(e&&a.pluginType=="native"){a.load();a.play()}if(c.options.success)typeof c.options.success=="string"?window[c.options.success](c.media,
+c.domNode,c):c.options.success(c.media,c.domNode,c)}},handleError:function(a){this.controls.hide();this.options.error&&this.options.error(a)},setPlayerSize:function(a,b){if(typeof a!="undefined")this.width=a;if(typeof b!="undefined")this.height=b;if(this.height.toString().indexOf("%")>0||this.$node.css("max-width")==="100%"||this.$node[0].currentStyle&&this.$node[0].currentStyle.maxWidth==="100%"){var c=this.isVideo?this.media.videoWidth&&this.media.videoWidth>0?this.media.videoWidth:this.options.defaultVideoWidth:
+this.options.defaultAudioWidth,d=this.isVideo?this.media.videoHeight&&this.media.videoHeight>0?this.media.videoHeight:this.options.defaultVideoHeight:this.options.defaultAudioHeight,e=this.container.parent().closest(":visible").width();c=this.isVideo||!this.options.autosizeProgress?parseInt(e*d/c,10):d;if(this.container.parent()[0].tagName.toLowerCase()==="body"){e=f(window).width();c=f(window).height()}if(c!=0&&e!=0){this.container.width(e).height(c);this.$media.add(this.container.find(".mejs-shim")).width("100%").height("100%");
+this.isVideo&&this.media.setVideoSize&&this.media.setVideoSize(e,c);this.layers.children(".mejs-layer").width("100%").height("100%")}}else{this.container.width(this.width).height(this.height);this.layers.children(".mejs-layer").width(this.width).height(this.height)}},setControlsSize:function(){var a=0,b=0,c=this.controls.find(".mejs-time-rail"),d=this.controls.find(".mejs-time-total");this.controls.find(".mejs-time-current");this.controls.find(".mejs-time-loaded");var e=c.siblings();if(this.options&&
+!this.options.autosizeProgress)b=parseInt(c.css("width"));if(b===0||!b){e.each(function(){var g=f(this);if(g.css("position")!="absolute"&&g.is(":visible"))a+=f(this).outerWidth(true)});b=this.controls.width()-a-(c.outerWidth(true)-c.width())}c.width(b);d.width(b-(d.outerWidth(true)-d.width()));this.setProgressRail&&this.setProgressRail();this.setCurrentRail&&this.setCurrentRail()},buildposter:function(a,b,c,d){var e=f('<div class="mejs-poster mejs-layer"></div>').appendTo(c);b=a.$media.attr("poster");
+if(a.options.poster!=="")b=a.options.poster;b!==""&&b!=null?this.setPoster(b):e.hide();d.addEventListener("play",function(){e.hide()},false)},setPoster:function(a){var b=this.container.find(".mejs-poster"),c=b.find("img");if(c.length==0)c=f('<img width="100%" height="100%" />').appendTo(b);c.attr("src",a)},buildoverlays:function(a,b,c,d){var e=this;if(a.isVideo){var g=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-loading"><span></span></div></div>').hide().appendTo(c),k=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-error"></div></div>').hide().appendTo(c),
+j=f('<div class="mejs-overlay mejs-layer mejs-overlay-play"><div class="mejs-overlay-button"></div></div>').appendTo(c).click(function(){if(e.options.clickToPlayPause)d.paused?d.play():d.pause()});d.addEventListener("play",function(){j.hide();g.hide();b.find(".mejs-time-buffering").hide();k.hide()},false);d.addEventListener("playing",function(){j.hide();g.hide();b.find(".mejs-time-buffering").hide();k.hide()},false);d.addEventListener("seeking",function(){g.show();b.find(".mejs-time-buffering").show()},
+false);d.addEventListener("seeked",function(){g.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("pause",function(){mejs.MediaFeatures.isiPhone||j.show()},false);d.addEventListener("waiting",function(){g.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("loadeddata",function(){g.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("canplay",function(){g.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("error",function(){g.hide();
+b.find(".mejs-time-buffering").hide();k.show();k.find("mejs-overlay-error").html("Error loading this resource")},false)}},buildkeyboard:function(a,b,c,d){this.globalBind("keydown",function(e){if(a.hasFocus&&a.options.enableKeyboard)for(var g=0,k=a.options.keyActions.length;g<k;g++)for(var j=a.options.keyActions[g],l=0,q=j.keys.length;l<q;l++)if(e.keyCode==j.keys[l]){e.preventDefault();j.action(a,d,e.keyCode);return false}return true});this.globalBind("click",function(e){if(f(e.target).closest(".mejs-container").length==
+0)a.hasFocus=false})},findTracks:function(){var a=this,b=a.$media.find("track");a.tracks=[];b.each(function(c,d){d=f(d);a.tracks.push({srclang:d.attr("srclang")?d.attr("srclang").toLowerCase():"",src:d.attr("src"),kind:d.attr("kind"),label:d.attr("label")||"",entries:[],isLoaded:false})})},changeSkin:function(a){this.container[0].className="mejs-container "+a;this.setPlayerSize(this.width,this.height);this.setControlsSize()},play:function(){this.media.play()},pause:function(){this.media.pause()},
+load:function(){this.media.load()},setMuted:function(a){this.media.setMuted(a)},setCurrentTime:function(a){this.media.setCurrentTime(a)},getCurrentTime:function(){return this.media.currentTime},setVolume:function(a){this.media.setVolume(a)},getVolume:function(){return this.media.volume},setSrc:function(a){this.media.setSrc(a)},remove:function(){var a,b;for(a in this.options.features){b=this.options.features[a];if(this["clean"+b])try{this["clean"+b](this)}catch(c){}}this.media.pluginType==="native"?
+this.$media.prop("controls",true):this.media.remove();this.isDynamic||this.$node.insertBefore(this.container);delete mejs.players[this.id];this.container.remove();this.globalUnbind();delete this.node.player}};(function(){function a(c,d){var e={d:[],w:[]};f.each((c||"").split(" "),function(g,k){e[b.test(k)?"w":"d"].push(k+"."+d)});e.d=e.d.join(" ");e.w=e.w.join(" ");return e}var b=/^((after|before)print|(before)?unload|hashchange|message|o(ff|n)line|page(hide|show)|popstate|resize|storage)\b/;mejs.MediaElementPlayer.prototype.globalBind=
+function(c,d,e){c=a(c,this.id);c.d&&f(document).bind(c.d,d,e);c.w&&f(window).bind(c.w,d,e)};mejs.MediaElementPlayer.prototype.globalUnbind=function(c,d){c=a(c,this.id);c.d&&f(document).unbind(c.d,d);c.w&&f(window).unbind(c.w,d)}})();if(typeof jQuery!="undefined")jQuery.fn.mediaelementplayer=function(a){a===false?this.each(function(){var b=jQuery(this).data("mediaelementplayer");b&&b.remove();jQuery(this).removeData("mediaelementplayer")}):this.each(function(){jQuery(this).data("mediaelementplayer",
+new mejs.MediaElementPlayer(this,a))});return this};f(document).ready(function(){f(".mejs-player").mediaelementplayer()});window.MediaElementPlayer=mejs.MediaElementPlayer})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{playpauseText:"Play/Pause"});f.extend(MediaElementPlayer.prototype,{buildplaypause:function(a,b,c,d){var e=f('<div class="mejs-button mejs-playpause-button mejs-play" ><button type="button" aria-controls="'+this.id+'" title="'+this.options.playpauseText+'" aria-label="'+this.options.playpauseText+'"></button></div>').appendTo(b).click(function(g){g.preventDefault();d.paused?d.play():d.pause();return false});d.addEventListener("play",function(){e.removeClass("mejs-play").addClass("mejs-pause")},
+false);d.addEventListener("playing",function(){e.removeClass("mejs-play").addClass("mejs-pause")},false);d.addEventListener("pause",function(){e.removeClass("mejs-pause").addClass("mejs-play")},false);d.addEventListener("paused",function(){e.removeClass("mejs-pause").addClass("mejs-play")},false)}})})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{stopText:"Stop"});f.extend(MediaElementPlayer.prototype,{buildstop:function(a,b,c,d){f('<div class="mejs-button mejs-stop-button mejs-stop"><button type="button" aria-controls="'+this.id+'" title="'+this.options.stopText+'" aria-label="'+this.options.stopText+'"></button></div>').appendTo(b).click(function(){d.paused||d.pause();if(d.currentTime>0){d.setCurrentTime(0);d.pause();b.find(".mejs-time-current").width("0px");b.find(".mejs-time-handle").css("left",
+"0px");b.find(".mejs-time-float-current").html(mejs.Utility.secondsToTimeCode(0));b.find(".mejs-currenttime").html(mejs.Utility.secondsToTimeCode(0));c.find(".mejs-poster").show()}})}})})(mejs.$);
(function(f){f.extend(MediaElementPlayer.prototype,{buildprogress:function(a,b,c,d){f('<div class="mejs-time-rail"><span class="mejs-time-total"><span class="mejs-time-buffering"></span><span class="mejs-time-loaded"></span><span class="mejs-time-current"></span><span class="mejs-time-handle"></span><span class="mejs-time-float"><span class="mejs-time-float-current">00:00</span><span class="mejs-time-float-corner"></span></span></span></div>').appendTo(b);b.find(".mejs-time-buffering").hide();var e=
-b.find(".mejs-time-total");c=b.find(".mejs-time-loaded");var g=b.find(".mejs-time-current"),k=b.find(".mejs-time-handle"),h=b.find(".mejs-time-float"),o=b.find(".mejs-time-float-current"),n=function(m){m=m.pageX;var q=e.offset(),i=e.outerWidth(true),j=0,l=j=0;if(d.duration){if(m<q.left)m=q.left;else if(m>i+q.left)m=i+q.left;l=m-q.left;j=l/i;j=j<=0.02?0:j*d.duration;p&&j!==d.currentTime&&d.setCurrentTime(j);if(!mejs.MediaFeatures.hasTouch){h.css("left",l);o.html(mejs.Utility.secondsToTimeCode(j));
-h.show()}}},p=false;e.bind("mousedown",function(m){if(m.which===1){p=true;n(m);f(document).bind("mousemove.dur",function(q){n(q)}).bind("mouseup.dur",function(){p=false;h.hide();f(document).unbind(".dur")});return false}}).bind("mouseenter",function(){f(document).bind("mousemove.dur",function(m){n(m)});mejs.MediaFeatures.hasTouch||h.show()}).bind("mouseleave",function(){if(!p){f(document).unbind(".dur");h.hide()}});d.addEventListener("progress",function(m){a.setProgressRail(m);a.setCurrentRail(m)},
-false);d.addEventListener("timeupdate",function(m){a.setProgressRail(m);a.setCurrentRail(m)},false);this.loaded=c;this.total=e;this.current=g;this.handle=k},setProgressRail:function(a){var b=a!=undefined?a.target:this.media,c=null;if(b&&b.buffered&&b.buffered.length>0&&b.buffered.end&&b.duration)c=b.buffered.end(0)/b.duration;else if(b&&b.bytesTotal!=undefined&&b.bytesTotal>0&&b.bufferedBytes!=undefined)c=b.bufferedBytes/b.bytesTotal;else if(a&&a.lengthComputable&&a.total!=0)c=a.loaded/a.total;if(c!==
-null){c=Math.min(1,Math.max(0,c));this.loaded&&this.total&&this.loaded.width(this.total.width()*c)}},setCurrentRail:function(){if(this.media.currentTime!=undefined&&this.media.duration)if(this.total&&this.handle){var a=this.total.width()*this.media.currentTime/this.media.duration,b=a-this.handle.outerWidth(true)/2;this.current.width(a);this.handle.css("left",b)}}})})(mejs.$);
+this,g=b.find(".mejs-time-total");c=b.find(".mejs-time-loaded");var k=b.find(".mejs-time-current"),j=b.find(".mejs-time-handle"),l=b.find(".mejs-time-float"),q=b.find(".mejs-time-float-current"),p=function(h){h=h.pageX;var m=g.offset(),r=g.outerWidth(true),n=0,o=n=0;if(d.duration){if(h<m.left)h=m.left;else if(h>r+m.left)h=r+m.left;o=h-m.left;n=o/r;n=n<=0.02?0:n*d.duration;t&&n!==d.currentTime&&d.setCurrentTime(n);if(!mejs.MediaFeatures.hasTouch){l.css("left",o);q.html(mejs.Utility.secondsToTimeCode(n));
+l.show()}}},t=false;g.bind("mousedown",function(h){if(h.which===1){t=true;p(h);e.globalBind("mousemove.dur",function(m){p(m)});e.globalBind("mouseup.dur",function(){t=false;l.hide();e.globalUnbind(".dur")});return false}}).bind("mouseenter",function(){e.globalBind("mousemove.dur",function(h){p(h)});mejs.MediaFeatures.hasTouch||l.show()}).bind("mouseleave",function(){if(!t){e.globalUnbind(".dur");l.hide()}});d.addEventListener("progress",function(h){a.setProgressRail(h);a.setCurrentRail(h)},false);
+d.addEventListener("timeupdate",function(h){a.setProgressRail(h);a.setCurrentRail(h)},false);e.loaded=c;e.total=g;e.current=k;e.handle=j},setProgressRail:function(a){var b=a!=undefined?a.target:this.media,c=null;if(b&&b.buffered&&b.buffered.length>0&&b.buffered.end&&b.duration)c=b.buffered.end(0)/b.duration;else if(b&&b.bytesTotal!=undefined&&b.bytesTotal>0&&b.bufferedBytes!=undefined)c=b.bufferedBytes/b.bytesTotal;else if(a&&a.lengthComputable&&a.total!=0)c=a.loaded/a.total;if(c!==null){c=Math.min(1,
+Math.max(0,c));this.loaded&&this.total&&this.loaded.width(this.total.width()*c)}},setCurrentRail:function(){if(this.media.currentTime!=undefined&&this.media.duration)if(this.total&&this.handle){var a=Math.round(this.total.width()*this.media.currentTime/this.media.duration),b=a-Math.round(this.handle.outerWidth(true)/2);this.current.width(a);this.handle.css("left",b)}}})})(mejs.$);
(function(f){f.extend(mejs.MepDefaults,{duration:-1,timeAndDurationSeparator:" <span> | </span> "});f.extend(MediaElementPlayer.prototype,{buildcurrent:function(a,b,c,d){f('<div class="mejs-time"><span class="mejs-currenttime">'+(a.options.alwaysShowHours?"00:":"")+(a.options.showTimecodeFrameCount?"00:00:00":"00:00")+"</span></div>").appendTo(b);this.currenttime=this.controls.find(".mejs-currenttime");d.addEventListener("timeupdate",function(){a.updateCurrent()},false)},buildduration:function(a,
b,c,d){if(b.children().last().find(".mejs-currenttime").length>0)f(this.options.timeAndDurationSeparator+'<span class="mejs-duration">'+(this.options.duration>0?mejs.Utility.secondsToTimeCode(this.options.duration,this.options.alwaysShowHours||this.media.duration>3600,this.options.showTimecodeFrameCount,this.options.framesPerSecond||25):(a.options.alwaysShowHours?"00:":"")+(a.options.showTimecodeFrameCount?"00:00:00":"00:00"))+"</span>").appendTo(b.find(".mejs-time"));else{b.find(".mejs-currenttime").parent().addClass("mejs-currenttime-container");
f('<div class="mejs-time mejs-duration-container"><span class="mejs-duration">'+(this.options.duration>0?mejs.Utility.secondsToTimeCode(this.options.duration,this.options.alwaysShowHours||this.media.duration>3600,this.options.showTimecodeFrameCount,this.options.framesPerSecond||25):(a.options.alwaysShowHours?"00:":"")+(a.options.showTimecodeFrameCount?"00:00:00":"00:00"))+"</span></div>").appendTo(b)}this.durationD=this.controls.find(".mejs-duration");d.addEventListener("timeupdate",function(){a.updateDuration()},
-false)},updateCurrent:function(){if(this.currenttime)this.currenttime.html(mejs.Utility.secondsToTimeCode(this.media.currentTime,this.options.alwaysShowHours||this.media.duration>3600,this.options.showTimecodeFrameCount,this.options.framesPerSecond||25))},updateDuration:function(){this.container.toggleClass("mejs-long-video",this.media.duration>3600);if(this.media.duration&&this.durationD)this.durationD.html(mejs.Utility.secondsToTimeCode(this.media.duration,this.options.alwaysShowHours,this.options.showTimecodeFrameCount,
-this.options.framesPerSecond||25))}})})(mejs.$);
-(function(f){f.extend(mejs.MepDefaults,{muteText:"Mute Toggle",hideVolumeOnTouchDevices:true,audioVolume:"horizontal",videoVolume:"vertical"});f.extend(MediaElementPlayer.prototype,{buildvolume:function(a,b,c,d){if(!(mejs.MediaFeatures.hasTouch&&this.options.hideVolumeOnTouchDevices)){var e=this.isVideo?this.options.videoVolume:this.options.audioVolume,g=e=="horizontal"?f('<div class="mejs-button mejs-volume-button mejs-mute"><button type="button" aria-controls="'+this.id+'" title="'+this.options.muteText+
-'"></button></div><div class="mejs-horizontal-volume-slider"><div class="mejs-horizontal-volume-total"></div><div class="mejs-horizontal-volume-current"></div><div class="mejs-horizontal-volume-handle"></div></div>').appendTo(b):f('<div class="mejs-button mejs-volume-button mejs-mute"><button type="button" aria-controls="'+this.id+'" title="'+this.options.muteText+'"></button><div class="mejs-volume-slider"><div class="mejs-volume-total"></div><div class="mejs-volume-current"></div><div class="mejs-volume-handle"></div></div></div>').appendTo(b),
-k=this.container.find(".mejs-volume-slider, .mejs-horizontal-volume-slider"),h=this.container.find(".mejs-volume-total, .mejs-horizontal-volume-total"),o=this.container.find(".mejs-volume-current, .mejs-horizontal-volume-current"),n=this.container.find(".mejs-volume-handle, .mejs-horizontal-volume-handle"),p=function(j,l){if(!k.is(":visible")&&typeof l=="undefined"){k.show();p(j,true);k.hide()}else{j=Math.max(0,j);j=Math.min(j,1);j==0?g.removeClass("mejs-mute").addClass("mejs-unmute"):g.removeClass("mejs-unmute").addClass("mejs-mute");
-if(e=="vertical"){var r=h.height(),s=h.position(),t=r-r*j;n.css("top",Math.round(s.top+t-n.height()/2));o.height(r-t);o.css("top",s.top+t)}else{r=h.width();s=h.position();r=r*j;n.css("left",Math.round(s.left+r-n.width()/2));o.width(Math.round(r))}}},m=function(j){var l=null,r=h.offset();if(e=="vertical"){l=h.height();parseInt(h.css("top").replace(/px/,""),10);l=(l-(j.pageY-r.top))/l;if(r.top==0||r.left==0)return}else{l=h.width();l=(j.pageX-r.left)/l}l=Math.max(0,l);l=Math.min(l,1);p(l);l==0?d.setMuted(true):
-d.setMuted(false);d.setVolume(l)},q=false,i=false;g.hover(function(){k.show();i=true},function(){i=false;!q&&e=="vertical"&&k.hide()});k.bind("mouseover",function(){i=true}).bind("mousedown",function(j){m(j);f(document).bind("mousemove.vol",function(l){m(l)}).bind("mouseup.vol",function(){q=false;f(document).unbind(".vol");!i&&e=="vertical"&&k.hide()});q=true;return false});g.find("button").click(function(){d.setMuted(!d.muted)});d.addEventListener("volumechange",function(){if(!q)if(d.muted){p(0);
-g.removeClass("mejs-mute").addClass("mejs-unmute")}else{p(d.volume);g.removeClass("mejs-unmute").addClass("mejs-mute")}},false);if(this.container.is(":visible")){p(a.options.startVolume);d.pluginType==="native"&&d.setVolume(a.options.startVolume)}}}})})(mejs.$);
-(function(f){f.extend(mejs.MepDefaults,{usePluginFullScreen:true,newWindowCallback:function(){return""},fullscreenText:mejs.i18n.t("Fullscreen")});f.extend(MediaElementPlayer.prototype,{isFullScreen:false,isNativeFullScreen:false,docStyleOverflow:null,isInIframe:false,buildfullscreen:function(a,b,c,d){if(a.isVideo){a.isInIframe=window.location!=window.parent.location;if(mejs.MediaFeatures.hasTrueNativeFullScreen){c=null;c=mejs.MediaFeatures.hasMozNativeFullScreen?f(document):a.container;c.bind(mejs.MediaFeatures.fullScreenEventName,
-function(){if(mejs.MediaFeatures.isFullScreen()){a.isNativeFullScreen=true;a.setControlsSize()}else{a.isNativeFullScreen=false;a.exitFullScreen()}})}var e=this,g=f('<div class="mejs-button mejs-fullscreen-button"><button type="button" aria-controls="'+e.id+'" title="'+e.options.fullscreenText+'"></button></div>').appendTo(b);if(e.media.pluginType==="native"||!e.options.usePluginFullScreen&&!mejs.MediaFeatures.isFirefox)g.click(function(){mejs.MediaFeatures.hasTrueNativeFullScreen&&mejs.MediaFeatures.isFullScreen()||
-a.isFullScreen?a.exitFullScreen():a.enterFullScreen()});else{var k=null;if(function(){var i=document.createElement("x"),j=document.documentElement,l=window.getComputedStyle;if(!("pointerEvents"in i.style))return false;i.style.pointerEvents="auto";i.style.pointerEvents="x";j.appendChild(i);l=l&&l(i,"").pointerEvents==="auto";j.removeChild(i);return!!l}()&&!mejs.MediaFeatures.isOpera){var h=false,o=function(){if(h){n.hide();p.hide();m.hide();g.css("pointer-events","");e.controls.css("pointer-events",
-"");h=false}},n=f('<div class="mejs-fullscreen-hover" />').appendTo(e.container).mouseover(o),p=f('<div class="mejs-fullscreen-hover" />').appendTo(e.container).mouseover(o),m=f('<div class="mejs-fullscreen-hover" />').appendTo(e.container).mouseover(o),q=function(){var i={position:"absolute",top:0,left:0};n.css(i);p.css(i);m.css(i);n.width(e.container.width()).height(e.container.height()-e.controls.height());i=g.offset().left-e.container.offset().left;fullScreenBtnWidth=g.outerWidth(true);p.width(i).height(e.controls.height()).css({top:e.container.height()-
-e.controls.height()});m.width(e.container.width()-i-fullScreenBtnWidth).height(e.controls.height()).css({top:e.container.height()-e.controls.height(),left:i+fullScreenBtnWidth})};f(document).resize(function(){q()});g.mouseover(function(){if(!e.isFullScreen){var i=g.offset(),j=a.container.offset();d.positionFullscreenButton(i.left-j.left,i.top-j.top,false);g.css("pointer-events","none");e.controls.css("pointer-events","none");n.show();m.show();p.show();q();h=true}});d.addEventListener("fullscreenchange",
-function(){o()})}else g.mouseover(function(){if(k!==null){clearTimeout(k);delete k}var i=g.offset(),j=a.container.offset();d.positionFullscreenButton(i.left-j.left,i.top-j.top,true)}).mouseout(function(){if(k!==null){clearTimeout(k);delete k}k=setTimeout(function(){d.hideFullscreenButton()},1500)})}a.fullscreenBtn=g;f(document).bind("keydown",function(i){if((mejs.MediaFeatures.hasTrueNativeFullScreen&&mejs.MediaFeatures.isFullScreen()||e.isFullScreen)&&i.keyCode==27)a.exitFullScreen()})}},enterFullScreen:function(){var a=
-this;if(!(a.media.pluginType!=="native"&&(mejs.MediaFeatures.isFirefox||a.options.usePluginFullScreen))){docStyleOverflow=document.documentElement.style.overflow;document.documentElement.style.overflow="hidden";normalHeight=a.container.height();normalWidth=a.container.width();if(a.media.pluginType==="native")if(mejs.MediaFeatures.hasTrueNativeFullScreen){mejs.MediaFeatures.requestFullScreen(a.container[0]);a.isInIframe&&setTimeout(function c(){if(a.isNativeFullScreen)f(window).width()!==screen.width?
-a.exitFullScreen():setTimeout(c,500)},500)}else if(mejs.MediaFeatures.hasSemiNativeFullScreen){a.media.webkitEnterFullscreen();return}if(a.isInIframe){var b=a.options.newWindowCallback(this);if(b!=="")if(mejs.MediaFeatures.hasTrueNativeFullScreen)setTimeout(function(){if(!a.isNativeFullScreen){a.pause();window.open(b,a.id,"top=0,left=0,width="+screen.availWidth+",height="+screen.availHeight+",resizable=yes,scrollbars=no,status=no,toolbar=no")}},250);else{a.pause();window.open(b,a.id,"top=0,left=0,width="+
-screen.availWidth+",height="+screen.availHeight+",resizable=yes,scrollbars=no,status=no,toolbar=no");return}}a.container.addClass("mejs-container-fullscreen").width("100%").height("100%");setTimeout(function(){a.container.css({width:"100%",height:"100%"});a.setControlsSize()},500);if(a.pluginType==="native")a.$media.width("100%").height("100%");else{a.container.find("object, embed, iframe").width("100%").height("100%");a.media.setVideoSize(f(window).width(),f(window).height())}a.layers.children("div").width("100%").height("100%");
-a.fullscreenBtn&&a.fullscreenBtn.removeClass("mejs-fullscreen").addClass("mejs-unfullscreen");a.setControlsSize();a.isFullScreen=true}},exitFullScreen:function(){if(this.media.pluginType!=="native"&&mejs.MediaFeatures.isFirefox)this.media.setFullscreen(false);else{if(mejs.MediaFeatures.hasTrueNativeFullScreen&&(mejs.MediaFeatures.isFullScreen()||this.isFullScreen))mejs.MediaFeatures.cancelFullScreen();document.documentElement.style.overflow=docStyleOverflow;this.container.removeClass("mejs-container-fullscreen").width(normalWidth).height(normalHeight);
-if(this.pluginType==="native")this.$media.width(normalWidth).height(normalHeight);else{this.container.find("object embed").width(normalWidth).height(normalHeight);this.media.setVideoSize(normalWidth,normalHeight)}this.layers.children("div").width(normalWidth).height(normalHeight);this.fullscreenBtn.removeClass("mejs-unfullscreen").addClass("mejs-fullscreen");this.setControlsSize();this.isFullScreen=false}}})})(mejs.$);
-(function(f){f.extend(mejs.MepDefaults,{startLanguage:"",tracksText:"Captions/Subtitles"});f.extend(MediaElementPlayer.prototype,{hasChapters:false,buildtracks:function(a,b,c,d){if(a.isVideo)if(a.tracks.length!=0){var e;a.chapters=f('<div class="mejs-chapters mejs-layer"></div>').prependTo(c).hide();a.captions=f('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position"><span class="mejs-captions-text"></span></div></div>').prependTo(c).hide();a.captionsText=a.captions.find(".mejs-captions-text");
-a.captionsButton=f('<div class="mejs-button mejs-captions-button"><button type="button" aria-controls="'+this.id+'" title="'+this.options.tracksText+'"></button><div class="mejs-captions-selector"><ul><li><input type="radio" name="'+a.id+'_captions" id="'+a.id+'_captions_none" value="none" checked="checked" /><label for="'+a.id+'_captions_none">None</label></li></ul></div></div>').appendTo(b).hover(function(){f(this).find(".mejs-captions-selector").css("visibility","visible")},function(){f(this).find(".mejs-captions-selector").css("visibility",
-"hidden")}).delegate("input[type=radio]","click",function(){lang=this.value;if(lang=="none")a.selectedTrack=null;else for(e=0;e<a.tracks.length;e++)if(a.tracks[e].srclang==lang){a.selectedTrack=a.tracks[e];a.captions.attr("lang",a.selectedTrack.srclang);a.displayCaptions();break}});a.options.alwaysShowControls?a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover"):a.container.bind("controlsshown",function(){a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover")}).bind("controlshidden",
-function(){d.paused||a.container.find(".mejs-captions-position").removeClass("mejs-captions-position-hover")});a.trackToLoad=-1;a.selectedTrack=null;a.isLoadingTrack=false;for(e=0;e<a.tracks.length;e++)a.tracks[e].kind=="subtitles"&&a.addTrackButton(a.tracks[e].srclang,a.tracks[e].label);a.loadNextTrack();d.addEventListener("timeupdate",function(){a.displayCaptions()},false);d.addEventListener("loadedmetadata",function(){a.displayChapters()},false);a.container.hover(function(){if(a.hasChapters){a.chapters.css("visibility",
-"visible");a.chapters.fadeIn(200).height(a.chapters.find(".mejs-chapter").outerHeight())}},function(){a.hasChapters&&!d.paused&&a.chapters.fadeOut(200,function(){f(this).css("visibility","hidden");f(this).css("display","block")})});a.node.getAttribute("autoplay")!==null&&a.chapters.css("visibility","hidden")}},loadNextTrack:function(){this.trackToLoad++;if(this.trackToLoad<this.tracks.length){this.isLoadingTrack=true;this.loadTrack(this.trackToLoad)}else this.isLoadingTrack=false},loadTrack:function(a){var b=
-this,c=b.tracks[a];f.ajax({url:c.src,dataType:"text",success:function(d){c.entries=typeof d=="string"&&/<tt\s+xml/ig.exec(d)?mejs.TrackFormatParser.dfxp.parse(d):mejs.TrackFormatParser.webvvt.parse(d);c.isLoaded=true;b.enableTrackButton(c.srclang,c.label);b.loadNextTrack();c.kind=="chapters"&&b.media.addEventListener("play",function(){b.media.duration>0&&b.displayChapters(c)},false)},error:function(){b.loadNextTrack()}})},enableTrackButton:function(a,b){if(b==="")b=mejs.language.codes[a]||a;this.captionsButton.find("input[value="+
-a+"]").prop("disabled",false).siblings("label").html(b);this.options.startLanguage==a&&f("#"+this.id+"_captions_"+a).click();this.adjustLanguageBox()},addTrackButton:function(a,b){if(b==="")b=mejs.language.codes[a]||a;this.captionsButton.find("ul").append(f('<li><input type="radio" name="'+this.id+'_captions" id="'+this.id+"_captions_"+a+'" value="'+a+'" disabled="disabled" /><label for="'+this.id+"_captions_"+a+'">'+b+" (loading)</label></li>"));this.adjustLanguageBox();this.container.find(".mejs-captions-translations option[value="+
-a+"]").remove()},adjustLanguageBox:function(){this.captionsButton.find(".mejs-captions-selector").height(this.captionsButton.find(".mejs-captions-selector ul").outerHeight(true)+this.captionsButton.find(".mejs-captions-translations").outerHeight(true))},displayCaptions:function(){if(typeof this.tracks!="undefined"){var a,b=this.selectedTrack;if(b!=null&&b.isLoaded)for(a=0;a<b.entries.times.length;a++)if(this.media.currentTime>=b.entries.times[a].start&&this.media.currentTime<=b.entries.times[a].stop){this.captionsText.html(b.entries.text[a]);
-this.captions.show().height(0);return}this.captions.hide()}},displayChapters:function(){var a;for(a=0;a<this.tracks.length;a++)if(this.tracks[a].kind=="chapters"&&this.tracks[a].isLoaded){this.drawChapters(this.tracks[a]);this.hasChapters=true;break}},drawChapters:function(a){var b=this,c,d,e=d=0;b.chapters.empty();for(c=0;c<a.entries.times.length;c++){d=a.entries.times[c].stop-a.entries.times[c].start;d=Math.floor(d/b.media.duration*100);if(d+e>100||c==a.entries.times.length-1&&d+e<100)d=100-e;b.chapters.append(f('<div class="mejs-chapter" rel="'+
-a.entries.times[c].start+'" style="left: '+e.toString()+"%;width: "+d.toString()+'%;"><div class="mejs-chapter-block'+(c==a.entries.times.length-1?" mejs-chapter-block-last":"")+'"><span class="ch-title">'+a.entries.text[c]+'</span><span class="ch-time">'+mejs.Utility.secondsToTimeCode(a.entries.times[c].start)+"&ndash;"+mejs.Utility.secondsToTimeCode(a.entries.times[c].stop)+"</span></div></div>"));e+=d}b.chapters.find("div.mejs-chapter").click(function(){b.media.setCurrentTime(parseFloat(f(this).attr("rel")));
-b.media.paused&&b.media.play()});b.chapters.show()}});mejs.language={codes:{af:"Afrikaans",sq:"Albanian",ar:"Arabic",be:"Belarusian",bg:"Bulgarian",ca:"Catalan",zh:"Chinese","zh-cn":"Chinese Simplified","zh-tw":"Chinese Traditional",hr:"Croatian",cs:"Czech",da:"Danish",nl:"Dutch",en:"English",et:"Estonian",tl:"Filipino",fi:"Finnish",fr:"French",gl:"Galician",de:"German",el:"Greek",ht:"Haitian Creole",iw:"Hebrew",hi:"Hindi",hu:"Hungarian",is:"Icelandic",id:"Indonesian",ga:"Irish",it:"Italian",ja:"Japanese",
-ko:"Korean",lv:"Latvian",lt:"Lithuanian",mk:"Macedonian",ms:"Malay",mt:"Maltese",no:"Norwegian",fa:"Persian",pl:"Polish",pt:"Portuguese",ro:"Romanian",ru:"Russian",sr:"Serbian",sk:"Slovak",sl:"Slovenian",es:"Spanish",sw:"Swahili",sv:"Swedish",tl:"Tagalog",th:"Thai",tr:"Turkish",uk:"Ukrainian",vi:"Vietnamese",cy:"Welsh",yi:"Yiddish"}};mejs.TrackFormatParser={webvvt:{pattern_identifier:/^([a-zA-z]+-)?[0-9]+$/,pattern_timecode:/^([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,
+false)},updateCurrent:function(){if(this.currenttime)this.currenttime.html(mejs.Utility.secondsToTimeCode(this.media.currentTime,this.options.alwaysShowHours||this.media.duration>3600,this.options.showTimecodeFrameCount,this.options.framesPerSecond||25))},updateDuration:function(){this.container.toggleClass("mejs-long-video",this.media.duration>3600);if(this.durationD&&(this.options.duration>0||this.media.duration))this.durationD.html(mejs.Utility.secondsToTimeCode(this.options.duration>0?this.options.duration:
+this.media.duration,this.options.alwaysShowHours,this.options.showTimecodeFrameCount,this.options.framesPerSecond||25))}})})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{muteText:"Mute Toggle",hideVolumeOnTouchDevices:true,audioVolume:"horizontal",videoVolume:"vertical"});f.extend(MediaElementPlayer.prototype,{buildvolume:function(a,b,c,d){if(!(mejs.MediaFeatures.hasTouch&&this.options.hideVolumeOnTouchDevices)){var e=this,g=e.isVideo?e.options.videoVolume:e.options.audioVolume,k=g=="horizontal"?f('<div class="mejs-button mejs-volume-button mejs-mute"><button type="button" aria-controls="'+e.id+'" title="'+e.options.muteText+
+'" aria-label="'+e.options.muteText+'"></button></div><div class="mejs-horizontal-volume-slider"><div class="mejs-horizontal-volume-total"></div><div class="mejs-horizontal-volume-current"></div><div class="mejs-horizontal-volume-handle"></div></div>').appendTo(b):f('<div class="mejs-button mejs-volume-button mejs-mute"><button type="button" aria-controls="'+e.id+'" title="'+e.options.muteText+'" aria-label="'+e.options.muteText+'"></button><div class="mejs-volume-slider"><div class="mejs-volume-total"></div><div class="mejs-volume-current"></div><div class="mejs-volume-handle"></div></div></div>').appendTo(b),
+j=e.container.find(".mejs-volume-slider, .mejs-horizontal-volume-slider"),l=e.container.find(".mejs-volume-total, .mejs-horizontal-volume-total"),q=e.container.find(".mejs-volume-current, .mejs-horizontal-volume-current"),p=e.container.find(".mejs-volume-handle, .mejs-horizontal-volume-handle"),t=function(n,o){if(!j.is(":visible")&&typeof o=="undefined"){j.show();t(n,true);j.hide()}else{n=Math.max(0,n);n=Math.min(n,1);n==0?k.removeClass("mejs-mute").addClass("mejs-unmute"):k.removeClass("mejs-unmute").addClass("mejs-mute");
+if(g=="vertical"){var s=l.height(),u=l.position(),v=s-s*n;p.css("top",Math.round(u.top+v-p.height()/2));q.height(s-v);q.css("top",u.top+v)}else{s=l.width();u=l.position();s=s*n;p.css("left",Math.round(u.left+s-p.width()/2));q.width(Math.round(s))}}},h=function(n){var o=null,s=l.offset();if(g=="vertical"){o=l.height();parseInt(l.css("top").replace(/px/,""),10);o=(o-(n.pageY-s.top))/o;if(s.top==0||s.left==0)return}else{o=l.width();o=(n.pageX-s.left)/o}o=Math.max(0,o);o=Math.min(o,1);t(o);o==0?d.setMuted(true):
+d.setMuted(false);d.setVolume(o)},m=false,r=false;k.hover(function(){j.show();r=true},function(){r=false;!m&&g=="vertical"&&j.hide()});j.bind("mouseover",function(){r=true}).bind("mousedown",function(n){h(n);e.globalBind("mousemove.vol",function(o){h(o)});e.globalBind("mouseup.vol",function(){m=false;e.globalUnbind(".vol");!r&&g=="vertical"&&j.hide()});m=true;return false});k.find("button").click(function(){d.setMuted(!d.muted)});d.addEventListener("volumechange",function(){if(!m)if(d.muted){t(0);
+k.removeClass("mejs-mute").addClass("mejs-unmute")}else{t(d.volume);k.removeClass("mejs-unmute").addClass("mejs-mute")}},false);if(e.container.is(":visible")){t(a.options.startVolume);a.options.startVolume===0&&d.setMuted(true);d.pluginType==="native"&&d.setVolume(a.options.startVolume)}}}})})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{usePluginFullScreen:true,newWindowCallback:function(){return""},fullscreenText:mejs.i18n.t("Fullscreen")});f.extend(MediaElementPlayer.prototype,{isFullScreen:false,isNativeFullScreen:false,docStyleOverflow:null,isInIframe:false,buildfullscreen:function(a,b,c,d){if(a.isVideo){a.isInIframe=window.location!=window.parent.location;if(mejs.MediaFeatures.hasTrueNativeFullScreen){c=function(){if(mejs.MediaFeatures.isFullScreen()){a.isNativeFullScreen=true;a.setControlsSize()}else{a.isNativeFullScreen=
+false;a.exitFullScreen()}};mejs.MediaFeatures.hasMozNativeFullScreen?a.globalBind(mejs.MediaFeatures.fullScreenEventName,c):a.container.bind(mejs.MediaFeatures.fullScreenEventName,c)}var e=this,g=f('<div class="mejs-button mejs-fullscreen-button"><button type="button" aria-controls="'+e.id+'" title="'+e.options.fullscreenText+'" aria-label="'+e.options.fullscreenText+'"></button></div>').appendTo(b);if(e.media.pluginType==="native"||!e.options.usePluginFullScreen&&!mejs.MediaFeatures.isFirefox)g.click(function(){mejs.MediaFeatures.hasTrueNativeFullScreen&&
+mejs.MediaFeatures.isFullScreen()||a.isFullScreen?a.exitFullScreen():a.enterFullScreen()});else{var k=null;if(function(){var h=document.createElement("x"),m=document.documentElement,r=window.getComputedStyle;if(!("pointerEvents"in h.style))return false;h.style.pointerEvents="auto";h.style.pointerEvents="x";m.appendChild(h);r=r&&r(h,"").pointerEvents==="auto";m.removeChild(h);return!!r}()&&!mejs.MediaFeatures.isOpera){var j=false,l=function(){if(j){for(var h in q)q[h].hide();g.css("pointer-events",
+"");e.controls.css("pointer-events","");j=false}},q={};b=["top","left","right","bottom"];var p,t=function(){var h=g.offset().left-e.container.offset().left,m=g.offset().top-e.container.offset().top,r=g.outerWidth(true),n=g.outerHeight(true),o=e.container.width(),s=e.container.height();for(p in q)q[p].css({position:"absolute",top:0,left:0});q.top.width(o).height(m);q.left.width(h).height(n).css({top:m});q.right.width(o-h-r).height(n).css({top:m,left:h+r});q.bottom.width(o).height(s-n-m).css({top:m+
+n})};e.globalBind("resize",function(){t()});p=0;for(c=b.length;p<c;p+=1)q[b[p]]=f('<div class="mejs-fullscreen-hover" />').appendTo(e.container).mouseover(l).hide();g.mouseover(function(){if(!e.isFullScreen){var h=g.offset(),m=a.container.offset();d.positionFullscreenButton(h.left-m.left,h.top-m.top,false);g.css("pointer-events","none");e.controls.css("pointer-events","none");for(p in q)q[p].show();t();j=true}});d.addEventListener("fullscreenchange",function(){l()})}else g.mouseover(function(){if(k!==
+null){clearTimeout(k);delete k}var h=g.offset(),m=a.container.offset();d.positionFullscreenButton(h.left-m.left,h.top-m.top,true)}).mouseout(function(){if(k!==null){clearTimeout(k);delete k}k=setTimeout(function(){d.hideFullscreenButton()},1500)})}a.fullscreenBtn=g;e.globalBind("keydown",function(h){if((mejs.MediaFeatures.hasTrueNativeFullScreen&&mejs.MediaFeatures.isFullScreen()||e.isFullScreen)&&h.keyCode==27)a.exitFullScreen()})}},cleanfullscreen:function(a){a.exitFullScreen()},containerSizeTimeout:null,
+enterFullScreen:function(){var a=this;if(!(a.media.pluginType!=="native"&&(mejs.MediaFeatures.isFirefox||a.options.usePluginFullScreen))){docStyleOverflow=document.documentElement.style.overflow;document.documentElement.style.overflow="hidden";normalHeight=a.container.height();normalWidth=a.container.width();if(a.media.pluginType==="native")if(mejs.MediaFeatures.hasTrueNativeFullScreen){mejs.MediaFeatures.requestFullScreen(a.container[0]);a.isInIframe&&setTimeout(function c(){if(a.isNativeFullScreen)f(window).width()!==
+screen.width?a.exitFullScreen():setTimeout(c,500)},500)}else if(mejs.MediaFeatures.hasSemiNativeFullScreen){a.media.webkitEnterFullscreen();return}if(a.isInIframe){var b=a.options.newWindowCallback(this);if(b!=="")if(mejs.MediaFeatures.hasTrueNativeFullScreen)setTimeout(function(){if(!a.isNativeFullScreen){a.pause();window.open(b,a.id,"top=0,left=0,width="+screen.availWidth+",height="+screen.availHeight+",resizable=yes,scrollbars=no,status=no,toolbar=no")}},250);else{a.pause();window.open(b,a.id,
+"top=0,left=0,width="+screen.availWidth+",height="+screen.availHeight+",resizable=yes,scrollbars=no,status=no,toolbar=no");return}}a.container.addClass("mejs-container-fullscreen").width("100%").height("100%");a.containerSizeTimeout=setTimeout(function(){a.container.css({width:"100%",height:"100%"});a.setControlsSize()},500);if(a.pluginType==="native")a.$media.width("100%").height("100%");else{a.container.find(".mejs-shim").width("100%").height("100%");a.media.setVideoSize(f(window).width(),f(window).height())}a.layers.children("div").width("100%").height("100%");
+a.fullscreenBtn&&a.fullscreenBtn.removeClass("mejs-fullscreen").addClass("mejs-unfullscreen");a.setControlsSize();a.isFullScreen=true}},exitFullScreen:function(){clearTimeout(this.containerSizeTimeout);if(this.media.pluginType!=="native"&&mejs.MediaFeatures.isFirefox)this.media.setFullscreen(false);else{if(mejs.MediaFeatures.hasTrueNativeFullScreen&&(mejs.MediaFeatures.isFullScreen()||this.isFullScreen))mejs.MediaFeatures.cancelFullScreen();document.documentElement.style.overflow=docStyleOverflow;
+this.container.removeClass("mejs-container-fullscreen").width(normalWidth).height(normalHeight);if(this.pluginType==="native")this.$media.width(normalWidth).height(normalHeight);else{this.container.find("object embed").width(normalWidth).height(normalHeight);this.media.setVideoSize(normalWidth,normalHeight)}this.layers.children("div").width(normalWidth).height(normalHeight);this.fullscreenBtn.removeClass("mejs-unfullscreen").addClass("mejs-fullscreen");this.setControlsSize();this.isFullScreen=false}}})})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{startLanguage:"",tracksText:"Captions/Subtitles",hideCaptionsButtonWhenEmpty:true,toggleCaptionsButtonWhenOnlyOne:false,slidesSelector:""});f.extend(MediaElementPlayer.prototype,{hasChapters:false,buildtracks:function(a,b,c,d){if(a.tracks.length!=0){a.chapters=f('<div class="mejs-chapters mejs-layer"></div>').prependTo(c).hide();a.captions=f('<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(c).hide();
+a.captionsText=a.captions.find(".mejs-captions-text");a.captionsButton=f('<div class="mejs-button mejs-captions-button"><button type="button" aria-controls="'+this.id+'" title="'+this.options.tracksText+'" aria-label="'+this.options.tracksText+'"></button><div class="mejs-captions-selector"><ul><li><input type="radio" name="'+a.id+'_captions" id="'+a.id+'_captions_none" value="none" checked="checked" /><label for="'+a.id+'_captions_none">None</label></li></ul></div></div>').appendTo(b);for(b=c=0;b<
+a.tracks.length;b++)a.tracks[b].kind=="subtitles"&&c++;this.options.toggleCaptionsButtonWhenOnlyOne&&c==1?a.captionsButton.on("click",function(){a.setTrack(a.selectedTrack==null?a.tracks[0].srclang:"none")}):a.captionsButton.hover(function(){f(this).find(".mejs-captions-selector").css("visibility","visible")},function(){f(this).find(".mejs-captions-selector").css("visibility","hidden")}).on("click","input[type=radio]",function(){lang=this.value;a.setTrack(lang)});a.options.alwaysShowControls?a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover"):
+a.container.bind("controlsshown",function(){a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover")}).bind("controlshidden",function(){d.paused||a.container.find(".mejs-captions-position").removeClass("mejs-captions-position-hover")});a.trackToLoad=-1;a.selectedTrack=null;a.isLoadingTrack=false;for(b=0;b<a.tracks.length;b++)a.tracks[b].kind=="subtitles"&&a.addTrackButton(a.tracks[b].srclang,a.tracks[b].label);a.loadNextTrack();d.addEventListener("timeupdate",function(){a.displayCaptions()},
+false);if(a.options.slidesSelector!=""){a.slidesContainer=f(a.options.slidesSelector);d.addEventListener("timeupdate",function(){a.displaySlides()},false)}d.addEventListener("loadedmetadata",function(){a.displayChapters()},false);a.container.hover(function(){if(a.hasChapters){a.chapters.css("visibility","visible");a.chapters.fadeIn(200).height(a.chapters.find(".mejs-chapter").outerHeight())}},function(){a.hasChapters&&!d.paused&&a.chapters.fadeOut(200,function(){f(this).css("visibility","hidden");
+f(this).css("display","block")})});a.node.getAttribute("autoplay")!==null&&a.chapters.css("visibility","hidden")}},setTrack:function(a){var b;if(a=="none"){this.selectedTrack=null;this.captionsButton.removeClass("mejs-captions-enabled")}else for(b=0;b<this.tracks.length;b++)if(this.tracks[b].srclang==a){this.selectedTrack==null&&this.captionsButton.addClass("mejs-captions-enabled");this.selectedTrack=this.tracks[b];this.captions.attr("lang",this.selectedTrack.srclang);this.displayCaptions();break}},
+loadNextTrack:function(){this.trackToLoad++;if(this.trackToLoad<this.tracks.length){this.isLoadingTrack=true;this.loadTrack(this.trackToLoad)}else{this.isLoadingTrack=false;this.checkForTracks()}},loadTrack:function(a){var b=this,c=b.tracks[a];f.ajax({url:c.src,dataType:"text",success:function(d){c.entries=typeof d=="string"&&/<tt\s+xml/ig.exec(d)?mejs.TrackFormatParser.dfxp.parse(d):mejs.TrackFormatParser.webvvt.parse(d);c.isLoaded=true;b.enableTrackButton(c.srclang,c.label);b.loadNextTrack();c.kind==
+"chapters"&&b.media.addEventListener("play",function(){b.media.duration>0&&b.displayChapters(c)},false);c.kind=="slides"&&b.setupSlides(c)},error:function(){b.loadNextTrack()}})},enableTrackButton:function(a,b){if(b==="")b=mejs.language.codes[a]||a;this.captionsButton.find("input[value="+a+"]").prop("disabled",false).siblings("label").html(b);this.options.startLanguage==a&&f("#"+this.id+"_captions_"+a).click();this.adjustLanguageBox()},addTrackButton:function(a,b){if(b==="")b=mejs.language.codes[a]||
+a;this.captionsButton.find("ul").append(f('<li><input type="radio" name="'+this.id+'_captions" id="'+this.id+"_captions_"+a+'" value="'+a+'" disabled="disabled" /><label for="'+this.id+"_captions_"+a+'">'+b+" (loading)</label></li>"));this.adjustLanguageBox();this.container.find(".mejs-captions-translations option[value="+a+"]").remove()},adjustLanguageBox:function(){this.captionsButton.find(".mejs-captions-selector").height(this.captionsButton.find(".mejs-captions-selector ul").outerHeight(true)+
+this.captionsButton.find(".mejs-captions-translations").outerHeight(true))},checkForTracks:function(){var a=false;if(this.options.hideCaptionsButtonWhenEmpty){for(i=0;i<this.tracks.length;i++)if(this.tracks[i].kind=="subtitles"){a=true;break}if(!a){this.captionsButton.hide();this.setControlsSize()}}},displayCaptions:function(){if(typeof this.tracks!="undefined"){var a,b=this.selectedTrack;if(b!=null&&b.isLoaded)for(a=0;a<b.entries.times.length;a++)if(this.media.currentTime>=b.entries.times[a].start&&
+this.media.currentTime<=b.entries.times[a].stop){this.captionsText.html(b.entries.text[a]);this.captions.show().height(0);return}this.captions.hide()}},setupSlides:function(a){this.slides=a;this.slides.entries.imgs=[this.slides.entries.text.length];this.showSlide(0)},showSlide:function(a){if(!(typeof this.tracks=="undefined"||typeof this.slidesContainer=="undefined")){var b=this,c=b.slides.entries.text[a],d=b.slides.entries.imgs[a];if(typeof d=="undefined"||typeof d.fadeIn=="undefined")b.slides.entries.imgs[a]=
+d=f('<img src="'+c+'">').on("load",function(){d.appendTo(b.slidesContainer).hide().fadeIn().siblings(":visible").fadeOut()});else if(!d.is(":visible")&&!d.is(":animated")){console.log("showing existing slide");d.fadeIn().siblings(":visible").fadeOut()}}},displaySlides:function(){if(typeof this.slides!="undefined"){var a=this.slides,b;for(b=0;b<a.entries.times.length;b++)if(this.media.currentTime>=a.entries.times[b].start&&this.media.currentTime<=a.entries.times[b].stop){this.showSlide(b);break}}},
+displayChapters:function(){var a;for(a=0;a<this.tracks.length;a++)if(this.tracks[a].kind=="chapters"&&this.tracks[a].isLoaded){this.drawChapters(this.tracks[a]);this.hasChapters=true;break}},drawChapters:function(a){var b=this,c,d,e=d=0;b.chapters.empty();for(c=0;c<a.entries.times.length;c++){d=a.entries.times[c].stop-a.entries.times[c].start;d=Math.floor(d/b.media.duration*100);if(d+e>100||c==a.entries.times.length-1&&d+e<100)d=100-e;b.chapters.append(f('<div class="mejs-chapter" rel="'+a.entries.times[c].start+
+'" style="left: '+e.toString()+"%;width: "+d.toString()+'%;"><div class="mejs-chapter-block'+(c==a.entries.times.length-1?" mejs-chapter-block-last":"")+'"><span class="ch-title">'+a.entries.text[c]+'</span><span class="ch-time">'+mejs.Utility.secondsToTimeCode(a.entries.times[c].start)+"&ndash;"+mejs.Utility.secondsToTimeCode(a.entries.times[c].stop)+"</span></div></div>"));e+=d}b.chapters.find("div.mejs-chapter").click(function(){b.media.setCurrentTime(parseFloat(f(this).attr("rel")));b.media.paused&&
+b.media.play()});b.chapters.show()}});mejs.language={codes:{af:"Afrikaans",sq:"Albanian",ar:"Arabic",be:"Belarusian",bg:"Bulgarian",ca:"Catalan",zh:"Chinese","zh-cn":"Chinese Simplified","zh-tw":"Chinese Traditional",hr:"Croatian",cs:"Czech",da:"Danish",nl:"Dutch",en:"English",et:"Estonian",tl:"Filipino",fi:"Finnish",fr:"French",gl:"Galician",de:"German",el:"Greek",ht:"Haitian Creole",iw:"Hebrew",hi:"Hindi",hu:"Hungarian",is:"Icelandic",id:"Indonesian",ga:"Irish",it:"Italian",ja:"Japanese",ko:"Korean",
+lv:"Latvian",lt:"Lithuanian",mk:"Macedonian",ms:"Malay",mt:"Maltese",no:"Norwegian",fa:"Persian",pl:"Polish",pt:"Portuguese",ro:"Romanian",ru:"Russian",sr:"Serbian",sk:"Slovak",sl:"Slovenian",es:"Spanish",sw:"Swahili",sv:"Swedish",tl:"Tagalog",th:"Thai",tr:"Turkish",uk:"Ukrainian",vi:"Vietnamese",cy:"Welsh",yi:"Yiddish"}};mejs.TrackFormatParser={webvvt:{pattern_identifier:/^([a-zA-z]+-)?[0-9]+$/,pattern_timecode:/^([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,
parse:function(a){var b=0;a=mejs.TrackFormatParser.split2(a,/\r?\n/);for(var c={text:[],times:[]},d,e;b<a.length;b++)if(this.pattern_identifier.exec(a[b])){b++;if((d=this.pattern_timecode.exec(a[b]))&&b<a.length){b++;e=a[b];for(b++;a[b]!==""&&b<a.length;){e=e+"\n"+a[b];b++}e=f.trim(e).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,"<a href='$1' target='_blank'>$1</a>");c.text.push(e);c.times.push({start:mejs.Utility.convertSMPTEtoSeconds(d[1])==0?0.2:mejs.Utility.convertSMPTEtoSeconds(d[1]),
stop:mejs.Utility.convertSMPTEtoSeconds(d[3]),settings:d[5]})}}return c}},dfxp:{parse:function(a){a=f(a).filter("tt");var b=0;b=a.children("div").eq(0);var c=b.find("p");b=a.find("#"+b.attr("style"));var d,e;a={text:[],times:[]};if(b.length){e=b.removeAttr("id").get(0).attributes;if(e.length){d={};for(b=0;b<e.length;b++)d[e[b].name.split(":")[1]]=e[b].value}}for(b=0;b<c.length;b++){var g;e={start:null,stop:null,style:null};if(c.eq(b).attr("begin"))e.start=mejs.Utility.convertSMPTEtoSeconds(c.eq(b).attr("begin"));
if(!e.start&&c.eq(b-1).attr("end"))e.start=mejs.Utility.convertSMPTEtoSeconds(c.eq(b-1).attr("end"));if(c.eq(b).attr("end"))e.stop=mejs.Utility.convertSMPTEtoSeconds(c.eq(b).attr("end"));if(!e.stop&&c.eq(b+1).attr("begin"))e.stop=mejs.Utility.convertSMPTEtoSeconds(c.eq(b+1).attr("begin"));if(d){g="";for(var k in d)g+=k+":"+d[k]+";"}if(g)e.style=g;if(e.start==0)e.start=0.2;a.times.push(e);e=f.trim(c.eq(b).html()).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
"<a href='$1' target='_blank'>$1</a>");a.text.push(e);if(a.times.start==0)a.times.start=2}return a}},split2:function(a,b){return a.split(b)}};if("x\n\ny".split(/\n/gi).length!=3)mejs.TrackFormatParser.split2=function(a,b){var c=[],d="",e;for(e=0;e<a.length;e++){d+=a.substring(e,e+1);if(b.test(d)){c.push(d.replace(b,""));d=""}}c.push(d);return c}})(mejs.$);
(function(f){f.extend(mejs.MepDefaults,{contextMenuItems:[{render:function(a){if(typeof a.enterFullScreen=="undefined")return null;return a.isFullScreen?"Turn off Fullscreen":"Go Fullscreen"},click:function(a){a.isFullScreen?a.exitFullScreen():a.enterFullScreen()}},{render:function(a){return a.media.muted?"Unmute":"Mute"},click:function(a){a.media.muted?a.setMuted(false):a.setMuted(true)}},{isSeparator:true},{render:function(){return"Download Video"},click:function(a){window.location.href=a.media.currentSrc}}]});
-f.extend(MediaElementPlayer.prototype,{buildcontextmenu:function(a){a.contextMenu=f('<div class="mejs-contextmenu"></div>').appendTo(f("body")).hide();a.container.bind("contextmenu",function(b){if(a.isContextMenuEnabled){b.preventDefault();a.renderContextMenu(b.clientX-1,b.clientY-1);return false}});a.container.bind("click",function(){a.contextMenu.hide()});a.contextMenu.bind("mouseleave",function(){a.startContextMenuTimer()})},isContextMenuEnabled:true,enableContextMenu:function(){this.isContextMenuEnabled=
-true},disableContextMenu:function(){this.isContextMenuEnabled=false},contextMenuTimeout:null,startContextMenuTimer:function(){var a=this;a.killContextMenuTimer();a.contextMenuTimer=setTimeout(function(){a.hideContextMenu();a.killContextMenuTimer()},750)},killContextMenuTimer:function(){var a=this.contextMenuTimer;if(a!=null){clearTimeout(a);delete a}},hideContextMenu:function(){this.contextMenu.hide()},renderContextMenu:function(a,b){for(var c=this,d="",e=c.options.contextMenuItems,g=0,k=e.length;g<
-k;g++)if(e[g].isSeparator)d+='<div class="mejs-contextmenu-separator"></div>';else{var h=e[g].render(c);if(h!=null)d+='<div class="mejs-contextmenu-item" data-itemindex="'+g+'" id="element-'+Math.random()*1E6+'">'+h+"</div>"}c.contextMenu.empty().append(f(d)).css({top:b,left:a}).show();c.contextMenu.find(".mejs-contextmenu-item").each(function(){var o=f(this),n=parseInt(o.data("itemindex"),10),p=c.options.contextMenuItems[n];typeof p.show!="undefined"&&p.show(o,c);o.click(function(){typeof p.click!=
-"undefined"&&p.click(c);c.contextMenu.hide()})});setTimeout(function(){c.killControlsTimer("rev3")},100)}})})(mejs.$);
+f.extend(MediaElementPlayer.prototype,{buildcontextmenu:function(a){a.contextMenu=f('<div class="mejs-contextmenu"></div>').appendTo(f("body")).hide();a.container.bind("contextmenu",function(b){if(a.isContextMenuEnabled){b.preventDefault();a.renderContextMenu(b.clientX-1,b.clientY-1);return false}});a.container.bind("click",function(){a.contextMenu.hide()});a.contextMenu.bind("mouseleave",function(){a.startContextMenuTimer()})},cleancontextmenu:function(a){a.contextMenu.remove()},isContextMenuEnabled:true,
+enableContextMenu:function(){this.isContextMenuEnabled=true},disableContextMenu:function(){this.isContextMenuEnabled=false},contextMenuTimeout:null,startContextMenuTimer:function(){var a=this;a.killContextMenuTimer();a.contextMenuTimer=setTimeout(function(){a.hideContextMenu();a.killContextMenuTimer()},750)},killContextMenuTimer:function(){var a=this.contextMenuTimer;if(a!=null){clearTimeout(a);delete a}},hideContextMenu:function(){this.contextMenu.hide()},renderContextMenu:function(a,b){for(var c=
+this,d="",e=c.options.contextMenuItems,g=0,k=e.length;g<k;g++)if(e[g].isSeparator)d+='<div class="mejs-contextmenu-separator"></div>';else{var j=e[g].render(c);if(j!=null)d+='<div class="mejs-contextmenu-item" data-itemindex="'+g+'" id="element-'+Math.random()*1E6+'">'+j+"</div>"}c.contextMenu.empty().append(f(d)).css({top:b,left:a}).show();c.contextMenu.find(".mejs-contextmenu-item").each(function(){var l=f(this),q=parseInt(l.data("itemindex"),10),p=c.options.contextMenuItems[q];typeof p.show!="undefined"&&
+p.show(l,c);l.click(function(){typeof p.click!="undefined"&&p.click(c);c.contextMenu.hide()})});setTimeout(function(){c.killControlsTimer("rev3")},100)}})})(mejs.$);
(function(f){f.extend(mejs.MepDefaults,{postrollCloseText:mejs.i18n.t("Close")});f.extend(MediaElementPlayer.prototype,{buildpostroll:function(a,b,c){var d=this.container.find('link[rel="postroll"]').attr("href");if(typeof d!=="undefined"){a.postroll=f('<div class="mejs-postroll-layer mejs-layer"><a class="mejs-postroll-close" onclick="$(this).parent().hide();return false;">'+this.options.postrollCloseText+'</a><div class="mejs-postroll-layer-content"></div></div>').prependTo(c).hide();this.media.addEventListener("ended",
function(){f.ajax({dataType:"html",url:d,success:function(e){c.find(".mejs-postroll-layer-content").html(e)}});a.postroll.show()},false)}}})})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/Builder.py b/files_videoviewer/mediaelement/src/Builder.py
index e5b2804e5..d65f0df27 100755
--- a/files_videoviewer/mediaelement/src/Builder.py
+++ b/files_videoviewer/mediaelement/src/Builder.py
@@ -19,6 +19,7 @@ me_files.append('me-mediaelements.js')
me_files.append('me-shim.js')
me_files.append('me-i18n.js')
me_files.append('me-i18n-locale-de.js')
+me_files.append('me-i18n-locale-zh.js')
code = ''
diff --git a/files_videoviewer/mediaelement/src/compiler.jar b/files_videoviewer/mediaelement/src/compiler.jar
index 4dfa5ad0b..4dfa5ad0b 100644..100755
--- a/files_videoviewer/mediaelement/src/compiler.jar
+++ b/files_videoviewer/mediaelement/src/compiler.jar
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/background.png b/files_videoviewer/mediaelement/src/css/background.png
index fd428412a..fd428412a 100644..100755
--- a/files_videoviewer/mediaelement/src/css/background.png
+++ b/files_videoviewer/mediaelement/src/css/background.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/bigplay.fw.png b/files_videoviewer/mediaelement/src/css/bigplay.fw.png
index 66d0e3cb7..66d0e3cb7 100644..100755
--- a/files_videoviewer/mediaelement/src/css/bigplay.fw.png
+++ b/files_videoviewer/mediaelement/src/css/bigplay.fw.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/bigplay.png b/files_videoviewer/mediaelement/src/css/bigplay.png
index 694553e31..694553e31 100644..100755
--- a/files_videoviewer/mediaelement/src/css/bigplay.png
+++ b/files_videoviewer/mediaelement/src/css/bigplay.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/bigplay.svg b/files_videoviewer/mediaelement/src/css/bigplay.svg
index c2f62bbc0..c2f62bbc0 100644..100755
--- a/files_videoviewer/mediaelement/src/css/bigplay.svg
+++ b/files_videoviewer/mediaelement/src/css/bigplay.svg
diff --git a/files_videoviewer/mediaelement/src/css/controls-ted.png b/files_videoviewer/mediaelement/src/css/controls-ted.png
index 3aac05aa8..3aac05aa8 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls-ted.png
+++ b/files_videoviewer/mediaelement/src/css/controls-ted.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/controls-wmp-bg.png b/files_videoviewer/mediaelement/src/css/controls-wmp-bg.png
index 89bb9b956..89bb9b956 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls-wmp-bg.png
+++ b/files_videoviewer/mediaelement/src/css/controls-wmp-bg.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/controls-wmp.png b/files_videoviewer/mediaelement/src/css/controls-wmp.png
index 4775ef5b0..4775ef5b0 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls-wmp.png
+++ b/files_videoviewer/mediaelement/src/css/controls-wmp.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/controls.fw.png b/files_videoviewer/mediaelement/src/css/controls.fw.png
index e27682ae1..e27682ae1 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls.fw.png
+++ b/files_videoviewer/mediaelement/src/css/controls.fw.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/controls.png b/files_videoviewer/mediaelement/src/css/controls.png
index f6a857d80..f6a857d80 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls.png
+++ b/files_videoviewer/mediaelement/src/css/controls.png
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/controls.svg b/files_videoviewer/mediaelement/src/css/controls.svg
index af3bd4160..af3bd4160 100644..100755
--- a/files_videoviewer/mediaelement/src/css/controls.svg
+++ b/files_videoviewer/mediaelement/src/css/controls.svg
diff --git a/files_videoviewer/mediaelement/src/css/loading.gif b/files_videoviewer/mediaelement/src/css/loading.gif
index 612222be5..612222be5 100644..100755
--- a/files_videoviewer/mediaelement/src/css/loading.gif
+++ b/files_videoviewer/mediaelement/src/css/loading.gif
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/css/mediaelementplayer.css b/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
index 8b9116ac2..8b9116ac2 100644..100755
--- a/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
+++ b/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
diff --git a/files_videoviewer/mediaelement/src/css/mejs-skins.css b/files_videoviewer/mediaelement/src/css/mejs-skins.css
index 814b9d4f0..814b9d4f0 100644..100755
--- a/files_videoviewer/mediaelement/src/css/mejs-skins.css
+++ b/files_videoviewer/mediaelement/src/css/mejs-skins.css
diff --git a/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as b/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as
index 6ae93e7b7..46899894c 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as
+++ b/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as
@@ -1 +1 @@
-package { import flash.display.*; import flash.events.*; import flash.media.*; import flash.net.*; import flash.text.*; import flash.system.*; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.geom.ColorTransform; import flash.filters.DropShadowFilter; import flash.utils.Timer; import flash.external.ExternalInterface; import flash.geom.Rectangle; import htmlelements.IMediaElement; import htmlelements.VideoElement; import htmlelements.AudioElement; import htmlelements.YouTubeElement; public class FlashMediaElement extends MovieClip { private var _mediaUrl:String; private var _autoplay:Boolean; private var _preload:String; private var _debug:Boolean; private var _isVideo:Boolean; private var _video:DisplayObject; private var _timerRate:Number; private var _stageWidth:Number; private var _stageHeight:Number; private var _enableSmoothing:Boolean; private var _allowedPluginDomain:String; private var _isFullScreen:Boolean = false; private var _startVolume:Number; private var _controlStyle:String; private var _autoHide:Boolean = true; private var _streamer:String = ""; // native video size (from meta data) private var _nativeVideoWidth:Number = 0; private var _nativeVideoHeight:Number = 0; // visual elements private var _output:TextField; private var _fullscreenButton:SimpleButton; // media private var _mediaElement:IMediaElement; // connection to fullscreen private var _connection:LocalConnection; private var _connectionName:String; //private var fullscreen_btn:SimpleButton; // CONTROLS private var _alwaysShowControls:Boolean; private var _controlBar:MovieClip; private var _controlBarBg:MovieClip; private var _scrubBar:MovieClip; private var _scrubTrack:MovieClip; private var _scrubOverlay:MovieClip; private var _scrubLoaded:MovieClip; private var _hoverTime:MovieClip; private var _hoverTimeText:TextField; private var _playButton:SimpleButton; private var _pauseButton:SimpleButton; private var _duration:TextField; private var _currentTime:TextField; private var _fullscreenIcon:SimpleButton; private var _volumeMuted:SimpleButton; private var _volumeUnMuted:SimpleButton; private var _scrubTrackColor:String; private var _scrubBarColor:String; private var _scrubLoadedColor:String; // IDLE Timer for mouse for showing/hiding controls private var _inactiveTime:int; private var _timer:Timer; private var _idleTime:int; private var _isMouseActive:Boolean private var _isOverStage:Boolean = false; public function FlashMediaElement() { // show allow this player to be called from a different domain than the HTML page hosting the player Security.allowDomain("*"); // get parameters var params:Object = LoaderInfo(this.root.loaderInfo).parameters; _mediaUrl = (params['file'] != undefined) ? String(params['file']) : ""; _autoplay = (params['autoplay'] != undefined) ? (String(params['autoplay']) == "true") : false; _debug = (params['debug'] != undefined) ? (String(params['debug']) == "true") : false; _isVideo = (params['isvideo'] != undefined) ? ((String(params['isvideo']) == "false") ? false : true ) : true; _timerRate = (params['timerrate'] != undefined) ? (parseInt(params['timerrate'], 10)) : 250; _alwaysShowControls = (params['controls'] != undefined) ? (String(params['controls']) == "true") : false; _enableSmoothing = (params['smoothing'] != undefined) ? (String(params['smoothing']) == "true") : false; _startVolume = (params['startvolume'] != undefined) ? (parseFloat(params['startvolume'])) : 0.8; _preload = (params['preload'] != undefined) ? params['preload'] : "none"; _controlStyle = (params['controlstyle'] != undefined) ? (String(params['controlstyle'])) : ""; // blank or "floating" _autoHide = (params['autohide'] != undefined) ? (String(params['autohide'])) : true; _scrubTrackColor = (params['scrubtrackcolor'] != undefined) ? (String(params['scrubtrackcolor'])) : "0x333333"; _scrubBarColor = (params['scrubbarcolor'] != undefined) ? (String(params['scrubbarcolor'])) : "0xefefef"; _scrubLoadedColor = (params['scrubloadedcolor'] != undefined) ? (String(params['scrubloadedcolor'])) : "0x3CACC8"; _streamer = (params['flashstreamer'] != undefined) ? (String(params['flashstreamer'])) : ""; if (isNaN(_timerRate)) _timerRate = 250; // setup stage and player sizes/scales stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; _stageWidth = stage.stageWidth; _stageHeight = stage.stageHeight; //_autoplay = true; //_mediaUrl = "http://mediafiles.dts.edu/chapel/mp4/20100609.mp4"; //_alwaysShowControls = true; //_mediaUrl = "../media/Parades-PastLives.mp3"; //_mediaUrl = "../media/echo-hereweare.mp4"; //_mediaUrl = "http://video.ted.com/talks/podcast/AlGore_2006_480.mp4"; //_mediaUrl = "rtmp://stream2.france24.yacast.net/france24_live/en/f24_liveen"; //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0"; // hosea //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=m5VDDJlsD6I"; // railer with notes //_alwaysShowControls = true; //_debug=true; // debugging _output = new TextField(); _output.textColor = 0xeeeeee; _output.width = stage.stageWidth - 100; _output.height = stage.stageHeight; _output.multiline = true; _output.wordWrap = true; _output.border = false; _output.filters = [new DropShadowFilter(1, 0x000000, 45, 1, 2, 2, 1)]; _output.text = "Initializing...\n"; addChild(_output); _output.visible = _debug; // position and hide _fullscreenButton = getChildByName("fullscreen_btn") as SimpleButton; //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _fullscreenButton.addEventListener(MouseEvent.CLICK, fullscreenClick, false); _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; // create media element if (_isVideo) { if (_mediaUrl.indexOf("youtube.com") > -1 || _mediaUrl.indexOf("youtu.be") > -1) { //Security.allowDomain("http://www.youtube.com"); _mediaElement = new YouTubeElement(this, _autoplay, _preload, _timerRate, _startVolume); _video = (_mediaElement as YouTubeElement).player; // these are set and then used once the player is loaded (_mediaElement as YouTubeElement).initWidth = _stageWidth; (_mediaElement as YouTubeElement).initHeight = _stageHeight; } else { _mediaElement = new VideoElement(this, _autoplay, _preload, _timerRate, _startVolume, _streamer); _video = (_mediaElement as VideoElement).video; _video.width = _stageWidth; _video.height = _stageHeight; (_video as Video).smoothing = _enableSmoothing; (_mediaElement as VideoElement).setReference(this); //_video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; addChild(_video); } } else { //var player2:AudioDecoder = new com.automatastudios.audio.audiodecoder.AudioDecoder(); _mediaElement = new AudioElement(this, _autoplay, _preload, _timerRate, _startVolume); } // controls! _controlBar = getChildByName("controls_mc") as MovieClip; _controlBarBg = _controlBar.getChildByName("controls_bg_mc") as MovieClip; _scrubTrack = _controlBar.getChildByName("scrubTrack") as MovieClip; _scrubBar = _controlBar.getChildByName("scrubBar") as MovieClip; _scrubOverlay = _controlBar.getChildByName("scrubOverlay") as MovieClip; _scrubLoaded = _controlBar.getChildByName("scrubLoaded") as MovieClip; _scrubOverlay.buttonMode = true; _scrubOverlay.useHandCursor = true applyColor(_scrubTrack, _scrubTrackColor); applyColor(_scrubBar, _scrubBarColor); applyColor(_scrubLoaded, _scrubLoadedColor); _fullscreenIcon = _controlBar.getChildByName("fullscreenIcon") as SimpleButton; // New fullscreenIcon for new fullscreen floating controls //if(_alwaysShowControls && _controlStyle.toUpperCase()=="FLOATING") { _fullscreenIcon.addEventListener(MouseEvent.CLICK, fullScreenIconClick, false); //} _volumeMuted = _controlBar.getChildByName("muted_mc") as SimpleButton; _volumeUnMuted = _controlBar.getChildByName("unmuted_mc") as SimpleButton; _volumeMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _volumeUnMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _playButton = _controlBar.getChildByName("play_btn") as SimpleButton; _playButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.play(); }); _pauseButton = _controlBar.getChildByName("pause_btn") as SimpleButton; _pauseButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.pause(); }); _pauseButton.visible = false; _duration = _controlBar.getChildByName("duration_txt") as TextField; _currentTime = _controlBar.getChildByName("currentTime_txt") as TextField; _hoverTime = _controlBar.getChildByName("hoverTime") as MovieClip; _hoverTimeText = _hoverTime.getChildByName("hoverTime_txt") as TextField; _hoverTime.visible=false; _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; // Add new timeline scrubber events _scrubOverlay.addEventListener(MouseEvent.MOUSE_MOVE, scrubMove); _scrubOverlay.addEventListener(MouseEvent.CLICK, scrubClick); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OVER, scrubOver); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OUT, scrubOut); if (_autoHide) { // && _alwaysShowControls) { // Add mouse activity for show/hide of controls stage.addEventListener(Event.MOUSE_LEAVE, mouseActivityLeave); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseActivityMove); _inactiveTime = 2500; _timer = new Timer(_inactiveTime) _timer.addEventListener(TimerEvent.TIMER, idleTimer); _timer.start(); // set } if(_alwaysShowControls) { if(_startVolume<=0) { trace("INITIAL VOLUME: "+_startVolume+" MUTED"); _volumeMuted.visible=true; _volumeUnMuted.visible=false; } else { trace("INITIAL VOLUME: "+_startVolume+" UNMUTED"); _volumeMuted.visible=false; _volumeUnMuted.visible=true; } } _controlBar.visible = _alwaysShowControls; setControlDepth(); _output.appendText("stage: " + stage.stageWidth + "x" + stage.stageHeight + "\n"); _output.appendText("file: " + _mediaUrl + "\n"); _output.appendText("autoplay: " + _autoplay.toString() + "\n"); _output.appendText("preload: " + _preload.toString() + "\n"); _output.appendText("isvideo: " + _isVideo.toString() + "\n"); _output.appendText("smoothing: " + _enableSmoothing.toString() + "\n"); _output.appendText("timerrate: " + _timerRate.toString() + "\n"); _output.appendText("displayState: " +(stage.hasOwnProperty("displayState")).toString() + "\n"); // attach javascript _output.appendText("ExternalInterface.available: " + ExternalInterface.available.toString() + "\n"); _output.appendText("ExternalInterface.objectID: " + ((ExternalInterface.objectID != null)? ExternalInterface.objectID.toString() : "null") + "\n"); if (_mediaUrl != "") { _mediaElement.setSrc(_mediaUrl); } positionControls(); // Fire this once just to set the width on some dynamically sized scrub bar items; _scrubBar.scaleX=0; _scrubLoaded.scaleX=0; if (ExternalInterface.available) { // && !_alwaysShowControls _output.appendText("Adding callbacks...\n"); try { if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { // add HTML media methods ExternalInterface.addCallback("playMedia", playMedia); ExternalInterface.addCallback("loadMedia", loadMedia); ExternalInterface.addCallback("pauseMedia", pauseMedia); ExternalInterface.addCallback("stopMedia", stopMedia); ExternalInterface.addCallback("setSrc", setSrc); ExternalInterface.addCallback("setCurrentTime", setCurrentTime); ExternalInterface.addCallback("setVolume", setVolume); ExternalInterface.addCallback("setMuted", setMuted); ExternalInterface.addCallback("setFullscreen", setFullscreen); ExternalInterface.addCallback("setVideoSize", setVideoSize); ExternalInterface.addCallback("positionFullscreenButton", positionFullscreenButton); ExternalInterface.addCallback("hideFullscreenButton", hideFullscreenButton); // fire init method ExternalInterface.call("mejs.MediaPluginBridge.initPlugin", ExternalInterface.objectID); } _output.appendText("Success...\n"); } catch (error:SecurityError) { _output.appendText("A SecurityError occurred: " + error.message + "\n"); } catch (error:Error) { _output.appendText("An Error occurred: " + error.message + "\n"); } } if (_preload != "none") { _mediaElement.load(); if (_autoplay) { _mediaElement.play(); } } else if (_autoplay) { _mediaElement.load(); _mediaElement.play(); } // listen for resize stage.addEventListener(Event.RESIZE, resizeHandler); // test stage.addEventListener(MouseEvent.MOUSE_DOWN, stageClicked); // resize stage.addEventListener(FullScreenEvent.FULL_SCREEN, stageFullScreenChanged); } public function setControlDepth():void { // put these on top addChild(_output); addChild(_controlBar); addChild(_fullscreenButton); } // START: Controls and events function mouseActivityMove(event:MouseEvent):void { // if mouse is in the video area if (_autoHide && (mouseX>=0 && mouseX<=stage.stageWidth) && (mouseY>=0 && mouseY<=stage.stageHeight)) { // This could be move to a nice fade at some point... _controlBar.visible = (_alwaysShowControls || _isFullScreen); _isMouseActive = true; _idleTime = 0; _timer.reset(); _timer.start() } } function mouseActivityLeave(event:Event):void { if (_autoHide) { _isOverStage = false; // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime = 0; _timer.reset(); _timer.stop(); } } function idleTimer(event:TimerEvent):void { if (_autoHide) { // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime += _inactiveTime; _idleTime = 0; _timer.reset(); _timer.stop(); } } function scrubMove(event:MouseEvent):void { //if (_alwaysShowControls) { if (_hoverTime.visible) { var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var hoverPos:Number = (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; if (_isFullScreen) { _hoverTime.x=event.target.parent.mouseX; } else { _hoverTime.x=mouseX; } _hoverTime.y = _scrubBar.y - (_hoverTime.height/2); _hoverTimeText.text = secondsToTimeCode(seekBarPosition); } //} //trace(event); } function scrubOver(event:MouseEvent):void { _hoverTime.y = _scrubBar.y-(_hoverTime.height/2)+1; _hoverTime.visible = true; trace(event); } function scrubOut(event:MouseEvent):void { _hoverTime.y = _scrubBar.y+(_hoverTime.height/2)+1; _hoverTime.visible = false; //_hoverTime.x=0; //trace(event); } function scrubClick(event:MouseEvent):void { //trace(event); var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var tmp:Number = (_mediaElement.currentTime()/_mediaElement.duration())*_scrubTrack.width; var canSeekToPosition:Boolean = _scrubLoaded.scaleX > (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; //var canSeekToPosition:Boolean = true; /* amountLoaded = ns.bytesLoaded / ns.bytesTotal; loader.loadbar._width = amountLoaded * 208.9; loader.scrub._x = ns.time / duration * 208.9; */ trace("seekBarPosition:"+seekBarPosition, "CanSeekToPosition: "+canSeekToPosition); if (seekBarPosition>0 && seekBarPosition<_mediaElement.duration() && canSeekToPosition) { _mediaElement.setCurrentTime(seekBarPosition); } } function toggleVolume(event:MouseEvent):void { trace(event.currentTarget.name); switch(event.currentTarget.name) { case "muted_mc": setMuted(false); break; case "unmuted_mc": setMuted(true); break; } } function toggleVolumeIcons(volume:Number) { if(volume<=0) { _volumeMuted.visible = true; _volumeUnMuted.visible = false; } else { _volumeMuted.visible = false; _volumeUnMuted.visible = true; } } public function positionControls(forced:Boolean=false) { if ( _controlStyle.toUpperCase() == "FLOATING" && _isFullScreen) { trace("CONTROLS: floating"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = 300; _controlBarBg.height = 93; //_controlBarBg.x = (stage.stageWidth/2) - (_controlBarBg.width/2); //_controlBarBg.y = stage.stageHeight - 300; _pauseButton.scaleX = _playButton.scaleX=3.5; _pauseButton.scaleY= _playButton.scaleY=3.5; // center the play button and make it big and at the top _pauseButton.x = _playButton.x = (_controlBarBg.width/2)-(_playButton.width/2)+7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-(14) _controlBar.x = (stage.stageWidth/2) -150; _controlBar.y = stage.stageHeight - _controlBar.height-100; // reposition the time and duration items _duration.x = _controlBarBg.width - _duration.width - 10; _duration.y = _controlBarBg.height - _duration.height -7; //_currentTime.x = _controlBarBg.width - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = 5 _currentTime.y= _controlBarBg.height - _currentTime.height-7; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 7; _volumeMuted.x = _volumeUnMuted.x = 7; _volumeMuted.y = _volumeUnMuted.y = 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x =_currentTime.x+_currentTime.width+7; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y=_controlBarBg.height-_scrubTrack.height-10; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-14); } else { trace("CONTROLS: normal, original"); /* // Original style bottom display _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBar.y = stage.stageHeight - _controlBar.height; _duration.x = stage.stageWidth - _duration.width - 10; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+10; _scrubOverlay.width = _scrubTrack.width; _scrubBar.width = _scrubTrack.width; */ // FLOATING MODE BOTTOM DISPLAY - similar to normal trace("THAT WAY!"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBarBg.height = 30; _controlBarBg.y=0; _controlBarBg.x=0; // _controlBarBg.x = 0; // _controlBarBg.y = stage.stageHeight - _controlBar.height; _pauseButton.scaleX = _playButton.scaleX=1; _pauseButton.scaleY = _playButton.scaleY=1; _pauseButton.x = _playButton.x = 7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-2; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 8; _volumeMuted.x = _volumeUnMuted.x = _fullscreenIcon.x - _volumeMuted.width - 10; _volumeMuted.y = _volumeUnMuted.y = 10; _duration.x = _volumeMuted.x - _volumeMuted.width - _duration.width + 5; _duration.y = _currentTime.y = _controlBarBg.height - _currentTime.height - 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x = _currentTime.x + _currentTime.width + 10; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y = _controlBarBg.height - _scrubTrack.height - 9; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+5; _controlBar.x = 0; _controlBar.y = stage.stageHeight - _controlBar.height; } } // END: Controls function stageClicked(e:MouseEvent):void { //_output.appendText("click: " + e.stageX.toString() +","+e.stageY.toString() + "\n"); sendEvent("click", ""); } function resizeHandler(e:Event):void { //_video.scaleX = stage.stageWidth / _stageWidth; //_video.scaleY = stage.stageHeight / _stageHeight; //positionControls(); repositionVideo(); } // START: Fullscreen function enterFullscreen() { _output.appendText("enterFullscreen()\n"); var screenRectangle:Rectangle = new Rectangle(0, 0, flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); stage.fullScreenSourceRect = screenRectangle; stage.displayState = StageDisplayState.FULL_SCREEN; repositionVideo(true); positionControls(); updateControls(HtmlMediaEvent.FULLSCREENCHANGE); _controlBar.visible = true; _isFullScreen = true; } function exitFullscreen() { stage.displayState = StageDisplayState.NORMAL; _controlBar.visible = false; _isFullScreen = false; } function setFullscreen(gofullscreen:Boolean) { _output.appendText("setFullscreen: " + gofullscreen.toString() + "\n"); try { //_fullscreenButton.visible = false; if (gofullscreen) { enterFullscreen(); } else { exitFullscreen(); } } catch (error:Error) { // show the button when the security error doesn't let it work //_fullscreenButton.visible = true; _fullscreenButton.alpha = 1; _isFullScreen = false; _output.appendText("error setting fullscreen: " + error.message.toString() + "\n"); } } // control bar button/icon function fullScreenIconClick(e:MouseEvent) { try { _controlBar.visible = true; setFullscreen(!_isFullScreen); repositionVideo(_isFullScreen); } catch (error:Error) { } } // special floating fullscreen icon function fullscreenClick(e:MouseEvent) { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0 try { _controlBar.visible = true; setFullscreen(true); repositionVideo(true); positionControls(); } catch (error:Error) { } } function stageFullScreenChanged(e:FullScreenEvent) { _output.appendText("fullscreen event: " + e.fullScreen.toString() + "\n"); //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _isFullScreen = e.fullScreen; sendEvent(HtmlMediaEvent.FULLSCREENCHANGE, "isFullScreen:" + e.fullScreen ); if (!e.fullScreen) { _controlBar.visible = _alwaysShowControls; } } // END: Fullscreen // START: external interface function playMedia() { _output.appendText("play\n"); _mediaElement.play(); } function loadMedia() { _output.appendText("load\n"); _mediaElement.load(); } function pauseMedia() { _output.appendText("pause\n"); _mediaElement.pause(); } function setSrc(url:String) { _output.appendText("setSrc: " + url + "\n"); _mediaElement.setSrc(url); } function stopMedia() { _output.appendText("stop\n"); _mediaElement.stop(); } function setCurrentTime(time:Number) { _output.appendText("seek: " + time.toString() + "\n"); _mediaElement.setCurrentTime(time); } function setVolume(volume:Number) { _output.appendText("volume: " + volume.toString() + "\n"); _mediaElement.setVolume(volume); toggleVolumeIcons(volume); } function setMuted(muted:Boolean) { _output.appendText("muted: " + muted.toString() + "\n"); _mediaElement.setMuted(muted); toggleVolumeIcons(_mediaElement.getVolume()); } function setVideoSize(width:Number, height:Number) { _output.appendText("setVideoSize: " + width.toString() + "," + height.toString() + "\n"); _stageWidth = width; _stageHeight = height; if (_video != null) { repositionVideo(); positionControls(); //_fullscreenButton.x = stage.stageWidth - _fullscreenButton.width - 10; _output.appendText("result: " + _video.width.toString() + "," + _video.height.toString() + "\n"); } } function positionFullscreenButton(x:Number, y:Number, visibleAndAbove:Boolean ) { _output.appendText("position FS: " + x.toString() + "x" + y.toString() + "\n"); // bottom corner /* _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; */ // position just above if (visibleAndAbove) { _fullscreenButton.x = x+1; _fullscreenButton.y = y - _fullscreenButton.height+1; } else { _fullscreenButton.x = x; _fullscreenButton.y = y; } // check for oversizing if ((_fullscreenButton.x + _fullscreenButton.width) > stage.stageWidth) _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; // show it! if (visibleAndAbove) { _fullscreenButton.alpha = 1; } } function hideFullscreenButton() { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; } // END: external interface function repositionVideo(fullscreen:Boolean = false):void { _output.appendText("positioning video\n"); if (_mediaElement is VideoElement) { if (isNaN(_nativeVideoWidth) || isNaN(_nativeVideoHeight) || _nativeVideoWidth <= 0 || _nativeVideoHeight <= 0) { _output.appendText("ERR: I dont' have the native dimension\n"); return; } // calculate ratios var stageRatio, nativeRatio; _video.x = 0; _video.y = 0; if(fullscreen == true) { stageRatio = flash.system.Capabilities.screenResolutionX/flash.system.Capabilities.screenResolutionY; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, _nativeVideoHeight * flash.system.Capabilities.screenResolutionX / _nativeVideoWidth); _video.y = flash.system.Capabilities.screenResolutionY/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize(_nativeVideoWidth * flash.system.Capabilities.screenResolutionY / _nativeVideoHeight, flash.system.Capabilities.screenResolutionY); _video.x = flash.system.Capabilities.screenResolutionX/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } } else { stageRatio = _stageWidth/_stageHeight; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(_stageWidth, _nativeVideoHeight * _stageWidth / _nativeVideoWidth); _video.y = _stageHeight/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize( _nativeVideoWidth * _stageHeight / _nativeVideoHeight, _stageHeight); _video.x = _stageWidth/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(_stageWidth, _stageHeight); } } } else if (_mediaElement is YouTubeElement) { if(fullscreen == true) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } else { _mediaElement.setSize(_stageWidth, _stageHeight); } } positionControls(); } // SEND events to JavaScript public function sendEvent(eventName:String, eventValues:String) { // special video event if (eventName == HtmlMediaEvent.LOADEDMETADATA && _isVideo) { _output.appendText("METADATA RECEIVED: "); try { if (_mediaElement is VideoElement) { _nativeVideoWidth = (_mediaElement as VideoElement).videoWidth; _nativeVideoHeight = (_mediaElement as VideoElement).videoHeight; } } catch (e:Error) { _output.appendText(e.toString() + "\n"); } _output.appendText(_nativeVideoWidth.toString() + "x" + _nativeVideoHeight.toString() + "\n"); if(stage.displayState == "fullScreen" ) { setVideoSize(_nativeVideoWidth, _nativeVideoHeight); repositionVideo(true); } else { repositionVideo(); } } updateControls(eventName); //trace((_mediaElement.duration()*1).toString() + " / " + (_mediaElement.currentTime()*1).toString()); //trace("CurrentProgress:"+_mediaElement.currentProgress()); if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { //_output.appendText("event:" + eventName + " : " + eventValues); //trace("event", eventName, eventValues); if (eventValues == null) eventValues == ""; if (_isVideo) { eventValues += (eventValues != "" ? "," : "") + "isFullScreen:" + _isFullScreen; } eventValues = "{" + eventValues + "}"; /* OLD DIRECT METHOD ExternalInterface.call( "function(id, name) { mejs.MediaPluginBridge.fireEvent(id,name," + eventValues + "); }", ExternalInterface.objectID, eventName); */ // use set timeout for performance reasons //if (!_alwaysShowControls) { ExternalInterface.call("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + ExternalInterface.objectID + "','" + eventName + "'," + eventValues + ")",0); //} } } function updateControls(eventName:String):void { //trace("updating controls"); try { // update controls switch (eventName) { case "pause": case "paused": case "ended": _playButton.visible = true; _pauseButton.visible = false; break; case "play": case "playing": _playButton.visible = false; _pauseButton.visible = true; break; } if (eventName == HtmlMediaEvent.TIMEUPDATE || eventName == HtmlMediaEvent.PROGRESS || eventName == HtmlMediaEvent.FULLSCREENCHANGE) { //_duration.text = (_mediaElement.duration()*1).toString(); _duration.text = secondsToTimeCode(_mediaElement.duration()); //_currentTime.text = (_mediaElement.currentTime()*1).toString(); _currentTime.text = secondsToTimeCode(_mediaElement.currentTime()); var pct:Number = (_mediaElement.currentTime() / _mediaElement.duration()) *_scrubTrack.scaleX; _scrubBar.scaleX = pct; _scrubLoaded.scaleX = (_mediaElement.currentProgress()*_scrubTrack.scaleX)/100; } } catch (error:Error) { trace("error: " + error.toString()); } } // START: utility function secondsToTimeCode(seconds:Number):String { var timeCode:String = ""; seconds = Math.round(seconds); var minutes:Number = Math.floor(seconds / 60); timeCode = (minutes >= 10) ? minutes.toString() : "0" + minutes.toString(); seconds = Math.floor(seconds % 60); timeCode += ":" + ((seconds >= 10) ? seconds.toString() : "0" + seconds.toString()); return timeCode; //minutes.toString() + ":" + seconds.toString(); } function applyColor(item:Object, color:String):void { var myColor:ColorTransform = item.transform.colorTransform; myColor.color = Number(color); item.transform.colorTransform = myColor; } // END: utility } } \ No newline at end of file
+package { import flash.display.*; import flash.events.*; import flash.media.*; import flash.net.*; import flash.text.*; import flash.system.*; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.geom.ColorTransform; import flash.filters.DropShadowFilter; import flash.utils.Timer; import flash.external.ExternalInterface; import flash.geom.Rectangle; import htmlelements.IMediaElement; import htmlelements.VideoElement; import htmlelements.AudioElement; import htmlelements.YouTubeElement; public class FlashMediaElement extends MovieClip { private var _mediaUrl:String; private var _autoplay:Boolean; private var _preload:String; private var _debug:Boolean; private var _isVideo:Boolean; private var _video:DisplayObject; private var _timerRate:Number; private var _stageWidth:Number; private var _stageHeight:Number; private var _enableSmoothing:Boolean; private var _allowedPluginDomain:String; private var _isFullScreen:Boolean = false; private var _startVolume:Number; private var _controlStyle:String; private var _autoHide:Boolean = true; private var _streamer:String = ""; private var _enablePseudoStreaming:Boolean; private var _pseudoStreamingStartQueryParam:String; // native video size (from meta data) private var _nativeVideoWidth:Number = 0; private var _nativeVideoHeight:Number = 0; // visual elements private var _output:TextField; private var _fullscreenButton:SimpleButton; // media private var _mediaElement:IMediaElement; // connection to fullscreen private var _connection:LocalConnection; private var _connectionName:String; //private var fullscreen_btn:SimpleButton; // CONTROLS private var _alwaysShowControls:Boolean; private var _controlBar:MovieClip; private var _controlBarBg:MovieClip; private var _scrubBar:MovieClip; private var _scrubTrack:MovieClip; private var _scrubOverlay:MovieClip; private var _scrubLoaded:MovieClip; private var _hoverTime:MovieClip; private var _hoverTimeText:TextField; private var _playButton:SimpleButton; private var _pauseButton:SimpleButton; private var _duration:TextField; private var _currentTime:TextField; private var _fullscreenIcon:SimpleButton; private var _volumeMuted:SimpleButton; private var _volumeUnMuted:SimpleButton; private var _scrubTrackColor:String; private var _scrubBarColor:String; private var _scrubLoadedColor:String; // IDLE Timer for mouse for showing/hiding controls private var _inactiveTime:int; private var _timer:Timer; private var _idleTime:int; private var _isMouseActive:Boolean private var _isOverStage:Boolean = false; // security checkes private var securityIssue:Boolean = false; // When SWF parameters contain illegal characters private var directAccess:Boolean = false; // When SWF visited directly with no parameters (or when security issue detected) public function FlashMediaElement() { // show allow this player to be called from a different domain than the HTML page hosting the player Security.allowDomain("*"); // check for security issues (borrowed from jPLayer) checkFlashVars(loaderInfo.parameters); // add debug output _output = new TextField(); _output.textColor = 0xeeeeee; _output.width = stage.stageWidth - 100; _output.height = stage.stageHeight; _output.multiline = true; _output.wordWrap = true; _output.border = false; _output.filters = [new DropShadowFilter(1, 0x000000, 45, 1, 2, 2, 1)]; _output.text = "Initializing...\n"; addChild(_output); _output.visible = securityIssue; if (securityIssue) { _output.text = "WARNING: Security issue detected. Player stopped."; return; } // get parameters var params:Object = LoaderInfo(this.root.loaderInfo).parameters; _mediaUrl = (params['file'] != undefined) ? String(params['file']) : ""; _autoplay = (params['autoplay'] != undefined) ? (String(params['autoplay']) == "true") : false; _debug = (params['debug'] != undefined) ? (String(params['debug']) == "true") : false; _isVideo = (params['isvideo'] != undefined) ? ((String(params['isvideo']) == "false") ? false : true ) : true; _timerRate = (params['timerrate'] != undefined) ? (parseInt(params['timerrate'], 10)) : 250; _alwaysShowControls = (params['controls'] != undefined) ? (String(params['controls']) == "true") : false; _enableSmoothing = (params['smoothing'] != undefined) ? (String(params['smoothing']) == "true") : false; _startVolume = (params['startvolume'] != undefined) ? (parseFloat(params['startvolume'])) : 0.8; _preload = (params['preload'] != undefined) ? params['preload'] : "none"; _controlStyle = (params['controlstyle'] != undefined) ? (String(params['controlstyle'])) : ""; // blank or "floating" _autoHide = (params['autohide'] != undefined) ? (String(params['autohide'])) : true; _scrubTrackColor = (params['scrubtrackcolor'] != undefined) ? (String(params['scrubtrackcolor'])) : "0x333333"; _scrubBarColor = (params['scrubbarcolor'] != undefined) ? (String(params['scrubbarcolor'])) : "0xefefef"; _scrubLoadedColor = (params['scrubloadedcolor'] != undefined) ? (String(params['scrubloadedcolor'])) : "0x3CACC8"; _enablePseudoStreaming = (params['pseudostreaming'] != undefined) ? (String(params['pseudostreaming']) == "true") : false; _pseudoStreamingStartQueryParam = (params['pseudostreamstart'] != undefined) ? (String(params['pseudostreamstart'])) : "start"; _streamer = (params['flashstreamer'] != undefined) ? (String(params['flashstreamer'])) : ""; _output.visible = _debug; if (isNaN(_timerRate)) _timerRate = 250; // setup stage and player sizes/scales stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; _stageWidth = stage.stageWidth; _stageHeight = stage.stageHeight; //_autoplay = true; //_mediaUrl = "http://mediafiles.dts.edu/chapel/mp4/20100609.mp4"; //_alwaysShowControls = true; //_mediaUrl = "../media/Parades-PastLives.mp3"; //_mediaUrl = "../media/echo-hereweare.mp4"; //_mediaUrl = "http://video.ted.com/talks/podcast/AlGore_2006_480.mp4"; //_mediaUrl = "rtmp://stream2.france24.yacast.net/france24_live/en/f24_liveen"; //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0"; // hosea //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=m5VDDJlsD6I"; // railer with notes //_alwaysShowControls = true; //_debug=true; // position and hide _fullscreenButton = getChildByName("fullscreen_btn") as SimpleButton; //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _fullscreenButton.addEventListener(MouseEvent.CLICK, fullscreenClick, false); _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; // create media element if (_isVideo) { if (_mediaUrl.indexOf("youtube.com") > -1 || _mediaUrl.indexOf("youtu.be") > -1) { //Security.allowDomain("http://www.youtube.com"); _mediaElement = new YouTubeElement(this, _autoplay, _preload, _timerRate, _startVolume); _video = (_mediaElement as YouTubeElement).player; // these are set and then used once the player is loaded (_mediaElement as YouTubeElement).initWidth = _stageWidth; (_mediaElement as YouTubeElement).initHeight = _stageHeight; } else { _mediaElement = new VideoElement(this, _autoplay, _preload, _timerRate, _startVolume, _streamer); _video = (_mediaElement as VideoElement).video; _video.width = _stageWidth; _video.height = _stageHeight; (_video as Video).smoothing = _enableSmoothing; (_mediaElement as VideoElement).setReference(this); (_mediaElement as VideoElement).setPseudoStreaming(_enablePseudoStreaming); (_mediaElement as VideoElement).setPseudoStreamingStartParam(_pseudoStreamingStartQueryParam); //_video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; addChild(_video); } } else { //var player2:AudioDecoder = new com.automatastudios.audio.audiodecoder.AudioDecoder(); _mediaElement = new AudioElement(this, _autoplay, _preload, _timerRate, _startVolume); } // controls! _controlBar = getChildByName("controls_mc") as MovieClip; _controlBarBg = _controlBar.getChildByName("controls_bg_mc") as MovieClip; _scrubTrack = _controlBar.getChildByName("scrubTrack") as MovieClip; _scrubBar = _controlBar.getChildByName("scrubBar") as MovieClip; _scrubOverlay = _controlBar.getChildByName("scrubOverlay") as MovieClip; _scrubLoaded = _controlBar.getChildByName("scrubLoaded") as MovieClip; _scrubOverlay.buttonMode = true; _scrubOverlay.useHandCursor = true applyColor(_scrubTrack, _scrubTrackColor); applyColor(_scrubBar, _scrubBarColor); applyColor(_scrubLoaded, _scrubLoadedColor); _fullscreenIcon = _controlBar.getChildByName("fullscreenIcon") as SimpleButton; // New fullscreenIcon for new fullscreen floating controls //if(_alwaysShowControls && _controlStyle.toUpperCase()=="FLOATING") { _fullscreenIcon.addEventListener(MouseEvent.CLICK, fullScreenIconClick, false); //} _volumeMuted = _controlBar.getChildByName("muted_mc") as SimpleButton; _volumeUnMuted = _controlBar.getChildByName("unmuted_mc") as SimpleButton; _volumeMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _volumeUnMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _playButton = _controlBar.getChildByName("play_btn") as SimpleButton; _playButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.play(); }); _pauseButton = _controlBar.getChildByName("pause_btn") as SimpleButton; _pauseButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.pause(); }); _pauseButton.visible = false; _duration = _controlBar.getChildByName("duration_txt") as TextField; _currentTime = _controlBar.getChildByName("currentTime_txt") as TextField; _hoverTime = _controlBar.getChildByName("hoverTime") as MovieClip; _hoverTimeText = _hoverTime.getChildByName("hoverTime_txt") as TextField; _hoverTime.visible=false; _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; // Add new timeline scrubber events _scrubOverlay.addEventListener(MouseEvent.MOUSE_MOVE, scrubMove); _scrubOverlay.addEventListener(MouseEvent.CLICK, scrubClick); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OVER, scrubOver); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OUT, scrubOut); if (_autoHide) { // && _alwaysShowControls) { // Add mouse activity for show/hide of controls stage.addEventListener(Event.MOUSE_LEAVE, mouseActivityLeave); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseActivityMove); _inactiveTime = 2500; _timer = new Timer(_inactiveTime) _timer.addEventListener(TimerEvent.TIMER, idleTimer); _timer.start(); // set } if(_alwaysShowControls) { if(_startVolume<=0) { trace("INITIAL VOLUME: "+_startVolume+" MUTED"); _volumeMuted.visible=true; _volumeUnMuted.visible=false; } else { trace("INITIAL VOLUME: "+_startVolume+" UNMUTED"); _volumeMuted.visible=false; _volumeUnMuted.visible=true; } } _controlBar.visible = _alwaysShowControls; setControlDepth(); _output.appendText("stage: " + stage.stageWidth + "x" + stage.stageHeight + "\n"); _output.appendText("file: " + _mediaUrl + "\n"); _output.appendText("autoplay: " + _autoplay.toString() + "\n"); _output.appendText("preload: " + _preload.toString() + "\n"); _output.appendText("isvideo: " + _isVideo.toString() + "\n"); _output.appendText("smoothing: " + _enableSmoothing.toString() + "\n"); _output.appendText("timerrate: " + _timerRate.toString() + "\n"); _output.appendText("displayState: " +(stage.hasOwnProperty("displayState")).toString() + "\n"); // attach javascript _output.appendText("ExternalInterface.available: " + ExternalInterface.available.toString() + "\n"); _output.appendText("ExternalInterface.objectID: " + ((ExternalInterface.objectID != null)? ExternalInterface.objectID.toString() : "null") + "\n"); if (_mediaUrl != "") { _mediaElement.setSrc(_mediaUrl); } positionControls(); // Fire this once just to set the width on some dynamically sized scrub bar items; _scrubBar.scaleX=0; _scrubLoaded.scaleX=0; if (ExternalInterface.available) { // && !_alwaysShowControls _output.appendText("Adding callbacks...\n"); try { if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { // add HTML media methods ExternalInterface.addCallback("playMedia", playMedia); ExternalInterface.addCallback("loadMedia", loadMedia); ExternalInterface.addCallback("pauseMedia", pauseMedia); ExternalInterface.addCallback("stopMedia", stopMedia); ExternalInterface.addCallback("setSrc", setSrc); ExternalInterface.addCallback("setCurrentTime", setCurrentTime); ExternalInterface.addCallback("setVolume", setVolume); ExternalInterface.addCallback("setMuted", setMuted); ExternalInterface.addCallback("setFullscreen", setFullscreen); ExternalInterface.addCallback("setVideoSize", setVideoSize); ExternalInterface.addCallback("positionFullscreenButton", positionFullscreenButton); ExternalInterface.addCallback("hideFullscreenButton", hideFullscreenButton); // fire init method ExternalInterface.call("mejs.MediaPluginBridge.initPlugin", ExternalInterface.objectID); } _output.appendText("Success...\n"); } catch (error:SecurityError) { _output.appendText("A SecurityError occurred: " + error.message + "\n"); } catch (error:Error) { _output.appendText("An Error occurred: " + error.message + "\n"); } } if (_preload != "none") { _mediaElement.load(); if (_autoplay) { _mediaElement.play(); } } else if (_autoplay) { _mediaElement.load(); _mediaElement.play(); } // listen for resize stage.addEventListener(Event.RESIZE, resizeHandler); // send click events up to javascript stage.addEventListener(MouseEvent.CLICK, stageClicked); // resize stage.addEventListener(FullScreenEvent.FULL_SCREEN, stageFullScreenChanged); } public function setControlDepth():void { // put these on top addChild(_output); addChild(_controlBar); addChild(_fullscreenButton); } // borrowed from jPLayer // https://github.com/happyworm/jPlayer/blob/e8ca190f7f972a6a421cb95f09e138720e40ed6d/actionscript/Jplayer.as#L228 private function checkFlashVars(p:Object):void { var i:Number = 0; for each (var s:String in p) { if (isIllegalChar(s)) { securityIssue = true; // Illegal char found } i++; } if(i === 0 || securityIssue) { directAccess = true; } } private function isIllegalChar(s:String):Boolean { var illegals:String = "' \" ( ) { } * + / \\ < > = document"; if(Boolean(s)) { // Otherwise exception if parameter null. for each (var illegal:String in illegals.split(' ')) { if(s.indexOf(illegal) >= 0) { return true; // Illegal char found } } } return false; } // START: Controls and events function mouseActivityMove(event:MouseEvent):void { // if mouse is in the video area if (_autoHide && (mouseX>=0 && mouseX<=stage.stageWidth) && (mouseY>=0 && mouseY<=stage.stageHeight)) { // This could be move to a nice fade at some point... _controlBar.visible = (_alwaysShowControls || _isFullScreen); _isMouseActive = true; _idleTime = 0; _timer.reset(); _timer.start() } } function mouseActivityLeave(event:Event):void { if (_autoHide) { _isOverStage = false; // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime = 0; _timer.reset(); _timer.stop(); } } function idleTimer(event:TimerEvent):void { if (_autoHide) { // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime += _inactiveTime; _idleTime = 0; _timer.reset(); _timer.stop(); } } function scrubMove(event:MouseEvent):void { //if (_alwaysShowControls) { if (_hoverTime.visible) { var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var hoverPos:Number = (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; if (_isFullScreen) { _hoverTime.x=event.target.parent.mouseX; } else { _hoverTime.x=mouseX; } _hoverTime.y = _scrubBar.y - (_hoverTime.height/2); _hoverTimeText.text = secondsToTimeCode(seekBarPosition); } //} //trace(event); } function scrubOver(event:MouseEvent):void { _hoverTime.y = _scrubBar.y-(_hoverTime.height/2)+1; _hoverTime.visible = true; trace(event); } function scrubOut(event:MouseEvent):void { _hoverTime.y = _scrubBar.y+(_hoverTime.height/2)+1; _hoverTime.visible = false; //_hoverTime.x=0; //trace(event); } function scrubClick(event:MouseEvent):void { //trace(event); var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var tmp:Number = (_mediaElement.currentTime()/_mediaElement.duration())*_scrubTrack.width; var canSeekToPosition:Boolean = _scrubLoaded.scaleX > (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; //var canSeekToPosition:Boolean = true; /* amountLoaded = ns.bytesLoaded / ns.bytesTotal; loader.loadbar._width = amountLoaded * 208.9; loader.scrub._x = ns.time / duration * 208.9; */ trace("seekBarPosition:"+seekBarPosition, "CanSeekToPosition: "+canSeekToPosition); if (seekBarPosition>0 && seekBarPosition<_mediaElement.duration() && canSeekToPosition) { _mediaElement.setCurrentTime(seekBarPosition); } } function toggleVolume(event:MouseEvent):void { trace(event.currentTarget.name); switch(event.currentTarget.name) { case "muted_mc": setMuted(false); break; case "unmuted_mc": setMuted(true); break; } } function toggleVolumeIcons(volume:Number) { if(volume<=0) { _volumeMuted.visible = true; _volumeUnMuted.visible = false; } else { _volumeMuted.visible = false; _volumeUnMuted.visible = true; } } public function positionControls(forced:Boolean=false) { if ( _controlStyle.toUpperCase() == "FLOATING" && _isFullScreen) { trace("CONTROLS: floating"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = 300; _controlBarBg.height = 93; //_controlBarBg.x = (stage.stageWidth/2) - (_controlBarBg.width/2); //_controlBarBg.y = stage.stageHeight - 300; _pauseButton.scaleX = _playButton.scaleX=3.5; _pauseButton.scaleY= _playButton.scaleY=3.5; // center the play button and make it big and at the top _pauseButton.x = _playButton.x = (_controlBarBg.width/2)-(_playButton.width/2)+7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-(14) _controlBar.x = (stage.stageWidth/2) -150; _controlBar.y = stage.stageHeight - _controlBar.height-100; // reposition the time and duration items _duration.x = _controlBarBg.width - _duration.width - 10; _duration.y = _controlBarBg.height - _duration.height -7; //_currentTime.x = _controlBarBg.width - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = 5 _currentTime.y= _controlBarBg.height - _currentTime.height-7; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 7; _volumeMuted.x = _volumeUnMuted.x = 7; _volumeMuted.y = _volumeUnMuted.y = 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x =_currentTime.x+_currentTime.width+7; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y=_controlBarBg.height-_scrubTrack.height-10; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-14); } else { trace("CONTROLS: normal, original"); /* // Original style bottom display _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBar.y = stage.stageHeight - _controlBar.height; _duration.x = stage.stageWidth - _duration.width - 10; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+10; _scrubOverlay.width = _scrubTrack.width; _scrubBar.width = _scrubTrack.width; */ // FLOATING MODE BOTTOM DISPLAY - similar to normal trace("THAT WAY!"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBarBg.height = 30; _controlBarBg.y=0; _controlBarBg.x=0; // _controlBarBg.x = 0; // _controlBarBg.y = stage.stageHeight - _controlBar.height; _pauseButton.scaleX = _playButton.scaleX=1; _pauseButton.scaleY = _playButton.scaleY=1; _pauseButton.x = _playButton.x = 7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-2; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 8; _volumeMuted.x = _volumeUnMuted.x = _fullscreenIcon.x - _volumeMuted.width - 10; _volumeMuted.y = _volumeUnMuted.y = 10; _duration.x = _volumeMuted.x - _volumeMuted.width - _duration.width + 5; _duration.y = _currentTime.y = _controlBarBg.height - _currentTime.height - 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x = _currentTime.x + _currentTime.width + 10; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y = _controlBarBg.height - _scrubTrack.height - 9; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+5; _controlBar.x = 0; _controlBar.y = stage.stageHeight - _controlBar.height; } } // END: Controls function stageClicked(e:MouseEvent):void { //_output.appendText("click: " + e.stageX.toString() +","+e.stageY.toString() + "\n"); if (e.target == stage) { sendEvent("click", ""); } } function resizeHandler(e:Event):void { //_video.scaleX = stage.stageWidth / _stageWidth; //_video.scaleY = stage.stageHeight / _stageHeight; //positionControls(); repositionVideo(); } // START: Fullscreen function enterFullscreen() { _output.appendText("enterFullscreen()\n"); var screenRectangle:Rectangle = new Rectangle(0, 0, flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); stage.fullScreenSourceRect = screenRectangle; stage.displayState = StageDisplayState.FULL_SCREEN; repositionVideo(true); positionControls(); updateControls(HtmlMediaEvent.FULLSCREENCHANGE); _controlBar.visible = true; _isFullScreen = true; } function exitFullscreen() { stage.displayState = StageDisplayState.NORMAL; _controlBar.visible = false; _isFullScreen = false; } function setFullscreen(gofullscreen:Boolean) { _output.appendText("setFullscreen: " + gofullscreen.toString() + "\n"); try { //_fullscreenButton.visible = false; if (gofullscreen) { enterFullscreen(); } else { exitFullscreen(); } } catch (error:Error) { // show the button when the security error doesn't let it work //_fullscreenButton.visible = true; _fullscreenButton.alpha = 1; _isFullScreen = false; _output.appendText("error setting fullscreen: " + error.message.toString() + "\n"); } } // control bar button/icon function fullScreenIconClick(e:MouseEvent) { try { _controlBar.visible = true; setFullscreen(!_isFullScreen); repositionVideo(_isFullScreen); } catch (error:Error) { } } // special floating fullscreen icon function fullscreenClick(e:MouseEvent) { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0 try { _controlBar.visible = true; setFullscreen(true); repositionVideo(true); positionControls(); } catch (error:Error) { } } function stageFullScreenChanged(e:FullScreenEvent) { _output.appendText("fullscreen event: " + e.fullScreen.toString() + "\n"); //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _isFullScreen = e.fullScreen; sendEvent(HtmlMediaEvent.FULLSCREENCHANGE, "isFullScreen:" + e.fullScreen ); if (!e.fullScreen) { _controlBar.visible = _alwaysShowControls; } } // END: Fullscreen // START: external interface function playMedia() { _output.appendText("play\n"); _mediaElement.play(); } function loadMedia() { _output.appendText("load\n"); _mediaElement.load(); } function pauseMedia() { _output.appendText("pause\n"); _mediaElement.pause(); } function setSrc(url:String) { _output.appendText("setSrc: " + url + "\n"); _mediaElement.setSrc(url); } function stopMedia() { _output.appendText("stop\n"); _mediaElement.stop(); } function setCurrentTime(time:Number) { _output.appendText("seek: " + time.toString() + "\n"); _mediaElement.setCurrentTime(time); } function setVolume(volume:Number) { _output.appendText("volume: " + volume.toString() + "\n"); _mediaElement.setVolume(volume); toggleVolumeIcons(volume); } function setMuted(muted:Boolean) { _output.appendText("muted: " + muted.toString() + "\n"); _mediaElement.setMuted(muted); toggleVolumeIcons(_mediaElement.getVolume()); } function setVideoSize(width:Number, height:Number) { _output.appendText("setVideoSize: " + width.toString() + "," + height.toString() + "\n"); _stageWidth = width; _stageHeight = height; if (_video != null) { repositionVideo(); positionControls(); //_fullscreenButton.x = stage.stageWidth - _fullscreenButton.width - 10; _output.appendText("result: " + _video.width.toString() + "," + _video.height.toString() + "\n"); } } function positionFullscreenButton(x:Number, y:Number, visibleAndAbove:Boolean ) { _output.appendText("position FS: " + x.toString() + "x" + y.toString() + "\n"); // bottom corner /* _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; */ // position just above if (visibleAndAbove) { _fullscreenButton.x = x+1; _fullscreenButton.y = y - _fullscreenButton.height+1; } else { _fullscreenButton.x = x; _fullscreenButton.y = y; } // check for oversizing if ((_fullscreenButton.x + _fullscreenButton.width) > stage.stageWidth) _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; // show it! if (visibleAndAbove) { _fullscreenButton.alpha = 1; } } function hideFullscreenButton() { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; } // END: external interface function repositionVideo(fullscreen:Boolean = false):void { _output.appendText("positioning video\n"); if (_mediaElement is VideoElement) { if (isNaN(_nativeVideoWidth) || isNaN(_nativeVideoHeight) || _nativeVideoWidth <= 0 || _nativeVideoHeight <= 0) { _output.appendText("ERR: I dont' have the native dimension\n"); return; } // calculate ratios var stageRatio, nativeRatio; _video.x = 0; _video.y = 0; if(fullscreen == true) { stageRatio = flash.system.Capabilities.screenResolutionX/flash.system.Capabilities.screenResolutionY; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, _nativeVideoHeight * flash.system.Capabilities.screenResolutionX / _nativeVideoWidth); _video.y = flash.system.Capabilities.screenResolutionY/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize(_nativeVideoWidth * flash.system.Capabilities.screenResolutionY / _nativeVideoHeight, flash.system.Capabilities.screenResolutionY); _video.x = flash.system.Capabilities.screenResolutionX/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } } else { stageRatio = _stageWidth/_stageHeight; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(_stageWidth, _nativeVideoHeight * _stageWidth / _nativeVideoWidth); _video.y = _stageHeight/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize( _nativeVideoWidth * _stageHeight / _nativeVideoHeight, _stageHeight); _video.x = _stageWidth/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(_stageWidth, _stageHeight); } } } else if (_mediaElement is YouTubeElement) { if(fullscreen == true) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } else { _mediaElement.setSize(_stageWidth, _stageHeight); } } positionControls(); } // SEND events to JavaScript public function sendEvent(eventName:String, eventValues:String) { // special video event if (eventName == HtmlMediaEvent.LOADEDMETADATA && _isVideo) { _output.appendText("METADATA RECEIVED: "); try { if (_mediaElement is VideoElement) { _nativeVideoWidth = (_mediaElement as VideoElement).videoWidth; _nativeVideoHeight = (_mediaElement as VideoElement).videoHeight; } } catch (e:Error) { _output.appendText(e.toString() + "\n"); } _output.appendText(_nativeVideoWidth.toString() + "x" + _nativeVideoHeight.toString() + "\n"); if(stage.displayState == "fullScreen" ) { setVideoSize(_nativeVideoWidth, _nativeVideoHeight); repositionVideo(true); } else { repositionVideo(); } } updateControls(eventName); //trace((_mediaElement.duration()*1).toString() + " / " + (_mediaElement.currentTime()*1).toString()); //trace("CurrentProgress:"+_mediaElement.currentProgress()); if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { //_output.appendText("event:" + eventName + " : " + eventValues); //trace("event", eventName, eventValues); if (eventValues == null) eventValues == ""; if (_isVideo) { eventValues += (eventValues != "" ? "," : "") + "isFullScreen:" + _isFullScreen; } eventValues = "{" + eventValues + "}"; /* OLD DIRECT METHOD ExternalInterface.call( "function(id, name) { mejs.MediaPluginBridge.fireEvent(id,name," + eventValues + "); }", ExternalInterface.objectID, eventName); */ // use set timeout for performance reasons //if (!_alwaysShowControls) { ExternalInterface.call("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + ExternalInterface.objectID + "','" + eventName + "'," + eventValues + ")",0); //} } } function updateControls(eventName:String):void { //trace("updating controls"); try { // update controls switch (eventName) { case "pause": case "paused": case "ended": _playButton.visible = true; _pauseButton.visible = false; break; case "play": case "playing": _playButton.visible = false; _pauseButton.visible = true; break; } if (eventName == HtmlMediaEvent.TIMEUPDATE || eventName == HtmlMediaEvent.PROGRESS || eventName == HtmlMediaEvent.FULLSCREENCHANGE) { //_duration.text = (_mediaElement.duration()*1).toString(); _duration.text = secondsToTimeCode(_mediaElement.duration()); //_currentTime.text = (_mediaElement.currentTime()*1).toString(); _currentTime.text = secondsToTimeCode(_mediaElement.currentTime()); var pct:Number = (_mediaElement.currentTime() / _mediaElement.duration()) *_scrubTrack.scaleX; _scrubBar.scaleX = pct; _scrubLoaded.scaleX = (_mediaElement.currentProgress()*_scrubTrack.scaleX)/100; } } catch (error:Error) { trace("error: " + error.toString()); } } // START: utility function secondsToTimeCode(seconds:Number):String { var timeCode:String = ""; seconds = Math.round(seconds); var minutes:Number = Math.floor(seconds / 60); timeCode = (minutes >= 10) ? minutes.toString() : "0" + minutes.toString(); seconds = Math.floor(seconds % 60); timeCode += ":" + ((seconds >= 10) ? seconds.toString() : "0" + seconds.toString()); return timeCode; //minutes.toString() + ":" + seconds.toString(); } function applyColor(item:Object, color:String):void { var myColor:ColorTransform = item.transform.colorTransform; myColor.color = Number(color); item.transform.colorTransform = myColor; } // END: utility } } \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/flash/FlashMediaElement.fla b/files_videoviewer/mediaelement/src/flash/FlashMediaElement.fla
index ea99fe2e5..b39f581e6 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/FlashMediaElement.fla
+++ b/files_videoviewer/mediaelement/src/flash/FlashMediaElement.fla
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/flash/HtmlMediaEvent.as b/files_videoviewer/mediaelement/src/flash/HtmlMediaEvent.as
index 6210df116..6210df116 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/HtmlMediaEvent.as
+++ b/files_videoviewer/mediaelement/src/flash/HtmlMediaEvent.as
diff --git a/files_videoviewer/mediaelement/src/flash/htmlelements/AudioElement.as b/files_videoviewer/mediaelement/src/flash/htmlelements/AudioElement.as
index 38f9704cc..bf90e9b13 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/htmlelements/AudioElement.as
+++ b/files_videoviewer/mediaelement/src/flash/htmlelements/AudioElement.as
@@ -1 +1 @@
- package htmlelements { import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.media.ID3Info; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundLoaderContext; import flash.media.SoundTransform; import flash.net.URLRequest; import flash.utils.Timer; /** * ... * @author DefaultUser (Tools -> Custom Arguments...) */ public class AudioElement implements IMediaElement { private var _sound:Sound; private var _soundTransform:SoundTransform; private var _soundChannel:SoundChannel; private var _soundLoaderContext:SoundLoaderContext; private var _volume:Number = 1; private var _preMuteVolume:Number = 0; private var _isMuted:Boolean = false; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _isLoaded:Boolean = false; private var _currentTime:Number = 0; private var _duration:Number = 0; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _element:FlashMediaElement; private var _timer:Timer; private var _firedCanPlay:Boolean = false; public function setSize(width:Number, height:Number):void { // do nothing! } public function duration():Number { return _duration; } public function currentTime():Number { return _currentTime; } public function currentProgress():Number { return Math.round(_bytesLoaded/_bytesTotal*100); } public function AudioElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _timer = new Timer(timerRate); _timer.addEventListener(TimerEvent.TIMER, timerEventHandler); _soundTransform = new SoundTransform(_volume); _soundLoaderContext = new SoundLoaderContext(); } // events function progressHandler(e:ProgressEvent):void { _bytesLoaded = e.bytesLoaded; _bytesTotal = e.bytesTotal; sendEvent(HtmlMediaEvent.PROGRESS); } function id3Handler(e:Event):void { sendEvent(HtmlMediaEvent.LOADEDMETADATA); try { var id3:ID3Info = _sound.id3; var obj = { type:'id3', album:id3.album, artist:id3.artist, comment:id3.comment, genre:id3.genre, songName:id3.songName, track:id3.track, year:id3.year } } catch (err:Error) {} } function timerEventHandler(e:TimerEvent) { _currentTime = _soundChannel.position/1000; // calculate duration var duration = Math.round(_sound.length * _sound.bytesTotal/_sound.bytesLoaded/100) / 10; // check to see if the estimated duration changed if (_duration != duration && !isNaN(duration)) { _duration = duration; sendEvent(HtmlMediaEvent.LOADEDMETADATA); } // send timeupdate sendEvent(HtmlMediaEvent.TIMEUPDATE); // sometimes the ended event doesn't fire, here's a fake one if (_duration > 0 && _currentTime >= _duration-0.2) { handleEnded(); } } function soundCompleteHandler(e:Event) { handleEnded(); } function handleEnded():void { _timer.stop(); _currentTime = 0; _isEnded = true; sendEvent(HtmlMediaEvent.ENDED); } //events // METHODS public function setSrc(url:String):void { _currentUrl = url; _isLoaded = false; } public function load():void { if (_currentUrl == "") return; _sound = new Sound(); //sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); _sound.addEventListener(ProgressEvent.PROGRESS,progressHandler); _sound.addEventListener(Event.ID3,id3Handler); _sound.load(new URLRequest(_currentUrl)); _currentTime = 0; sendEvent(HtmlMediaEvent.LOADSTART); _isLoaded = true; sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); _firedCanPlay = true; if (_playAfterLoading) { _playAfterLoading = false; play(); } } private var _playAfterLoading:Boolean= false; public function play():void { if (!_isLoaded) { _playAfterLoading = true; load(); return; } _timer.stop(); _soundChannel = _sound.play(_currentTime*1000, 0, _soundTransform); _soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); _soundChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); _timer.start(); didStartPlaying(); } public function pause():void { _timer.stop(); if (_soundChannel != null) { _currentTime = _soundChannel.position/1000; _soundChannel.stop(); } _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); } public function stop():void { if (_timer != null) { _timer.stop(); } if (_soundChannel != null) { _soundChannel.stop(); _sound.close(); } unload(); sendEvent(HtmlMediaEvent.STOP); } public function setCurrentTime(pos:Number):void { sendEvent(HtmlMediaEvent.SEEKING); _timer.stop(); _currentTime = pos; _soundChannel.stop(); _sound.length _soundChannel = _sound.play(_currentTime * 1000, 0, _soundTransform); sendEvent(HtmlMediaEvent.SEEKED); _timer.start(); didStartPlaying(); } private function didStartPlaying():void { _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); if (!_firedCanPlay) { sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); _firedCanPlay = true; } } public function setVolume(volume:Number):void { _volume = volume; _soundTransform.volume = volume; if (_soundChannel != null) { _soundChannel.soundTransform = _soundTransform; } _isMuted = (_volume == 0); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } public function getVolume():Number { if(_isMuted) { return 0; } else { return _volume; } } public function setMuted(muted:Boolean):void { // ignore if already set if ( (muted && _isMuted) || (!muted && !_isMuted)) return; if (muted) { _preMuteVolume = _soundTransform.volume; setVolume(0); } else { setVolume(_preMuteVolume); } _isMuted = muted; } public function unload():void { _sound = null; _isLoaded = false; } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",currentTime:" + _currentTime + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ""; _element.sendEvent(eventName, values); } } } \ No newline at end of file
+ package htmlelements { import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.media.ID3Info; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundLoaderContext; import flash.media.SoundTransform; import flash.net.URLRequest; import flash.utils.Timer; /** * ... * @author DefaultUser (Tools -> Custom Arguments...) */ public class AudioElement implements IMediaElement { private var _sound:Sound; private var _soundTransform:SoundTransform; private var _soundChannel:SoundChannel; private var _soundLoaderContext:SoundLoaderContext; private var _volume:Number = 1; private var _preMuteVolume:Number = 0; private var _isMuted:Boolean = false; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _isLoaded:Boolean = false; private var _currentTime:Number = 0; private var _duration:Number = 0; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _bufferingChanged:Boolean = false; private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _element:FlashMediaElement; private var _timer:Timer; private var _firedCanPlay:Boolean = false; public function setSize(width:Number, height:Number):void { // do nothing! } public function duration():Number { return _duration; } public function currentTime():Number { return _currentTime; } public function currentProgress():Number { return Math.round(_bytesLoaded/_bytesTotal*100); } public function AudioElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _timer = new Timer(timerRate); _timer.addEventListener(TimerEvent.TIMER, timerEventHandler); _soundTransform = new SoundTransform(_volume); _soundLoaderContext = new SoundLoaderContext(); } // events function progressHandler(e:ProgressEvent):void { _bytesLoaded = e.bytesLoaded; _bytesTotal = e.bytesTotal; // this happens too much to send every time //sendEvent(HtmlMediaEvent.PROGRESS); // so now we just trigger a flag and send with the timer _bufferingChanged = true; } function id3Handler(e:Event):void { sendEvent(HtmlMediaEvent.LOADEDMETADATA); try { var id3:ID3Info = _sound.id3; var obj = { type:'id3', album:id3.album, artist:id3.artist, comment:id3.comment, genre:id3.genre, songName:id3.songName, track:id3.track, year:id3.year } } catch (err:Error) {} } function timerEventHandler(e:TimerEvent) { _currentTime = _soundChannel.position/1000; // calculate duration var duration = Math.round(_sound.length * _sound.bytesTotal/_sound.bytesLoaded/100) / 10; // check to see if the estimated duration changed if (_duration != duration && !isNaN(duration)) { _duration = duration; sendEvent(HtmlMediaEvent.LOADEDMETADATA); } // check for progress if (_bufferingChanged) { sendEvent(HtmlMediaEvent.PROGRESS); _bufferingChanged = false; } // send timeupdate sendEvent(HtmlMediaEvent.TIMEUPDATE); // sometimes the ended event doesn't fire, here's a fake one if (_duration > 0 && _currentTime >= _duration-0.2) { handleEnded(); } } function soundCompleteHandler(e:Event) { handleEnded(); } function handleEnded():void { _timer.stop(); _currentTime = 0; _isEnded = true; sendEvent(HtmlMediaEvent.ENDED); } //events // METHODS public function setSrc(url:String):void { _currentUrl = url; _isLoaded = false; } public function load():void { if (_currentUrl == "") return; _sound = new Sound(); //sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); _sound.addEventListener(ProgressEvent.PROGRESS,progressHandler); _sound.addEventListener(Event.ID3,id3Handler); _sound.load(new URLRequest(_currentUrl)); _currentTime = 0; sendEvent(HtmlMediaEvent.LOADSTART); _isLoaded = true; sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); _firedCanPlay = true; if (_playAfterLoading) { _playAfterLoading = false; play(); } } private var _playAfterLoading:Boolean= false; public function play():void { if (!_isLoaded) { _playAfterLoading = true; load(); return; } _timer.stop(); _soundChannel = _sound.play(_currentTime*1000, 0, _soundTransform); _soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); _soundChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); _timer.start(); didStartPlaying(); } public function pause():void { _timer.stop(); if (_soundChannel != null) { _currentTime = _soundChannel.position/1000; _soundChannel.stop(); } _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); } public function stop():void { if (_timer != null) { _timer.stop(); } if (_soundChannel != null) { _soundChannel.stop(); _sound.close(); } unload(); sendEvent(HtmlMediaEvent.STOP); } public function setCurrentTime(pos:Number):void { sendEvent(HtmlMediaEvent.SEEKING); _timer.stop(); _currentTime = pos; _soundChannel.stop(); _sound.length _soundChannel = _sound.play(_currentTime * 1000, 0, _soundTransform); sendEvent(HtmlMediaEvent.SEEKED); _timer.start(); didStartPlaying(); } private function didStartPlaying():void { _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); if (!_firedCanPlay) { sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); _firedCanPlay = true; } } public function setVolume(volume:Number):void { _volume = volume; _soundTransform.volume = volume; if (_soundChannel != null) { _soundChannel.soundTransform = _soundTransform; } _isMuted = (_volume == 0); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } public function getVolume():Number { if(_isMuted) { return 0; } else { return _volume; } } public function setMuted(muted:Boolean):void { // ignore if already set if ( (muted && _isMuted) || (!muted && !_isMuted)) return; if (muted) { _preMuteVolume = _soundTransform.volume; setVolume(0); } else { setVolume(_preMuteVolume); } _isMuted = muted; } public function unload():void { _sound = null; _isLoaded = false; } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",currentTime:" + _currentTime + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ""; _element.sendEvent(eventName, values); } } } \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/flash/htmlelements/IMediaElement.as b/files_videoviewer/mediaelement/src/flash/htmlelements/IMediaElement.as
index 6adfc7014..6adfc7014 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/htmlelements/IMediaElement.as
+++ b/files_videoviewer/mediaelement/src/flash/htmlelements/IMediaElement.as
diff --git a/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as b/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as
index d3507ee14..e7e4ce21a 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as
+++ b/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as
@@ -1 +1 @@
-package htmlelements { import flash.display.Sprite; import flash.events.*; import flash.net.NetConnection; import flash.net.NetStream; import flash.media.Video; import flash.media.SoundTransform; import flash.utils.Timer; import FlashMediaElement; import HtmlMediaEvent; public class VideoElement extends Sprite implements IMediaElement { private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _isPreloading:Boolean = false; private var _connection:NetConnection; private var _stream:NetStream; private var _video:Video; private var _element:FlashMediaElement; private var _soundTransform; private var _oldVolume:Number = 1; // event values private var _duration:Number = 0; private var _framerate:Number; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _volume:Number = 1; private var _isMuted:Boolean = false; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _bufferEmpty:Boolean = false; private var _videoWidth:Number = -1; private var _videoHeight:Number = -1; private var _timer:Timer; private var _isRTMP:Boolean = false; private var _streamer:String = ""; private var _isConnected:Boolean = false; private var _playWhenConnected:Boolean = false; private var _hasStartedPlaying:Boolean = false; private var _parentReference:Object; public function setReference(arg:Object):void { _parentReference = arg; } public function setSize(width:Number, height:Number):void { _video.width = width; _video.height = height; } public function get video():Video { return _video; } public function get videoHeight():Number { return _videoHeight; } public function get videoWidth():Number { return _videoWidth; } public function duration():Number { return _duration; } public function currentProgress():Number { if(_stream != null) { return Math.round(_stream.bytesLoaded/_stream.bytesTotal*100); } else { return 0; } } public function currentTime():Number { if (_stream != null) { return _stream.time; } else { return 0; } } // (1) load() // calls _connection.connect(); // waits for NetConnection.Connect.Success // _stream gets created public function VideoElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number, streamer:String) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _streamer = streamer; _video = new Video(); addChild(_video); _connection = new NetConnection(); _connection.client = { onBWDone: function():void{} }; _connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); //_connection.connect(null); _timer = new Timer(timerRate); _timer.addEventListener("timer", timerHandler); } private function timerHandler(e:TimerEvent) { _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; if (!_isPaused) sendEvent(HtmlMediaEvent.TIMEUPDATE); //trace("bytes", _bytesLoaded, _bytesTotal); if (_bytesLoaded < _bytesTotal) sendEvent(HtmlMediaEvent.PROGRESS); } // internal events private function netStatusHandler(event:NetStatusEvent):void { trace("netStatus", event.info.code); switch (event.info.code) { case "NetStream.Buffer.Empty": _bufferEmpty = true; _isEnded ? sendEvent(HtmlMediaEvent.ENDED) : null; break; case "NetStream.Buffer.Full": _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; _bufferEmpty = false; sendEvent(HtmlMediaEvent.PROGRESS); break; case "NetConnection.Connect.Success": connectStream(); break; case "NetStream.Play.StreamNotFound": trace("Unable to locate video"); break; // STREAM case "NetStream.Play.Start": _isPaused = false; sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); if (!_isPreloading) { sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } _timer.start(); break; case "NetStream.Seek.Notify": sendEvent(HtmlMediaEvent.SEEKED); break; case "NetStream.Pause.Notify": _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); break; case "NetStream.Play.Stop": _isEnded = true; _isPaused = false; _timer.stop(); _bufferEmpty ? sendEvent(HtmlMediaEvent.ENDED) : null; break; } } private function securityErrorHandler(event:SecurityErrorEvent):void { trace("securityErrorHandler: " + event); } private function asyncErrorHandler(event:AsyncErrorEvent):void { // ignore AsyncErrorEvent events. } private function onMetaDataHandler(info:Object):void { _duration = info.duration; _framerate = info.framerate; _videoWidth = info.width; _videoHeight = info.height; // set size? sendEvent(HtmlMediaEvent.LOADEDMETADATA); if (_isPreloading) { _stream.pause(); _isPaused = true; _isPreloading = false; sendEvent(HtmlMediaEvent.PROGRESS); sendEvent(HtmlMediaEvent.TIMEUPDATE); } } // interface members public function setSrc(url:String):void { if (_isConnected && _stream) { // stop and restart _stream.pause(); } _currentUrl = url; _isRTMP = !!_currentUrl.match(/^rtmp(s|t|e|te)?\:\/\//) || _streamer != ""; _isConnected = false; _hasStartedPlaying = false; } public function load():void { // disconnect existing stream and connection if (_isConnected && _stream) { _stream.pause(); _stream.close(); _connection.close(); } _isConnected = false; _isPreloading = false; _isEnded = false; _bufferEmpty = false; // start new connection if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); if (_streamer != "") { rtmpInfo.server = _streamer; rtmpInfo.stream = _currentUrl; } _connection.connect(rtmpInfo.server); } else { _connection.connect(null); } // in a few moments the "NetConnection.Connect.Success" event will fire // and call createConnection which finishes the "load" sequence sendEvent(HtmlMediaEvent.LOADSTART); } private function connectStream():void { trace("connectStream"); _stream = new NetStream(_connection); // explicitly set the sound since it could have come before the connection was made _soundTransform = new SoundTransform(_volume); _stream.soundTransform = _soundTransform; _stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // same event as connection _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); var customClient:Object = new Object(); customClient.onMetaData = onMetaDataHandler; _stream.client = customClient; _video.attachNetStream(_stream); // start downloading without playing )based on preload and play() hasn't been called) // I wish flash had a load() command to make this less awkward if (_preload != "none" && !_playWhenConnected) { _isPaused = true; //stream.bufferTime = 20; _stream.play(_currentUrl, 0, 0); _stream.pause(); _isPreloading = true; //_stream.pause(); // //sendEvent(HtmlMediaEvent.PAUSE); // have to send this because the "playing" event gets sent via event handlers } _isConnected = true; if (_playWhenConnected && !_hasStartedPlaying) { play(); _playWhenConnected = false; } } public function play():void { if (!_hasStartedPlaying && !_isConnected) { _playWhenConnected = true; load(); return; } if (_hasStartedPlaying) { if (_isPaused) { _stream.resume(); _timer.start(); _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } } else { if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); _stream.play(rtmpInfo.stream); } else { _stream.play(_currentUrl); } _timer.start(); _isPaused = false; _hasStartedPlaying = true; // don't toss play/playing events here, because we haven't sent a // canplay / loadeddata event yet. that'll be handled in the net // event listener } } public function pause():void { if (_stream == null) return; _stream.pause(); _isPaused = true; if (_bytesLoaded == _bytesTotal) { _timer.stop(); } _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); } public function stop():void { if (_stream == null) return; _stream.close(); _isPaused = false; _timer.stop(); sendEvent(HtmlMediaEvent.STOP); } public function setCurrentTime(pos:Number):void { if (_stream == null) return; sendEvent(HtmlMediaEvent.SEEKING); _stream.seek(pos); if (!_isEnded) { sendEvent(HtmlMediaEvent.TIMEUPDATE); } } public function setVolume(volume:Number):void { if (_stream != null) { _soundTransform = new SoundTransform(volume); _stream.soundTransform = _soundTransform; } _volume = volume; _isMuted = (_volume == 0); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } public function getVolume():Number { if(_isMuted) { return 0; } else { return _volume; } } public function setMuted(muted:Boolean):void { if (_isMuted == muted) return; if (muted) { _oldVolume = (_stream == null) ? _oldVolume : _stream.soundTransform.volume; setVolume(0); } else { setVolume(_oldVolume); } _isMuted = muted; } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",framerate:" + _framerate + ",currentTime:" + (_stream != null ? _stream.time : 0) + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ",videoWidth:" + _videoWidth + ",videoHeight:" + _videoHeight + ""; _element.sendEvent(eventName, values); } private function parseRTMP(url:String) { var match:Array = url.match(/(.*)\/((flv|mp4|mp3):.*)/); var rtmpInfo:Object = { server: null, stream: null }; if (match) { rtmpInfo.server = match[1]; rtmpInfo.stream = match[2]; } else { rtmpInfo.server = url.replace(/\/[^\/]+$/,"/"); rtmpInfo.stream = url.split("/").pop(); } trace("parseRTMP - server: " + rtmpInfo.server + " stream: " + rtmpInfo.stream); return rtmpInfo; } } } \ No newline at end of file
+package htmlelements { import flash.display.Sprite; import flash.events.*; import flash.net.NetConnection; import flash.net.NetStream; import flash.media.Video; import flash.media.SoundTransform; import flash.utils.Timer; import FlashMediaElement; import HtmlMediaEvent; public class VideoElement extends Sprite implements IMediaElement { private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _isPreloading:Boolean = false; private var _connection:NetConnection; private var _stream:NetStream; private var _video:Video; private var _element:FlashMediaElement; private var _soundTransform; private var _oldVolume:Number = 1; // event values private var _duration:Number = 0; private var _framerate:Number; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _volume:Number = 1; private var _isMuted:Boolean = false; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _bufferEmpty:Boolean = false; private var _bufferingChanged:Boolean = false; private var _seekOffset:Number = 0; private var _videoWidth:Number = -1; private var _videoHeight:Number = -1; private var _timer:Timer; private var _isRTMP:Boolean = false; private var _streamer:String = ""; private var _isConnected:Boolean = false; private var _playWhenConnected:Boolean = false; private var _hasStartedPlaying:Boolean = false; private var _parentReference:Object; private var _pseudoStreamingEnabled:Boolean = false; private var _pseudoStreamingStartQueryParam:String = "start"; public function setReference(arg:Object):void { _parentReference = arg; } public function setSize(width:Number, height:Number):void { _video.width = width; _video.height = height; } public function setPseudoStreaming(enablePseudoStreaming:Boolean):void { _pseudoStreamingEnabled = enablePseudoStreaming; } public function setPseudoStreamingStartParam(pseudoStreamingStartQueryParam:String):void { _pseudoStreamingStartQueryParam = pseudoStreamingStartQueryParam; } public function get video():Video { return _video; } public function get videoHeight():Number { return _videoHeight; } public function get videoWidth():Number { return _videoWidth; } public function duration():Number { return _duration; } public function currentProgress():Number { if(_stream != null) { return Math.round(_stream.bytesLoaded/_stream.bytesTotal*100); } else { return 0; } } public function currentTime():Number { var currentTime:Number = 0; if (_stream != null) { currentTime = _stream.time; if (_pseudoStreamingEnabled) { currentTime += _seekOffset; } } return currentTime; } // (1) load() // calls _connection.connect(); // waits for NetConnection.Connect.Success // _stream gets created public function VideoElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number, streamer:String) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _streamer = streamer; _video = new Video(); addChild(_video); _connection = new NetConnection(); _connection.client = { onBWDone: function():void{} }; _connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); //_connection.connect(null); _timer = new Timer(timerRate); _timer.addEventListener("timer", timerHandler); } private function timerHandler(e:TimerEvent) { _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; if (!_isPaused) { sendEvent(HtmlMediaEvent.TIMEUPDATE); } //trace("bytes", _bytesLoaded, _bytesTotal); if (_bytesLoaded < _bytesTotal) sendEvent(HtmlMediaEvent.PROGRESS); } // internal events private function netStatusHandler(event:NetStatusEvent):void { trace("netStatus", event.info.code); switch (event.info.code) { case "NetStream.Buffer.Empty": _bufferEmpty = true; _isEnded ? sendEvent(HtmlMediaEvent.ENDED) : null; break; case "NetStream.Buffer.Full": _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; _bufferEmpty = false; sendEvent(HtmlMediaEvent.PROGRESS); break; case "NetConnection.Connect.Success": connectStream(); break; case "NetStream.Play.StreamNotFound": trace("Unable to locate video"); break; // STREAM case "NetStream.Play.Start": _isPaused = false; sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); if (!_isPreloading) { sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } _timer.start(); break; case "NetStream.Seek.Notify": sendEvent(HtmlMediaEvent.SEEKED); break; case "NetStream.Pause.Notify": _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); break; case "NetStream.Play.Stop": _isEnded = true; _isPaused = false; _timer.stop(); _bufferEmpty ? sendEvent(HtmlMediaEvent.ENDED) : null; break; } } private function securityErrorHandler(event:SecurityErrorEvent):void { trace("securityErrorHandler: " + event); } private function asyncErrorHandler(event:AsyncErrorEvent):void { // ignore AsyncErrorEvent events. } private function onMetaDataHandler(info:Object):void { // Only set the duration when we first load the video if (_duration == 0) { _duration = info.duration; } _framerate = info.framerate; _videoWidth = info.width; _videoHeight = info.height; // set size? sendEvent(HtmlMediaEvent.LOADEDMETADATA); if (_isPreloading) { _stream.pause(); _isPaused = true; _isPreloading = false; sendEvent(HtmlMediaEvent.PROGRESS); sendEvent(HtmlMediaEvent.TIMEUPDATE); } } // interface members public function setSrc(url:String):void { if (_isConnected && _stream) { // stop and restart _stream.pause(); } _currentUrl = url; _isRTMP = !!_currentUrl.match(/^rtmp(s|t|e|te)?\:\/\//) || _streamer != ""; _isConnected = false; _hasStartedPlaying = false; } public function load():void { // disconnect existing stream and connection if (_isConnected && _stream) { _stream.pause(); _stream.close(); _connection.close(); } _isConnected = false; _isPreloading = false; _isEnded = false; _bufferEmpty = false; // start new connection if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); if (_streamer != "") { rtmpInfo.server = _streamer; rtmpInfo.stream = _currentUrl; } _connection.connect(rtmpInfo.server); } else { _connection.connect(null); } // in a few moments the "NetConnection.Connect.Success" event will fire // and call createConnection which finishes the "load" sequence sendEvent(HtmlMediaEvent.LOADSTART); } private function connectStream():void { trace("connectStream"); _stream = new NetStream(_connection); // explicitly set the sound since it could have come before the connection was made _soundTransform = new SoundTransform(_volume); stream.soundTransform = _soundTransform; // set the buffer to ensure nice playback _stream.bufferTime = 1; _stream.bufferTimeMax = 3; _stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // same event as connection _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); var customClient:Object = new Object(); customClient.onMetaData = onMetaDataHandler; _stream.client = customClient; _video.attachNetStream(_stream); // start downloading without playing )based on preload and play() hasn't been called) // I wish flash had a load() command to make this less awkward if (_preload != "none" && !_playWhenConnected) { _isPaused = true; //stream.bufferTime = 20; _stream.play(getCurrentUrl(0), 0, 0); _stream.pause(); _isPreloading = true; //_stream.pause(); // //sendEvent(HtmlMediaEvent.PAUSE); // have to send this because the "playing" event gets sent via event handlers } _isConnected = true; if (_playWhenConnected && !_hasStartedPlaying) { play(); _playWhenConnected = false; } } public function play():void { if (!_hasStartedPlaying && !_isConnected) { _playWhenConnected = true; load(); return; } if (_hasStartedPlaying) { if (_isPaused) { _stream.resume(); _timer.start(); _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } } else { if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); _stream.play(rtmpInfo.stream); } else { _stream.play(getCurrentUrl(0)); } _timer.start(); _isPaused = false; _hasStartedPlaying = true; // don't toss play/playing events here, because we haven't sent a // canplay / loadeddata event yet. that'll be handled in the net // event listener } } public function pause():void { if (_stream == null) return; _stream.pause(); _isPaused = true; if (_bytesLoaded == _bytesTotal) { _timer.stop(); } _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); } public function stop():void { if (_stream == null) return; _stream.close(); _isPaused = false; _timer.stop(); sendEvent(HtmlMediaEvent.STOP); } public function setCurrentTime(pos:Number):void { if (_stream == null) { return; } // Calculate the position of the buffered video var bufferPosition:Number = _bytesLoaded / _bytesTotal * _duration; if (_pseudoStreamingEnabled) { sendEvent(HtmlMediaEvent.SEEKING); // Normal seek if it is in buffer and this is the first seek if (pos < bufferPosition && _seekOffset == 0) { _stream.seek(pos); } else { // Uses server-side pseudo-streaming to seek _stream.play(getCurrentUrl(pos)); _seekOffset = pos; } } else { sendEvent(HtmlMediaEvent.SEEKING); _stream.seek(pos); } if (!_isEnded) { sendEvent(HtmlMediaEvent.TIMEUPDATE); } } public function setVolume(volume:Number):void { if (_stream != null) { _soundTransform = new SoundTransform(volume); _stream.soundTransform = _soundTransform; } _volume = volume; _isMuted = (_volume == 0); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } public function getVolume():Number { if(_isMuted) { return 0; } else { return _volume; } } public function setMuted(muted:Boolean):void { if (_isMuted == muted) return; if (muted) { _oldVolume = (_stream == null) ? _oldVolume : _stream.soundTransform.volume; setVolume(0); } else { setVolume(_oldVolume); } _isMuted = muted; } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",framerate:" + _framerate + ",currentTime:" + currentTime() + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ",videoWidth:" + _videoWidth + ",videoHeight:" + _videoHeight + ""; _element.sendEvent(eventName, values); } private function parseRTMP(url:String) { var match:Array = url.match(/(.*)\/((flv|mp4|mp3):.*)/); var rtmpInfo:Object = { server: null, stream: null }; if (match) { rtmpInfo.server = match[1]; rtmpInfo.stream = match[2]; } else { rtmpInfo.server = url.replace(/\/[^\/]+$/,"/"); rtmpInfo.stream = url.split("/").pop(); } trace("parseRTMP - server: " + rtmpInfo.server + " stream: " + rtmpInfo.stream); return rtmpInfo; } private function getCurrentUrl(pos:Number):String { var url:String = _currentUrl; if (_pseudoStreamingEnabled) { if (url.indexOf('?') > -1) { url = url + '&' + _pseudoStreamingStartQueryParam + '=' + pos; } else { url = url + '?' + _pseudoStreamingStartQueryParam + '=' + pos; } } return url; } } } \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/flash/htmlelements/YouTubeElement.as b/files_videoviewer/mediaelement/src/flash/htmlelements/YouTubeElement.as
index cdba22162..f77343da7 100644..100755
--- a/files_videoviewer/mediaelement/src/flash/htmlelements/YouTubeElement.as
+++ b/files_videoviewer/mediaelement/src/flash/htmlelements/YouTubeElement.as
@@ -1 +1,403 @@
-package htmlelements { import flash.display.Sprite; import flash.events.*; import flash.net.NetConnection; import flash.net.NetStream; import flash.media.Video; import flash.media.SoundTransform; import flash.utils.Timer; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLVariables; import flash.net.URLRequestMethod; import flash.display.MovieClip; import flash.display.Loader; import flash.display.DisplayObject; import FlashMediaElement; import HtmlMediaEvent; public class YouTubeElement extends Sprite implements IMediaElement { private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _element:FlashMediaElement; // event values private var _currentTime:Number = 0; private var _duration:Number = 0; private var _framerate:Number; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _volume:Number = 1; private var _isMuted:Boolean = false; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _bufferEmpty:Boolean = false; private var _videoWidth:Number = -1; private var _videoHeight:Number = -1; private var _timer:Timer; // YouTube stuff private var _playerLoader:Loader; private var _player:Object = null; private var _playerIsLoaded:Boolean = false; private var _youTubeId:String = ""; //http://code.google.com/p/gdata-samples/source/browse/trunk/ytplayer/actionscript3/com/google/youtube/examples/AS3Player.as private static const WIDESCREEN_ASPECT_RATIO:String = "widescreen"; private static const QUALITY_TO_PLAYER_WIDTH:Object = { small: 320, medium: 640, large: 854, hd720: 1280 }; private static const STATE_ENDED:Number = 0; private static const STATE_PLAYING:Number = 1; private static const STATE_PAUSED:Number = 2; private static const STATE_CUED:Number = 5; public function get player():DisplayObject { return _player; } public function setSize(width:Number, height:Number):void { if (_player != null) { _player.setSize(width, height); } else { initHeight = height; initWidth = width; } } public function get videoHeight():Number { return _videoHeight; } public function get videoWidth():Number { return _videoWidth; } public function duration():Number { return _duration; } public function currentProgress():Number { if(_bytesTotal> 0) { return Math.round(_bytesLoaded/_bytesTotal*100); } else { return 0; } } public function currentTime():Number { return _currentTime; } public var initHeight:Number; public var initWidth:Number; // (1) load() // calls _connection.connect(); // waits for NetConnection.Connect.Success // _stream gets created private var _isChromeless:Boolean = false; public function YouTubeElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; initHeight = 0; initWidth = 0; _playerLoader = new Loader(); _playerLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, playerLoaderInitHandler); // chromeless if (_isChromeless) { _playerLoader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3&controls=1&rel=0&showinfo=0&iv_load_policy=1")); } _timer = new Timer(timerRate); _timer.addEventListener("timer", timerHandler); _timer.start(); } private function playerLoaderInitHandler(event:Event):void { trace("yt player init"); _element.addChild(_playerLoader.content); _element.setControlDepth(); _playerLoader.content.addEventListener("onReady", onPlayerReady); _playerLoader.content.addEventListener("onError", onPlayerError); _playerLoader.content.addEventListener("onStateChange", onPlayerStateChange); _playerLoader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange); } private function onPlayerReady(event:Event):void { _playerIsLoaded = true; _player = _playerLoader.content; if (initHeight > 0 && initWidth > 0) _player.setSize(initWidth, initHeight); if (_youTubeId != "") { // && _isChromeless) { if (_autoplay) { player.loadVideoById(_youTubeId); } else { player.cueVideoById(_youTubeId); } _timer.start(); } } private function onPlayerError(event:Event):void { // trace("Player error:", Object(event).data); } private function onPlayerStateChange(event:Event):void { trace("State is", Object(event).data); _duration = _player.getDuration(); switch (Object(event).data) { case STATE_ENDED: _isEnded = true; _isPaused = false; sendEvent(HtmlMediaEvent.ENDED); break; case STATE_PLAYING: _isEnded = false; _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); break; case STATE_PAUSED: _isEnded = false; _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); break; case STATE_CUED: sendEvent(HtmlMediaEvent.CANPLAY); // resize? break; } } private function onVideoPlaybackQualityChange(event:Event):void { trace("Current video quality:", Object(event).data); //resizePlayer(Object(event).data); } private function timerHandler(e:TimerEvent) { if (_playerIsLoaded) { _bytesLoaded = _player.getVideoBytesLoaded(); _bytesTotal = _player.getVideoBytesTotal(); _currentTime = player.getCurrentTime(); if (!_isPaused) sendEvent(HtmlMediaEvent.TIMEUPDATE); if (_bytesLoaded < _bytesTotal) sendEvent(HtmlMediaEvent.PROGRESS); } } private function getYouTubeId(url:String):String { // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 // http://www.youtube.com/v/VIDEO_ID?version=3 // http://youtu.be/Djd6tPrxc08 url = unescape(url); var youTubeId:String = ""; if (url.indexOf("?") > 0) { // assuming: http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 youTubeId = getYouTubeIdFromParam(url); // if it's http://www.youtube.com/v/VIDEO_ID?version=3 if (youTubeId == "") { youTubeId = getYouTubeIdFromUrl(url); } } else { youTubeId = getYouTubeIdFromUrl(url); } return youTubeId; } // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 private function getYouTubeIdFromParam(url:String):String { var youTubeId:String = ""; var parts:Array = url.split('?'); var parameters:Array = parts[1].split('&'); for (var i:Number=0; i<parameters.length; i++) { var paramParts = parameters[i].split('='); if (paramParts[0] == "v") { youTubeId = paramParts[1]; break; } } return youTubeId; } // http://www.youtube.com/v/VIDEO_ID?version=3 // http://youtu.be/Djd6tPrxc08 private function getYouTubeIdFromUrl(url:String):String { var youTubeId:String = ""; // remove any querystring elements var parts:Array = url.split('?'); url = parts[0]; youTubeId = url.substring(url.lastIndexOf("/")+1); return youTubeId; } // interface members public function setSrc(url:String):void { trace("yt setSrc()" + url ); _currentUrl = url; _youTubeId = getYouTubeId(url); if (!_playerIsLoaded && !_isChromeless) { _playerLoader.load(new URLRequest("http://www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1")); } } public function load():void { // do nothing trace("yt load()"); if (_playerIsLoaded) { player.loadVideoById(_youTubeId); _timer.start(); } else { /* if (!_isChromless && _youTubeId != "") { _playerLoader.load(new URLRequest("http://www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1")); } */ } } public function play():void { if (_playerIsLoaded) { _player.playVideo(); } } public function pause():void { if (_playerIsLoaded) { _player.pauseVideo(); } } public function stop():void { if (_playerIsLoaded) { _player.pauseVideo(); } } public function setCurrentTime(pos:Number):void { //_player.seekTo(pos, false); _player.seekTo(pos, true); // works in all places now } public function setVolume(volume:Number):void { _player.setVolume(volume*100); _volume = volume; } public function getVolume():Number { return _player.getVolume()*100; } public function setMuted(muted:Boolean):void { if (muted) { _player.mute(); } else { _player.unMute(); } _muted = _player.isMuted(); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",framerate:" + _framerate + ",currentTime:" + _currentTime + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ",videoWidth:" + _videoWidth + ",videoHeight:" + _videoHeight + ""; _element.sendEvent(eventName, values); } } } \ No newline at end of file
+package htmlelements
+{
+ import flash.display.Sprite;
+ import flash.events.*;
+ import flash.net.NetConnection;
+ import flash.net.NetStream;
+ import flash.media.Video;
+ import flash.media.SoundTransform;
+ import flash.utils.Timer;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
+ import flash.net.URLVariables;
+ import flash.net.URLRequestMethod;
+ import flash.display.MovieClip;
+ import flash.display.Loader;
+ import flash.display.DisplayObject;
+
+
+
+ import FlashMediaElement;
+ import HtmlMediaEvent;
+
+ public class YouTubeElement extends Sprite implements IMediaElement
+ {
+ private var _currentUrl:String = "";
+ private var _autoplay:Boolean = true;
+ private var _preload:String = "";
+
+ private var _element:FlashMediaElement;
+
+ // event values
+ private var _currentTime:Number = 0;
+ private var _duration:Number = 0;
+ private var _framerate:Number;
+ private var _isPaused:Boolean = true;
+ private var _isEnded:Boolean = false;
+ private var _volume:Number = 1;
+ private var _isMuted:Boolean = false;
+
+ private var _bytesLoaded:Number = 0;
+ private var _bytesTotal:Number = 0;
+ private var _bufferedTime:Number = 0;
+ private var _bufferEmpty:Boolean = false;
+
+ private var _videoWidth:Number = -1;
+ private var _videoHeight:Number = -1;
+
+ private var _timer:Timer;
+
+ // YouTube stuff
+ private var _playerLoader:Loader;
+ private var _player:Object = null;
+ private var _playerIsLoaded:Boolean = false;
+ private var _youTubeId:String = "";
+
+ //http://code.google.com/p/gdata-samples/source/browse/trunk/ytplayer/actionscript3/com/google/youtube/examples/AS3Player.as
+ private static const WIDESCREEN_ASPECT_RATIO:String = "widescreen";
+ private static const QUALITY_TO_PLAYER_WIDTH:Object = {
+ small: 320,
+ medium: 640,
+ large: 854,
+ hd720: 1280
+ };
+ private static const STATE_ENDED:Number = 0;
+ private static const STATE_PLAYING:Number = 1;
+ private static const STATE_PAUSED:Number = 2;
+ private static const STATE_CUED:Number = 5;
+
+
+ public function get player():DisplayObject {
+ return _player;
+ }
+
+ public function setSize(width:Number, height:Number):void {
+ if (_player != null) {
+ _player.setSize(width, height);
+ } else {
+ initHeight = height;
+ initWidth = width;
+ }
+ }
+
+ public function get videoHeight():Number {
+ return _videoHeight;
+ }
+
+ public function get videoWidth():Number {
+ return _videoWidth;
+ }
+
+
+ public function duration():Number {
+ return _duration;
+ }
+
+ public function currentProgress():Number {
+ if(_bytesTotal> 0) {
+ return Math.round(_bytesLoaded/_bytesTotal*100);
+ } else {
+ return 0;
+ }
+ }
+
+ public function currentTime():Number {
+ return _currentTime;
+ }
+
+
+ public var initHeight:Number;
+ public var initWidth:Number;
+
+ // (1) load()
+ // calls _connection.connect();
+ // waits for NetConnection.Connect.Success
+ // _stream gets created
+
+ private var _isChromeless:Boolean = false;
+
+
+ public function YouTubeElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number)
+ {
+ _element = element;
+ _autoplay = autoplay;
+ _volume = startVolume;
+ _preload = preload;
+ initHeight = 0;
+ initWidth = 0;
+
+ _playerLoader = new Loader();
+ _playerLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, playerLoaderInitHandler);
+
+ // chromeless
+ if (_isChromeless) {
+ _playerLoader.load(new URLRequest("//www.youtube.com/apiplayer?version=3&controls=1&rel=0&showinfo=0&iv_load_policy=1"));
+ }
+
+
+ _timer = new Timer(timerRate);
+ _timer.addEventListener("timer", timerHandler);
+ _timer.start();
+ }
+
+ private function playerLoaderInitHandler(event:Event):void {
+
+ trace("yt player init");
+
+ _element.addChild(_playerLoader.content);
+ _element.setControlDepth();
+ _playerLoader.content.addEventListener("onReady", onPlayerReady);
+ _playerLoader.content.addEventListener("onError", onPlayerError);
+ _playerLoader.content.addEventListener("onStateChange", onPlayerStateChange);
+ _playerLoader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange);
+ }
+
+ private function onPlayerReady(event:Event):void {
+ _playerIsLoaded = true;
+
+ _player = _playerLoader.content;
+
+ if (initHeight > 0 && initWidth > 0)
+ _player.setSize(initWidth, initHeight);
+
+ if (_youTubeId != "") { // && _isChromeless) {
+ if (_autoplay) {
+ player.loadVideoById(_youTubeId);
+ } else {
+ player.cueVideoById(_youTubeId);
+ }
+ _timer.start();
+ }
+ }
+
+ private function onPlayerError(event:Event):void {
+ // trace("Player error:", Object(event).data);
+ }
+
+ private function onPlayerStateChange(event:Event):void {
+ trace("State is", Object(event).data);
+
+ _duration = _player.getDuration();
+
+ switch (Object(event).data) {
+ case STATE_ENDED:
+ _isEnded = true;
+ _isPaused = false;
+
+ sendEvent(HtmlMediaEvent.ENDED);
+
+ break;
+
+ case STATE_PLAYING:
+ _isEnded = false;
+ _isPaused = false;
+
+ sendEvent(HtmlMediaEvent.PLAY);
+ sendEvent(HtmlMediaEvent.PLAYING);
+ break;
+
+ case STATE_PAUSED:
+ _isEnded = false;
+ _isPaused = true;
+
+ sendEvent(HtmlMediaEvent.PAUSE);
+
+ break;
+
+ case STATE_CUED:
+ sendEvent(HtmlMediaEvent.CANPLAY);
+
+ // resize?
+
+ break;
+ }
+ }
+
+ private function onVideoPlaybackQualityChange(event:Event):void {
+ trace("Current video quality:", Object(event).data);
+ //resizePlayer(Object(event).data);
+ }
+
+ private function timerHandler(e:TimerEvent) {
+
+ if (_playerIsLoaded) {
+ _bytesLoaded = _player.getVideoBytesLoaded();
+ _bytesTotal = _player.getVideoBytesTotal();
+ _currentTime = player.getCurrentTime();
+
+ if (!_isPaused)
+ sendEvent(HtmlMediaEvent.TIMEUPDATE);
+
+ if (_bytesLoaded < _bytesTotal)
+ sendEvent(HtmlMediaEvent.PROGRESS);
+ }
+
+ }
+
+ private function getYouTubeId(url:String):String {
+ // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0
+ // http://www.youtube.com/v/VIDEO_ID?version=3
+ // http://youtu.be/Djd6tPrxc08
+
+ url = unescape(url);
+
+ var youTubeId:String = "";
+
+ if (url.indexOf("?") > 0) {
+ // assuming: http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0
+ youTubeId = getYouTubeIdFromParam(url);
+
+ // if it's http://www.youtube.com/v/VIDEO_ID?version=3
+ if (youTubeId == "") {
+ youTubeId = getYouTubeIdFromUrl(url);
+ }
+ } else {
+ youTubeId = getYouTubeIdFromUrl(url);
+ }
+
+ return youTubeId;
+ }
+
+ // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0
+ private function getYouTubeIdFromParam(url:String):String {
+
+
+ var youTubeId:String = "";
+ var parts:Array = url.split('?');
+ var parameters:Array = parts[1].split('&');
+
+ for (var i:Number=0; i<parameters.length; i++) {
+ var paramParts = parameters[i].split('=');
+ if (paramParts[0] == "v") {
+
+ youTubeId = paramParts[1];
+ break;
+ }
+
+ }
+
+
+ return youTubeId;
+ }
+
+
+ // http://www.youtube.com/v/VIDEO_ID?version=3
+ // http://youtu.be/Djd6tPrxc08
+ private function getYouTubeIdFromUrl(url:String):String {
+
+
+ var youTubeId:String = "";
+
+ // remove any querystring elements
+ var parts:Array = url.split('?');
+ url = parts[0];
+
+ youTubeId = url.substring(url.lastIndexOf("/")+1);
+
+ return youTubeId;
+ }
+
+
+ // interface members
+ public function setSrc(url:String):void {
+ trace("yt setSrc()" + url );
+
+ _currentUrl = url;
+
+ _youTubeId = getYouTubeId(url);
+
+ if (!_playerIsLoaded && !_isChromeless) {
+ _playerLoader.load(new URLRequest("//www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1"));
+ }
+ }
+
+
+
+
+ public function load():void {
+ // do nothing
+ trace("yt load()");
+
+ if (_playerIsLoaded) {
+ player.loadVideoById(_youTubeId);
+ _timer.start();
+ } else {
+ /*
+ if (!_isChromless && _youTubeId != "") {
+ _playerLoader.load(new URLRequest("http://www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1"));
+ }
+ */
+ }
+ }
+
+ public function play():void {
+ if (_playerIsLoaded) {
+ _player.playVideo();
+ }
+
+ }
+
+ public function pause():void {
+ if (_playerIsLoaded) {
+ _player.pauseVideo();
+ }
+ }
+
+ public function stop():void {
+ if (_playerIsLoaded) {
+ _player.pauseVideo();
+ }
+ }
+
+ public function setCurrentTime(pos:Number):void {
+ //_player.seekTo(pos, false);
+ _player.seekTo(pos, true); // works in all places now
+ }
+
+ public function setVolume(volume:Number):void {
+ _player.setVolume(volume*100);
+ _volume = volume;
+ }
+
+ public function getVolume():Number {
+ return _player.getVolume()*100;
+ }
+
+ public function setMuted(muted:Boolean):void {
+ if (muted) {
+ _player.mute();
+
+ } else {
+ _player.unMute();
+ }
+ _muted = _player.isMuted();
+ sendEvent(HtmlMediaEvent.VOLUMECHANGE);
+ }
+
+
+ private function sendEvent(eventName:String) {
+
+ // calculate this to mimic HTML5
+ _bufferedTime = _bytesLoaded / _bytesTotal * _duration;
+
+ // build JSON
+ var values:String =
+ "duration:" + _duration +
+ ",framerate:" + _framerate +
+ ",currentTime:" + _currentTime +
+ ",muted:" + _isMuted +
+ ",paused:" + _isPaused +
+ ",ended:" + _isEnded +
+ ",volume:" + _volume +
+ ",src:\"" + _currentUrl + "\"" +
+ ",bytesTotal:" + _bytesTotal +
+ ",bufferedBytes:" + _bytesLoaded +
+ ",bufferedTime:" + _bufferedTime +
+ ",videoWidth:" + _videoWidth +
+ ",videoHeight:" + _videoHeight +
+ "";
+
+ _element.sendEvent(eventName, values);
+ }
+ }
+} \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/js/jeesh-extras.js b/files_videoviewer/mediaelement/src/js/jeesh-extras.js
index 7e662791a..7e662791a 100644..100755
--- a/files_videoviewer/mediaelement/src/js/jeesh-extras.js
+++ b/files_videoviewer/mediaelement/src/js/jeesh-extras.js
diff --git a/files_videoviewer/mediaelement/src/js/jeesh.js b/files_videoviewer/mediaelement/src/js/jeesh.js
index 42e3e43db..42e3e43db 100644..100755
--- a/files_videoviewer/mediaelement/src/js/jeesh.js
+++ b/files_videoviewer/mediaelement/src/js/jeesh.js
diff --git a/files_videoviewer/mediaelement/src/js/me-featuredetection.js b/files_videoviewer/mediaelement/src/js/me-featuredetection.js
index e7fcdd6a7..e7fcdd6a7 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-featuredetection.js
+++ b/files_videoviewer/mediaelement/src/js/me-featuredetection.js
diff --git a/files_videoviewer/mediaelement/src/js/me-header.js b/files_videoviewer/mediaelement/src/js/me-header.js
index 444d26682..444d26682 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-header.js
+++ b/files_videoviewer/mediaelement/src/js/me-header.js
diff --git a/files_videoviewer/mediaelement/src/js/me-i18n-locale-de.js b/files_videoviewer/mediaelement/src/js/me-i18n-locale-de.js
index c3f4638a9..c3f4638a9 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-i18n-locale-de.js
+++ b/files_videoviewer/mediaelement/src/js/me-i18n-locale-de.js
diff --git a/files_videoviewer/mediaelement/src/js/me-i18n-locale-zh.js b/files_videoviewer/mediaelement/src/js/me-i18n-locale-zh.js
new file mode 100755
index 000000000..ac2b3cb25
--- /dev/null
+++ b/files_videoviewer/mediaelement/src/js/me-i18n-locale-zh.js
@@ -0,0 +1,26 @@
+/*!
+ * This is a i18n.locale language object.
+ *
+ *<de> Traditional chinese translation by Tim Latz, latz.tim@gmail.com
+ *
+ * @author
+ * Tim Latz (latz.tim@gmail.com)
+ *
+ * @see
+ * me-i18n.js
+ *
+ * @params
+ * - exports - CommonJS, window ..
+ */
+;(function(exports, undefined) {
+
+ "use strict";
+
+ exports.zh = {
+ "Fullscreen" : "全螢幕",
+ "Go Fullscreen" : "全屏模式",
+ "Turn off Fullscreen" : "退出全屏模式",
+ "Close" : "關閉"
+ };
+
+}(mejs.i18n.locale.strings));
diff --git a/files_videoviewer/mediaelement/src/js/me-i18n.js b/files_videoviewer/mediaelement/src/js/me-i18n.js
index 97df9115e..5efe64f02 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-i18n.js
+++ b/files_videoviewer/mediaelement/src/js/me-i18n.js
@@ -37,12 +37,11 @@
* me-i18n-locale.js
*
* @params
- * - $ - zepto || jQuery ..
* - context - document, iframe ..
* - exports - CommonJS, window ..
*
*/
-;(function($, context, exports, undefined) {
+;(function(context, exports, undefined) {
"use strict";
var i18n = {
"locale": {
@@ -192,4 +191,4 @@
// end i18n
exports.i18n = i18n;
-}(jQuery, document, mejs)); \ No newline at end of file
+}(document, mejs));
diff --git a/files_videoviewer/mediaelement/src/js/me-mediaelements.js b/files_videoviewer/mediaelement/src/js/me-mediaelements.js
index 2918b32a5..5aab607bc 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-mediaelements.js
+++ b/files_videoviewer/mediaelement/src/js/me-mediaelements.js
@@ -153,13 +153,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) {
@@ -322,5 +322,6 @@ mejs.PluginMediaElement.prototype = {
remove: function() {
mejs.Utility.removeSwf(this.pluginElement.id);
+ mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
}
};
diff --git a/files_videoviewer/mediaelement/src/js/me-namespace.js b/files_videoviewer/mediaelement/src/js/me-namespace.js
index d4e6a9e44..c9fc1d785 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-namespace.js
+++ b/files_videoviewer/mediaelement/src/js/me-namespace.js
@@ -2,7 +2,7 @@
var mejs = mejs || {};
// version number
-mejs.version = '2.10.3';
+mejs.version = '2.11.1';
// player number (for missing, same id attr)
mejs.meIndex = 0;
@@ -17,9 +17,9 @@ 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']}
]
-}; \ No newline at end of file
+};
diff --git a/files_videoviewer/mediaelement/src/js/me-plugindetector.js b/files_videoviewer/mediaelement/src/js/me-plugindetector.js
index e71495f85..e71495f85 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-plugindetector.js
+++ b/files_videoviewer/mediaelement/src/js/me-plugindetector.js
diff --git a/files_videoviewer/mediaelement/src/js/me-shim.js b/files_videoviewer/mediaelement/src/js/me-shim.js
index 13af7bdee..63992b9bc 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-shim.js
+++ b/files_videoviewer/mediaelement/src/js/me-shim.js
@@ -9,6 +9,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) {
@@ -97,6 +102,10 @@ mejs.MediaElementDefaults = {
flashStreamer: '',
// turns on the smoothing filter in Flash
enablePluginSmoothing: false,
+ // enabled pseudo-streaming (seek) on .mp4 files
+ enablePseudoStreaming: false,
+ // start query parameter sent to server for pseudo-streaming
+ pseudoStreamingStartQueryParam: 'start',
// name of silverlight file
silverlightName: 'silverlightmediaelement.xap',
// default if the <video width> is not specified
@@ -362,7 +371,7 @@ mejs.HtmlMediaElementShim = {
getTypeFromFile: function(url) {
url = url.split('?')[0];
- var ext = url.substring(url.lastIndexOf('.') + 1);
+ var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return (/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext);
},
@@ -479,7 +488,8 @@ mejs.HtmlMediaElementShim = {
'startvolume=' + options.startVolume,
'timerrate=' + options.timerRate,
'flashstreamer=' + options.flashStreamer,
- 'height=' + height];
+ 'height=' + height,
+ 'pseudostreamstart=' + options.pseudoStreamingStartQueryParam];
if (playback.url !== null) {
if (playback.method == 'flash') {
@@ -494,6 +504,9 @@ mejs.HtmlMediaElementShim = {
if (options.enablePluginSmoothing) {
initVars.push('smoothing=true');
}
+ if (options.enablePseudoStreaming) {
+ initVars.push('pseudostreaming=true');
+ }
if (controls) {
initVars.push('controls=true'); // shows controls in the plugin if desired
}
@@ -504,7 +517,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" />' +
@@ -521,7 +534,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" />' +
@@ -546,7 +559,8 @@ mejs.HtmlMediaElementShim = {
'src="' + options.pluginPath + options.flashName + '" ' +
'flashvars="' + initVars.join('&') + '" ' +
'width="' + width + '" ' +
-'height="' + height + '"></embed>';
+'height="' + height + '" ' +
+'class="mejs-shim"></embed>';
}
break;
@@ -579,16 +593,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>';
*/
@@ -772,7 +786,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>';
@@ -786,7 +800,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" />' +
@@ -795,7 +809,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>';
diff --git a/files_videoviewer/mediaelement/src/js/me-utility.js b/files_videoviewer/mediaelement/src/js/me-utility.js
index 383aa478b..00c1a9381 100644..100755
--- a/files_videoviewer/mediaelement/src/js/me-utility.js
+++ b/files_videoviewer/mediaelement/src/js/me-utility.js
@@ -1,4 +1,3 @@
-
/*
Utility methods
*/
@@ -20,6 +19,7 @@ mejs.Utility = {
j,
path = '',
name = '',
+ pos,
script,
scripts = document.getElementsByTagName('script'),
il = scripts.length,
@@ -29,8 +29,9 @@ mejs.Utility = {
script = scripts[i].src;
for (j = 0; j < jl; j++) {
name = scriptNames[j];
- if (script.indexOf(name) > -1) {
- path = script.substring(0, script.indexOf(name));
+ pos = script.indexOf(name);
+ if (pos > -1 && pos == script.length - name.length) {
+ path = script.substring(0, pos);
break;
}
}
@@ -110,7 +111,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(){
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-ads-vast.js b/files_videoviewer/mediaelement/src/js/mep-feature-ads-vast.js
new file mode 100755
index 000000000..623419dc2
--- /dev/null
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-ads-vast.js
@@ -0,0 +1,243 @@
+
+// VAST ads plugin
+// Sponsored by Minoto Video
+
+(function($) {
+
+ $.extend(mejs.MepDefaults, {
+ // URL to vast data: 'http://minotovideo.com/sites/minotovideo.com/files/upload/eday_vast_tag.xml'
+ vastAdTagUrl: ''
+ });
+
+ $.extend(MediaElementPlayer.prototype, {
+ buildvast: function(player, controls, layers, media) {
+
+ var t = this;
+
+ // begin loading
+ if (t.options.vastAdTagUrl != '') {
+ t.vastLoadAdTagInfo();
+ }
+
+ // make sure the preroll ad system is ready (it will ensure it can't be called twice)
+ t.buildads(player, controls, layers, media);
+
+
+ t.vastSetupEvents();
+ },
+
+ vastAdTagIsLoading: false,
+
+ vastAdTagIsLoaded: false,
+
+ vastStartedPlaying: false,
+
+ vastAdTags: [],
+
+ vastSetupEvents: function() {
+ var t = this;
+
+
+ // START: preroll
+ t.container.on('mejsprerollstarted', function() {
+
+ console.log('VAST','mejsprerollstarted');
+
+ if (t.vastAdTags.length > 0) {
+
+ var adTag = t.vastAdTags[0];
+
+ // always fire this event
+ if (adTag.trackingEvents['start']) {
+ t.adsLoadUrl(adTag.trackingEvents['start']);
+ }
+
+ // only do impressions once
+ if (!adTag.shown && adTag.impressions.length > 0) {
+
+ for (var i=0, il=adTag.impressions.length; i<il; i++) {
+ t.adsLoadUrl(adTag.impressions[i]);
+ }
+ }
+
+ adTag.shown = true;
+ }
+
+ });
+
+ // END: preroll
+ t.container.on('mejsprerollended', function() {
+
+ console.log('VAST','mejsprerollended');
+
+ if (t.vastAdTags.length > 0 && t.vastAdTags[0].trackingEvents['complete']) {
+ t.adsLoadUrl(t.vastAdTags[0].trackingEvents['complete']);
+ }
+
+ });
+
+ },
+
+ vastSetAdTagUrl: function(url) {
+
+ var t = this;
+
+ // set and reset
+ t.options.vastAdTagUrl = url;
+ t.vastAdTagIsLoaded = false;
+ t.vastAdTags = [];
+ },
+
+ vastLoadAdTagInfo: function() {
+ console.log('loading vast ad data');
+
+ var t = this;
+
+ // set this to stop playback
+ t.adsDataIsLoading = true;
+ t.vastAdTagIsLoading = true;
+
+ // try straight load first
+ t.loadAdTagInfoDirect();
+ },
+
+ loadAdTagInfoDirect: function() {
+ console.log('loading vast:direct');
+
+ var t= this;
+
+ $.ajax({
+ url: t.options.vastAdTagUrl,
+ crossDomain: true,
+ success: function(data) {
+ console.log('vast:direct:success', data);
+
+ t.vastParseVastData(data)
+ },
+ error: function(err) {
+ console.log('vast:direct:error', err);
+
+ // fallback to Yahoo proxy
+ t.loadAdTagInfoProxy();
+ }
+ });
+ },
+
+ loadAdTagInfoProxy: function() {
+ console.log('loading vast:proxy:yahoo');
+
+ var t = this,
+ protocol = location.protocol,
+ hostname = location.hostname,
+ exRegex = RegExp(protocol + '//' + hostname),
+ query = 'select * from xml where url="' + encodeURI(t.options.vastAdTagUrl) +'"',
+ yahooUrl = 'http' + (/^https/.test(protocol)?'s':'') + '://query.yahooapis.com/v1/public/yql?format=xml&q=' + query;
+
+
+
+ $.ajax({
+ url: yahooUrl,
+ crossDomain: true,
+ success: function(data) {
+ console.log('vast:proxy:yahoo:success', data);
+
+ t.vastParseVastData(data);
+ },
+ error: function(err) {
+ console.log('vast:proxy:yahoo:error', err);
+ }
+ });
+ },
+
+ vastParseVastData: function(data) {
+
+ var t = this;
+
+ // clear out data
+ t.vastAdTags = [];
+
+ $(data).find('Ad').each(function(index, node) {
+
+ var
+ adNode = $(node),
+
+ adTag = {
+ id: adNode.attr('id'),
+ title: $.trim( adNode.find('AdTitle').text() ),
+ description: $.trim( adNode.find('Description').text() ),
+ impressions: [],
+ clickThrough: $.trim( adNode.find('ClickThrough').text() ),
+ mediaFiles: [],
+ trackingEvents: {},
+
+ // internal tracking if it's been used
+ shown: false
+ };
+
+ t.vastAdTags.push(adTag);
+
+
+ // parse all needed nodes
+ adNode.find('Impression').each(function() {
+ adTag.impressions.push( $.trim( $(this).text() ) );
+ });
+
+ adNode.find('Tracking').each(function(index, node) {
+ var trackingEvent = $(node);
+
+ adTag.trackingEvents[trackingEvent.attr('event')] = $.trim( trackingEvent.text() );
+
+ });
+
+
+ adNode.find('MediaFile').each(function(index, node) {
+ var mediaFile = $(node),
+ type = mediaFile.attr('type');
+
+ if (t.media.canPlayType(type).toString().replace(/no/,'').replace(/false/,'') != '') {
+
+ adTag.mediaFiles.push({
+ id: mediaFile.attr('id'),
+ delivery: mediaFile.attr('delivery'),
+ type: mediaFile.attr('type'),
+ bitrate: mediaFile.attr('bitrate'),
+ width: mediaFile.attr('width'),
+ height: mediaFile.attr('height'),
+ url: $.trim( mediaFile.text() )
+ } );
+ }
+ });
+
+ });
+
+ // DONE
+ t.vastLoaded();
+ },
+
+ vastLoaded: function() {
+ var t = this;
+
+ t.vastAdTagIsLoaded = true;
+ t.vastAdTagIsLoading = false;
+ t.adsDataIsLoading = false;
+
+ t.vastStartPreroll();
+ },
+
+ vastStartPreroll: function() {
+ console.log('vastStartPreroll');
+
+ var t = this;
+
+ // if we have a media URL, then send it up to the ads plugin as a preroll
+ if (t.vastAdTags.length > 0 && t.vastAdTags[0].mediaFiles.length > 0) {
+
+ t.options.adsPrerollMediaUrl = t.vastAdTags[0].mediaFiles[0].url;
+ t.options.adsPrerollAdUrl = t.vastAdTags[0].clickThrough;
+ t.adsStartPreroll();
+ }
+ }
+
+ });
+
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-ads.js b/files_videoviewer/mediaelement/src/js/mep-feature-ads.js
new file mode 100755
index 000000000..9a8176fcc
--- /dev/null
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-ads.js
@@ -0,0 +1,312 @@
+// VAST ads plugin
+// Sponsored by Minoto Video
+
+// 2013/02/01 0.5 research
+// 2013/02/09 1.5 build loading mechanism
+// 2013/02/10 2.5 events to play preroll, skip function, start/end calls, \
+// 2013/02/11 2 click events
+// ----
+// 2013/02/23 3.5 split into a generic pre-roll plugin
+
+
+(function($) {
+
+ // on time insert into head
+ $('head').append($('<style>' +
+'.mejs-ads a {' +
+' display: block; ' +
+' position: absolute;' +
+' right: 0;' +
+' top: 0;' +
+' width: 100%; ' +
+' height: 100%; ' +
+' display: block; ' +
+'}' +
+'.mejs-ads .mejs-ads-skip-block {' +
+' display: block; ' +
+' position: absolute;' +
+' right: 0;' +
+' top: 0;' +
+' padding: 10px; ' +
+' background: #000; ' +
+' background: rgba(0,0,0,0.5); ' +
+' color: #fff; ' +
+'}' +
+'.mejs-ads .mejs-ads-skip-button {' +
+' cursor: pointer; ' +
+'}' +
+'.mejs-ads .mejs-ads-skip-button:hover {' +
+' text-decoration: underline; ' +
+'}' +
+ '</style>'));
+
+
+ $.extend(mejs.MepDefaults, {
+ // URL to a media file
+ adsPrerollMediaUrl: '',
+
+ // URL for lcicking ad
+ adsPrerollAdUrl: '',
+
+ // if true, allows user to skip the pre-roll ad
+ adsPrerollAdEnableSkip: false,
+
+ // if adsPrerollAdEnableSkip=true and this is a positive number, it will only allow skipping after the time has elasped
+ adsPrerollAdSkipSeconds: -1
+ });
+
+ $.extend(MediaElementPlayer.prototype, {
+
+ // allows other plugins to all this one
+ adsLoaded: false,
+
+ // prevents playback in until async ad data is ready (e.g. VAST)
+ adsDataIsLoading: false,
+
+ // stores the main media URL when an ad is playing
+ adsCurrentMediaUrl: '',
+ adsCurrentMediaDuration: 0,
+
+ // true when the user clicks play for the first time, or if autoplay is set
+ adsPlayerHasStarted: false,
+
+ buildads: function(player, controls, layers, media) {
+
+ var t = this;
+
+ if (t.adsLoaded) {
+ return;
+ } else {
+ t.adsLoaded = true;
+ }
+
+ // add layer for ad links and skipping
+ player.adsLayer =
+ $('<div class="mejs-layer mejs-overlay mejs-ads">' +
+ '<a href="#" target="_blank">&nbsp;</a>' +
+ '<div class="mejs-ads-skip-block">' +
+ '<span class="mejs-ads-skip-message"></span>' +
+ '<span class="mejs-ads-skip-button">Skip Ad &raquo;</span>' +
+ '</div>' +
+ '</div>')
+ .insertBefore( layers.find('.mejs-overlay-play') )
+ .hide();
+
+ player.adsLayer.find('a')
+ .on('click', $.proxy(t.adsAdClick, t) );
+
+ player.adsSkipBlock = player.adsLayer.find('.mejs-ads-skip-block').hide();
+ player.adsSkipMessage = player.adsLayer.find('.mejs-ads-skip-message').hide();
+
+ player.adsSkipButton = player.adsLayer.find('.mejs-ads-skip-button')
+ .on('click', $.proxy(t.adsSkipClick, t) );
+
+
+ // create proxies (only needed for events we want to remove later)
+ t.adsMediaTryingToStartProxy = $.proxy(t.adsMediaTryingToStart, t);
+ t.adsPrerollStartedProxy = $.proxy(t.adsPrerollStarted, t);
+ t.adsPrerollMetaProxy = $.proxy(t.adsPrerollMeta, t);
+ t.adsPrerollUpdateProxy = $.proxy(t.adsPrerollUpdate, t);
+ t.adsPrerollEndedProxy = $.proxy(t.adsPrerollEnded, t);
+
+ // check for start
+ t.media.addEventListener('play', t.adsMediaTryingToStartProxy );
+ t.media.addEventListener('playing', t.adsMediaTryingToStartProxy );
+ t.media.addEventListener('canplay', t.adsMediaTryingToStartProxy );
+ t.media.addEventListener('loadedmetadata', t.adsMediaTryingToStartProxy );
+
+ console.log('setup ads', t.options.adsPrerollMediaUrl);
+
+ if (t.options.adsPrerollMediaUrl != '') {
+ t.adsStartPreroll();
+ }
+ },
+
+
+ adsMediaTryingToStart: function() {
+
+ var t = this;
+
+ // make sure to pause until the ad data is loaded
+ if (t.adsDataIsLoading && !t.media.paused) {
+ t.media.pause();
+ }
+
+ t.adsPlayerHasStarted = true;
+ },
+
+ adsStartPreroll: function() {
+
+ var t = this;
+
+ console.log('adsStartPreroll', 'url', t.options.adsPrerollMediaUrl);
+
+
+ t.media.addEventListener('loadedmetadata', t.adsPrerollMetaProxy );
+ t.media.addEventListener('playing', t.adsPrerollStartedProxy );
+ t.media.addEventListener('ended', t.adsPrerollEndedProxy )
+ t.media.addEventListener('timeupdate', t.adsPrerollUpdateProxy );
+
+ // change URLs to the preroll ad
+ t.adsCurrentMediaUrl = t.media.src;
+ t.adsCurrentMediaDuration = t.media.duration;
+
+ t.media.setSrc(t.options.adsPrerollMediaUrl);
+ t.media.load();
+
+ // if autoplay was on, or if the user pressed play
+ // while the ad data was still loading, then start the ad right away
+ if (t.adsPlayerHasStarted) {
+ t.media.play();
+ }
+ },
+
+ adsPrerollMeta: function() {
+
+ var t = this,
+ newDuration = 0;
+
+ console.log('loadedmetadata', t.media.duration, t.adsCurrentMediaDuration);
+
+ // if duration has been set, show that
+ if (t.options.duration > 0) {
+ newDuration = t.options.duration;
+ } else if (!isNaN(t.adsCurrentMediaDuration)) {
+ newDuration = t.adsCurrentMediaDuration;
+ }
+
+ setTimeout(function() {
+ t.controls.find('.mejs-duration').html(
+ mejs.Utility.secondsToTimeCode(newDuration, t.options.alwaysShowHours || newDuration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25)
+ );
+ }, 250);
+ },
+
+ adsPrerollStarted: function() {
+ console.log('adsPrerollStarted');
+
+ var t = this;
+ t.media.removeEventListener('playing', t.adsPrerollStartedProxy);
+
+ // turn off controls until the preroll is done
+ t.disableControls();
+ t.hideControls();
+
+ // enable clicking through
+ t.adsLayer.show();
+ if (t.options.adsPrerollAdUrl != '') {
+ t.adsLayer.find('a').attr('href', t.options.adsPrerollAdUrl);
+ }
+
+ // possibly allow the skip button to work
+ if (t.options.adsPrerollAdEnableSkip) {
+ t.adsSkipBlock.show();
+
+ if (t.options.adsPrerollAdSkipSeconds > 0) {
+ t.adsSkipMessage.html('Skip in ' + t.options.adsPrerollAdSkipSeconds.toString() + ' seconds.').show();
+ t.adsSkipButton.hide();
+ } else {
+ t.adsSkipMessage.hide();
+ t.adsSkipButton.show();
+ }
+ } else {
+ t.adsSkipBlock.hide();
+ }
+
+ // send click events
+ t.container.trigger('mejsprerollstarted');
+ },
+
+ adsPrerollUpdate: function() {
+ //console.log('adsPrerollUpdate');
+
+ var t = this;
+
+ if (t.options.adsPrerollAdEnableSkip && t.options.adsPrerollAdSkipSeconds > 0) {
+ // update message
+ if (t.media.currentTime > t.options.adsPrerollAdSkipSeconds) {
+ t.adsSkipButton.show();
+ t.adsSkipMessage.hide();
+ } else {
+ t.adsSkipMessage.html('Skip in ' + Math.round( t.options.adsPrerollAdSkipSeconds - t.media.currentTime ).toString() + ' seconds.')
+ }
+
+ }
+
+ t.container.trigger('mejsprerolltimeupdate');
+ },
+
+ adsPrerollEnded: function() {
+ console.log('adsPrerollEnded');
+
+ var t = this;
+
+ t.container.trigger('mejsprerollended');
+
+ t.adRestoreMainMedia();
+ },
+
+ adRestoreMainMedia: function() {
+
+ console.log('adRestoreMainMedia', this.adsCurrentMediaUrl);
+
+ var t = this;
+
+ t.media.setSrc(t.adsCurrentMediaUrl);
+ setTimeout(function() {
+ t.media.load();
+ t.media.play();
+ }, 10);
+
+ t.enableControls();
+ t.showControls();
+
+ t.adsLayer.hide();
+
+ t.media.removeEventListener('ended', t.adsPrerollEndedProxy);
+ t.media.removeEventListener('loadedmetadata', t.adsPrerollMetaProxy);
+ t.media.removeEventListener('timeupdate', t.adsPrerollUpdateProxy);
+
+ t.container.trigger('mejsprerollmainstarted');
+ },
+
+ adsAdClick: function(e) {
+ console.log('adsAdClicked');
+
+ var t = this;
+
+ if (t.media.paused) {
+ t.media.play();
+ } else {
+ t.media.pause();
+ }
+
+ t.container.trigger('mejsprerolladsclicked');
+ },
+
+ adsSkipClick: function() {
+ console.log('adsSkipClick');
+ var t = this;
+
+ t.container.trigger('mejsprerollskipclicked');
+ t.container.trigger('mejsprerollended');
+
+ t.adRestoreMainMedia();
+ },
+
+ // fires off fake XHR requests
+ adsLoadUrl: function(url) {
+ console.log('adsLoadUrl', url);
+
+ var img = new Image(),
+ rnd = Math.round(Math.random()*100000);
+
+ img.src = url + ((url.indexOf('?') > 0) ? '&' : '?') + 'random' + rnd + '=' + rnd;
+ img.loaded = function() {
+ img = null;
+ }
+ }
+
+ });
+
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-backlight.js b/files_videoviewer/mediaelement/src/js/mep-feature-backlight.js
index 8d972c5e4..8d972c5e4 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-backlight.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-backlight.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js b/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
index f92a0bd33..f15d7a643 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
@@ -92,6 +92,10 @@ $.extend(mejs.MepDefaults,
});
},
+
+ cleancontextmenu: function(player) {
+ player.contextMenu.remove();
+ },
isContextMenuEnabled: true,
enableContextMenu: function() {
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-endedhtml.js b/files_videoviewer/mediaelement/src/js/mep-feature-endedhtml.js
index 1a4fabb66..1a4fabb66 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-endedhtml.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-endedhtml.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js b/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
index 49c089f7b..5eaaf3f6b 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
@@ -27,15 +27,7 @@
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;
@@ -47,7 +39,13 @@
// 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,
@@ -56,7 +54,7 @@
container = player.container,
fullscreenBtn =
$('<div class="mejs-button mejs-fullscreen-button">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '" aria-label="' + t.options.fullscreenText + '"></button>' +
'</div>')
.appendTo(controls);
@@ -110,9 +108,9 @@
restoreControls = function() {
if (fullscreenIsDisabled) {
// hide the hovers
- videoHoverDiv.hide();
- controlsLeftHoverDiv.hide();
- controlsRightHoverDiv.hide();
+ for (var i in hoverDivs) {
+ hoverDivs[i].hide();
+ }
// restore the control bar
fullscreenBtn.css('pointer-events', '');
@@ -122,41 +120,54 @@
fullscreenIsDisabled = false;
}
},
- videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
- controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
- controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
+ hoverDivs = {},
+ hoverDivNames = ['top', 'left', 'right', 'bottom'],
+ i, len,
positionHoverDivs = function() {
- var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
- videoHoverDiv.css(style);
- controlsLeftHoverDiv.css(style);
- controlsRightHoverDiv.css(style);
+ var fullScreenBtnOffsetLeft = fullscreenBtn.offset().left - t.container.offset().left,
+ fullScreenBtnOffsetTop = fullscreenBtn.offset().top - t.container.offset().top,
+ fullScreenBtnWidth = fullscreenBtn.outerWidth(true),
+ fullScreenBtnHeight = fullscreenBtn.outerHeight(true),
+ containerWidth = t.container.width(),
+ containerHeight = t.container.height();
+
+ for (i in hoverDivs) {
+ hoverDivs[i].css({position: 'absolute', top: 0, left: 0}); //, backgroundColor: '#f00'});
+ }
// over video, but not controls
- videoHoverDiv
- .width( t.container.width() )
- .height( t.container.height() - t.controls.height() );
+ hoverDivs['top']
+ .width( containerWidth )
+ .height( fullScreenBtnOffsetTop );
// over controls, but not the fullscreen button
- var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
- fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
-
- controlsLeftHoverDiv
- .width( fullScreenBtnOffset )
- .height( t.controls.height() )
- .css({top: t.container.height() - t.controls.height()});
+ hoverDivs['left']
+ .width( fullScreenBtnOffsetLeft )
+ .height( fullScreenBtnHeight )
+ .css({top: fullScreenBtnOffsetTop});
// after the fullscreen button
- controlsRightHoverDiv
- .width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
- .height( t.controls.height() )
- .css({top: t.container.height() - t.controls.height(),
- left: fullScreenBtnOffset + fullScreenBtnWidth});
+ hoverDivs['right']
+ .width( containerWidth - fullScreenBtnOffsetLeft - fullScreenBtnWidth )
+ .height( fullScreenBtnHeight )
+ .css({top: fullScreenBtnOffsetTop,
+ left: fullScreenBtnOffsetLeft + fullScreenBtnWidth});
+
+ // under the fullscreen button
+ hoverDivs['bottom']
+ .width( containerWidth )
+ .height( containerHeight - fullScreenBtnHeight - fullScreenBtnOffsetTop )
+ .css({top: fullScreenBtnOffsetTop + fullScreenBtnHeight});
};
- $(document).resize(function() {
+ t.globalBind('resize', function() {
positionHoverDivs();
});
+ for (i = 0, len = hoverDivNames.length; i < len; i += 1) {
+ hoverDivs[hoverDivNames[i]] = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls).hide();
+ }
+
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
fullscreenBtn
.mouseover(function() {
@@ -174,9 +185,9 @@
t.controls.css('pointer-events', 'none');
// show the divs that will restore things
- videoHoverDiv.show();
- controlsRightHoverDiv.show();
- controlsLeftHoverDiv.show();
+ for (i in hoverDivs) {
+ hoverDivs[i].show();
+ }
positionHoverDivs();
fullscreenIsDisabled = true;
@@ -193,7 +204,7 @@
// 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) {
@@ -251,13 +262,20 @@
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();
+ },
+
+ containerSizeTimeout: null,
+
enterFullScreen: function() {
var t = this;
@@ -350,7 +368,7 @@
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
// Actually, it seems to be needed for IE8, too
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
- setTimeout(function() {
+ t.containerSizeTimeout = setTimeout(function() {
t.container.css({width: '100%', height: '100%'});
t.setControlsSize();
}, 500);
@@ -361,7 +379,7 @@
.width('100%')
.height('100%');
} else {
- t.container.find('object, embed, iframe')
+ t.container.find('.mejs-shim')
.width('100%')
.height('100%');
@@ -388,6 +406,9 @@
var t = this;
+ // Prevent container from attempting to stretch a second time
+ clearTimeout(t.containerSizeTimeout);
+
// firefox can't adjust plugins
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
t.media.setFullscreen(false);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-googleanalytics.js b/files_videoviewer/mediaelement/src/js/mep-feature-googleanalytics.js
index fdef1fecf..fdef1fecf 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-googleanalytics.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-googleanalytics.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-loop.js b/files_videoviewer/mediaelement/src/js/mep-feature-loop.js
index 5c6a796a2..b30da6c42 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-loop.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-loop.js
@@ -7,7 +7,7 @@
// create the loop button
loop =
$('<div class="mejs-button mejs-loop-button ' + ((player.options.loop) ? 'mejs-loop-on' : 'mejs-loop-off') + '">' +
- '<button type="button" aria-controls="' + t.id + '" title="Toggle Loop"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="Toggle Loop" aria-label="Toggle Loop"></button>' +
'</div>')
// append it to the toolbar
.appendTo(controls)
@@ -23,4 +23,4 @@
}
});
-})(mejs.$); \ No newline at end of file
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-playlist.js b/files_videoviewer/mediaelement/src/js/mep-feature-playlist.js
index 93dcad7ae..93dcad7ae 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-playlist.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-playlist.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-playpause.js b/files_videoviewer/mediaelement/src/js/mep-feature-playpause.js
index d0363a2e4..1d88e5079 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-playpause.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-playpause.js
@@ -11,7 +11,7 @@
t = this,
play =
$('<div class="mejs-button mejs-playpause-button mejs-play" >' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.playpauseText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.playpauseText + '" aria-label="' + t.options.playpauseText + '"></button>' +
'</div>')
.appendTo(controls)
.click(function(e) {
@@ -43,4 +43,4 @@
}
});
-})(mejs.$); \ No newline at end of file
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-postroll.js b/files_videoviewer/mediaelement/src/js/mep-feature-postroll.js
index 5de9a342a..5de9a342a 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-postroll.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-postroll.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-progress.js b/files_videoviewer/mediaelement/src/js/mep-feature-progress.js
index 0fb476094..bfc1c4ce2 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-progress.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-progress.js
@@ -71,21 +71,20 @@
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) {
@@ -95,7 +94,7 @@
.bind('mouseleave',function(e) {
mouseIsOver = false;
if (!mouseIsDown) {
- $(document).unbind('.dur');
+ t.globalUnbind('.dur');
timefloat.hide();
}
});
@@ -161,8 +160,8 @@
// 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);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-sourcechooser.js b/files_videoviewer/mediaelement/src/js/mep-feature-sourcechooser.js
index a2723c17e..bdaf14ec7 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-sourcechooser.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-sourcechooser.js
@@ -12,7 +12,7 @@
player.sourcechooserButton =
$('<div class="mejs-button mejs-sourcechooser-button">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.sourcechooserText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.sourcechooserText + '" aria-label="' + t.options.sourcechooserText + '"></button>'+
'<div class="mejs-sourcechooser-selector">'+
'<ul>'+
'</ul>'+
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-speed.js b/files_videoviewer/mediaelement/src/js/mep-feature-speed.js
index 4250652aa..4250652aa 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-speed.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-speed.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-stop.js b/files_videoviewer/mediaelement/src/js/mep-feature-stop.js
index f9ad38cfb..d70481ec6 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-stop.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-stop.js
@@ -10,7 +10,7 @@
var t = this,
stop =
$('<div class="mejs-button mejs-stop-button mejs-stop">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '"></button>' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '" aria-label="' + t.options.stopText + '"></button>' +
'</div>')
.appendTo(controls)
.click(function() {
@@ -30,4 +30,4 @@
}
});
-})(mejs.$); \ No newline at end of file
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-time.js b/files_videoviewer/mediaelement/src/js/mep-feature-time.js
index 4c35df5b5..9240ec31a 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-time.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-time.js
@@ -69,14 +69,14 @@
}
},
- 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));
}
}
});
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js b/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
index baa519777..f3d3ce8af 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
@@ -4,8 +4,17 @@
$.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, {
@@ -13,24 +22,23 @@
hasChapters: false,
buildtracks: function(player, controls, layers, media) {
- if (!player.isVideo)
- return;
-
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 =
$('<div class="mejs-button mejs-captions-button">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.tracksText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.tracksText + '" aria-label="' + t.options.tracksText + '"></button>'+
'<div class="mejs-captions-selector">'+
'<ul>'+
'<li>'+
@@ -40,35 +48,42 @@
'</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;
-
- 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')
- //});
+ 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
+ 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
@@ -101,12 +116,22 @@
}
}
+ // 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();
@@ -134,6 +159,28 @@
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;
@@ -145,6 +192,8 @@
} else {
// add done?
t.isLoadingTrack = false;
+
+ t.checkForTracks();
}
},
@@ -186,6 +235,10 @@
}
}, false);
}
+
+ if (track.kind == 'slides') {
+ t.setupSlides(track);
+ }
},
error: function() {
t.loadNextTrack();
@@ -241,6 +294,27 @@
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() {
@@ -265,6 +339,70 @@
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
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-visualcontrols.js b/files_videoviewer/mediaelement/src/js/mep-feature-visualcontrols.js
index 893aabe0e..893aabe0e 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-visualcontrols.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-visualcontrols.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-volume.js b/files_videoviewer/mediaelement/src/js/mep-feature-volume.js
index 278311c05..bcf2c2414 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-feature-volume.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-volume.js
@@ -21,7 +21,7 @@
// horizontal version
$('<div class="mejs-button mejs-volume-button mejs-mute">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '" aria-label="' + t.options.muteText + '"></button>'+
'</div>' +
'<div class="mejs-horizontal-volume-slider">'+ // outer background
'<div class="mejs-horizontal-volume-total"></div>'+ // line background
@@ -33,7 +33,7 @@
// vertical version
$('<div class="mejs-button mejs-volume-button mejs-mute">'+
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '"></button>'+
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.muteText + '" aria-label="' + t.options.muteText + '"></button>'+
'<div class="mejs-volume-slider">'+ // outer background
'<div class="mejs-volume-total"></div>'+ // line background
'<div class="mejs-volume-current"></div>'+ // current volume
@@ -170,18 +170,17 @@
})
.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;
@@ -209,7 +208,12 @@
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);
diff --git a/files_videoviewer/mediaelement/src/js/mep-header.js b/files_videoviewer/mediaelement/src/js/mep-header.js
index ef283252e..ef283252e 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-header.js
+++ b/files_videoviewer/mediaelement/src/js/mep-header.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-library.js b/files_videoviewer/mediaelement/src/js/mep-library.js
index 9bdb99be2..9bdb99be2 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-library.js
+++ b/files_videoviewer/mediaelement/src/js/mep-library.js
diff --git a/files_videoviewer/mediaelement/src/js/mep-player.js b/files_videoviewer/mediaelement/src/js/mep-player.js
index 342276537..58c97585e 100644..100755
--- a/files_videoviewer/mediaelement/src/js/mep-player.js
+++ b/files_videoviewer/mediaelement/src/js/mep-player.js
@@ -50,6 +50,8 @@
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
@@ -151,7 +153,7 @@
mejs.mepIndex = 0;
- mejs.players = [];
+ mejs.players = {};
// wraps a MediaElement object in player controls
mejs.MediaElementPlayer = function(node, o) {
@@ -183,8 +185,11 @@
// 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();
@@ -236,7 +241,7 @@
t.media.play();
}
- } else if (mf.isAndroid && t.AndroidUseNativeControls) {
+ } else if (mf.isAndroid && t.options.AndroidUseNativeControls) {
// leave default player
@@ -247,9 +252,6 @@
// 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') + '">'+
@@ -341,8 +343,10 @@
// create MediaElement shim
mejs.MediaElement(t.$media[0], meOptions);
- // controls are shown when loaded
- t.container.trigger('controlsshown');
+ if (typeof(t.container) != 'undefined'){
+ // controls are shown when loaded
+ t.container.trigger('controlsshown');
+ }
},
showControls: function(doAnimation) {
@@ -588,7 +592,11 @@
}
});
}
-
+
+ if(t.options.hideVideoControlsOnLoad) {
+ t.hideControls(false);
+ }
+
// check for autoplay
if (autoplay && !t.options.alwaysShowControls) {
t.hideControls();
@@ -612,10 +620,11 @@
// 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();
}
@@ -672,7 +681,7 @@
}, 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)) ) {
@@ -746,17 +755,12 @@
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) {
@@ -807,7 +811,8 @@
// 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);
}
});
@@ -972,7 +977,7 @@
var t = this;
// listen for key presses
- $(document).keydown(function(e) {
+ t.globalBind('keydown', function(e) {
if (player.hasFocus && player.options.enableKeyboard) {
@@ -994,7 +999,7 @@
});
// 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;
}
@@ -1013,7 +1018,7 @@
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') || '',
@@ -1055,29 +1060,97 @@
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 object so that pauseOtherPlayers doesn't blow up when trying to pause a non existance flash api.
+ delete mejs.players[t.id];
t.container.remove();
+ t.globalUnbind();
+ delete t.node.player;
}
};
+ (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;
};
}
diff --git a/files_videoviewer/mediaelement/src/silverlight/App.xaml b/files_videoviewer/mediaelement/src/silverlight/App.xaml
index 47cf6fb13..47cf6fb13 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/App.xaml
+++ b/files_videoviewer/mediaelement/src/silverlight/App.xaml
diff --git a/files_videoviewer/mediaelement/src/silverlight/App.xaml.cs b/files_videoviewer/mediaelement/src/silverlight/App.xaml.cs
index be67bfbf7..be67bfbf7 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/App.xaml.cs
+++ b/files_videoviewer/mediaelement/src/silverlight/App.xaml.cs
diff --git a/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml b/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml
index 54af028fe..54af028fe 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml
+++ b/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml
diff --git a/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml.cs b/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml.cs
index 5f5da703f..5f5da703f 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml.cs
+++ b/files_videoviewer/mediaelement/src/silverlight/MainPage.xaml.cs
diff --git a/files_videoviewer/mediaelement/src/silverlight/Properties/AppManifest.xml b/files_videoviewer/mediaelement/src/silverlight/Properties/AppManifest.xml
index 6712a1178..6712a1178 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/Properties/AppManifest.xml
+++ b/files_videoviewer/mediaelement/src/silverlight/Properties/AppManifest.xml
diff --git a/files_videoviewer/mediaelement/src/silverlight/Properties/AssemblyInfo.cs b/files_videoviewer/mediaelement/src/silverlight/Properties/AssemblyInfo.cs
index 8d8bbce31..8d8bbce31 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/Properties/AssemblyInfo.cs
+++ b/files_videoviewer/mediaelement/src/silverlight/Properties/AssemblyInfo.cs
diff --git a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj
index 565830460..565830460 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj
+++ b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj
diff --git a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj.user b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj.user
index 2fe79f9ea..2fe79f9ea 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj.user
+++ b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.csproj.user
diff --git a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.sln b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.sln
index b3110c843..b3110c843 100644..100755
--- a/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.sln
+++ b/files_videoviewer/mediaelement/src/silverlight/SilverlightMediaElement.sln
diff --git a/files_videoviewer/mediaelement/src/yuicompressor-2.4.2.jar b/files_videoviewer/mediaelement/src/yuicompressor-2.4.2.jar
index c29470bd0..c29470bd0 100644..100755
--- a/files_videoviewer/mediaelement/src/yuicompressor-2.4.2.jar
+++ b/files_videoviewer/mediaelement/src/yuicompressor-2.4.2.jar
Binary files differ