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:
authorVicDeo <victor.dubiniuk@gmail.com>2012-10-31 14:25:35 +0400
committerVicDeo <victor.dubiniuk@gmail.com>2012-10-31 14:33:12 +0400
commit726d420c432ba30eb87755d8019ba48c1f4bb825 (patch)
tree1845f0f566d8fd64fbb565a990ee276474dfbb3c /files_videoviewer
parent8deca4f94acd3ae451af778f363b519838e98a4f (diff)
Update mediaelement.js to 2.9.5. Closes #66
Diffstat (limited to 'files_videoviewer')
-rw-r--r--files_videoviewer/css/mediaelementplayer.css1
-rw-r--r--files_videoviewer/js/flashmediaelement.swfbin27285 -> 27763 bytes
-rw-r--r--files_videoviewer/js/mediaelement-and-player.js4052
-rw-r--r--files_videoviewer/js/mediaelement-and-player.min.js125
-rw-r--r--files_videoviewer/mediaelement/src/.DS_Storebin6148 -> 0 bytes
-rwxr-xr-xfiles_videoviewer/mediaelement/src/Builder.py262
-rw-r--r--files_videoviewer/mediaelement/src/css/mediaelementplayer.css1
-rw-r--r--files_videoviewer/mediaelement/src/css/mejs-skins.css3
-rw-r--r--files_videoviewer/mediaelement/src/flash/FlashMediaElement.as2
-rw-r--r--files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as2
-rw-r--r--files_videoviewer/mediaelement/src/js/me-namespace.js48
-rw-r--r--files_videoviewer/mediaelement/src/js/me-shim.js3
-rw-r--r--files_videoviewer/mediaelement/src/js/me-utility.js255
-rw-r--r--files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js384
-rw-r--r--files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js874
-rw-r--r--files_videoviewer/mediaelement/src/js/mep-feature-time.js160
-rw-r--r--files_videoviewer/mediaelement/src/js/mep-feature-tracks.js175
-rw-r--r--files_videoviewer/mediaelement/src/js/mep-player.js2152
18 files changed, 4328 insertions, 4171 deletions
diff --git a/files_videoviewer/css/mediaelementplayer.css b/files_videoviewer/css/mediaelementplayer.css
index 2b7a596e7..692949bfd 100644
--- a/files_videoviewer/css/mediaelementplayer.css
+++ b/files_videoviewer/css/mediaelementplayer.css
@@ -4,6 +4,7 @@
font-family: Helvetica, Arial;
text-align: left;
vertical-align: top;
+ text-indent: 0;
}
.me-plugin {
diff --git a/files_videoviewer/js/flashmediaelement.swf b/files_videoviewer/js/flashmediaelement.swf
index 34584b3d9..3e347aa23 100644
--- 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 e152f4ec7..7ba6f881f 100644
--- a/files_videoviewer/js/mediaelement-and-player.js
+++ b/files_videoviewer/js/mediaelement-and-player.js
@@ -11,147 +11,170 @@
* Dual licensed under the MIT or GPL Version 2 licenses.
*
*/
-// Namespace
-var mejs = mejs || {};
-
-// version number
-mejs.version = '2.9.3';
-
-// player number (for missing, same id attr)
-mejs.meIndex = 0;
-
-// media types accepted by plugins
-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/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
- //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
- ],
- youtube: [
- {version: null, types: ['video/youtube', 'video/x-youtube']}
- ],
- vimeo: [
- {version: null, types: ['video/vimeo']}
- ]
+// Namespace
+var mejs = mejs || {};
+
+// version number
+mejs.version = '2.9.5';
+
+// player number (for missing, same id attr)
+mejs.meIndex = 0;
+
+// media types accepted by plugins
+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']}
+ //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
+ ],
+ youtube: [
+ {version: null, types: ['video/youtube', 'video/x-youtube']}
+ ],
+ vimeo: [
+ {version: null, types: ['video/vimeo']}
+ ]
+};
+
+/*
+Utility methods
+*/
+mejs.Utility = {
+ encodeUrl: function(url) {
+ return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
+ },
+ escapeHTML: function(s) {
+ return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
+ },
+ absolutizeUrl: function(url) {
+ var el = document.createElement('div');
+ el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
+ return el.firstChild.href;
+ },
+ getScriptPath: function(scriptNames) {
+ var
+ i = 0,
+ j,
+ path = '',
+ name = '',
+ script,
+ scripts = document.getElementsByTagName('script'),
+ il = scripts.length,
+ jl = scriptNames.length;
+
+ for (; i < il; i++) {
+ 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));
+ break;
+ }
+ }
+ if (path !== '') {
+ break;
+ }
+ }
+ return path;
+ },
+ secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
+ //add framecount
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var hours = Math.floor(time / 3600) % 24,
+ minutes = Math.floor(time / 60) % 60,
+ seconds = Math.floor(time % 60),
+ frames = Math.floor(((time % 1)*fps).toFixed(3)),
+ result =
+ ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
+ + (minutes < 10 ? '0' + minutes : minutes) + ':'
+ + (seconds < 10 ? '0' + seconds : seconds)
+ + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
+
+ return result;
+ },
+
+ timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var tc_array = hh_mm_ss_ff.split(":"),
+ tc_hh = parseInt(tc_array[0], 10),
+ tc_mm = parseInt(tc_array[1], 10),
+ tc_ss = parseInt(tc_array[2], 10),
+ tc_ff = 0,
+ tc_in_seconds = 0;
+
+ if (showFrameCount) {
+ tc_ff = parseInt(tc_array[3])/fps;
+ }
+
+ tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
+
+ return tc_in_seconds;
+ },
+
+
+ convertSMPTEtoSeconds: function (SMPTE) {
+ if (typeof SMPTE != 'string')
+ return false;
+
+ SMPTE = SMPTE.replace(',', '.');
+
+ var secs = 0,
+ decimalLen = (SMPTE.indexOf('.') != -1) ? SMPTE.split('.')[1].length : 0,
+ multiplier = 1;
+
+ SMPTE = SMPTE.split(':').reverse();
+
+ for (var i = 0; i < SMPTE.length; i++) {
+ multiplier = 1;
+ if (i > 0) {
+ multiplier = Math.pow(60, i);
+ }
+ secs += Number(SMPTE[i]) * multiplier;
+ }
+ return Number(secs.toFixed(decimalLen));
+ },
+
+ /* 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 (mejs.MediaFeatures.isIE) {
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ mejs.Utility.removeObjectInIE(id);
+ } else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ } else {
+ obj.parentNode.removeChild(obj);
+ }
+ }
+ },
+ removeObjectInIE: function(id) {
+ var obj = document.getElementById(id);
+ if (obj) {
+ for (var i in obj) {
+ if (typeof obj[i] == "function") {
+ obj[i] = null;
+ }
+ }
+ obj.parentNode.removeChild(obj);
+ }
+ }
};
-
-/*
-Utility methods
-*/
-mejs.Utility = {
- encodeUrl: function(url) {
- return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
- },
- escapeHTML: function(s) {
- return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
- },
- absolutizeUrl: function(url) {
- var el = document.createElement('div');
- el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
- return el.firstChild.href;
- },
- getScriptPath: function(scriptNames) {
- var
- i = 0,
- j,
- path = '',
- name = '',
- script,
- scripts = document.getElementsByTagName('script'),
- il = scripts.length,
- jl = scriptNames.length;
-
- for (; i < il; i++) {
- 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));
- break;
- }
- }
- if (path !== '') {
- break;
- }
- }
- return path;
- },
- secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
- //add framecount
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var hours = Math.floor(time / 3600) % 24,
- minutes = Math.floor(time / 60) % 60,
- seconds = Math.floor(time % 60),
- frames = Math.floor(((time % 1)*fps).toFixed(3)),
- result =
- ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
- + (minutes < 10 ? '0' + minutes : minutes) + ':'
- + (seconds < 10 ? '0' + seconds : seconds)
- + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
-
- return result;
- },
-
- timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var tc_array = hh_mm_ss_ff.split(":"),
- tc_hh = parseInt(tc_array[0], 10),
- tc_mm = parseInt(tc_array[1], 10),
- tc_ss = parseInt(tc_array[2], 10),
- tc_ff = 0,
- tc_in_seconds = 0;
-
- if (showFrameCount) {
- tc_ff = parseInt(tc_array[3])/fps;
- }
-
- tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
-
- return tc_in_seconds;
- },
-
- /* 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 (mejs.MediaFeatures.isIE) {
- obj.style.display = "none";
- (function(){
- if (obj.readyState == 4) {
- mejs.Utility.removeObjectInIE(id);
- } else {
- setTimeout(arguments.callee, 10);
- }
- })();
- } else {
- obj.parentNode.removeChild(obj);
- }
- }
- },
- removeObjectInIE: function(id) {
- var obj = document.getElementById(id);
- if (obj) {
- for (var i in obj) {
- if (typeof obj[i] == "function") {
- obj[i] = null;
- }
- }
- obj.parentNode.removeChild(obj);
- }
- }
-};
// Core detector, plugins are added below
@@ -774,6 +797,8 @@ mejs.MediaElementDefaults = {
pluginPath: mejs.Utility.getScriptPath(['mediaelement.js','mediaelement.min.js','mediaelement-and-player.js','mediaelement-and-player.min.js']),
// name of flash file
flashName: 'flashmediaelement.swf',
+ // streamer for RTMP streaming
+ flashStreamer: '',
// turns on the smoothing filter in Flash
enablePluginSmoothing: false,
// name of silverlight file
@@ -1151,6 +1176,7 @@ mejs.HtmlMediaElementShim = {
'width=' + width,
'startvolume=' + options.startVolume,
'timerrate=' + options.timerRate,
+ 'flashstreamer=' + options.flashStreamer,
'height=' + height];
if (playback.url !== null) {
@@ -1562,1082 +1588,1082 @@ if (typeof jQuery != 'undefined') {
} else if (typeof ender != 'undefined') {
mejs.$ = ender;
}
-(function ($) {
-
- // default player values
- mejs.MepDefaults = {
- // url to poster (to fix iOS 3.x)
- poster: '',
- // default if the <video width> is not specified
- defaultVideoWidth: 480,
- // default if the <video height> is not specified
- defaultVideoHeight: 270,
- // if set, overrides <video width>
- videoWidth: -1,
- // if set, overrides <video height>
- videoHeight: -1,
- // default if the user doesn't specify
- defaultAudioWidth: 400,
- // default if the user doesn't specify
- defaultAudioHeight: 30,
-
- // default amount to move back when back key is pressed
- defaultSeekBackwardInterval: function(media) {
- return (media.duration * 0.05);
- },
- // default amount to move forward when forward key is pressed
- defaultSeekForwardInterval: function(media) {
- return (media.duration * 0.05);
- },
-
- // width of audio player
- audioWidth: -1,
- // height of audio player
- audioHeight: -1,
- // initial volume when the player starts (overrided by user cookie)
- startVolume: 0.8,
- // useful for <audio> player loops
- loop: false,
- // resize to media dimensions
- enableAutosize: true,
- // forces the hour marker (##:00:00)
- alwaysShowHours: false,
-
- // show framecount in timecode (##:00:00:00)
- showTimecodeFrameCount: false,
- // used when showTimecodeFrameCount is set to true
- framesPerSecond: 25,
-
- // automatically calculate the width of the progress bar based on the sizes of other elements
- autosizeProgress : true,
- // Hide controls when playing and mouse is not over the video
- alwaysShowControls: false,
- // force iPad's native controls
- iPadUseNativeControls: false,
- // force iPhone's native controls
- iPhoneUseNativeControls: false,
- // force Android's native controls
- AndroidUseNativeControls: false,
- // features to show
- features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
- // only for dynamic
- isVideo: true,
-
- // turns keyboard support on and off for this instance
- enableKeyboard: true,
-
- // whenthis player starts, it will pause other players
- pauseOtherPlayers: true,
-
- // array of keyboard actions such as play pause
- keyActions: [
- {
- keys: [
- 32, // SPACE
- 179 // GOOGLE play/pause button
- ],
- action: function(player, media) {
- if (media.paused || media.ended) {
- media.play();
- } else {
- media.pause();
- }
- }
- },
- {
- keys: [38], // UP
- action: function(player, media) {
- var newVolume = Math.min(media.volume + 0.1, 1);
- media.setVolume(newVolume);
- }
- },
- {
- keys: [40], // DOWN
- action: function(player, media) {
- var newVolume = Math.max(media.volume - 0.1, 0);
- media.setVolume(newVolume);
- }
- },
- {
- keys: [
- 37, // LEFT
- 227 // Google TV rewind
- ],
- action: function(player, media) {
- if (!isNaN(media.duration) && media.duration > 0) {
- if (player.isVideo) {
- player.showControls();
- player.startControlsTimer();
- }
-
- // 5%
- var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
- media.setCurrentTime(newTime);
- }
- }
- },
- {
- keys: [
- 39, // RIGHT
- 228 // Google TV forward
- ],
- action: function(player, media) {
- if (!isNaN(media.duration) && media.duration > 0) {
- if (player.isVideo) {
- player.showControls();
- player.startControlsTimer();
- }
-
- // 5%
- var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
- media.setCurrentTime(newTime);
- }
- }
- },
- {
- keys: [70], // f
- action: function(player, media) {
- if (typeof player.enterFullScreen != 'undefined') {
- if (player.isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- }
- }
- }
- ]
- };
-
- mejs.mepIndex = 0;
-
- mejs.players = [];
-
- // wraps a MediaElement object in player controls
- mejs.MediaElementPlayer = function(node, o) {
- // enforce object, even without "new" (via John Resig)
- if ( !(this instanceof mejs.MediaElementPlayer) ) {
- return new mejs.MediaElementPlayer(node, o);
- }
-
- var t = this;
-
- // these will be reset after the MediaElement.success fires
- t.$media = t.$node = $(node);
- t.node = t.media = t.$media[0];
-
- // check for existing player
- if (typeof t.node.player != 'undefined') {
- return t.node.player;
- } else {
- // attach player to DOM node for reference
- t.node.player = t;
- }
-
-
- // try to get options from data-mejsoptions
- if (typeof o == 'undefined') {
- o = t.$node.data('mejsoptions');
- }
-
- // extend default options
- t.options = $.extend({},mejs.MepDefaults,o);
-
- // add to player array (for focus events)
- mejs.players.push(t);
-
- // start up
- t.init();
-
- return t;
- };
-
- // actual player
- mejs.MediaElementPlayer.prototype = {
-
- hasFocus: false,
-
- controlsAreVisible: true,
-
- init: function() {
-
- var
- t = this,
- mf = mejs.MediaFeatures,
- // options for MediaElement (shim)
- meOptions = $.extend(true, {}, t.options, {
- success: function(media, domNode) { t.meReady(media, domNode); },
- error: function(e) { t.handleError(e);}
- }),
- tagName = t.media.tagName.toLowerCase();
-
- t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
-
- if (t.isDynamic) {
- // get video from src or href?
- t.isVideo = t.options.isVideo;
- } else {
- t.isVideo = (tagName !== 'audio' && t.options.isVideo);
- }
-
- // use native controls in iPad, iPhone, and Android
- if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
-
- // add controls and stop
- t.$media.attr('controls', 'controls');
-
- // attempt to fix iOS 3 bug
- //t.$media.removeAttr('poster');
- // no Issue found on iOS3 -ttroxell
-
- // override Apple's autoplay override for iPads
- if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
- t.media.load();
- t.media.play();
- }
-
- } else if (mf.isAndroid && t.AndroidUseNativeControls) {
-
- // leave default player
-
- } else {
-
- // DESKTOP: use MediaElementPlayer controls
-
- // 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">'+
- '<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(t.$media[0].className)
- .insertBefore(t.$media);
-
- // add classes for user and content
- t.container.addClass(
- (mf.isAndroid ? 'mejs-android ' : '') +
- (mf.isiOS ? 'mejs-ios ' : '') +
- (mf.isiPad ? 'mejs-ipad ' : '') +
- (mf.isiPhone ? 'mejs-iphone ' : '') +
- (t.isVideo ? 'mejs-video ' : 'mejs-audio ')
- );
-
-
- // move the <video/video> tag into the right spot
- if (mf.isiOS) {
-
- // sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
- var $newMedia = t.$media.clone();
-
- t.container.find('.mejs-mediaelement').append($newMedia);
-
- t.$media.remove();
- t.$node = t.$media = $newMedia;
- t.node = t.media = $newMedia[0]
-
- } else {
-
- // normal way of moving it into place (doesn't work on iOS)
- t.container.find('.mejs-mediaelement').append(t.$media);
- }
-
- // find parts
- t.controls = t.container.find('.mejs-controls');
- t.layers = t.container.find('.mejs-layers');
-
- // determine the size
-
- /* size priority:
- (1) videoWidth (forced),
- (2) style="width;height;"
- (3) width attribute,
- (4) defaultVideoWidth (for unspecified cases)
- */
-
- var tagType = (t.isVideo ? 'video' : 'audio'),
- capsTagName = tagType.substring(0,1).toUpperCase() + tagType.substring(1);
-
-
- if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
- t.width = t.options[tagType + 'Width'];
- } else if (t.media.style.width !== '' && t.media.style.width !== null) {
- t.width = t.media.style.width;
- } else if (t.media.getAttribute('width') !== null) {
- t.width = t.$media.attr('width');
- } else {
- t.width = t.options['default' + capsTagName + 'Width'];
- }
-
- if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
- t.height = t.options[tagType + 'Height'];
- } else if (t.media.style.height !== '' && t.media.style.height !== null) {
- t.height = t.media.style.height;
- } else if (t.$media[0].getAttribute('height') !== null) {
- t.height = t.$media.attr('height');
- } else {
- t.height = t.options['default' + capsTagName + 'Height'];
- }
-
- // set the size, while we wait for the plugins to load below
- t.setPlayerSize(t.width, t.height);
-
- // create MediaElementShim
- meOptions.pluginWidth = t.height;
- meOptions.pluginHeight = t.width;
- }
-
-
-
- // create MediaElement shim
- mejs.MediaElement(t.$media[0], meOptions);
- },
-
- showControls: function(doAnimation) {
- var t = this;
-
- doAnimation = typeof doAnimation == 'undefined' || doAnimation;
-
- if (t.controlsAreVisible)
- return;
-
- if (doAnimation) {
- t.controls
- .css('visibility','visible')
- .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control')
- .css('visibility','visible')
- .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
-
- } else {
- t.controls
- .css('visibility','visible')
- .css('display','block');
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control')
- .css('visibility','visible')
- .css('display','block');
-
- t.controlsAreVisible = true;
- }
-
- t.setControlsSize();
-
- },
-
- hideControls: function(doAnimation) {
- var t = this;
-
- doAnimation = typeof doAnimation == 'undefined' || doAnimation;
-
- if (!t.controlsAreVisible)
- return;
-
- if (doAnimation) {
- // fade out main controls
- t.controls.stop(true, true).fadeOut(200, function() {
- $(this)
- .css('visibility','hidden')
- .css('display','block');
-
- t.controlsAreVisible = false;
- });
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
- $(this)
- .css('visibility','hidden')
- .css('display','block');
- });
- } else {
-
- // hide main controls
- t.controls
- .css('visibility','hidden')
- .css('display','block');
-
- // hide others
- t.container.find('.mejs-control')
- .css('visibility','hidden')
- .css('display','block');
-
- t.controlsAreVisible = false;
- }
- },
-
- controlsTimer: null,
-
- startControlsTimer: function(timeout) {
-
- var t = this;
-
- timeout = typeof timeout != 'undefined' ? timeout : 1500;
-
- t.killControlsTimer('start');
-
- t.controlsTimer = setTimeout(function() {
- //console.log('timer fired');
- t.hideControls();
- t.killControlsTimer('hide');
- }, timeout);
- },
-
- killControlsTimer: function(src) {
-
- var t = this;
-
- if (t.controlsTimer !== null) {
- clearTimeout(t.controlsTimer);
- delete t.controlsTimer;
- t.controlsTimer = null;
- }
- },
-
- controlsEnabled: true,
-
- disableControls: function() {
- var t= this;
-
- t.killControlsTimer();
- t.hideControls(false);
- this.controlsEnabled = false;
- },
-
- enableControls: function() {
- var t= this;
-
- t.showControls(false);
-
- t.controlsEnabled = true;
- },
-
-
- // Sets up all controls and events
- meReady: function(media, domNode) {
-
-
- var t = this,
- mf = mejs.MediaFeatures,
- autoplayAttr = domNode.getAttribute('autoplay'),
- autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
- featureIndex,
- feature;
-
- // make sure it can't create itself again if a plugin reloads
- if (t.created)
- return;
- else
- t.created = true;
-
- t.media = media;
- t.domNode = domNode;
-
- if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
-
- // two built in features
- t.buildposter(t, t.controls, t.layers, t.media);
- t.buildkeyboard(t, t.controls, t.layers, t.media);
- t.buildoverlays(t, t.controls, t.layers, t.media);
-
- // grab for use by features
- t.findTracks();
-
- // add user-defined features/controls
- for (featureIndex in t.options.features) {
- feature = t.options.features[featureIndex];
- if (t['build' + feature]) {
- try {
- t['build' + feature](t, t.controls, t.layers, t.media);
- } catch (e) {
- // TODO: report control error
- //throw e;
- //console.log('error building ' + feature);
- //console.log(e);
- }
- }
- }
-
- t.container.trigger('controlsready');
-
- // reset all layers and controls
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
-
-
- // controls fade
- if (t.isVideo) {
-
- if (mejs.MediaFeatures.hasTouch) {
-
- // for touch devices (iOS, Android)
- // show/hide without animation on touch
-
- t.$media.bind('touchstart', function() {
-
-
- // toggle controls
- if (t.controlsAreVisible) {
- t.hideControls(false);
- } else {
- if (t.controlsEnabled) {
- t.showControls(false);
- }
- }
- });
-
- } else {
- // click controls
- var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
-
- // click to play/pause
- clickElement.click(function() {
- if (media.paused) {
- media.play();
- } else {
- media.pause();
- }
- });
-
-
- // show/hide controls
- t.container
- .bind('mouseenter mouseover', function () {
- if (t.controlsEnabled) {
- if (!t.options.alwaysShowControls) {
- t.killControlsTimer('enter');
- t.showControls();
- t.startControlsTimer(2500);
- }
- }
- })
- .bind('mousemove', function() {
- if (t.controlsEnabled) {
- if (!t.controlsAreVisible) {
- t.showControls();
- }
- //t.killControlsTimer('move');
- if (!t.options.alwaysShowControls) {
- t.startControlsTimer(2500);
- }
- }
- })
- .bind('mouseleave', function () {
- if (t.controlsEnabled) {
- if (!t.media.paused && !t.options.alwaysShowControls) {
- t.startControlsTimer(1000);
- }
- }
- });
- }
-
- // check for autoplay
- if (autoplay && !t.options.alwaysShowControls) {
- t.hideControls();
- }
-
- // resizer
- if (t.options.enableAutosize) {
- t.media.addEventListener('loadedmetadata', function(e) {
- // if the <video height> was not set and the options.videoHeight was not set
- // then resize to the real dimensions
- if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
- t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
- t.setControlsSize();
- t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
- }
- }, false);
- }
- }
-
- // EVENTS
-
- // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
- media.addEventListener('play', function() {
-
- // go through all other players
- for (var i=0, il=mejs.players.length; i<il; i++) {
- var p = mejs.players[i];
- if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
- p.pause();
- }
- p.hasFocus = false;
- }
-
- t.hasFocus = true;
- },false);
-
-
- // ended for all
- t.media.addEventListener('ended', function (e) {
- try{
- t.media.setCurrentTime(0);
- } catch (exp) {
-
- }
- t.media.pause();
-
- if (t.setProgressRail)
- t.setProgressRail();
- if (t.setCurrentRail)
- t.setCurrentRail();
-
- if (t.options.loop) {
- t.media.play();
- } else if (!t.options.alwaysShowControls && t.controlsEnabled) {
- t.showControls();
- }
- }, false);
-
- // resize on the first play
- t.media.addEventListener('loadedmetadata', function(e) {
- if (t.updateDuration) {
- t.updateDuration();
- }
- if (t.updateCurrent) {
- t.updateCurrent();
- }
-
- if (!t.isFullScreen) {
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
- }
- }, false);
-
-
- // webkit has trouble doing this without a delay
- setTimeout(function () {
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
- }, 50);
-
- // adjust controls whenever window sizes (used to be in fullscreen only)
- $(window).resize(function() {
-
- // don't resize for fullscreen mode
- if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
- t.setPlayerSize(t.width, t.height);
- }
-
- // always adjust controls
- t.setControlsSize();
- });
-
- // TEMP: needs to be moved somewhere else
- if (t.media.pluginType == 'youtube') {
- t.container.find('.mejs-overlay-play').hide();
- }
- }
-
- // force autoplay for HTML5
- if (autoplay && media.pluginType == 'native') {
- media.load();
- media.play();
- }
-
-
- if (t.options.success) {
-
- if (typeof t.options.success == 'string') {
- window[t.options.success](t.media, t.domNode, t);
- } else {
- t.options.success(t.media, t.domNode, t);
- }
- }
- },
-
- handleError: function(e) {
- var t = this;
-
- t.controls.hide();
-
- // Tell user that the file cannot be played
- if (t.options.error) {
- t.options.error(e);
- }
- },
-
- setPlayerSize: function(width,height) {
- var t = this;
-
- if (typeof width != 'undefined')
- t.width = width;
-
- if (typeof height != 'undefined')
- t.height = height;
-
- // detect 100% mode
- if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width') === '100%') {
-
- // do we have the native dimensions yet?
- var
- nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
- nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
- parentWidth = t.container.parent().width(),
- newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
-
- if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
- parentWidth = $(window).width();
- newHeight = $(window).height();
- }
-
- if ( newHeight != 0 ) {
- // set outer container size
- t.container
- .width(parentWidth)
- .height(newHeight);
-
- // set native <video>
- t.$media
- .width('100%')
- .height('100%');
-
- // set shims
- t.container.find('object, embed, iframe')
- .width('100%')
- .height('100%');
-
- // if shim is ready, send the size to the embeded plugin
- if (t.isVideo) {
- if (t.media.setVideoSize) {
- t.media.setVideoSize(parentWidth, newHeight);
- }
- }
-
- // set the layers
- t.layers.children('.mejs-layer')
- .width('100%')
- .height('100%');
- }
-
-
- } else {
-
- t.container
- .width(t.width)
- .height(t.height);
-
- t.layers.children('.mejs-layer')
- .width(t.width)
- .height(t.height);
-
- }
- },
-
- setControlsSize: function() {
- var t = this,
- usedWidth = 0,
- railWidth = 0,
- rail = t.controls.find('.mejs-time-rail'),
- total = t.controls.find('.mejs-time-total'),
- current = t.controls.find('.mejs-time-current'),
- loaded = t.controls.find('.mejs-time-loaded'),
- others = rail.siblings();
-
-
- // allow the size to come from custom CSS
- if (t.options && !t.options.autosizeProgress) {
- // Also, frontends devs can be more flexible
- // due the opportunity of absolute positioning.
- railWidth = parseInt(rail.css('width'));
- }
-
- // attempt to autosize
- if (railWidth === 0 || !railWidth) {
-
- // find the size of all the other controls besides the rail
- others.each(function() {
- if ($(this).css('position') != 'absolute') {
- usedWidth += $(this).outerWidth(true);
- }
- });
-
- // fit the rail into the remaining space
- railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
- }
-
- // outer area
- rail.width(railWidth);
- // dark space
- total.width(railWidth - (total.outerWidth(true) - total.width()));
-
- if (t.setProgressRail)
- t.setProgressRail();
- if (t.setCurrentRail)
- t.setCurrentRail();
- },
-
-
- buildposter: function(player, controls, layers, media) {
- var t = this,
- poster =
- $('<div class="mejs-poster mejs-layer">' +
- '</div>')
- .appendTo(layers),
- posterUrl = player.$media.attr('poster');
-
- // prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
- if (player.options.poster !== '') {
- posterUrl = player.options.poster;
- }
-
- // second, try the real poster
- if (posterUrl !== '' && posterUrl != null) {
- t.setPoster(posterUrl);
- } else {
- poster.hide();
- }
-
- media.addEventListener('play',function() {
- poster.hide();
- }, false);
- },
-
- setPoster: function(url) {
- var t = this,
- posterDiv = t.container.find('.mejs-poster'),
- posterImg = posterDiv.find('img');
-
- if (posterImg.length == 0) {
- posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
- }
-
- posterImg.attr('src', url);
- },
-
- buildoverlays: function(player, controls, layers, media) {
- if (!player.isVideo)
- return;
-
- var
- loading =
- $('<div class="mejs-overlay mejs-layer">'+
- '<div class="mejs-overlay-loading"><span></span></div>'+
- '</div>')
- .hide() // start out hidden
- .appendTo(layers),
- error =
- $('<div class="mejs-overlay mejs-layer">'+
- '<div class="mejs-overlay-error"></div>'+
- '</div>')
- .hide() // start out hidden
- .appendTo(layers),
- // this needs to come last so it's on top
- bigPlay =
- $('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
- '<div class="mejs-overlay-button"></div>'+
- '</div>')
- .appendTo(layers)
- .click(function() {
- if (media.paused) {
- media.play();
- } else {
- media.pause();
- }
- });
-
- /*
- if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
- bigPlay.remove();
- loading.remove();
- }
- */
-
-
- // show/hide big play button
- media.addEventListener('play',function() {
- bigPlay.hide();
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.hide();
- }, false);
-
- media.addEventListener('playing', function() {
- bigPlay.hide();
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.hide();
- }, false);
-
- media.addEventListener('seeking', function() {
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
-
- media.addEventListener('seeked', function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- }, false);
-
- media.addEventListener('pause',function() {
- if (!mejs.MediaFeatures.isiPhone) {
- bigPlay.show();
- }
- }, false);
-
- media.addEventListener('waiting', function() {
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
-
-
- // show/hide loading
- media.addEventListener('loadeddata',function() {
- // for some reason Chrome is firing this event
- //if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
- // return;
-
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
- media.addEventListener('canplay',function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- }, false);
-
- // error handling
- media.addEventListener('error',function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.show();
- error.find('mejs-overlay-error').html("Error loading this resource");
- }, false);
- },
-
- buildkeyboard: function(player, controls, layers, media) {
-
- var t = this;
-
- // listen for key presses
- $(document).keydown(function(e) {
-
- if (player.hasFocus && player.options.enableKeyboard) {
-
- // find a matching key
- for (var i=0, il=player.options.keyActions.length; i<il; i++) {
- var keyAction = player.options.keyActions[i];
-
- for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
- if (e.keyCode == keyAction.keys[j]) {
- e.preventDefault();
- keyAction.action(player, media, e.keyCode);
- return false;
- }
- }
- }
- }
-
- return true;
- });
-
- // check if someone clicked outside a player region, then kill its focus
- $(document).click(function(event) {
- if ($(event.target).closest('.mejs-container').length == 0) {
- player.hasFocus = false;
- }
- });
-
- },
-
- findTracks: function() {
- var t = this,
- tracktags = t.$media.find('track');
-
- // store for use by plugins
- t.tracks = [];
- tracktags.each(function(index, track) {
-
- track = $(track);
-
- t.tracks.push({
- srclang: track.attr('srclang').toLowerCase(),
- src: track.attr('src'),
- kind: track.attr('kind'),
- label: track.attr('label') || '',
- entries: [],
- isLoaded: false
- });
- });
- },
- changeSkin: function(className) {
- this.container[0].className = 'mejs-container ' + className;
- 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(muted) {
- this.media.setMuted(muted);
- },
- setCurrentTime: function(time) {
- this.media.setCurrentTime(time);
- },
- getCurrentTime: function() {
- return this.media.currentTime;
- },
- setVolume: function(volume) {
- this.media.setVolume(volume);
- },
- getVolume: function() {
- return this.media.volume;
- },
- setSrc: function(src) {
- this.media.setSrc(src);
- },
- remove: function() {
- var t = this;
-
- if (t.media.pluginType === 'flash') {
- t.media.remove();
- } else if (t.media.pluginType === 'native') {
- t.$media.prop('controls', true);
- }
-
- // grab video and put it back in place
- if (!t.isDynamic) {
- t.$node.insertBefore(t.container)
- }
-
- t.container.remove();
- }
- };
-
- // turn into jQuery plugin
- if (typeof jQuery != 'undefined') {
- jQuery.fn.mediaelementplayer = function (options) {
- return this.each(function () {
- new mejs.MediaElementPlayer(this, options);
- });
- };
- }
-
- $(document).ready(function() {
- // auto enable using JSON attribute
- $('.mejs-player').mediaelementplayer();
- });
-
- // push out to window
- window.MediaElementPlayer = mejs.MediaElementPlayer;
-
-})(mejs.$);
+(function ($) {
+
+ // default player values
+ mejs.MepDefaults = {
+ // url to poster (to fix iOS 3.x)
+ poster: '',
+ // default if the <video width> is not specified
+ defaultVideoWidth: 480,
+ // default if the <video height> is not specified
+ defaultVideoHeight: 270,
+ // if set, overrides <video width>
+ videoWidth: -1,
+ // if set, overrides <video height>
+ videoHeight: -1,
+ // default if the user doesn't specify
+ defaultAudioWidth: 400,
+ // default if the user doesn't specify
+ defaultAudioHeight: 30,
+
+ // default amount to move back when back key is pressed
+ defaultSeekBackwardInterval: function(media) {
+ return (media.duration * 0.05);
+ },
+ // default amount to move forward when forward key is pressed
+ defaultSeekForwardInterval: function(media) {
+ return (media.duration * 0.05);
+ },
+
+ // width of audio player
+ audioWidth: -1,
+ // height of audio player
+ audioHeight: -1,
+ // initial volume when the player starts (overrided by user cookie)
+ startVolume: 0.8,
+ // useful for <audio> player loops
+ loop: false,
+ // resize to media dimensions
+ enableAutosize: true,
+ // forces the hour marker (##:00:00)
+ alwaysShowHours: false,
+
+ // show framecount in timecode (##:00:00:00)
+ showTimecodeFrameCount: false,
+ // used when showTimecodeFrameCount is set to true
+ framesPerSecond: 25,
+
+ // automatically calculate the width of the progress bar based on the sizes of other elements
+ autosizeProgress : true,
+ // Hide controls when playing and mouse is not over the video
+ alwaysShowControls: false,
+ // force iPad's native controls
+ iPadUseNativeControls: false,
+ // force iPhone's native controls
+ iPhoneUseNativeControls: false,
+ // force Android's native controls
+ AndroidUseNativeControls: false,
+ // features to show
+ features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
+ // only for dynamic
+ isVideo: true,
+
+ // turns keyboard support on and off for this instance
+ enableKeyboard: true,
+
+ // whenthis player starts, it will pause other players
+ pauseOtherPlayers: true,
+
+ // array of keyboard actions such as play pause
+ keyActions: [
+ {
+ keys: [
+ 32, // SPACE
+ 179 // GOOGLE play/pause button
+ ],
+ action: function(player, media) {
+ if (media.paused || media.ended) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ }
+ },
+ {
+ keys: [38], // UP
+ action: function(player, media) {
+ var newVolume = Math.min(media.volume + 0.1, 1);
+ media.setVolume(newVolume);
+ }
+ },
+ {
+ keys: [40], // DOWN
+ action: function(player, media) {
+ var newVolume = Math.max(media.volume - 0.1, 0);
+ media.setVolume(newVolume);
+ }
+ },
+ {
+ keys: [
+ 37, // LEFT
+ 227 // Google TV rewind
+ ],
+ action: function(player, media) {
+ if (!isNaN(media.duration) && media.duration > 0) {
+ if (player.isVideo) {
+ player.showControls();
+ player.startControlsTimer();
+ }
+
+ // 5%
+ var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
+ media.setCurrentTime(newTime);
+ }
+ }
+ },
+ {
+ keys: [
+ 39, // RIGHT
+ 228 // Google TV forward
+ ],
+ action: function(player, media) {
+ if (!isNaN(media.duration) && media.duration > 0) {
+ if (player.isVideo) {
+ player.showControls();
+ player.startControlsTimer();
+ }
+
+ // 5%
+ var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
+ media.setCurrentTime(newTime);
+ }
+ }
+ },
+ {
+ keys: [70], // f
+ action: function(player, media) {
+ if (typeof player.enterFullScreen != 'undefined') {
+ if (player.isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ }
+ }
+ }
+ ]
+ };
+
+ mejs.mepIndex = 0;
+
+ mejs.players = [];
+
+ // wraps a MediaElement object in player controls
+ mejs.MediaElementPlayer = function(node, o) {
+ // enforce object, even without "new" (via John Resig)
+ if ( !(this instanceof mejs.MediaElementPlayer) ) {
+ return new mejs.MediaElementPlayer(node, o);
+ }
+
+ var t = this;
+
+ // these will be reset after the MediaElement.success fires
+ t.$media = t.$node = $(node);
+ t.node = t.media = t.$media[0];
+
+ // check for existing player
+ if (typeof t.node.player != 'undefined') {
+ return t.node.player;
+ } else {
+ // attach player to DOM node for reference
+ t.node.player = t;
+ }
+
+
+ // try to get options from data-mejsoptions
+ if (typeof o == 'undefined') {
+ o = t.$node.data('mejsoptions');
+ }
+
+ // extend default options
+ t.options = $.extend({},mejs.MepDefaults,o);
+
+ // add to player array (for focus events)
+ mejs.players.push(t);
+
+ // start up
+ t.init();
+
+ return t;
+ };
+
+ // actual player
+ mejs.MediaElementPlayer.prototype = {
+
+ hasFocus: false,
+
+ controlsAreVisible: true,
+
+ init: function() {
+
+ var
+ t = this,
+ mf = mejs.MediaFeatures,
+ // options for MediaElement (shim)
+ meOptions = $.extend(true, {}, t.options, {
+ success: function(media, domNode) { t.meReady(media, domNode); },
+ error: function(e) { t.handleError(e);}
+ }),
+ tagName = t.media.tagName.toLowerCase();
+
+ t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
+
+ if (t.isDynamic) {
+ // get video from src or href?
+ t.isVideo = t.options.isVideo;
+ } else {
+ t.isVideo = (tagName !== 'audio' && t.options.isVideo);
+ }
+
+ // use native controls in iPad, iPhone, and Android
+ if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
+
+ // add controls and stop
+ t.$media.attr('controls', 'controls');
+
+ // attempt to fix iOS 3 bug
+ //t.$media.removeAttr('poster');
+ // no Issue found on iOS3 -ttroxell
+
+ // override Apple's autoplay override for iPads
+ if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
+ t.media.load();
+ t.media.play();
+ }
+
+ } else if (mf.isAndroid && t.AndroidUseNativeControls) {
+
+ // leave default player
+
+ } else {
+
+ // DESKTOP: use MediaElementPlayer controls
+
+ // 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">'+
+ '<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(t.$media[0].className)
+ .insertBefore(t.$media);
+
+ // add classes for user and content
+ t.container.addClass(
+ (mf.isAndroid ? 'mejs-android ' : '') +
+ (mf.isiOS ? 'mejs-ios ' : '') +
+ (mf.isiPad ? 'mejs-ipad ' : '') +
+ (mf.isiPhone ? 'mejs-iphone ' : '') +
+ (t.isVideo ? 'mejs-video ' : 'mejs-audio ')
+ );
+
+
+ // move the <video/video> tag into the right spot
+ if (mf.isiOS) {
+
+ // sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
+ var $newMedia = t.$media.clone();
+
+ t.container.find('.mejs-mediaelement').append($newMedia);
+
+ t.$media.remove();
+ t.$node = t.$media = $newMedia;
+ t.node = t.media = $newMedia[0]
+
+ } else {
+
+ // normal way of moving it into place (doesn't work on iOS)
+ t.container.find('.mejs-mediaelement').append(t.$media);
+ }
+
+ // find parts
+ t.controls = t.container.find('.mejs-controls');
+ t.layers = t.container.find('.mejs-layers');
+
+ // determine the size
+
+ /* size priority:
+ (1) videoWidth (forced),
+ (2) style="width;height;"
+ (3) width attribute,
+ (4) defaultVideoWidth (for unspecified cases)
+ */
+
+ var tagType = (t.isVideo ? 'video' : 'audio'),
+ capsTagName = tagType.substring(0,1).toUpperCase() + tagType.substring(1);
+
+
+ if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
+ t.width = t.options[tagType + 'Width'];
+ } else if (t.media.style.width !== '' && t.media.style.width !== null) {
+ t.width = t.media.style.width;
+ } else if (t.media.getAttribute('width') !== null) {
+ t.width = t.$media.attr('width');
+ } else {
+ t.width = t.options['default' + capsTagName + 'Width'];
+ }
+
+ if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
+ t.height = t.options[tagType + 'Height'];
+ } else if (t.media.style.height !== '' && t.media.style.height !== null) {
+ t.height = t.media.style.height;
+ } else if (t.$media[0].getAttribute('height') !== null) {
+ t.height = t.$media.attr('height');
+ } else {
+ t.height = t.options['default' + capsTagName + 'Height'];
+ }
+
+ // set the size, while we wait for the plugins to load below
+ t.setPlayerSize(t.width, t.height);
+
+ // create MediaElementShim
+ meOptions.pluginWidth = t.height;
+ meOptions.pluginHeight = t.width;
+ }
+
+
+
+ // create MediaElement shim
+ mejs.MediaElement(t.$media[0], meOptions);
+ },
+
+ showControls: function(doAnimation) {
+ var t = this;
+
+ doAnimation = typeof doAnimation == 'undefined' || doAnimation;
+
+ if (t.controlsAreVisible)
+ return;
+
+ if (doAnimation) {
+ t.controls
+ .css('visibility','visible')
+ .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control')
+ .css('visibility','visible')
+ .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
+
+ } else {
+ t.controls
+ .css('visibility','visible')
+ .css('display','block');
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control')
+ .css('visibility','visible')
+ .css('display','block');
+
+ t.controlsAreVisible = true;
+ }
+
+ t.setControlsSize();
+
+ },
+
+ hideControls: function(doAnimation) {
+ var t = this;
+
+ doAnimation = typeof doAnimation == 'undefined' || doAnimation;
+
+ if (!t.controlsAreVisible)
+ return;
+
+ if (doAnimation) {
+ // fade out main controls
+ t.controls.stop(true, true).fadeOut(200, function() {
+ $(this)
+ .css('visibility','hidden')
+ .css('display','block');
+
+ t.controlsAreVisible = false;
+ });
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
+ $(this)
+ .css('visibility','hidden')
+ .css('display','block');
+ });
+ } else {
+
+ // hide main controls
+ t.controls
+ .css('visibility','hidden')
+ .css('display','block');
+
+ // hide others
+ t.container.find('.mejs-control')
+ .css('visibility','hidden')
+ .css('display','block');
+
+ t.controlsAreVisible = false;
+ }
+ },
+
+ controlsTimer: null,
+
+ startControlsTimer: function(timeout) {
+
+ var t = this;
+
+ timeout = typeof timeout != 'undefined' ? timeout : 1500;
+
+ t.killControlsTimer('start');
+
+ t.controlsTimer = setTimeout(function() {
+ //console.log('timer fired');
+ t.hideControls();
+ t.killControlsTimer('hide');
+ }, timeout);
+ },
+
+ killControlsTimer: function(src) {
+
+ var t = this;
+
+ if (t.controlsTimer !== null) {
+ clearTimeout(t.controlsTimer);
+ delete t.controlsTimer;
+ t.controlsTimer = null;
+ }
+ },
+
+ controlsEnabled: true,
+
+ disableControls: function() {
+ var t= this;
+
+ t.killControlsTimer();
+ t.hideControls(false);
+ this.controlsEnabled = false;
+ },
+
+ enableControls: function() {
+ var t= this;
+
+ t.showControls(false);
+
+ t.controlsEnabled = true;
+ },
+
+
+ // Sets up all controls and events
+ meReady: function(media, domNode) {
+
+
+ var t = this,
+ mf = mejs.MediaFeatures,
+ autoplayAttr = domNode.getAttribute('autoplay'),
+ autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
+ featureIndex,
+ feature;
+
+ // make sure it can't create itself again if a plugin reloads
+ if (t.created)
+ return;
+ else
+ t.created = true;
+
+ t.media = media;
+ t.domNode = domNode;
+
+ if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
+
+ // two built in features
+ t.buildposter(t, t.controls, t.layers, t.media);
+ t.buildkeyboard(t, t.controls, t.layers, t.media);
+ t.buildoverlays(t, t.controls, t.layers, t.media);
+
+ // grab for use by features
+ t.findTracks();
+
+ // add user-defined features/controls
+ for (featureIndex in t.options.features) {
+ feature = t.options.features[featureIndex];
+ if (t['build' + feature]) {
+ try {
+ t['build' + feature](t, t.controls, t.layers, t.media);
+ } catch (e) {
+ // TODO: report control error
+ //throw e;
+ //console.log('error building ' + feature);
+ //console.log(e);
+ }
+ }
+ }
+
+ t.container.trigger('controlsready');
+
+ // reset all layers and controls
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+
+
+ // controls fade
+ if (t.isVideo) {
+
+ if (mejs.MediaFeatures.hasTouch) {
+
+ // for touch devices (iOS, Android)
+ // show/hide without animation on touch
+
+ t.$media.bind('touchstart', function() {
+
+
+ // toggle controls
+ if (t.controlsAreVisible) {
+ t.hideControls(false);
+ } else {
+ if (t.controlsEnabled) {
+ t.showControls(false);
+ }
+ }
+ });
+
+ } else {
+ // click controls
+ var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
+
+ // click to play/pause
+ clickElement.click(function() {
+ if (media.paused) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ });
+
+
+ // show/hide controls
+ t.container
+ .bind('mouseenter mouseover', function () {
+ if (t.controlsEnabled) {
+ if (!t.options.alwaysShowControls) {
+ t.killControlsTimer('enter');
+ t.showControls();
+ t.startControlsTimer(2500);
+ }
+ }
+ })
+ .bind('mousemove', function() {
+ if (t.controlsEnabled) {
+ if (!t.controlsAreVisible) {
+ t.showControls();
+ }
+ //t.killControlsTimer('move');
+ if (!t.options.alwaysShowControls) {
+ t.startControlsTimer(2500);
+ }
+ }
+ })
+ .bind('mouseleave', function () {
+ if (t.controlsEnabled) {
+ if (!t.media.paused && !t.options.alwaysShowControls) {
+ t.startControlsTimer(1000);
+ }
+ }
+ });
+ }
+
+ // check for autoplay
+ if (autoplay && !t.options.alwaysShowControls) {
+ t.hideControls();
+ }
+
+ // resizer
+ if (t.options.enableAutosize) {
+ t.media.addEventListener('loadedmetadata', function(e) {
+ // if the <video height> was not set and the options.videoHeight was not set
+ // then resize to the real dimensions
+ if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
+ t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
+ t.setControlsSize();
+ t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
+ }
+ }, false);
+ }
+ }
+
+ // EVENTS
+
+ // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
+ media.addEventListener('play', function() {
+
+ // go through all other players
+ for (var i=0, il=mejs.players.length; i<il; i++) {
+ var p = mejs.players[i];
+ if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
+ p.pause();
+ }
+ p.hasFocus = false;
+ }
+
+ t.hasFocus = true;
+ },false);
+
+
+ // ended for all
+ t.media.addEventListener('ended', function (e) {
+ try{
+ t.media.setCurrentTime(0);
+ } catch (exp) {
+
+ }
+ t.media.pause();
+
+ if (t.setProgressRail)
+ t.setProgressRail();
+ if (t.setCurrentRail)
+ t.setCurrentRail();
+
+ if (t.options.loop) {
+ t.media.play();
+ } else if (!t.options.alwaysShowControls && t.controlsEnabled) {
+ t.showControls();
+ }
+ }, false);
+
+ // resize on the first play
+ t.media.addEventListener('loadedmetadata', function(e) {
+ if (t.updateDuration) {
+ t.updateDuration();
+ }
+ if (t.updateCurrent) {
+ t.updateCurrent();
+ }
+
+ if (!t.isFullScreen) {
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+ }
+ }, false);
+
+
+ // webkit has trouble doing this without a delay
+ setTimeout(function () {
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+ }, 50);
+
+ // adjust controls whenever window sizes (used to be in fullscreen only)
+ $(window).resize(function() {
+
+ // don't resize for fullscreen mode
+ if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
+ t.setPlayerSize(t.width, t.height);
+ }
+
+ // always adjust controls
+ t.setControlsSize();
+ });
+
+ // TEMP: needs to be moved somewhere else
+ if (t.media.pluginType == 'youtube') {
+ t.container.find('.mejs-overlay-play').hide();
+ }
+ }
+
+ // force autoplay for HTML5
+ if (autoplay && media.pluginType == 'native') {
+ media.load();
+ media.play();
+ }
+
+
+ if (t.options.success) {
+
+ if (typeof t.options.success == 'string') {
+ window[t.options.success](t.media, t.domNode, t);
+ } else {
+ t.options.success(t.media, t.domNode, t);
+ }
+ }
+ },
+
+ handleError: function(e) {
+ var t = this;
+
+ t.controls.hide();
+
+ // Tell user that the file cannot be played
+ if (t.options.error) {
+ t.options.error(e);
+ }
+ },
+
+ setPlayerSize: function(width,height) {
+ var t = this;
+
+ if (typeof width != 'undefined')
+ t.width = width;
+
+ if (typeof height != 'undefined')
+ t.height = height;
+
+ // detect 100% mode
+ if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width') === '100%') {
+
+ // do we have the native dimensions yet?
+ var
+ nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
+ nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
+ parentWidth = t.container.parent().width(),
+ newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
+
+ if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
+ parentWidth = $(window).width();
+ newHeight = $(window).height();
+ }
+
+ if ( newHeight != 0 ) {
+ // set outer container size
+ t.container
+ .width(parentWidth)
+ .height(newHeight);
+
+ // set native <video>
+ t.$media
+ .width('100%')
+ .height('100%');
+
+ // set shims
+ t.container.find('object, embed, iframe')
+ .width('100%')
+ .height('100%');
+
+ // if shim is ready, send the size to the embeded plugin
+ if (t.isVideo) {
+ if (t.media.setVideoSize) {
+ t.media.setVideoSize(parentWidth, newHeight);
+ }
+ }
+
+ // set the layers
+ t.layers.children('.mejs-layer')
+ .width('100%')
+ .height('100%');
+ }
+
+
+ } else {
+
+ t.container
+ .width(t.width)
+ .height(t.height);
+
+ t.layers.children('.mejs-layer')
+ .width(t.width)
+ .height(t.height);
+
+ }
+ },
+
+ setControlsSize: function() {
+ var t = this,
+ usedWidth = 0,
+ railWidth = 0,
+ rail = t.controls.find('.mejs-time-rail'),
+ total = t.controls.find('.mejs-time-total'),
+ current = t.controls.find('.mejs-time-current'),
+ loaded = t.controls.find('.mejs-time-loaded'),
+ others = rail.siblings();
+
+
+ // allow the size to come from custom CSS
+ if (t.options && !t.options.autosizeProgress) {
+ // Also, frontends devs can be more flexible
+ // due the opportunity of absolute positioning.
+ railWidth = parseInt(rail.css('width'));
+ }
+
+ // attempt to autosize
+ if (railWidth === 0 || !railWidth) {
+
+ // find the size of all the other controls besides the rail
+ others.each(function() {
+ if ($(this).css('position') != 'absolute') {
+ usedWidth += $(this).outerWidth(true);
+ }
+ });
+
+ // fit the rail into the remaining space
+ railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
+ }
+
+ // outer area
+ rail.width(railWidth);
+ // dark space
+ total.width(railWidth - (total.outerWidth(true) - total.width()));
+
+ if (t.setProgressRail)
+ t.setProgressRail();
+ if (t.setCurrentRail)
+ t.setCurrentRail();
+ },
+
+
+ buildposter: function(player, controls, layers, media) {
+ var t = this,
+ poster =
+ $('<div class="mejs-poster mejs-layer">' +
+ '</div>')
+ .appendTo(layers),
+ posterUrl = player.$media.attr('poster');
+
+ // prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
+ if (player.options.poster !== '') {
+ posterUrl = player.options.poster;
+ }
+
+ // second, try the real poster
+ if (posterUrl !== '' && posterUrl != null) {
+ t.setPoster(posterUrl);
+ } else {
+ poster.hide();
+ }
+
+ media.addEventListener('play',function() {
+ poster.hide();
+ }, false);
+ },
+
+ setPoster: function(url) {
+ var t = this,
+ posterDiv = t.container.find('.mejs-poster'),
+ posterImg = posterDiv.find('img');
+
+ if (posterImg.length == 0) {
+ posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
+ }
+
+ posterImg.attr('src', url);
+ },
+
+ buildoverlays: function(player, controls, layers, media) {
+ if (!player.isVideo)
+ return;
+
+ var
+ loading =
+ $('<div class="mejs-overlay mejs-layer">'+
+ '<div class="mejs-overlay-loading"><span></span></div>'+
+ '</div>')
+ .hide() // start out hidden
+ .appendTo(layers),
+ error =
+ $('<div class="mejs-overlay mejs-layer">'+
+ '<div class="mejs-overlay-error"></div>'+
+ '</div>')
+ .hide() // start out hidden
+ .appendTo(layers),
+ // this needs to come last so it's on top
+ bigPlay =
+ $('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
+ '<div class="mejs-overlay-button"></div>'+
+ '</div>')
+ .appendTo(layers)
+ .click(function() {
+ if (media.paused) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ });
+
+ /*
+ if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
+ bigPlay.remove();
+ loading.remove();
+ }
+ */
+
+
+ // show/hide big play button
+ media.addEventListener('play',function() {
+ bigPlay.hide();
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.hide();
+ }, false);
+
+ media.addEventListener('playing', function() {
+ bigPlay.hide();
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.hide();
+ }, false);
+
+ media.addEventListener('seeking', function() {
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+
+ media.addEventListener('seeked', function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ }, false);
+
+ media.addEventListener('pause',function() {
+ if (!mejs.MediaFeatures.isiPhone) {
+ bigPlay.show();
+ }
+ }, false);
+
+ media.addEventListener('waiting', function() {
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+
+
+ // show/hide loading
+ media.addEventListener('loadeddata',function() {
+ // for some reason Chrome is firing this event
+ //if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
+ // return;
+
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+ media.addEventListener('canplay',function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ }, false);
+
+ // error handling
+ media.addEventListener('error',function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.show();
+ error.find('mejs-overlay-error').html("Error loading this resource");
+ }, false);
+ },
+
+ buildkeyboard: function(player, controls, layers, media) {
+
+ var t = this;
+
+ // listen for key presses
+ $(document).keydown(function(e) {
+
+ if (player.hasFocus && player.options.enableKeyboard) {
+
+ // find a matching key
+ for (var i=0, il=player.options.keyActions.length; i<il; i++) {
+ var keyAction = player.options.keyActions[i];
+
+ for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
+ if (e.keyCode == keyAction.keys[j]) {
+ e.preventDefault();
+ keyAction.action(player, media, e.keyCode);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ });
+
+ // check if someone clicked outside a player region, then kill its focus
+ $(document).click(function(event) {
+ if ($(event.target).closest('.mejs-container').length == 0) {
+ player.hasFocus = false;
+ }
+ });
+
+ },
+
+ findTracks: function() {
+ var t = this,
+ tracktags = t.$media.find('track');
+
+ // store for use by plugins
+ t.tracks = [];
+ tracktags.each(function(index, track) {
+
+ track = $(track);
+
+ t.tracks.push({
+ srclang: track.attr('srclang').toLowerCase(),
+ src: track.attr('src'),
+ kind: track.attr('kind'),
+ label: track.attr('label') || '',
+ entries: [],
+ isLoaded: false
+ });
+ });
+ },
+ changeSkin: function(className) {
+ this.container[0].className = 'mejs-container ' + className;
+ 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(muted) {
+ this.media.setMuted(muted);
+ },
+ setCurrentTime: function(time) {
+ this.media.setCurrentTime(time);
+ },
+ getCurrentTime: function() {
+ return this.media.currentTime;
+ },
+ setVolume: function(volume) {
+ this.media.setVolume(volume);
+ },
+ getVolume: function() {
+ return this.media.volume;
+ },
+ setSrc: function(src) {
+ this.media.setSrc(src);
+ },
+ remove: function() {
+ var t = this;
+
+ if (t.media.pluginType === 'flash') {
+ t.media.remove();
+ } else if (t.media.pluginType === 'native') {
+ t.$media.prop('controls', true);
+ }
+
+ // grab video and put it back in place
+ if (!t.isDynamic) {
+ t.$node.insertBefore(t.container)
+ }
+
+ t.container.remove();
+ }
+ };
+
+ // turn into jQuery plugin
+ if (typeof jQuery != 'undefined') {
+ jQuery.fn.mediaelementplayer = function (options) {
+ return this.each(function () {
+ new mejs.MediaElementPlayer(this, options);
+ });
+ };
+ }
+
+ $(document).ready(function() {
+ // auto enable using JSON attribute
+ $('.mejs-player').mediaelementplayer();
+ });
+
+ // push out to window
+ window.MediaElementPlayer = mejs.MediaElementPlayer;
+
+})(mejs.$);
(function($) {
@@ -2884,86 +2910,86 @@ if (typeof jQuery != 'undefined') {
}
});
})(mejs.$);
-(function($) {
-
- // options
- $.extend(mejs.MepDefaults, {
- duration: -1,
- timeAndDurationSeparator: ' <span> | </span> '
- });
-
-
- // current and duration 00:00 / 00:00
- $.extend(MediaElementPlayer.prototype, {
- buildcurrent: function(player, controls, layers, media) {
- var t = this;
-
- $('<div class="mejs-time">'+
- '<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
- + (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
- '</div>')
- .appendTo(controls);
-
- t.currenttime = t.controls.find('.mejs-currenttime');
-
- media.addEventListener('timeupdate',function() {
- player.updateCurrent();
- }, false);
- },
-
-
- buildduration: function(player, controls, layers, media) {
- var t = this;
-
- if (controls.children().last().find('.mejs-currenttime').length > 0) {
- $(t.options.timeAndDurationSeparator +
- '<span class="mejs-duration">' +
- (t.options.duration > 0 ?
- mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
- ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
- ) +
- '</span>')
- .appendTo(controls.find('.mejs-time'));
- } else {
-
- // add class to current time
- controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
-
- $('<div class="mejs-time mejs-duration-container">'+
- '<span class="mejs-duration">' +
- (t.options.duration > 0 ?
- mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
- ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
- ) +
- '</span>' +
- '</div>')
- .appendTo(controls);
- }
-
- t.durationD = t.controls.find('.mejs-duration');
-
- media.addEventListener('timeupdate',function() {
- player.updateDuration();
- }, false);
- },
-
- updateCurrent: function() {
- var t = this;
-
- if (t.currenttime) {
- t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
- }
- },
-
- updateDuration: function() {
- var t = this;
-
- 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));
- }
- }
- });
-
+(function($) {
+
+ // options
+ $.extend(mejs.MepDefaults, {
+ duration: -1,
+ timeAndDurationSeparator: ' <span> | </span> '
+ });
+
+
+ // current and duration 00:00 / 00:00
+ $.extend(MediaElementPlayer.prototype, {
+ buildcurrent: function(player, controls, layers, media) {
+ var t = this;
+
+ $('<div class="mejs-time">'+
+ '<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
+ + (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
+ '</div>')
+ .appendTo(controls);
+
+ t.currenttime = t.controls.find('.mejs-currenttime');
+
+ media.addEventListener('timeupdate',function() {
+ player.updateCurrent();
+ }, false);
+ },
+
+
+ buildduration: function(player, controls, layers, media) {
+ var t = this;
+
+ if (controls.children().last().find('.mejs-currenttime').length > 0) {
+ $(t.options.timeAndDurationSeparator +
+ '<span class="mejs-duration">' +
+ (t.options.duration > 0 ?
+ mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
+ ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
+ ) +
+ '</span>')
+ .appendTo(controls.find('.mejs-time'));
+ } else {
+
+ // add class to current time
+ controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
+
+ $('<div class="mejs-time mejs-duration-container">'+
+ '<span class="mejs-duration">' +
+ (t.options.duration > 0 ?
+ mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
+ ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
+ ) +
+ '</span>' +
+ '</div>')
+ .appendTo(controls);
+ }
+
+ t.durationD = t.controls.find('.mejs-duration');
+
+ media.addEventListener('timeupdate',function() {
+ player.updateDuration();
+ }, false);
+ },
+
+ updateCurrent: function() {
+ var t = this;
+
+ if (t.currenttime) {
+ t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
+ }
+ },
+
+ updateDuration: function() {
+ var t = this;
+
+ 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));
+ }
+ }
+ });
+
})(mejs.$);
(function($) {
@@ -3187,443 +3213,443 @@ if (typeof jQuery != 'undefined') {
})(mejs.$);
-(function($) {
-
- $.extend(mejs.MepDefaults, {
- usePluginFullScreen: true,
- newWindowCallback: function() { return '';},
- fullscreenText: 'Fullscreen'
- });
-
- $.extend(MediaElementPlayer.prototype, {
-
- isFullScreen: false,
-
- isNativeFullScreen: false,
-
- docStyleOverflow: null,
-
- isInIframe: false,
-
- buildfullscreen: function(player, controls, layers, media) {
-
- if (!player.isVideo)
- return;
-
- player.isInIframe = (window.location != window.parent.location);
-
- // native events
- 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) {
-
- if (mejs.MediaFeatures.isFullScreen()) {
- player.isNativeFullScreen = true;
- // reset the controls once we are fully in full screen
- player.setControlsSize();
- } else {
- player.isNativeFullScreen = false;
- // when a user presses ESC
- // make sure to put the player back into place
- player.exitFullScreen();
- }
- });
- }
-
- var t = this,
- normalHeight = 0,
- normalWidth = 0,
- container = player.container,
- fullscreenBtn =
- $('<div class="mejs-button mejs-fullscreen-button">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
- '</div>')
- .appendTo(controls);
-
- if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
-
- fullscreenBtn.click(function() {
- var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
-
- if (isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- });
-
- } else {
-
- var hideTimeout = null,
- supportsPointerEvents = (function() {
- // TAKEN FROM MODERNIZR
- var element = document.createElement('x'),
- documentElement = document.documentElement,
- getComputedStyle = window.getComputedStyle,
- supports;
- if(!('pointerEvents' in element.style)){
- return false;
- }
- element.style.pointerEvents = 'auto';
- element.style.pointerEvents = 'x';
- documentElement.appendChild(element);
- supports = getComputedStyle &&
- getComputedStyle(element, '').pointerEvents === 'auto';
- documentElement.removeChild(element);
- return !!supports;
- })();
-
- //console.log('supportsPointerEvents', supportsPointerEvents);
-
- if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
-
- // allows clicking through the fullscreen button and controls down directly to Flash
-
- /*
- When a user puts his mouse over the fullscreen button, the controls are disabled
- So we put a div over the video and another one on iether side of the fullscreen button
- that caputre mouse movement
- and restore the controls once the mouse moves outside of the fullscreen button
- */
-
- var fullscreenIsDisabled = false,
- restoreControls = function() {
- if (fullscreenIsDisabled) {
- // hide the hovers
- videoHoverDiv.hide();
- controlsLeftHoverDiv.hide();
- controlsRightHoverDiv.hide();
-
- // restore the control bar
- fullscreenBtn.css('pointer-events', '');
- t.controls.css('pointer-events', '');
-
- // store for later
- 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),
- positionHoverDivs = function() {
- var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
- videoHoverDiv.css(style);
- controlsLeftHoverDiv.css(style);
- controlsRightHoverDiv.css(style);
-
- // over video, but not controls
- videoHoverDiv
- .width( t.container.width() )
- .height( t.container.height() - t.controls.height() );
-
- // 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()});
-
- // 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});
- };
-
- $(document).resize(function() {
- positionHoverDivs();
- });
-
- // on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
- fullscreenBtn
- .mouseover(function() {
-
- if (!t.isFullScreen) {
-
- var buttonPos = fullscreenBtn.offset(),
- containerPos = player.container.offset();
-
- // move the button in Flash into place
- media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
-
- // allows click through
- fullscreenBtn.css('pointer-events', 'none');
- t.controls.css('pointer-events', 'none');
-
- // show the divs that will restore things
- videoHoverDiv.show();
- controlsRightHoverDiv.show();
- controlsLeftHoverDiv.show();
- positionHoverDivs();
-
- fullscreenIsDisabled = true;
- }
-
- });
-
- // restore controls anytime the user enters or leaves fullscreen
- media.addEventListener('fullscreenchange', function(e) {
- restoreControls();
- });
-
-
- // 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) {
-
- // if the mouse is anywhere but the fullsceen button, then restore it all
- if (fullscreenIsDisabled) {
-
- var fullscreenBtnPos = fullscreenBtn.offset();
-
-
- if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
- e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
- ) {
-
- fullscreenBtn.css('pointer-events', '');
- t.controls.css('pointer-events', '');
-
- fullscreenIsDisabled = false;
- }
- }
- });
- */
-
-
- } else {
-
- // the hover state will show the fullscreen button in Flash to hover up and click
-
- fullscreenBtn
- .mouseover(function() {
-
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
- delete hideTimeout;
- }
-
- var buttonPos = fullscreenBtn.offset(),
- containerPos = player.container.offset();
-
- media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
-
- })
- .mouseout(function() {
-
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
- delete hideTimeout;
- }
-
- hideTimeout = setTimeout(function() {
- media.hideFullscreenButton();
- }, 1500);
-
-
- });
- }
- }
-
- player.fullscreenBtn = fullscreenBtn;
-
- $(document).bind('keydown',function (e) {
- if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
- player.exitFullScreen();
- }
- });
-
- },
- enterFullScreen: function() {
-
- var t = this;
-
- // firefox+flash can't adjust plugin sizes without resetting :(
- if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
- //t.media.setFullscreen(true);
- //player.isFullScreen = true;
- return;
- }
-
- // store overflow
- docStyleOverflow = document.documentElement.style.overflow;
- // set it to not show scroll bars so 100% will work
- document.documentElement.style.overflow = 'hidden';
-
- // store sizing
- normalHeight = t.container.height();
- normalWidth = t.container.width();
-
- // attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
- if (t.media.pluginType === 'native') {
- if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
-
- mejs.MediaFeatures.requestFullScreen(t.container[0]);
- //return;
-
- if (t.isInIframe) {
- // sometimes exiting from fullscreen doesn't work
- // notably in Chrome <iframe>. Fixed in version 17
- setTimeout(function checkFullscreen() {
-
- if (t.isNativeFullScreen) {
-
- // check if the video is suddenly not really fullscreen
- if ($(window).width() !== screen.width) {
- // manually exit
- t.exitFullScreen();
- } else {
- // test again
- setTimeout(checkFullscreen, 500);
- }
- }
-
-
- }, 500);
- }
-
- } else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
- t.media.webkitEnterFullscreen();
- return;
- }
- }
-
- // check for iframe launch
- if (t.isInIframe) {
- var url = t.options.newWindowCallback(this);
-
-
- if (url !== '') {
-
- // launch immediately
- if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
- t.pause();
- window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
- return;
- } else {
- setTimeout(function() {
- if (!t.isNativeFullScreen) {
- t.pause();
- window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
- }
- }, 250);
- }
- }
-
- }
-
- // full window code
-
-
-
- // make full size
- t.container
- .addClass('mejs-container-fullscreen')
- .width('100%')
- .height('100%');
- //.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
-
- // 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.container.css({width: '100%', height: '100%'});
- t.setControlsSize();
- }, 500);
- //}
-
- if (t.pluginType === 'native') {
- t.$media
- .width('100%')
- .height('100%');
- } else {
- t.container.find('object, embed, iframe')
- .width('100%')
- .height('100%');
-
- //if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
- t.media.setVideoSize($(window).width(),$(window).height());
- //}
- }
-
- t.layers.children('div')
- .width('100%')
- .height('100%');
-
- if (t.fullscreenBtn) {
- t.fullscreenBtn
- .removeClass('mejs-fullscreen')
- .addClass('mejs-unfullscreen');
- }
-
- t.setControlsSize();
- t.isFullScreen = true;
- },
-
- exitFullScreen: function() {
-
- var t = this;
-
- // firefox can't adjust plugins
- if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
- t.media.setFullscreen(false);
- //player.isFullScreen = false;
- return;
- }
-
- // come outo of native fullscreen
- if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
- mejs.MediaFeatures.cancelFullScreen();
- }
-
- // restore scroll bars to document
- document.documentElement.style.overflow = docStyleOverflow;
-
- t.container
- .removeClass('mejs-container-fullscreen')
- .width(normalWidth)
- .height(normalHeight);
- //.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
-
- if (t.pluginType === 'native') {
- t.$media
- .width(normalWidth)
- .height(normalHeight);
- } else {
- t.container.find('object embed')
- .width(normalWidth)
- .height(normalHeight);
-
- t.media.setVideoSize(normalWidth, normalHeight);
- }
-
- t.layers.children('div')
- .width(normalWidth)
- .height(normalHeight);
-
- t.fullscreenBtn
- .removeClass('mejs-unfullscreen')
- .addClass('mejs-fullscreen');
-
- t.setControlsSize();
- t.isFullScreen = false;
- }
- });
-
-})(mejs.$);
+(function($) {
+
+ $.extend(mejs.MepDefaults, {
+ usePluginFullScreen: true,
+ newWindowCallback: function() { return '';},
+ fullscreenText: 'Fullscreen'
+ });
+
+ $.extend(MediaElementPlayer.prototype, {
+
+ isFullScreen: false,
+
+ isNativeFullScreen: false,
+
+ docStyleOverflow: null,
+
+ isInIframe: false,
+
+ buildfullscreen: function(player, controls, layers, media) {
+
+ if (!player.isVideo)
+ return;
+
+ player.isInIframe = (window.location != window.parent.location);
+
+ // native events
+ 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) {
+
+ if (mejs.MediaFeatures.isFullScreen()) {
+ player.isNativeFullScreen = true;
+ // reset the controls once we are fully in full screen
+ player.setControlsSize();
+ } else {
+ player.isNativeFullScreen = false;
+ // when a user presses ESC
+ // make sure to put the player back into place
+ player.exitFullScreen();
+ }
+ });
+ }
+
+ var t = this,
+ normalHeight = 0,
+ normalWidth = 0,
+ container = player.container,
+ fullscreenBtn =
+ $('<div class="mejs-button mejs-fullscreen-button">' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
+ '</div>')
+ .appendTo(controls);
+
+ if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
+
+ fullscreenBtn.click(function() {
+ var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
+
+ if (isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ });
+
+ } else {
+
+ var hideTimeout = null,
+ supportsPointerEvents = (function() {
+ // TAKEN FROM MODERNIZR
+ var element = document.createElement('x'),
+ documentElement = document.documentElement,
+ getComputedStyle = window.getComputedStyle,
+ supports;
+ if(!('pointerEvents' in element.style)){
+ return false;
+ }
+ element.style.pointerEvents = 'auto';
+ element.style.pointerEvents = 'x';
+ documentElement.appendChild(element);
+ supports = getComputedStyle &&
+ getComputedStyle(element, '').pointerEvents === 'auto';
+ documentElement.removeChild(element);
+ return !!supports;
+ })();
+
+ //console.log('supportsPointerEvents', supportsPointerEvents);
+
+ if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
+
+ // allows clicking through the fullscreen button and controls down directly to Flash
+
+ /*
+ When a user puts his mouse over the fullscreen button, the controls are disabled
+ So we put a div over the video and another one on iether side of the fullscreen button
+ that caputre mouse movement
+ and restore the controls once the mouse moves outside of the fullscreen button
+ */
+
+ var fullscreenIsDisabled = false,
+ restoreControls = function() {
+ if (fullscreenIsDisabled) {
+ // hide the hovers
+ videoHoverDiv.hide();
+ controlsLeftHoverDiv.hide();
+ controlsRightHoverDiv.hide();
+
+ // restore the control bar
+ fullscreenBtn.css('pointer-events', '');
+ t.controls.css('pointer-events', '');
+
+ // store for later
+ 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),
+ positionHoverDivs = function() {
+ var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
+ videoHoverDiv.css(style);
+ controlsLeftHoverDiv.css(style);
+ controlsRightHoverDiv.css(style);
+
+ // over video, but not controls
+ videoHoverDiv
+ .width( t.container.width() )
+ .height( t.container.height() - t.controls.height() );
+
+ // 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()});
+
+ // 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});
+ };
+
+ $(document).resize(function() {
+ positionHoverDivs();
+ });
+
+ // on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
+ fullscreenBtn
+ .mouseover(function() {
+
+ if (!t.isFullScreen) {
+
+ var buttonPos = fullscreenBtn.offset(),
+ containerPos = player.container.offset();
+
+ // move the button in Flash into place
+ media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
+
+ // allows click through
+ fullscreenBtn.css('pointer-events', 'none');
+ t.controls.css('pointer-events', 'none');
+
+ // show the divs that will restore things
+ videoHoverDiv.show();
+ controlsRightHoverDiv.show();
+ controlsLeftHoverDiv.show();
+ positionHoverDivs();
+
+ fullscreenIsDisabled = true;
+ }
+
+ });
+
+ // restore controls anytime the user enters or leaves fullscreen
+ media.addEventListener('fullscreenchange', function(e) {
+ restoreControls();
+ });
+
+
+ // 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) {
+
+ // if the mouse is anywhere but the fullsceen button, then restore it all
+ if (fullscreenIsDisabled) {
+
+ var fullscreenBtnPos = fullscreenBtn.offset();
+
+
+ if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
+ e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
+ ) {
+
+ fullscreenBtn.css('pointer-events', '');
+ t.controls.css('pointer-events', '');
+
+ fullscreenIsDisabled = false;
+ }
+ }
+ });
+ */
+
+
+ } else {
+
+ // the hover state will show the fullscreen button in Flash to hover up and click
+
+ fullscreenBtn
+ .mouseover(function() {
+
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
+ delete hideTimeout;
+ }
+
+ var buttonPos = fullscreenBtn.offset(),
+ containerPos = player.container.offset();
+
+ media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
+
+ })
+ .mouseout(function() {
+
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
+ delete hideTimeout;
+ }
+
+ hideTimeout = setTimeout(function() {
+ media.hideFullscreenButton();
+ }, 1500);
+
+
+ });
+ }
+ }
+
+ player.fullscreenBtn = fullscreenBtn;
+
+ $(document).bind('keydown',function (e) {
+ if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
+ player.exitFullScreen();
+ }
+ });
+
+ },
+ enterFullScreen: function() {
+
+ var t = this;
+
+ // firefox+flash can't adjust plugin sizes without resetting :(
+ if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
+ //t.media.setFullscreen(true);
+ //player.isFullScreen = true;
+ return;
+ }
+
+ // store overflow
+ docStyleOverflow = document.documentElement.style.overflow;
+ // set it to not show scroll bars so 100% will work
+ document.documentElement.style.overflow = 'hidden';
+
+ // store sizing
+ normalHeight = t.container.height();
+ normalWidth = t.container.width();
+
+ // attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
+ if (t.media.pluginType === 'native') {
+ if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
+
+ mejs.MediaFeatures.requestFullScreen(t.container[0]);
+ //return;
+
+ if (t.isInIframe) {
+ // sometimes exiting from fullscreen doesn't work
+ // notably in Chrome <iframe>. Fixed in version 17
+ setTimeout(function checkFullscreen() {
+
+ if (t.isNativeFullScreen) {
+
+ // check if the video is suddenly not really fullscreen
+ if ($(window).width() !== screen.width) {
+ // manually exit
+ t.exitFullScreen();
+ } else {
+ // test again
+ setTimeout(checkFullscreen, 500);
+ }
+ }
+
+
+ }, 500);
+ }
+
+ } else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
+ t.media.webkitEnterFullscreen();
+ return;
+ }
+ }
+
+ // check for iframe launch
+ if (t.isInIframe) {
+ var url = t.options.newWindowCallback(this);
+
+
+ if (url !== '') {
+
+ // launch immediately
+ if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
+ t.pause();
+ window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
+ return;
+ } else {
+ setTimeout(function() {
+ if (!t.isNativeFullScreen) {
+ t.pause();
+ window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
+ }
+ }, 250);
+ }
+ }
+
+ }
+
+ // full window code
+
+
+
+ // make full size
+ t.container
+ .addClass('mejs-container-fullscreen')
+ .width('100%')
+ .height('100%');
+ //.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
+
+ // 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.container.css({width: '100%', height: '100%'});
+ t.setControlsSize();
+ }, 500);
+ //}
+
+ if (t.pluginType === 'native') {
+ t.$media
+ .width('100%')
+ .height('100%');
+ } else {
+ t.container.find('object, embed, iframe')
+ .width('100%')
+ .height('100%');
+
+ //if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
+ t.media.setVideoSize($(window).width(),$(window).height());
+ //}
+ }
+
+ t.layers.children('div')
+ .width('100%')
+ .height('100%');
+
+ if (t.fullscreenBtn) {
+ t.fullscreenBtn
+ .removeClass('mejs-fullscreen')
+ .addClass('mejs-unfullscreen');
+ }
+
+ t.setControlsSize();
+ t.isFullScreen = true;
+ },
+
+ exitFullScreen: function() {
+
+ var t = this;
+
+ // firefox can't adjust plugins
+ if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
+ t.media.setFullscreen(false);
+ //player.isFullScreen = false;
+ return;
+ }
+
+ // come outo of native fullscreen
+ if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
+ mejs.MediaFeatures.cancelFullScreen();
+ }
+
+ // restore scroll bars to document
+ document.documentElement.style.overflow = docStyleOverflow;
+
+ t.container
+ .removeClass('mejs-container-fullscreen')
+ .width(normalWidth)
+ .height(normalHeight);
+ //.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
+
+ if (t.pluginType === 'native') {
+ t.$media
+ .width(normalWidth)
+ .height(normalHeight);
+ } else {
+ t.container.find('object embed')
+ .width(normalWidth)
+ .height(normalHeight);
+
+ t.media.setVideoSize(normalWidth, normalHeight);
+ }
+
+ t.layers.children('div')
+ .width(normalWidth)
+ .height(normalHeight);
+
+ t.fullscreenBtn
+ .removeClass('mejs-unfullscreen')
+ .addClass('mejs-fullscreen');
+
+ t.setControlsSize();
+ t.isFullScreen = false;
+ }
+ });
+
+})(mejs.$);
(function($) {
@@ -3791,35 +3817,29 @@ if (typeof jQuery != 'undefined') {
};
- if (track.isTranslation) {
-
- // translate the first track
- mejs.TrackFormatParser.translateTrackText(t.tracks[0].entries, t.tracks[0].srclang, track.srclang, t.options.googleApiKey, function(newOne) {
- // store the new translation
- track.entries = newOne;
+ $.ajax({
+ url: track.src,
+ dataType: "text",
+ success: function(d) {
+ // parse the loaded file
+ if (typeof d == "string" && (/<tt\s+xml/ig).exec(d)) {
+ track.entries = mejs.TrackFormatParser.dfxp.parse(d);
+ } else {
+ track.entries = mejs.TrackFormatParser.webvvt.parse(d);
+ }
+
after();
- });
-
- } else {
- $.ajax({
- url: track.src,
- success: function(d) {
- // parse the loaded file
- track.entries = mejs.TrackFormatParser.parse(d);
- after();
-
- if (track.kind == 'chapters' && t.media.duration > 0) {
- t.drawChapters(track);
- }
- },
- error: function() {
- t.loadNextTrack();
+ if (track.kind == 'chapters' && t.media.duration > 0) {
+ t.drawChapters(track);
}
- });
- }
+ },
+ error: function() {
+ t.loadNextTrack();
+ }
+ });
},
enableTrackButton: function(lang, label) {
@@ -4037,53 +4057,106 @@ if (typeof jQuery != 'undefined') {
Adapted from: http://www.delphiki.com/html5/playr
*/
mejs.TrackFormatParser = {
- // match start "chapter-" (or anythingelse)
- 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})?)(.*)$/,
-
- split2: function (text, regex) {
- // normal version for compliant browsers
- // see below for IE fix
- return text.split(regex);
- },
- parse: function(trackText) {
- var
- i = 0,
- lines = this.split2(trackText, /\r?\n/),
- entries = {text:[], times:[]},
- timecode,
- text;
-
- for(; i<lines.length; i++) {
- // check for the line number
- if (this.pattern_identifier.exec(lines[i])){
- // skip to the next line where the start --> end time code should be
- i++;
- timecode = this.pattern_timecode.exec(lines[i]);
-
- if (timecode && i<lines.length){
- i++;
- // grab all the (possibly multi-line) text that follows
- text = lines[i];
+ webvvt: {
+ // match start "chapter-" (or anythingelse)
+ 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(trackText) {
+ var
+ i = 0,
+ lines = mejs.TrackFormatParser.split2(trackText, /\r?\n/),
+ entries = {text:[], times:[]},
+ timecode,
+ text;
+ for(; i<lines.length; i++) {
+ // check for the line number
+ if (this.pattern_identifier.exec(lines[i])){
+ // skip to the next line where the start --> end time code should be
i++;
- while(lines[i] !== '' && i<lines.length){
- text = text + '\n' + lines[i];
+ timecode = this.pattern_timecode.exec(lines[i]);
+
+ if (timecode && i<lines.length){
+ i++;
+ // grab all the (possibly multi-line) text that follows
+ text = lines[i];
i++;
+ while(lines[i] !== '' && i<lines.length){
+ text = text + '\n' + lines[i];
+ i++;
+ }
+ text = $.trim(text).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
+ // Text is in a different array so I can use .join
+ entries.text.push(text);
+ entries.times.push(
+ {
+ start: (mejs.Utility.convertSMPTEtoSeconds(timecode[1]) == 0) ? 0.200 : mejs.Utility.convertSMPTEtoSeconds(timecode[1]),
+ stop: mejs.Utility.convertSMPTEtoSeconds(timecode[3]),
+ settings: timecode[5]
+ });
}
-
- // Text is in a different array so I can use .join
- entries.text.push(text);
- entries.times.push(
- {
- start: mejs.Utility.timeCodeToSeconds(timecode[1]),
- stop: mejs.Utility.timeCodeToSeconds(timecode[3]),
- settings: timecode[5]
- });
}
}
+ return entries;
}
+ },
+ // Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
+ dfxp: {
+ parse: function(trackText) {
+ trackText = $(trackText).filter("tt");
+ var
+ i = 0,
+ container = trackText.children("div").eq(0),
+ lines = container.find("p"),
+ styleNode = trackText.find("#" + container.attr("style")),
+ styles,
+ begin,
+ end,
+ text,
+ entries = {text:[], times:[]};
+
+
+ if (styleNode.length) {
+ var attributes = styleNode.removeAttr("id").get(0).attributes;
+ if (attributes.length) {
+ styles = {};
+ for (i = 0; i < attributes.length; i++) {
+ styles[attributes[i].name.split(":")[1]] = attributes[i].value;
+ }
+ }
+ }
- return entries;
+ for(i = 0; i<lines.length; i++) {
+ var style;
+ var _temp_times = {
+ start: null,
+ stop: null,
+ style: null
+ };
+ if (lines.eq(i).attr("begin")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("begin"));
+ if (!_temp_times.start && lines.eq(i-1).attr("end")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i-1).attr("end"));
+ if (lines.eq(i).attr("end")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("end"));
+ if (!_temp_times.stop && lines.eq(i+1).attr("begin")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i+1).attr("begin"));
+ if (styles) {
+ style = "";
+ for (var _style in styles) {
+ style += _style + ":" + styles[_style] + ";";
+ }
+ }
+ if (style) _temp_times.style = style;
+ if (_temp_times.start == 0) _temp_times.start = 0.200;
+ entries.times.push(_temp_times);
+ text = $.trim(lines.eq(i).html()).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
+ entries.text.push(text);
+ if (entries.times.start == 0) entries.times.start = 2;
+ }
+ return entries;
+ }
+ },
+ split2: function (text, regex) {
+ // normal version for compliant browsers
+ // see below for IE fix
+ return text.split(regex);
}
};
@@ -4110,196 +4183,197 @@ if (typeof jQuery != 'undefined') {
})(mejs.$);
-/*
-* ContextMenu Plugin
-*
-*
-*/
-
-(function($) {
-
-$.extend(mejs.MepDefaults,
- { 'contextMenuItems': [
- // demo of a fullscreen option
- {
- render: function(player) {
-
- // check for fullscreen plugin
- if (typeof player.enterFullScreen == 'undefined')
- return null;
-
- if (player.isFullScreen) {
- return "Turn off Fullscreen";
- } else {
- return "Go Fullscreen";
- }
- },
- click: function(player) {
- if (player.isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- }
- }
- ,
- // demo of a mute/unmute button
- {
- render: function(player) {
- if (player.media.muted) {
- return "Unmute";
- } else {
- return "Mute";
- }
- },
- click: function(player) {
- if (player.media.muted) {
- player.setMuted(false);
- } else {
- player.setMuted(true);
- }
- }
- },
- // separator
- {
- isSeparator: true
- }
- ,
- // demo of simple download video
- {
- render: function(player) {
- return "Download Video";
- },
- click: function(player) {
- window.location.href = player.media.currentSrc;
- }
- }
- ]}
-);
-
-
- $.extend(MediaElementPlayer.prototype, {
- buildcontextmenu: function(player, controls, layers, media) {
-
- // create context menu
- player.contextMenu = $('<div class="mejs-contextmenu"></div>')
- .appendTo($('body'))
- .hide();
-
- // create events for showing context menu
- player.container.bind('contextmenu', function(e) {
- if (player.isContextMenuEnabled) {
- e.preventDefault();
- player.renderContextMenu(e.clientX-1, e.clientY-1);
- return false;
- }
- });
- player.container.bind('click', function() {
- player.contextMenu.hide();
- });
- player.contextMenu.bind('mouseleave', function() {
-
- //console.log('context hover out');
- player.startContextMenuTimer();
-
- });
- },
-
- isContextMenuEnabled: true,
- enableContextMenu: function() {
- this.isContextMenuEnabled = true;
- },
- disableContextMenu: function() {
- this.isContextMenuEnabled = false;
- },
-
- contextMenuTimeout: null,
- startContextMenuTimer: function() {
- //console.log('startContextMenuTimer');
-
- var t = this;
-
- t.killContextMenuTimer();
-
- t.contextMenuTimer = setTimeout(function() {
- t.hideContextMenu();
- t.killContextMenuTimer();
- }, 750);
- },
- killContextMenuTimer: function() {
- var timer = this.contextMenuTimer;
-
- //console.log('killContextMenuTimer', timer);
-
- if (timer != null) {
- clearTimeout(timer);
- delete timer;
- timer = null;
- }
- },
-
- hideContextMenu: function() {
- this.contextMenu.hide();
- },
-
- renderContextMenu: function(x,y) {
-
- // alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
- var t = this,
- html = '',
- items = t.options.contextMenuItems;
-
- for (var i=0, il=items.length; i<il; i++) {
-
- if (items[i].isSeparator) {
- html += '<div class="mejs-contextmenu-separator"></div>';
- } else {
-
- var rendered = items[i].render(t);
-
- // render can return null if the item doesn't need to be used at the moment
- if (rendered != null) {
- html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
- }
- }
- }
-
- // position and show the context menu
- t.contextMenu
- .empty()
- .append($(html))
- .css({top:y, left:x})
- .show();
-
- // bind events
- t.contextMenu.find('.mejs-contextmenu-item').each(function() {
-
- // which one is this?
- var $dom = $(this),
- itemIndex = parseInt( $dom.data('itemindex'), 10 ),
- item = t.options.contextMenuItems[itemIndex];
-
- // bind extra functionality?
- if (typeof item.show != 'undefined')
- item.show( $dom , t);
-
- // bind click action
- $dom.click(function() {
- // perform click action
- if (typeof item.click != 'undefined')
- item.click(t);
-
- // close
- t.contextMenu.hide();
- });
- });
-
- // stop the controls from hiding
- setTimeout(function() {
- t.killControlsTimer('rev3');
- }, 100);
-
- }
- });
-
+/*
+* ContextMenu Plugin
+*
+*
+*/
+
+(function($) {
+
+$.extend(mejs.MepDefaults,
+ { 'contextMenuItems': [
+ // demo of a fullscreen option
+ {
+ render: function(player) {
+
+ // check for fullscreen plugin
+ if (typeof player.enterFullScreen == 'undefined')
+ return null;
+
+ if (player.isFullScreen) {
+ return "Turn off Fullscreen";
+ } else {
+ return "Go Fullscreen";
+ }
+ },
+ click: function(player) {
+ if (player.isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ }
+ }
+ ,
+ // demo of a mute/unmute button
+ {
+ render: function(player) {
+ if (player.media.muted) {
+ return "Unmute";
+ } else {
+ return "Mute";
+ }
+ },
+ click: function(player) {
+ if (player.media.muted) {
+ player.setMuted(false);
+ } else {
+ player.setMuted(true);
+ }
+ }
+ },
+ // separator
+ {
+ isSeparator: true
+ }
+ ,
+ // demo of simple download video
+ {
+ render: function(player) {
+ return "Download Video";
+ },
+ click: function(player) {
+ window.location.href = player.media.currentSrc;
+ }
+ }
+ ]}
+);
+
+
+ $.extend(MediaElementPlayer.prototype, {
+ buildcontextmenu: function(player, controls, layers, media) {
+
+ // create context menu
+ player.contextMenu = $('<div class="mejs-contextmenu"></div>')
+ .appendTo($('body'))
+ .hide();
+
+ // create events for showing context menu
+ player.container.bind('contextmenu', function(e) {
+ if (player.isContextMenuEnabled) {
+ e.preventDefault();
+ player.renderContextMenu(e.clientX-1, e.clientY-1);
+ return false;
+ }
+ });
+ player.container.bind('click', function() {
+ player.contextMenu.hide();
+ });
+ player.contextMenu.bind('mouseleave', function() {
+
+ //console.log('context hover out');
+ player.startContextMenuTimer();
+
+ });
+ },
+
+ isContextMenuEnabled: true,
+ enableContextMenu: function() {
+ this.isContextMenuEnabled = true;
+ },
+ disableContextMenu: function() {
+ this.isContextMenuEnabled = false;
+ },
+
+ contextMenuTimeout: null,
+ startContextMenuTimer: function() {
+ //console.log('startContextMenuTimer');
+
+ var t = this;
+
+ t.killContextMenuTimer();
+
+ t.contextMenuTimer = setTimeout(function() {
+ t.hideContextMenu();
+ t.killContextMenuTimer();
+ }, 750);
+ },
+ killContextMenuTimer: function() {
+ var timer = this.contextMenuTimer;
+
+ //console.log('killContextMenuTimer', timer);
+
+ if (timer != null) {
+ clearTimeout(timer);
+ delete timer;
+ timer = null;
+ }
+ },
+
+ hideContextMenu: function() {
+ this.contextMenu.hide();
+ },
+
+ renderContextMenu: function(x,y) {
+
+ // alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
+ var t = this,
+ html = '',
+ items = t.options.contextMenuItems;
+
+ for (var i=0, il=items.length; i<il; i++) {
+
+ if (items[i].isSeparator) {
+ html += '<div class="mejs-contextmenu-separator"></div>';
+ } else {
+
+ var rendered = items[i].render(t);
+
+ // render can return null if the item doesn't need to be used at the moment
+ if (rendered != null) {
+ html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
+ }
+ }
+ }
+
+ // position and show the context menu
+ t.contextMenu
+ .empty()
+ .append($(html))
+ .css({top:y, left:x})
+ .show();
+
+ // bind events
+ t.contextMenu.find('.mejs-contextmenu-item').each(function() {
+
+ // which one is this?
+ var $dom = $(this),
+ itemIndex = parseInt( $dom.data('itemindex'), 10 ),
+ item = t.options.contextMenuItems[itemIndex];
+
+ // bind extra functionality?
+ if (typeof item.show != 'undefined')
+ item.show( $dom , t);
+
+ // bind click action
+ $dom.click(function() {
+ // perform click action
+ if (typeof item.click != 'undefined')
+ item.click(t);
+
+ // close
+ t.contextMenu.hide();
+ });
+ });
+
+ // stop the controls from hiding
+ setTimeout(function() {
+ t.killControlsTimer('rev3');
+ }, 100);
+
+ }
+ });
+
})(mejs.$);
+
diff --git a/files_videoviewer/js/mediaelement-and-player.min.js b/files_videoviewer/js/mediaelement-and-player.min.js
index 07760a774..c31dccb34 100644
--- a/files_videoviewer/js/mediaelement-and-player.min.js
+++ b/files_videoviewer/js/mediaelement-and-player.min.js
@@ -10,10 +10,12 @@
* Copyright 2010-2012, John Dyer (http://j.hn)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
-*/var mejs=mejs||{};mejs.version="2.9.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/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"]}]};
+*/var mejs=mejs||{};mejs.version="2.9.5";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"]}]};
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"),j=f.length,h=a.length;b<j;b++){g=f[b].src;for(c=0;c<h;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,j=0;if(c)f=parseInt(a[3])/d;return j=b*3600+e*60+g+f},removeSwf:function(a){var b=document.getElementById(a);if(b&&b.nodeName=="OBJECT")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)}}};
+10);var e=parseInt(a[1],10),g=parseInt(a[2],10),f=0,j=0;if(c)f=parseInt(a[3])/d;return j=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=
+"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}};
mejs.PluginDetector.addPlugin("flash","Shockwave Flash","application/x-shockwave-flash","ShockwaveFlash.ShockwaveFlash",function(a){var b=[];if(a=a.GetVariable("$version")){a=a.split(" ")[1].split(",");b=[parseInt(a[0],10),parseInt(a[1],10),parseInt(a[2],10)]}return b});
@@ -33,8 +35,8 @@ this.setFullscreen(false)},addEventListener:function(a,b){this.events[a]=this.ev
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];a.ended=false;a.paused=true;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",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)};
+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)};
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 j=d.getAttribute("autoplay"),h=d.getAttribute("preload"),l=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;h=typeof h=="undefined"||h===null||h==="false"?
"none":h;j=!(typeof j=="undefined"||j===null||j==="false");l=!(typeof l=="undefined"||l===null||l==="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,j,h)}else if(k.method!=="")return this.createPlugin(k,c,e,j,h,l);else{this.createErrorMessage(k,c,e);return this}},
determinePlayback:function(a,b,c,d,e){var g=[],f,j,h={method:"",url:"",htmlMediaElement:a,isVideo:a.tagName.toLowerCase()!="audio"},l,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){j=this.formatType(e,a.getAttribute("type"));g.push({type:j,url:e})}else for(f=0;f<a.childNodes.length;f++){j=a.childNodes[f];if(j.nodeType==1&&j.tagName.toLowerCase()=="source"){e=j.getAttribute("src");
@@ -44,12 +46,12 @@ k.version))for(d=0;d<k.types.length;d++)if(j==k.types[d]){h.method=e;h.url=g[f].
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>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,j=1,h="me_"+a.method+"_"+mejs.meIndex++,l=new mejs.PluginMediaElement(h,a.method,a.url),k=document.createElement("div"),m;l.tagName=c.tagName;for(m=0;m<c.attributes.length;m++){var n=c.attributes[m];n.specified==true&&l.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;j=b.videoHeight>0?b.videoHeight:c.getAttribute("height")!==null?c.getAttribute("height"):b.defaultVideoHeight;f=mejs.Utility.encodeUrl(f);j=mejs.Utility.encodeUrl(j)}else if(b.enablePluginDebug){f=320;j=240}l.success=b.success;mejs.MediaPluginBridge.registerPluginElement(h,l,c);k.className="me-plugin";k.id=h+"_container";a.isVideo?c.parentNode.insertBefore(k,c):document.body.insertBefore(k,document.body.childNodes[0]);
-d=["id="+h,"isvideo="+(a.isVideo?"true":"false"),"autoplay="+(d?"true":"false"),"preload="+e,"width="+f,"startvolume="+b.startVolume,"timerrate="+b.timerRate,"height="+j];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="'+
-h+'" name="'+h+'" width="'+f+'" height="'+j+'"><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="'+
-h+'" width="'+f+'" height="'+j+'"><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="'+h+'" name="'+h+'" 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="'+j+'"></embed>';break;case "youtube":b=a.url.substr(a.url.lastIndexOf("=")+1);youtubeSettings={container:k,containerId:k.id,pluginMediaElement:l,pluginId:h,videoId:b,height:j,width:f};mejs.PluginDetector.hasPluginVersion("flash",[10,0,0])?mejs.YouTubeApi.createFlash(youtubeSettings):mejs.YouTubeApi.enqueueIframe(youtubeSettings);break;case "vimeo":l.vimeoid=a.url.substr(a.url.lastIndexOf("/")+1);k.innerHTML='<object width="'+
-f+'" height="'+j+'"><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='+l.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='+l.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="'+
-f+'" height="'+j+'"></embed></object>'}c.style.display="none";return l},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}};
+d=["id="+h,"isvideo="+(a.isVideo?"true":"false"),"autoplay="+(d?"true":"false"),"preload="+e,"width="+f,"startvolume="+b.startVolume,"timerrate="+b.timerRate,"flashstreamer="+b.flashStreamer,"height="+j];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="'+h+'" name="'+h+'" width="'+f+'" height="'+j+'"><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="'+h+'" width="'+f+'" height="'+j+'"><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="'+h+'" name="'+h+'" 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="'+j+'"></embed>';break;case "youtube":b=a.url.substr(a.url.lastIndexOf("=")+1);youtubeSettings={container:k,containerId:k.id,pluginMediaElement:l,pluginId:h,videoId:b,
+height:j,width:f};mejs.PluginDetector.hasPluginVersion("flash",[10,0,0])?mejs.YouTubeApi.createFlash(youtubeSettings):mejs.YouTubeApi.enqueueIframe(youtubeSettings);break;case "vimeo":l.vimeoid=a.url.substr(a.url.lastIndexOf("/")+1);k.innerHTML='<object width="'+f+'" height="'+j+'"><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='+l.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='+
+l.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="'+f+'" height="'+j+'"></embed></object>'}c.style.display="none";return l},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]=
@@ -73,76 +75,79 @@ c,"pause");break;case 3:mejs.YouTubeApi.createEvent(b,c,"progress")}}};function
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();
+controlsAreVisible:true,init:function(){var a=this,b=mejs.MediaFeatures,c=f.extend(true,{},a.options,{success:function(d,g){a.meReady(d,g)},error:function(d){a.handleError(d)}}),e=a.media.tagName.toLowerCase();a.isDynamic=e!=="audio"&&e!=="video";a.isVideo=a.isDynamic?a.options.isVideo:e!=="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"><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);
+"")+(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";e=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"+e+"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"+e+"Height"];a.setPlayerSize(a.width,a.height);
c.pluginWidth=a.height;c.pluginHeight=a.width}mejs.MediaElement(a.$media[0],c)},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.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.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.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}},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)});
+this.hideControls(false);this.controlsEnabled=false},enableControls:function(){this.showControls(false);this.controlsEnabled=true},meReady:function(a,b){var c=this,e=mejs.MediaFeatures,d=b.getAttribute("autoplay");d=!(typeof d=="undefined"||d===null||d==="false");var g;if(!c.created){c.created=true;c.media=a;c.domNode=b;if(!(e.isAndroid&&c.options.AndroidUseNativeControls)&&!(e.isiPad&&c.options.iPadUseNativeControls)&&!(e.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){e=c.options.features[g];if(c["build"+e])try{c["build"+e](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.pluginType=="native"?c.$media:f(c.media.pluginElement)).click(function(){a.paused?a.play():a.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<
+!c.options.alwaysShowControls&&c.startControlsTimer(1E3)})}d&&!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(){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();
+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(d&&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%"){var c=this.media.videoWidth&&this.media.videoWidth>0?this.media.videoWidth:
-this.options.defaultVideoWidth,d=this.media.videoHeight&&this.media.videoHeight>0?this.media.videoHeight:this.options.defaultVideoHeight,e=this.container.parent().width();c=parseInt(e*d/c,10);if(this.container.parent()[0].tagName.toLowerCase()==="body"){e=f(window).width();c=f(window).height()}if(c!=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){if(a.isVideo){var e=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-loading"><span></span></div></div>').hide().appendTo(c),g=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-error"></div></div>').hide().appendTo(c),
-k=f('<div class="mejs-overlay mejs-layer mejs-overlay-play"><div class="mejs-overlay-button"></div></div>').appendTo(c).click(function(){d.paused?d.play():d.pause()});d.addEventListener("play",function(){k.hide();e.hide();b.find(".mejs-time-buffering").hide();g.hide()},false);d.addEventListener("playing",function(){k.hide();e.hide();b.find(".mejs-time-buffering").hide();g.hide()},false);d.addEventListener("seeking",function(){e.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("seeked",
-function(){e.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("pause",function(){mejs.MediaFeatures.isiPhone||k.show()},false);d.addEventListener("waiting",function(){e.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("loadeddata",function(){e.show();b.find(".mejs-time-buffering").show()},false);d.addEventListener("canplay",function(){e.hide();b.find(".mejs-time-buffering").hide()},false);d.addEventListener("error",function(){e.hide();b.find(".mejs-time-buffering").hide();
-g.show();g.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)},
+this.options.defaultVideoWidth,e=this.media.videoHeight&&this.media.videoHeight>0?this.media.videoHeight:this.options.defaultVideoHeight,d=this.container.parent().width();c=parseInt(d*e/c,10);if(this.container.parent()[0].tagName.toLowerCase()==="body"){d=f(window).width();c=f(window).height()}if(c!=0){this.container.width(d).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(d,
+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"),e=this.controls.find(".mejs-time-total");this.controls.find(".mejs-time-current");this.controls.find(".mejs-time-loaded");var d=c.siblings();if(this.options&&!this.options.autosizeProgress)b=parseInt(c.css("width"));if(b===
+0||!b){d.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);e.width(b-(e.outerWidth(true)-e.width()));this.setProgressRail&&this.setProgressRail();this.setCurrentRail&&this.setCurrentRail()},buildposter:function(a,b,c,e){var d=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):d.hide();
+e.addEventListener("play",function(){d.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,e){if(a.isVideo){var d=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-loading"><span></span></div></div>').hide().appendTo(c),g=f('<div class="mejs-overlay mejs-layer"><div class="mejs-overlay-error"></div></div>').hide().appendTo(c),
+k=f('<div class="mejs-overlay mejs-layer mejs-overlay-play"><div class="mejs-overlay-button"></div></div>').appendTo(c).click(function(){e.paused?e.play():e.pause()});e.addEventListener("play",function(){k.hide();d.hide();b.find(".mejs-time-buffering").hide();g.hide()},false);e.addEventListener("playing",function(){k.hide();d.hide();b.find(".mejs-time-buffering").hide();g.hide()},false);e.addEventListener("seeking",function(){d.show();b.find(".mejs-time-buffering").show()},false);e.addEventListener("seeked",
+function(){d.hide();b.find(".mejs-time-buffering").hide()},false);e.addEventListener("pause",function(){mejs.MediaFeatures.isiPhone||k.show()},false);e.addEventListener("waiting",function(){d.show();b.find(".mejs-time-buffering").show()},false);e.addEventListener("loadeddata",function(){d.show();b.find(".mejs-time-buffering").show()},false);e.addEventListener("canplay",function(){d.hide();b.find(".mejs-time-buffering").hide()},false);e.addEventListener("error",function(){d.hide();b.find(".mejs-time-buffering").hide();
+g.show();g.find("mejs-overlay-error").html("Error loading this resource")},false)}},buildkeyboard:function(a,b,c,e){f(document).keydown(function(d){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(d.keyCode==h.keys[o]){d.preventDefault();h.action(a,e,d.keyCode);return false}return true});f(document).click(function(d){if(f(d.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,e){e=f(e);a.tracks.push({srclang:e.attr("srclang").toLowerCase(),src:e.attr("src"),kind:e.attr("kind"),label:e.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);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));
+(function(f){f.extend(mejs.MepDefaults,{playpauseText:"Play/Pause"});f.extend(MediaElementPlayer.prototype,{buildplaypause:function(a,b,c,e){var d=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();e.paused?e.play():e.pause();return false});e.addEventListener("play",function(){d.removeClass("mejs-play").addClass("mejs-pause")},false);
+e.addEventListener("playing",function(){d.removeClass("mejs-play").addClass("mejs-pause")},false);e.addEventListener("pause",function(){d.removeClass("mejs-pause").addClass("mejs-play")},false);e.addEventListener("paused",function(){d.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,e){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(){e.paused||e.pause();if(e.currentTime>0){e.setCurrentTime(0);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(l){l=l.pageX;var q=e.offset(),i=e.outerWidth(),j=0;j=0;var m=l-q.left;if(l>q.left&&l<=i+q.left&&d.duration){j=(l-q.left)/i;j=j<=0.02?0:j*d.duration;p&&d.setCurrentTime(j);if(!mejs.MediaFeatures.hasTouch){h.css("left",m);o.html(mejs.Utility.secondsToTimeCode(j));h.show()}}},p=false;e.bind("mousedown",function(l){if(l.which===
-1){p=true;n(l);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(l){n(l)});mejs.MediaFeatures.hasTouch||h.show()}).bind("mouseleave",function(){if(!p){f(document).unbind(".dur");h.hide()}});d.addEventListener("progress",function(l){a.setProgressRail(l);a.setCurrentRail(l)},false);d.addEventListener("timeupdate",function(l){a.setProgressRail(l);
-a.setCurrentRail(l)},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()*
+(function(f){f.extend(MediaElementPlayer.prototype,{buildprogress:function(a,b,c,e){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 d=
+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(l){l=l.pageX;var q=d.offset(),i=d.outerWidth(),j=0;j=0;var m=l-q.left;if(l>q.left&&l<=i+q.left&&e.duration){j=(l-q.left)/i;j=j<=0.02?0:j*e.duration;p&&e.setCurrentTime(j);if(!mejs.MediaFeatures.hasTouch){h.css("left",m);o.html(mejs.Utility.secondsToTimeCode(j));h.show()}}},p=false;d.bind("mousedown",function(l){if(l.which===
+1){p=true;n(l);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(l){n(l)});mejs.MediaFeatures.hasTouch||h.show()}).bind("mouseleave",function(){if(!p){f(document).unbind(".dur");h.hide()}});e.addEventListener("progress",function(l){a.setProgressRail(l);a.setCurrentRail(l)},false);e.addEventListener("timeupdate",function(l){a.setProgressRail(l);
+a.setCurrentRail(l)},false);this.loaded=c;this.total=d;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.$);
-(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()},
+(function(f){f.extend(mejs.MepDefaults,{duration:-1,timeAndDurationSeparator:" <span> | </span> "});f.extend(MediaElementPlayer.prototype,{buildcurrent:function(a,b,c,e){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");e.addEventListener("timeupdate",function(){a.updateCurrent()},false)},buildduration:function(a,
+b,c,e){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");e.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(){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+
+(function(f){f.extend(mejs.MepDefaults,{muteText:"Mute Toggle",hideVolumeOnTouchDevices:true,audioVolume:"horizontal",videoVolume:"vertical"});f.extend(MediaElementPlayer.prototype,{buildvolume:function(a,b,c,e){if(!(mejs.MediaFeatures.hasTouch&&this.options.hideVolumeOnTouchDevices)){var d=this.isVideo?this.options.videoVolume:this.options.audioVolume,g=d=="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,m){if(!k.is(":visible")&&typeof m!="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",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",s.left+r-n.width()/2);o.width(r)}}},l=function(j){var m=null,r=h.offset();if(e=="vertical"){m=h.height();parseInt(h.css("top").replace(/px/,""),10);m=(m-(j.pageY-r.top))/m;if(r.top==0||r.left==0)return}else{m=h.width();m=(j.pageX-r.left)/m}m=Math.max(0,m);m=Math.min(m,1);p(m);m==0?d.setMuted(true):d.setMuted(false);d.setVolume(m)},
-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){l(j);f(document).bind("mousemove.vol",function(m){l(m)}).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:"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,m=window.getComputedStyle;if(!("pointerEvents"in i.style))return false;i.style.pointerEvents="auto";i.style.pointerEvents="x";j.appendChild(i);m=m&&m(i,"").pointerEvents==="auto";j.removeChild(i);return!!m}()&&!mejs.MediaFeatures.isOpera){var h=false,o=function(){if(h){n.hide();p.hide();l.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),l=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);l.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()});l.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();l.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=
+if(d=="vertical"){var r=h.height(),s=h.position(),t=r-r*j;n.css("top",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",s.left+r-n.width()/2);o.width(r)}}},l=function(j){var m=null,r=h.offset();if(d=="vertical"){m=h.height();parseInt(h.css("top").replace(/px/,""),10);m=(m-(j.pageY-r.top))/m;if(r.top==0||r.left==0)return}else{m=h.width();m=(j.pageX-r.left)/m}m=Math.max(0,m);m=Math.min(m,1);p(m);m==0?e.setMuted(true):e.setMuted(false);e.setVolume(m)},
+q=false,i=false;g.hover(function(){k.show();i=true},function(){i=false;!q&&d=="vertical"&&k.hide()});k.bind("mouseover",function(){i=true}).bind("mousedown",function(j){l(j);f(document).bind("mousemove.vol",function(m){l(m)}).bind("mouseup.vol",function(){q=false;f(document).unbind(".vol");!i&&d=="vertical"&&k.hide()});q=true;return false});g.find("button").click(function(){e.setMuted(!e.muted)});e.addEventListener("volumechange",function(){if(!q)if(e.muted){p(0);g.removeClass("mejs-mute").addClass("mejs-unmute")}else{p(e.volume);
+g.removeClass("mejs-unmute").addClass("mejs-mute")}},false);if(this.container.is(":visible")){p(a.options.startVolume);e.pluginType==="native"&&e.setVolume(a.options.startVolume)}}}})})(mejs.$);
+(function(f){f.extend(mejs.MepDefaults,{usePluginFullScreen:true,newWindowCallback:function(){return""},fullscreenText:"Fullscreen"});f.extend(MediaElementPlayer.prototype,{isFullScreen:false,isNativeFullScreen:false,docStyleOverflow:null,isInIframe:false,buildfullscreen:function(a,b,c,e){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 d=this,g=f('<div class="mejs-button mejs-fullscreen-button"><button type="button" aria-controls="'+d.id+'" title="'+d.options.fullscreenText+'"></button></div>').appendTo(b);if(d.media.pluginType==="native"||!d.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,m=window.getComputedStyle;if(!("pointerEvents"in i.style))return false;i.style.pointerEvents="auto";i.style.pointerEvents="x";j.appendChild(i);m=m&&m(i,"").pointerEvents==="auto";j.removeChild(i);return!!m}()&&!mejs.MediaFeatures.isOpera){var h=false,o=function(){if(h){n.hide();p.hide();l.hide();g.css("pointer-events","");d.controls.css("pointer-events",
+"");h=false}},n=f('<div class="mejs-fullscreen-hover" />').appendTo(d.container).mouseover(o),p=f('<div class="mejs-fullscreen-hover" />').appendTo(d.container).mouseover(o),l=f('<div class="mejs-fullscreen-hover" />').appendTo(d.container).mouseover(o),q=function(){var i={position:"absolute",top:0,left:0};n.css(i);p.css(i);l.css(i);n.width(d.container.width()).height(d.container.height()-d.controls.height());i=g.offset().left-d.container.offset().left;fullScreenBtnWidth=g.outerWidth(true);p.width(i).height(d.controls.height()).css({top:d.container.height()-
+d.controls.height()});l.width(d.container.width()-i-fullScreenBtnWidth).height(d.controls.height()).css({top:d.container.height()-d.controls.height(),left:i+fullScreenBtnWidth})};f(document).resize(function(){q()});g.mouseover(function(){if(!d.isFullScreen){var i=g.offset(),j=a.container.offset();e.positionFullscreenButton(i.left-j.left,i.top-j.top,false);g.css("pointer-events","none");d.controls.css("pointer-events","none");n.show();l.show();p.show();q();h=true}});e.addEventListener("fullscreenchange",
+function(){o()})}else g.mouseover(function(){if(k!==null){clearTimeout(k);delete k}var i=g.offset(),j=a.container.offset();e.positionFullscreenButton(i.left-j.left,i.top-j.top,true)}).mouseout(function(){if(k!==null){clearTimeout(k);delete k}k=setTimeout(function(){e.hideFullscreenButton()},1500)})}a.fullscreenBtn=g;f(document).bind("keydown",function(i){if((mejs.MediaFeatures.hasTrueNativeFullScreen&&mejs.MediaFeatures.isFullScreen()||d.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");
+(function(f){f.extend(mejs.MepDefaults,{startLanguage:"",tracksText:"Captions/Subtitles"});f.extend(MediaElementPlayer.prototype,{hasChapters:false,buildtracks:function(a,b,c,e){if(a.isVideo)if(a.tracks.length!=0){var d;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("mouseenter",function(){a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover")}).bind("mouseleave",
-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],d=function(){c.isLoaded=true;b.enableTrackButton(c.srclang,c.label);b.loadNextTrack()};c.isTranslation?mejs.TrackFormatParser.translateTrackText(b.tracks[0].entries,b.tracks[0].srclang,c.srclang,b.options.googleApiKey,function(e){c.entries=e;d()}):f.ajax({url:c.src,success:function(e){c.entries=mejs.TrackFormatParser.parse(e);d();c.kind=="chapters"&&b.media.duration>0&&b.drawChapters(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))},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={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})?)(.*)$/,split2:function(a,b){return a.split(b)},parse:function(a){var b=0;a=this.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++}c.text.push(e);c.times.push({start:mejs.Utility.timeCodeToSeconds(d[1]),stop:mejs.Utility.timeCodeToSeconds(d[3]),
-settings:d[5]})}}return c}};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.$);
+"hidden")}).delegate("input[type=radio]","click",function(){lang=this.value;if(lang=="none")a.selectedTrack=null;else for(d=0;d<a.tracks.length;d++)if(a.tracks[d].srclang==lang){a.selectedTrack=a.tracks[d];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("mouseenter",function(){a.container.find(".mejs-captions-position").addClass("mejs-captions-position-hover")}).bind("mouseleave",
+function(){e.paused||a.container.find(".mejs-captions-position").removeClass("mejs-captions-position-hover")});a.trackToLoad=-1;a.selectedTrack=null;a.isLoadingTrack=false;for(d=0;d<a.tracks.length;d++)a.tracks[d].kind=="subtitles"&&a.addTrackButton(a.tracks[d].srclang,a.tracks[d].label);a.loadNextTrack();e.addEventListener("timeupdate",function(){a.displayCaptions()},false);e.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&&!e.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(e){c.entries=typeof e=="string"&&/<tt\s+xml/ig.exec(e)?mejs.TrackFormatParser.dfxp.parse(e):mejs.TrackFormatParser.webvvt.parse(e);c.isLoaded=true;b.enableTrackButton(c.srclang,c.label);b.loadNextTrack();c.kind=="chapters"&&b.media.duration>0&&b.drawChapters(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))},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,e,d=e=0;b.chapters.empty();for(c=0;c<a.entries.times.length;c++){e=a.entries.times[c].stop-a.entries.times[c].start;e=Math.floor(e/b.media.duration*100);if(e+d>100||c==a.entries.times.length-1&&e+d<100)e=100-d;b.chapters.append(f('<div class="mejs-chapter" rel="'+
+a.entries.times[c].start+'" style="left: '+d.toString()+"%;width: "+e.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>"));d+=e}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:[]},e,d;b<a.length;b++)if(this.pattern_identifier.exec(a[b])){b++;if((e=this.pattern_timecode.exec(a[b]))&&b<a.length){b++;d=a[b];for(b++;a[b]!==""&&b<a.length;){d=d+"\n"+a[b];b++}d=f.trim(d).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,"<a href='$1' target='_blank'>$1</a>");c.text.push(d);c.times.push({start:mejs.Utility.convertSMPTEtoSeconds(e[1])==0?0.2:mejs.Utility.convertSMPTEtoSeconds(e[1]),
+stop:mejs.Utility.convertSMPTEtoSeconds(e[3]),settings:e[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 e,d;a={text:[],times:[]};if(b.length){d=b.removeAttr("id").get(0).attributes;if(d.length){e={};for(b=0;b<d.length;b++)e[d[b].name.split(":")[1]]=d[b].value}}for(b=0;b<c.length;b++){var g;d={start:null,stop:null,style:null};if(c.eq(b).attr("begin"))d.start=mejs.Utility.convertSMPTEtoSeconds(c.eq(b).attr("begin"));
+if(!d.start&&c.eq(b-1).attr("end"))d.start=mejs.Utility.convertSMPTEtoSeconds(c.eq(b-1).attr("end"));if(c.eq(b).attr("end"))d.stop=mejs.Utility.convertSMPTEtoSeconds(c.eq(b).attr("end"));if(!d.stop&&c.eq(b+1).attr("begin"))d.stop=mejs.Utility.convertSMPTEtoSeconds(c.eq(b+1).attr("begin"));if(e){g="";for(var k in e)g+=k+":"+e[k]+";"}if(g)d.style=g;if(d.start==0)d.start=0.2;a.times.push(d);d=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(d);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=[],e="",d;for(d=0;d<a.length;d++){e+=a.substring(d,d+1);if(b.test(e)){c.push(e.replace(b,""));e=""}}c.push(e);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!=
+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,e="",d=c.options.contextMenuItems,g=0,k=d.length;g<
+k;g++)if(d[g].isSeparator)e+='<div class="mejs-contextmenu-separator"></div>';else{var h=d[g].render(c);if(h!=null)e+='<div class="mejs-contextmenu-item" data-itemindex="'+g+'" id="element-'+Math.random()*1E6+'">'+h+"</div>"}c.contextMenu.empty().append(f(e)).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.$);
+
diff --git a/files_videoviewer/mediaelement/src/.DS_Store b/files_videoviewer/mediaelement/src/.DS_Store
deleted file mode 100644
index bf5648835..000000000
--- a/files_videoviewer/mediaelement/src/.DS_Store
+++ /dev/null
Binary files differ
diff --git a/files_videoviewer/mediaelement/src/Builder.py b/files_videoviewer/mediaelement/src/Builder.py
index 4e03b0862..cec018e54 100755
--- a/files_videoviewer/mediaelement/src/Builder.py
+++ b/files_videoviewer/mediaelement/src/Builder.py
@@ -1,131 +1,131 @@
-import sys
-import os
-import shutil
-
-me_filename = 'mediaelement'
-mep_filename = 'mediaelementplayer'
-combined_filename = 'mediaelement-and-player'
-
-# BUILD MediaElement (single file)
-
-print('building MediaElement.js')
-me_files = []
-me_files.append('me-header.js')
-me_files.append('me-namespace.js')
-me_files.append('me-utility.js')
-me_files.append('me-plugindetector.js')
-me_files.append('me-featuredetection.js')
-me_files.append('me-mediaelements.js')
-me_files.append('me-shim.js')
-
-code = ''
-
-for item in me_files:
- src_file = open('js/' + item,'r')
- code += src_file.read() + "\n"
-
-tmp_file = open('../build/' + me_filename + '.js','w')
-tmp_file.write(code)
-tmp_file.close()
-
-# BUILD MediaElementPlayer (single file)
-print('building MediaElementPlayer.js')
-mep_files = []
-mep_files.append('mep-header.js')
-mep_files.append('mep-library.js')
-mep_files.append('mep-player.js')
-mep_files.append('mep-feature-playpause.js')
-mep_files.append('mep-feature-stop.js')
-mep_files.append('mep-feature-progress.js')
-mep_files.append('mep-feature-time.js')
-mep_files.append('mep-feature-volume.js')
-mep_files.append('mep-feature-fullscreen.js')
-mep_files.append('mep-feature-tracks.js')
-mep_files.append('mep-feature-contextmenu.js')
-# mep_files.append('mep-feature-sourcechooser.js')
-
-code = ''
-
-for item in mep_files:
- src_file = open('js/' + item,'r')
- code += src_file.read() + "\n"
-
-tmp_file = open('../build/' + mep_filename + '.js','w')
-tmp_file.write(code)
-tmp_file.close()
-
-# MINIFY both scripts
-
-print('Minifying JavaScript')
-# os.system("java -jar yuicompressor-2.4.2.jar ../build/" + me_filename + ".js -o ../build/" + me_filename + ".min.js --charset utf-8 -v")
-# os.system("java -jar yuicompressor-2.4.2.jar ../build/" + mep_filename + ".js -o ../build/" + mep_filename + ".min.js --charset utf-8 -v")
-os.system("java -jar compiler.jar --js ../build/" + me_filename + ".js --js_output_file ../build/" + me_filename + ".min.js")
-os.system("java -jar compiler.jar --js ../build/" + mep_filename + ".js --js_output_file ../build/" + mep_filename + ".min.js")
-
-# PREPEND intros
-def addHeader(headerFilename, filename):
-
- # get the header text
- tmp_file = open(headerFilename)
- header_txt = tmp_file.read();
- tmp_file.close()
-
- # read the current contents of the file
- tmp_file = open(filename)
- file_txt = tmp_file.read()
- tmp_file.close()
-
- # open the file again for writing
- tmp_file = open(filename, 'w')
- tmp_file.write(header_txt)
- # write the original contents
- tmp_file.write(file_txt)
- tmp_file.close()
-
-addHeader('js/me-header.js', '../build/' + me_filename + '.min.js')
-addHeader('js/mep-header.js', '../build/' + mep_filename + '.min.js')
-
-
-# COMBINE into single script
-print('Combining scripts')
-code = ''
-src_file = open('../build/' + me_filename + '.js','r')
-code += src_file.read() + "\n"
-src_file = open('../build/' + mep_filename + '.js','r')
-code += src_file.read() + "\n"
-
-tmp_file = open('../build/' + combined_filename + '.js','w')
-tmp_file.write(code)
-tmp_file.close()
-
-code = ''
-src_file = open('../build/' + me_filename + '.min.js','r')
-code += src_file.read() + "\n"
-src_file = open('../build/' + mep_filename + '.min.js','r')
-code += src_file.read() + "\n"
-
-tmp_file = open('../build/' + combined_filename + '.min.js','w')
-tmp_file.write(code)
-tmp_file.close()
-
-
-# MINIFY CSS
-print('Minifying CSS')
-src_file = open('css/mediaelementplayer.css','r')
-tmp_file = open('../build/mediaelementplayer.css','w')
-tmp_file.write(src_file.read())
-tmp_file.close()
-os.system("java -jar yuicompressor-2.4.2.jar ../build/mediaelementplayer.css -o ../build/mediaelementplayer.min.css --charset utf-8 -v")
-
-#COPY skin files
-print('Copying Skin Files')
-shutil.copy2('css/controls.png','../build/controls.png')
-shutil.copy2('css/bigplay.png','../build/bigplay.png')
-shutil.copy2('css/loading.gif','../build/loading.gif')
-
-shutil.copy2('css/mejs-skins.css','../build/mejs-skins.css')
-shutil.copy2('css/controls-ted.png','../build/controls-ted.png')
-shutil.copy2('css/controls-wmp.png','../build/controls-wmp.png')
-shutil.copy2('css/controls-wmp-bg.png','../build/controls-wmp-bg.png')
-
-print('DONE!')
+import sys
+import os
+import shutil
+
+me_filename = 'mediaelement'
+mep_filename = 'mediaelementplayer'
+combined_filename = 'mediaelement-and-player'
+
+# BUILD MediaElement (single file)
+
+print('building MediaElement.js')
+me_files = []
+me_files.append('me-header.js')
+me_files.append('me-namespace.js')
+me_files.append('me-utility.js')
+me_files.append('me-plugindetector.js')
+me_files.append('me-featuredetection.js')
+me_files.append('me-mediaelements.js')
+me_files.append('me-shim.js')
+
+code = ''
+
+for item in me_files:
+ src_file = open('js/' + item,'r')
+ code += src_file.read() + "\n"
+
+tmp_file = open('../build/' + me_filename + '.js','w')
+tmp_file.write(code)
+tmp_file.close()
+
+# BUILD MediaElementPlayer (single file)
+print('building MediaElementPlayer.js')
+mep_files = []
+mep_files.append('mep-header.js')
+mep_files.append('mep-library.js')
+mep_files.append('mep-player.js')
+mep_files.append('mep-feature-playpause.js')
+mep_files.append('mep-feature-stop.js')
+mep_files.append('mep-feature-progress.js')
+mep_files.append('mep-feature-time.js')
+mep_files.append('mep-feature-volume.js')
+mep_files.append('mep-feature-fullscreen.js')
+mep_files.append('mep-feature-tracks.js')
+mep_files.append('mep-feature-contextmenu.js')
+# mep_files.append('mep-feature-sourcechooser.js')
+
+code = ''
+
+for item in mep_files:
+ src_file = open('js/' + item,'r')
+ code += src_file.read() + "\n"
+
+tmp_file = open('../build/' + mep_filename + '.js','w')
+tmp_file.write(code)
+tmp_file.close()
+
+# MINIFY both scripts
+
+print('Minifying JavaScript')
+# os.system("java -jar yuicompressor-2.4.2.jar ../build/" + me_filename + ".js -o ../build/" + me_filename + ".min.js --charset utf-8 -v")
+# os.system("java -jar yuicompressor-2.4.2.jar ../build/" + mep_filename + ".js -o ../build/" + mep_filename + ".min.js --charset utf-8 -v")
+os.system("java -jar compiler.jar --js ../build/" + me_filename + ".js --js_output_file ../build/" + me_filename + ".min.js")
+os.system("java -jar compiler.jar --js ../build/" + mep_filename + ".js --js_output_file ../build/" + mep_filename + ".min.js")
+
+# PREPEND intros
+def addHeader(headerFilename, filename):
+
+ # get the header text
+ tmp_file = open(headerFilename)
+ header_txt = tmp_file.read();
+ tmp_file.close()
+
+ # read the current contents of the file
+ tmp_file = open(filename)
+ file_txt = tmp_file.read()
+ tmp_file.close()
+
+ # open the file again for writing
+ tmp_file = open(filename, 'w')
+ tmp_file.write(header_txt)
+ # write the original contents
+ tmp_file.write(file_txt)
+ tmp_file.close()
+
+addHeader('js/me-header.js', '../build/' + me_filename + '.min.js')
+addHeader('js/mep-header.js', '../build/' + mep_filename + '.min.js')
+
+
+# COMBINE into single script
+print('Combining scripts')
+code = ''
+src_file = open('../build/' + me_filename + '.js','r')
+code += src_file.read() + "\n"
+src_file = open('../build/' + mep_filename + '.js','r')
+code += src_file.read() + "\n"
+
+tmp_file = open('../build/' + combined_filename + '.js','w')
+tmp_file.write(code)
+tmp_file.close()
+
+code = ''
+src_file = open('../build/' + me_filename + '.min.js','r')
+code += src_file.read() + "\n"
+src_file = open('../build/' + mep_filename + '.min.js','r')
+code += src_file.read() + "\n"
+
+tmp_file = open('../build/' + combined_filename + '.min.js','w')
+tmp_file.write(code)
+tmp_file.close()
+
+
+# MINIFY CSS
+print('Minifying CSS')
+src_file = open('css/mediaelementplayer.css','r')
+tmp_file = open('../build/mediaelementplayer.css','w')
+tmp_file.write(src_file.read())
+tmp_file.close()
+os.system("java -jar yuicompressor-2.4.2.jar ../build/mediaelementplayer.css -o ../build/mediaelementplayer.min.css --charset utf-8 -v")
+
+#COPY skin files
+print('Copying Skin Files')
+shutil.copy2('css/controls.png','../build/controls.png')
+shutil.copy2('css/bigplay.png','../build/bigplay.png')
+shutil.copy2('css/loading.gif','../build/loading.gif')
+
+shutil.copy2('css/mejs-skins.css','../build/mejs-skins.css')
+shutil.copy2('css/controls-ted.png','../build/controls-ted.png')
+shutil.copy2('css/controls-wmp.png','../build/controls-wmp.png')
+shutil.copy2('css/controls-wmp-bg.png','../build/controls-wmp-bg.png')
+
+print('DONE!')
diff --git a/files_videoviewer/mediaelement/src/css/mediaelementplayer.css b/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
index 6cc6f03bf..81468345b 100644
--- a/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
+++ b/files_videoviewer/mediaelement/src/css/mediaelementplayer.css
@@ -4,6 +4,7 @@
font-family: Helvetica, Arial;
text-align: left;
vertical-align: top;
+ text-indent: 0;
}
.me-plugin {
diff --git a/files_videoviewer/mediaelement/src/css/mejs-skins.css b/files_videoviewer/mediaelement/src/css/mejs-skins.css
index c71f3d005..814b9d4f0 100644
--- a/files_videoviewer/mediaelement/src/css/mejs-skins.css
+++ b/files_videoviewer/mediaelement/src/css/mejs-skins.css
@@ -278,3 +278,6 @@
display: none;
}
/* END: WMP player */
+
+
+
diff --git a/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as b/files_videoviewer/mediaelement/src/flash/FlashMediaElement.as
index aa147b794..6ae93e7b7 100644
--- 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; // 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"; 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); _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 (_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 = ""; // 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
diff --git a/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as b/files_videoviewer/mediaelement/src/flash/htmlelements/VideoElement.as
index fe529212c..2448830c5 100644
--- 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 _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) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _video = new Video(); addChild(_video); _connection = new NetConnection(); _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)?\:\/\//); _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) { _connection.connect(_currentUrl.replace(/\/[^\/]+$/,"/")); } 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) { _stream.play(_currentUrl.split("/").pop()); } 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); 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); } } } \ 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 _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); 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
diff --git a/files_videoviewer/mediaelement/src/js/me-namespace.js b/files_videoviewer/mediaelement/src/js/me-namespace.js
index 6d2fff06d..b3ef557c0 100644
--- a/files_videoviewer/mediaelement/src/js/me-namespace.js
+++ b/files_videoviewer/mediaelement/src/js/me-namespace.js
@@ -1,25 +1,25 @@
-// Namespace
-var mejs = mejs || {};
-
-// version number
-mejs.version = '2.9.3';
-
-// player number (for missing, same id attr)
-mejs.meIndex = 0;
-
-// media types accepted by plugins
-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/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
- //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
- ],
- youtube: [
- {version: null, types: ['video/youtube', 'video/x-youtube']}
- ],
- vimeo: [
- {version: null, types: ['video/vimeo']}
- ]
+// Namespace
+var mejs = mejs || {};
+
+// version number
+mejs.version = '2.9.5';
+
+// player number (for missing, same id attr)
+mejs.meIndex = 0;
+
+// media types accepted by plugins
+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']}
+ //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
+ ],
+ youtube: [
+ {version: null, types: ['video/youtube', 'video/x-youtube']}
+ ],
+ vimeo: [
+ {version: null, types: ['video/vimeo']}
+ ]
}; \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/js/me-shim.js b/files_videoviewer/mediaelement/src/js/me-shim.js
index 5f0061d03..f8d800b78 100644
--- a/files_videoviewer/mediaelement/src/js/me-shim.js
+++ b/files_videoviewer/mediaelement/src/js/me-shim.js
@@ -96,6 +96,8 @@ mejs.MediaElementDefaults = {
pluginPath: mejs.Utility.getScriptPath(['mediaelement.js','mediaelement.min.js','mediaelement-and-player.js','mediaelement-and-player.min.js']),
// name of flash file
flashName: 'flashmediaelement.swf',
+ // streamer for RTMP streaming
+ flashStreamer: '',
// turns on the smoothing filter in Flash
enablePluginSmoothing: false,
// name of silverlight file
@@ -473,6 +475,7 @@ mejs.HtmlMediaElementShim = {
'width=' + width,
'startvolume=' + options.startVolume,
'timerrate=' + options.timerRate,
+ 'flashstreamer=' + options.flashStreamer,
'height=' + height];
if (playback.url !== null) {
diff --git a/files_videoviewer/mediaelement/src/js/me-utility.js b/files_videoviewer/mediaelement/src/js/me-utility.js
index 177d04c89..383aa478b 100644
--- a/files_videoviewer/mediaelement/src/js/me-utility.js
+++ b/files_videoviewer/mediaelement/src/js/me-utility.js
@@ -1,116 +1,139 @@
-
-/*
-Utility methods
-*/
-mejs.Utility = {
- encodeUrl: function(url) {
- return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
- },
- escapeHTML: function(s) {
- return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
- },
- absolutizeUrl: function(url) {
- var el = document.createElement('div');
- el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
- return el.firstChild.href;
- },
- getScriptPath: function(scriptNames) {
- var
- i = 0,
- j,
- path = '',
- name = '',
- script,
- scripts = document.getElementsByTagName('script'),
- il = scripts.length,
- jl = scriptNames.length;
-
- for (; i < il; i++) {
- 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));
- break;
- }
- }
- if (path !== '') {
- break;
- }
- }
- return path;
- },
- secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
- //add framecount
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var hours = Math.floor(time / 3600) % 24,
- minutes = Math.floor(time / 60) % 60,
- seconds = Math.floor(time % 60),
- frames = Math.floor(((time % 1)*fps).toFixed(3)),
- result =
- ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
- + (minutes < 10 ? '0' + minutes : minutes) + ':'
- + (seconds < 10 ? '0' + seconds : seconds)
- + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
-
- return result;
- },
-
- timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var tc_array = hh_mm_ss_ff.split(":"),
- tc_hh = parseInt(tc_array[0], 10),
- tc_mm = parseInt(tc_array[1], 10),
- tc_ss = parseInt(tc_array[2], 10),
- tc_ff = 0,
- tc_in_seconds = 0;
-
- if (showFrameCount) {
- tc_ff = parseInt(tc_array[3])/fps;
- }
-
- tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
-
- return tc_in_seconds;
- },
-
- /* 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 (mejs.MediaFeatures.isIE) {
- obj.style.display = "none";
- (function(){
- if (obj.readyState == 4) {
- mejs.Utility.removeObjectInIE(id);
- } else {
- setTimeout(arguments.callee, 10);
- }
- })();
- } else {
- obj.parentNode.removeChild(obj);
- }
- }
- },
- removeObjectInIE: function(id) {
- var obj = document.getElementById(id);
- if (obj) {
- for (var i in obj) {
- if (typeof obj[i] == "function") {
- obj[i] = null;
- }
- }
- obj.parentNode.removeChild(obj);
- }
- }
-};
+
+/*
+Utility methods
+*/
+mejs.Utility = {
+ encodeUrl: function(url) {
+ return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
+ },
+ escapeHTML: function(s) {
+ return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
+ },
+ absolutizeUrl: function(url) {
+ var el = document.createElement('div');
+ el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
+ return el.firstChild.href;
+ },
+ getScriptPath: function(scriptNames) {
+ var
+ i = 0,
+ j,
+ path = '',
+ name = '',
+ script,
+ scripts = document.getElementsByTagName('script'),
+ il = scripts.length,
+ jl = scriptNames.length;
+
+ for (; i < il; i++) {
+ 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));
+ break;
+ }
+ }
+ if (path !== '') {
+ break;
+ }
+ }
+ return path;
+ },
+ secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
+ //add framecount
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var hours = Math.floor(time / 3600) % 24,
+ minutes = Math.floor(time / 60) % 60,
+ seconds = Math.floor(time % 60),
+ frames = Math.floor(((time % 1)*fps).toFixed(3)),
+ result =
+ ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
+ + (minutes < 10 ? '0' + minutes : minutes) + ':'
+ + (seconds < 10 ? '0' + seconds : seconds)
+ + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
+
+ return result;
+ },
+
+ timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var tc_array = hh_mm_ss_ff.split(":"),
+ tc_hh = parseInt(tc_array[0], 10),
+ tc_mm = parseInt(tc_array[1], 10),
+ tc_ss = parseInt(tc_array[2], 10),
+ tc_ff = 0,
+ tc_in_seconds = 0;
+
+ if (showFrameCount) {
+ tc_ff = parseInt(tc_array[3])/fps;
+ }
+
+ tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
+
+ return tc_in_seconds;
+ },
+
+
+ convertSMPTEtoSeconds: function (SMPTE) {
+ if (typeof SMPTE != 'string')
+ return false;
+
+ SMPTE = SMPTE.replace(',', '.');
+
+ var secs = 0,
+ decimalLen = (SMPTE.indexOf('.') != -1) ? SMPTE.split('.')[1].length : 0,
+ multiplier = 1;
+
+ SMPTE = SMPTE.split(':').reverse();
+
+ for (var i = 0; i < SMPTE.length; i++) {
+ multiplier = 1;
+ if (i > 0) {
+ multiplier = Math.pow(60, i);
+ }
+ secs += Number(SMPTE[i]) * multiplier;
+ }
+ return Number(secs.toFixed(decimalLen));
+ },
+
+ /* 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 (mejs.MediaFeatures.isIE) {
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ mejs.Utility.removeObjectInIE(id);
+ } else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ } else {
+ obj.parentNode.removeChild(obj);
+ }
+ }
+ },
+ removeObjectInIE: function(id) {
+ var obj = document.getElementById(id);
+ if (obj) {
+ for (var i in obj) {
+ if (typeof obj[i] == "function") {
+ obj[i] = null;
+ }
+ }
+ obj.parentNode.removeChild(obj);
+ }
+ }
+};
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js b/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
index e1c34fd18..f92a0bd33 100644
--- a/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-contextmenu.js
@@ -1,193 +1,193 @@
-/*
-* ContextMenu Plugin
-*
-*
-*/
-
-(function($) {
-
-$.extend(mejs.MepDefaults,
- { 'contextMenuItems': [
- // demo of a fullscreen option
- {
- render: function(player) {
-
- // check for fullscreen plugin
- if (typeof player.enterFullScreen == 'undefined')
- return null;
-
- if (player.isFullScreen) {
- return "Turn off Fullscreen";
- } else {
- return "Go Fullscreen";
- }
- },
- click: function(player) {
- if (player.isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- }
- }
- ,
- // demo of a mute/unmute button
- {
- render: function(player) {
- if (player.media.muted) {
- return "Unmute";
- } else {
- return "Mute";
- }
- },
- click: function(player) {
- if (player.media.muted) {
- player.setMuted(false);
- } else {
- player.setMuted(true);
- }
- }
- },
- // separator
- {
- isSeparator: true
- }
- ,
- // demo of simple download video
- {
- render: function(player) {
- return "Download Video";
- },
- click: function(player) {
- window.location.href = player.media.currentSrc;
- }
- }
- ]}
-);
-
-
- $.extend(MediaElementPlayer.prototype, {
- buildcontextmenu: function(player, controls, layers, media) {
-
- // create context menu
- player.contextMenu = $('<div class="mejs-contextmenu"></div>')
- .appendTo($('body'))
- .hide();
-
- // create events for showing context menu
- player.container.bind('contextmenu', function(e) {
- if (player.isContextMenuEnabled) {
- e.preventDefault();
- player.renderContextMenu(e.clientX-1, e.clientY-1);
- return false;
- }
- });
- player.container.bind('click', function() {
- player.contextMenu.hide();
- });
- player.contextMenu.bind('mouseleave', function() {
-
- //console.log('context hover out');
- player.startContextMenuTimer();
-
- });
- },
-
- isContextMenuEnabled: true,
- enableContextMenu: function() {
- this.isContextMenuEnabled = true;
- },
- disableContextMenu: function() {
- this.isContextMenuEnabled = false;
- },
-
- contextMenuTimeout: null,
- startContextMenuTimer: function() {
- //console.log('startContextMenuTimer');
-
- var t = this;
-
- t.killContextMenuTimer();
-
- t.contextMenuTimer = setTimeout(function() {
- t.hideContextMenu();
- t.killContextMenuTimer();
- }, 750);
- },
- killContextMenuTimer: function() {
- var timer = this.contextMenuTimer;
-
- //console.log('killContextMenuTimer', timer);
-
- if (timer != null) {
- clearTimeout(timer);
- delete timer;
- timer = null;
- }
- },
-
- hideContextMenu: function() {
- this.contextMenu.hide();
- },
-
- renderContextMenu: function(x,y) {
-
- // alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
- var t = this,
- html = '',
- items = t.options.contextMenuItems;
-
- for (var i=0, il=items.length; i<il; i++) {
-
- if (items[i].isSeparator) {
- html += '<div class="mejs-contextmenu-separator"></div>';
- } else {
-
- var rendered = items[i].render(t);
-
- // render can return null if the item doesn't need to be used at the moment
- if (rendered != null) {
- html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
- }
- }
- }
-
- // position and show the context menu
- t.contextMenu
- .empty()
- .append($(html))
- .css({top:y, left:x})
- .show();
-
- // bind events
- t.contextMenu.find('.mejs-contextmenu-item').each(function() {
-
- // which one is this?
- var $dom = $(this),
- itemIndex = parseInt( $dom.data('itemindex'), 10 ),
- item = t.options.contextMenuItems[itemIndex];
-
- // bind extra functionality?
- if (typeof item.show != 'undefined')
- item.show( $dom , t);
-
- // bind click action
- $dom.click(function() {
- // perform click action
- if (typeof item.click != 'undefined')
- item.click(t);
-
- // close
- t.contextMenu.hide();
- });
- });
-
- // stop the controls from hiding
- setTimeout(function() {
- t.killControlsTimer('rev3');
- }, 100);
-
- }
- });
-
+/*
+* ContextMenu Plugin
+*
+*
+*/
+
+(function($) {
+
+$.extend(mejs.MepDefaults,
+ { 'contextMenuItems': [
+ // demo of a fullscreen option
+ {
+ render: function(player) {
+
+ // check for fullscreen plugin
+ if (typeof player.enterFullScreen == 'undefined')
+ return null;
+
+ if (player.isFullScreen) {
+ return "Turn off Fullscreen";
+ } else {
+ return "Go Fullscreen";
+ }
+ },
+ click: function(player) {
+ if (player.isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ }
+ }
+ ,
+ // demo of a mute/unmute button
+ {
+ render: function(player) {
+ if (player.media.muted) {
+ return "Unmute";
+ } else {
+ return "Mute";
+ }
+ },
+ click: function(player) {
+ if (player.media.muted) {
+ player.setMuted(false);
+ } else {
+ player.setMuted(true);
+ }
+ }
+ },
+ // separator
+ {
+ isSeparator: true
+ }
+ ,
+ // demo of simple download video
+ {
+ render: function(player) {
+ return "Download Video";
+ },
+ click: function(player) {
+ window.location.href = player.media.currentSrc;
+ }
+ }
+ ]}
+);
+
+
+ $.extend(MediaElementPlayer.prototype, {
+ buildcontextmenu: function(player, controls, layers, media) {
+
+ // create context menu
+ player.contextMenu = $('<div class="mejs-contextmenu"></div>')
+ .appendTo($('body'))
+ .hide();
+
+ // create events for showing context menu
+ player.container.bind('contextmenu', function(e) {
+ if (player.isContextMenuEnabled) {
+ e.preventDefault();
+ player.renderContextMenu(e.clientX-1, e.clientY-1);
+ return false;
+ }
+ });
+ player.container.bind('click', function() {
+ player.contextMenu.hide();
+ });
+ player.contextMenu.bind('mouseleave', function() {
+
+ //console.log('context hover out');
+ player.startContextMenuTimer();
+
+ });
+ },
+
+ isContextMenuEnabled: true,
+ enableContextMenu: function() {
+ this.isContextMenuEnabled = true;
+ },
+ disableContextMenu: function() {
+ this.isContextMenuEnabled = false;
+ },
+
+ contextMenuTimeout: null,
+ startContextMenuTimer: function() {
+ //console.log('startContextMenuTimer');
+
+ var t = this;
+
+ t.killContextMenuTimer();
+
+ t.contextMenuTimer = setTimeout(function() {
+ t.hideContextMenu();
+ t.killContextMenuTimer();
+ }, 750);
+ },
+ killContextMenuTimer: function() {
+ var timer = this.contextMenuTimer;
+
+ //console.log('killContextMenuTimer', timer);
+
+ if (timer != null) {
+ clearTimeout(timer);
+ delete timer;
+ timer = null;
+ }
+ },
+
+ hideContextMenu: function() {
+ this.contextMenu.hide();
+ },
+
+ renderContextMenu: function(x,y) {
+
+ // alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
+ var t = this,
+ html = '',
+ items = t.options.contextMenuItems;
+
+ for (var i=0, il=items.length; i<il; i++) {
+
+ if (items[i].isSeparator) {
+ html += '<div class="mejs-contextmenu-separator"></div>';
+ } else {
+
+ var rendered = items[i].render(t);
+
+ // render can return null if the item doesn't need to be used at the moment
+ if (rendered != null) {
+ html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
+ }
+ }
+ }
+
+ // position and show the context menu
+ t.contextMenu
+ .empty()
+ .append($(html))
+ .css({top:y, left:x})
+ .show();
+
+ // bind events
+ t.contextMenu.find('.mejs-contextmenu-item').each(function() {
+
+ // which one is this?
+ var $dom = $(this),
+ itemIndex = parseInt( $dom.data('itemindex'), 10 ),
+ item = t.options.contextMenuItems[itemIndex];
+
+ // bind extra functionality?
+ if (typeof item.show != 'undefined')
+ item.show( $dom , t);
+
+ // bind click action
+ $dom.click(function() {
+ // perform click action
+ if (typeof item.click != 'undefined')
+ item.click(t);
+
+ // close
+ t.contextMenu.hide();
+ });
+ });
+
+ // stop the controls from hiding
+ setTimeout(function() {
+ t.killControlsTimer('rev3');
+ }, 100);
+
+ }
+ });
+
})(mejs.$); \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js b/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
index bbc7f27cb..8544a324e 100644
--- a/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-fullscreen.js
@@ -1,437 +1,437 @@
-(function($) {
-
- $.extend(mejs.MepDefaults, {
- usePluginFullScreen: true,
- newWindowCallback: function() { return '';},
- fullscreenText: 'Fullscreen'
- });
-
- $.extend(MediaElementPlayer.prototype, {
-
- isFullScreen: false,
-
- isNativeFullScreen: false,
-
- docStyleOverflow: null,
-
- isInIframe: false,
-
- buildfullscreen: function(player, controls, layers, media) {
-
- if (!player.isVideo)
- return;
-
- player.isInIframe = (window.location != window.parent.location);
-
- // native events
- 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) {
-
- if (mejs.MediaFeatures.isFullScreen()) {
- player.isNativeFullScreen = true;
- // reset the controls once we are fully in full screen
- player.setControlsSize();
- } else {
- player.isNativeFullScreen = false;
- // when a user presses ESC
- // make sure to put the player back into place
- player.exitFullScreen();
- }
- });
- }
-
- var t = this,
- normalHeight = 0,
- normalWidth = 0,
- container = player.container,
- fullscreenBtn =
- $('<div class="mejs-button mejs-fullscreen-button">' +
- '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
- '</div>')
- .appendTo(controls);
-
- if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
-
- fullscreenBtn.click(function() {
- var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
-
- if (isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- });
-
- } else {
-
- var hideTimeout = null,
- supportsPointerEvents = (function() {
- // TAKEN FROM MODERNIZR
- var element = document.createElement('x'),
- documentElement = document.documentElement,
- getComputedStyle = window.getComputedStyle,
- supports;
- if(!('pointerEvents' in element.style)){
- return false;
- }
- element.style.pointerEvents = 'auto';
- element.style.pointerEvents = 'x';
- documentElement.appendChild(element);
- supports = getComputedStyle &&
- getComputedStyle(element, '').pointerEvents === 'auto';
- documentElement.removeChild(element);
- return !!supports;
- })();
-
- //console.log('supportsPointerEvents', supportsPointerEvents);
-
- if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
-
- // allows clicking through the fullscreen button and controls down directly to Flash
-
- /*
- When a user puts his mouse over the fullscreen button, the controls are disabled
- So we put a div over the video and another one on iether side of the fullscreen button
- that caputre mouse movement
- and restore the controls once the mouse moves outside of the fullscreen button
- */
-
- var fullscreenIsDisabled = false,
- restoreControls = function() {
- if (fullscreenIsDisabled) {
- // hide the hovers
- videoHoverDiv.hide();
- controlsLeftHoverDiv.hide();
- controlsRightHoverDiv.hide();
-
- // restore the control bar
- fullscreenBtn.css('pointer-events', '');
- t.controls.css('pointer-events', '');
-
- // store for later
- 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),
- positionHoverDivs = function() {
- var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
- videoHoverDiv.css(style);
- controlsLeftHoverDiv.css(style);
- controlsRightHoverDiv.css(style);
-
- // over video, but not controls
- videoHoverDiv
- .width( t.container.width() )
- .height( t.container.height() - t.controls.height() );
-
- // 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()});
-
- // 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});
- };
-
- $(document).resize(function() {
- positionHoverDivs();
- });
-
- // on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
- fullscreenBtn
- .mouseover(function() {
-
- if (!t.isFullScreen) {
-
- var buttonPos = fullscreenBtn.offset(),
- containerPos = player.container.offset();
-
- // move the button in Flash into place
- media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
-
- // allows click through
- fullscreenBtn.css('pointer-events', 'none');
- t.controls.css('pointer-events', 'none');
-
- // show the divs that will restore things
- videoHoverDiv.show();
- controlsRightHoverDiv.show();
- controlsLeftHoverDiv.show();
- positionHoverDivs();
-
- fullscreenIsDisabled = true;
- }
-
- });
-
- // restore controls anytime the user enters or leaves fullscreen
- media.addEventListener('fullscreenchange', function(e) {
- restoreControls();
- });
-
-
- // 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) {
-
- // if the mouse is anywhere but the fullsceen button, then restore it all
- if (fullscreenIsDisabled) {
-
- var fullscreenBtnPos = fullscreenBtn.offset();
-
-
- if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
- e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
- ) {
-
- fullscreenBtn.css('pointer-events', '');
- t.controls.css('pointer-events', '');
-
- fullscreenIsDisabled = false;
- }
- }
- });
- */
-
-
- } else {
-
- // the hover state will show the fullscreen button in Flash to hover up and click
-
- fullscreenBtn
- .mouseover(function() {
-
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
- delete hideTimeout;
- }
-
- var buttonPos = fullscreenBtn.offset(),
- containerPos = player.container.offset();
-
- media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
-
- })
- .mouseout(function() {
-
- if (hideTimeout !== null) {
- clearTimeout(hideTimeout);
- delete hideTimeout;
- }
-
- hideTimeout = setTimeout(function() {
- media.hideFullscreenButton();
- }, 1500);
-
-
- });
- }
- }
-
- player.fullscreenBtn = fullscreenBtn;
-
- $(document).bind('keydown',function (e) {
- if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
- player.exitFullScreen();
- }
- });
-
- },
- enterFullScreen: function() {
-
- var t = this;
-
- // firefox+flash can't adjust plugin sizes without resetting :(
- if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
- //t.media.setFullscreen(true);
- //player.isFullScreen = true;
- return;
- }
-
- // store overflow
- docStyleOverflow = document.documentElement.style.overflow;
- // set it to not show scroll bars so 100% will work
- document.documentElement.style.overflow = 'hidden';
-
- // store sizing
- normalHeight = t.container.height();
- normalWidth = t.container.width();
-
- // attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
- if (t.media.pluginType === 'native') {
- if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
-
- mejs.MediaFeatures.requestFullScreen(t.container[0]);
- //return;
-
- if (t.isInIframe) {
- // sometimes exiting from fullscreen doesn't work
- // notably in Chrome <iframe>. Fixed in version 17
- setTimeout(function checkFullscreen() {
-
- if (t.isNativeFullScreen) {
-
- // check if the video is suddenly not really fullscreen
- if ($(window).width() !== screen.width) {
- // manually exit
- t.exitFullScreen();
- } else {
- // test again
- setTimeout(checkFullscreen, 500);
- }
- }
-
-
- }, 500);
- }
-
- } else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
- t.media.webkitEnterFullscreen();
- return;
- }
- }
-
- // check for iframe launch
- if (t.isInIframe) {
- var url = t.options.newWindowCallback(this);
-
-
- if (url !== '') {
-
- // launch immediately
- if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
- t.pause();
- window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
- return;
- } else {
- setTimeout(function() {
- if (!t.isNativeFullScreen) {
- t.pause();
- window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
- }
- }, 250);
- }
- }
-
- }
-
- // full window code
-
-
-
- // make full size
- t.container
- .addClass('mejs-container-fullscreen')
- .width('100%')
- .height('100%');
- //.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
-
- // 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.container.css({width: '100%', height: '100%'});
- t.setControlsSize();
- }, 500);
- //}
-
- if (t.pluginType === 'native') {
- t.$media
- .width('100%')
- .height('100%');
- } else {
- t.container.find('object, embed, iframe')
- .width('100%')
- .height('100%');
-
- //if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
- t.media.setVideoSize($(window).width(),$(window).height());
- //}
- }
-
- t.layers.children('div')
- .width('100%')
- .height('100%');
-
- if (t.fullscreenBtn) {
- t.fullscreenBtn
- .removeClass('mejs-fullscreen')
- .addClass('mejs-unfullscreen');
- }
-
- t.setControlsSize();
- t.isFullScreen = true;
- },
-
- exitFullScreen: function() {
-
- var t = this;
-
- // firefox can't adjust plugins
- if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
- t.media.setFullscreen(false);
- //player.isFullScreen = false;
- return;
- }
-
- // come outo of native fullscreen
- if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
- mejs.MediaFeatures.cancelFullScreen();
- }
-
- // restore scroll bars to document
- document.documentElement.style.overflow = docStyleOverflow;
-
- t.container
- .removeClass('mejs-container-fullscreen')
- .width(normalWidth)
- .height(normalHeight);
- //.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
-
- if (t.pluginType === 'native') {
- t.$media
- .width(normalWidth)
- .height(normalHeight);
- } else {
- t.container.find('object embed')
- .width(normalWidth)
- .height(normalHeight);
-
- t.media.setVideoSize(normalWidth, normalHeight);
- }
-
- t.layers.children('div')
- .width(normalWidth)
- .height(normalHeight);
-
- t.fullscreenBtn
- .removeClass('mejs-unfullscreen')
- .addClass('mejs-fullscreen');
-
- t.setControlsSize();
- t.isFullScreen = false;
- }
- });
-
-})(mejs.$);
+(function($) {
+
+ $.extend(mejs.MepDefaults, {
+ usePluginFullScreen: true,
+ newWindowCallback: function() { return '';},
+ fullscreenText: 'Fullscreen'
+ });
+
+ $.extend(MediaElementPlayer.prototype, {
+
+ isFullScreen: false,
+
+ isNativeFullScreen: false,
+
+ docStyleOverflow: null,
+
+ isInIframe: false,
+
+ buildfullscreen: function(player, controls, layers, media) {
+
+ if (!player.isVideo)
+ return;
+
+ player.isInIframe = (window.location != window.parent.location);
+
+ // native events
+ 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) {
+
+ if (mejs.MediaFeatures.isFullScreen()) {
+ player.isNativeFullScreen = true;
+ // reset the controls once we are fully in full screen
+ player.setControlsSize();
+ } else {
+ player.isNativeFullScreen = false;
+ // when a user presses ESC
+ // make sure to put the player back into place
+ player.exitFullScreen();
+ }
+ });
+ }
+
+ var t = this,
+ normalHeight = 0,
+ normalWidth = 0,
+ container = player.container,
+ fullscreenBtn =
+ $('<div class="mejs-button mejs-fullscreen-button">' +
+ '<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
+ '</div>')
+ .appendTo(controls);
+
+ if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
+
+ fullscreenBtn.click(function() {
+ var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
+
+ if (isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ });
+
+ } else {
+
+ var hideTimeout = null,
+ supportsPointerEvents = (function() {
+ // TAKEN FROM MODERNIZR
+ var element = document.createElement('x'),
+ documentElement = document.documentElement,
+ getComputedStyle = window.getComputedStyle,
+ supports;
+ if(!('pointerEvents' in element.style)){
+ return false;
+ }
+ element.style.pointerEvents = 'auto';
+ element.style.pointerEvents = 'x';
+ documentElement.appendChild(element);
+ supports = getComputedStyle &&
+ getComputedStyle(element, '').pointerEvents === 'auto';
+ documentElement.removeChild(element);
+ return !!supports;
+ })();
+
+ //console.log('supportsPointerEvents', supportsPointerEvents);
+
+ if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
+
+ // allows clicking through the fullscreen button and controls down directly to Flash
+
+ /*
+ When a user puts his mouse over the fullscreen button, the controls are disabled
+ So we put a div over the video and another one on iether side of the fullscreen button
+ that caputre mouse movement
+ and restore the controls once the mouse moves outside of the fullscreen button
+ */
+
+ var fullscreenIsDisabled = false,
+ restoreControls = function() {
+ if (fullscreenIsDisabled) {
+ // hide the hovers
+ videoHoverDiv.hide();
+ controlsLeftHoverDiv.hide();
+ controlsRightHoverDiv.hide();
+
+ // restore the control bar
+ fullscreenBtn.css('pointer-events', '');
+ t.controls.css('pointer-events', '');
+
+ // store for later
+ 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),
+ positionHoverDivs = function() {
+ var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
+ videoHoverDiv.css(style);
+ controlsLeftHoverDiv.css(style);
+ controlsRightHoverDiv.css(style);
+
+ // over video, but not controls
+ videoHoverDiv
+ .width( t.container.width() )
+ .height( t.container.height() - t.controls.height() );
+
+ // 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()});
+
+ // 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});
+ };
+
+ $(document).resize(function() {
+ positionHoverDivs();
+ });
+
+ // on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
+ fullscreenBtn
+ .mouseover(function() {
+
+ if (!t.isFullScreen) {
+
+ var buttonPos = fullscreenBtn.offset(),
+ containerPos = player.container.offset();
+
+ // move the button in Flash into place
+ media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
+
+ // allows click through
+ fullscreenBtn.css('pointer-events', 'none');
+ t.controls.css('pointer-events', 'none');
+
+ // show the divs that will restore things
+ videoHoverDiv.show();
+ controlsRightHoverDiv.show();
+ controlsLeftHoverDiv.show();
+ positionHoverDivs();
+
+ fullscreenIsDisabled = true;
+ }
+
+ });
+
+ // restore controls anytime the user enters or leaves fullscreen
+ media.addEventListener('fullscreenchange', function(e) {
+ restoreControls();
+ });
+
+
+ // 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) {
+
+ // if the mouse is anywhere but the fullsceen button, then restore it all
+ if (fullscreenIsDisabled) {
+
+ var fullscreenBtnPos = fullscreenBtn.offset();
+
+
+ if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
+ e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
+ ) {
+
+ fullscreenBtn.css('pointer-events', '');
+ t.controls.css('pointer-events', '');
+
+ fullscreenIsDisabled = false;
+ }
+ }
+ });
+ */
+
+
+ } else {
+
+ // the hover state will show the fullscreen button in Flash to hover up and click
+
+ fullscreenBtn
+ .mouseover(function() {
+
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
+ delete hideTimeout;
+ }
+
+ var buttonPos = fullscreenBtn.offset(),
+ containerPos = player.container.offset();
+
+ media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
+
+ })
+ .mouseout(function() {
+
+ if (hideTimeout !== null) {
+ clearTimeout(hideTimeout);
+ delete hideTimeout;
+ }
+
+ hideTimeout = setTimeout(function() {
+ media.hideFullscreenButton();
+ }, 1500);
+
+
+ });
+ }
+ }
+
+ player.fullscreenBtn = fullscreenBtn;
+
+ $(document).bind('keydown',function (e) {
+ if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
+ player.exitFullScreen();
+ }
+ });
+
+ },
+ enterFullScreen: function() {
+
+ var t = this;
+
+ // firefox+flash can't adjust plugin sizes without resetting :(
+ if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
+ //t.media.setFullscreen(true);
+ //player.isFullScreen = true;
+ return;
+ }
+
+ // store overflow
+ docStyleOverflow = document.documentElement.style.overflow;
+ // set it to not show scroll bars so 100% will work
+ document.documentElement.style.overflow = 'hidden';
+
+ // store sizing
+ normalHeight = t.container.height();
+ normalWidth = t.container.width();
+
+ // attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
+ if (t.media.pluginType === 'native') {
+ if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
+
+ mejs.MediaFeatures.requestFullScreen(t.container[0]);
+ //return;
+
+ if (t.isInIframe) {
+ // sometimes exiting from fullscreen doesn't work
+ // notably in Chrome <iframe>. Fixed in version 17
+ setTimeout(function checkFullscreen() {
+
+ if (t.isNativeFullScreen) {
+
+ // check if the video is suddenly not really fullscreen
+ if ($(window).width() !== screen.width) {
+ // manually exit
+ t.exitFullScreen();
+ } else {
+ // test again
+ setTimeout(checkFullscreen, 500);
+ }
+ }
+
+
+ }, 500);
+ }
+
+ } else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
+ t.media.webkitEnterFullscreen();
+ return;
+ }
+ }
+
+ // check for iframe launch
+ if (t.isInIframe) {
+ var url = t.options.newWindowCallback(this);
+
+
+ if (url !== '') {
+
+ // launch immediately
+ if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
+ t.pause();
+ window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
+ return;
+ } else {
+ setTimeout(function() {
+ if (!t.isNativeFullScreen) {
+ t.pause();
+ window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
+ }
+ }, 250);
+ }
+ }
+
+ }
+
+ // full window code
+
+
+
+ // make full size
+ t.container
+ .addClass('mejs-container-fullscreen')
+ .width('100%')
+ .height('100%');
+ //.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
+
+ // 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.container.css({width: '100%', height: '100%'});
+ t.setControlsSize();
+ }, 500);
+ //}
+
+ if (t.pluginType === 'native') {
+ t.$media
+ .width('100%')
+ .height('100%');
+ } else {
+ t.container.find('object, embed, iframe')
+ .width('100%')
+ .height('100%');
+
+ //if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
+ t.media.setVideoSize($(window).width(),$(window).height());
+ //}
+ }
+
+ t.layers.children('div')
+ .width('100%')
+ .height('100%');
+
+ if (t.fullscreenBtn) {
+ t.fullscreenBtn
+ .removeClass('mejs-fullscreen')
+ .addClass('mejs-unfullscreen');
+ }
+
+ t.setControlsSize();
+ t.isFullScreen = true;
+ },
+
+ exitFullScreen: function() {
+
+ var t = this;
+
+ // firefox can't adjust plugins
+ if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
+ t.media.setFullscreen(false);
+ //player.isFullScreen = false;
+ return;
+ }
+
+ // come outo of native fullscreen
+ if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
+ mejs.MediaFeatures.cancelFullScreen();
+ }
+
+ // restore scroll bars to document
+ document.documentElement.style.overflow = docStyleOverflow;
+
+ t.container
+ .removeClass('mejs-container-fullscreen')
+ .width(normalWidth)
+ .height(normalHeight);
+ //.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
+
+ if (t.pluginType === 'native') {
+ t.$media
+ .width(normalWidth)
+ .height(normalHeight);
+ } else {
+ t.container.find('object embed')
+ .width(normalWidth)
+ .height(normalHeight);
+
+ t.media.setVideoSize(normalWidth, normalHeight);
+ }
+
+ t.layers.children('div')
+ .width(normalWidth)
+ .height(normalHeight);
+
+ t.fullscreenBtn
+ .removeClass('mejs-unfullscreen')
+ .addClass('mejs-fullscreen');
+
+ t.setControlsSize();
+ t.isFullScreen = false;
+ }
+ });
+
+})(mejs.$);
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-time.js b/files_videoviewer/mediaelement/src/js/mep-feature-time.js
index c928b77d2..7fa107c6b 100644
--- a/files_videoviewer/mediaelement/src/js/mep-feature-time.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-time.js
@@ -1,81 +1,81 @@
-(function($) {
-
- // options
- $.extend(mejs.MepDefaults, {
- duration: -1,
- timeAndDurationSeparator: ' <span> | </span> '
- });
-
-
- // current and duration 00:00 / 00:00
- $.extend(MediaElementPlayer.prototype, {
- buildcurrent: function(player, controls, layers, media) {
- var t = this;
-
- $('<div class="mejs-time">'+
- '<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
- + (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
- '</div>')
- .appendTo(controls);
-
- t.currenttime = t.controls.find('.mejs-currenttime');
-
- media.addEventListener('timeupdate',function() {
- player.updateCurrent();
- }, false);
- },
-
-
- buildduration: function(player, controls, layers, media) {
- var t = this;
-
- if (controls.children().last().find('.mejs-currenttime').length > 0) {
- $(t.options.timeAndDurationSeparator +
- '<span class="mejs-duration">' +
- (t.options.duration > 0 ?
- mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
- ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
- ) +
- '</span>')
- .appendTo(controls.find('.mejs-time'));
- } else {
-
- // add class to current time
- controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
-
- $('<div class="mejs-time mejs-duration-container">'+
- '<span class="mejs-duration">' +
- (t.options.duration > 0 ?
- mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
- ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
- ) +
- '</span>' +
- '</div>')
- .appendTo(controls);
- }
-
- t.durationD = t.controls.find('.mejs-duration');
-
- media.addEventListener('timeupdate',function() {
- player.updateDuration();
- }, false);
- },
-
- updateCurrent: function() {
- var t = this;
-
- if (t.currenttime) {
- t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
- }
- },
-
- updateDuration: function() {
- var t = this;
-
- 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));
- }
- }
- });
-
+(function($) {
+
+ // options
+ $.extend(mejs.MepDefaults, {
+ duration: -1,
+ timeAndDurationSeparator: ' <span> | </span> '
+ });
+
+
+ // current and duration 00:00 / 00:00
+ $.extend(MediaElementPlayer.prototype, {
+ buildcurrent: function(player, controls, layers, media) {
+ var t = this;
+
+ $('<div class="mejs-time">'+
+ '<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
+ + (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
+ '</div>')
+ .appendTo(controls);
+
+ t.currenttime = t.controls.find('.mejs-currenttime');
+
+ media.addEventListener('timeupdate',function() {
+ player.updateCurrent();
+ }, false);
+ },
+
+
+ buildduration: function(player, controls, layers, media) {
+ var t = this;
+
+ if (controls.children().last().find('.mejs-currenttime').length > 0) {
+ $(t.options.timeAndDurationSeparator +
+ '<span class="mejs-duration">' +
+ (t.options.duration > 0 ?
+ mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
+ ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
+ ) +
+ '</span>')
+ .appendTo(controls.find('.mejs-time'));
+ } else {
+
+ // add class to current time
+ controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
+
+ $('<div class="mejs-time mejs-duration-container">'+
+ '<span class="mejs-duration">' +
+ (t.options.duration > 0 ?
+ mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
+ ((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
+ ) +
+ '</span>' +
+ '</div>')
+ .appendTo(controls);
+ }
+
+ t.durationD = t.controls.find('.mejs-duration');
+
+ media.addEventListener('timeupdate',function() {
+ player.updateDuration();
+ }, false);
+ },
+
+ updateCurrent: function() {
+ var t = this;
+
+ if (t.currenttime) {
+ t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
+ }
+ },
+
+ updateDuration: function() {
+ var t = this;
+
+ 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));
+ }
+ }
+ });
+
})(mejs.$); \ No newline at end of file
diff --git a/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js b/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
index cbb058b1c..a02fdc661 100644
--- a/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
+++ b/files_videoviewer/mediaelement/src/js/mep-feature-tracks.js
@@ -164,35 +164,29 @@
};
- if (track.isTranslation) {
- // translate the first track
- mejs.TrackFormatParser.translateTrackText(t.tracks[0].entries, t.tracks[0].srclang, track.srclang, t.options.googleApiKey, function(newOne) {
-
- // store the new translation
- track.entries = newOne;
+ $.ajax({
+ url: track.src,
+ dataType: "text",
+ success: function(d) {
+ // parse the loaded file
+ if (typeof d == "string" && (/<tt\s+xml/ig).exec(d)) {
+ track.entries = mejs.TrackFormatParser.dfxp.parse(d);
+ } else {
+ track.entries = mejs.TrackFormatParser.webvvt.parse(d);
+ }
+
after();
- });
-
- } else {
- $.ajax({
- url: track.src,
- success: function(d) {
- // parse the loaded file
- track.entries = mejs.TrackFormatParser.parse(d);
- after();
-
- if (track.kind == 'chapters' && t.media.duration > 0) {
- t.drawChapters(track);
- }
- },
- error: function() {
- t.loadNextTrack();
+ if (track.kind == 'chapters' && t.media.duration > 0) {
+ t.drawChapters(track);
}
- });
- }
+ },
+ error: function() {
+ t.loadNextTrack();
+ }
+ });
},
enableTrackButton: function(lang, label) {
@@ -410,53 +404,106 @@
Adapted from: http://www.delphiki.com/html5/playr
*/
mejs.TrackFormatParser = {
- // match start "chapter-" (or anythingelse)
- 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})?)(.*)$/,
-
- split2: function (text, regex) {
- // normal version for compliant browsers
- // see below for IE fix
- return text.split(regex);
- },
- parse: function(trackText) {
- var
- i = 0,
- lines = this.split2(trackText, /\r?\n/),
- entries = {text:[], times:[]},
- timecode,
- text;
-
- for(; i<lines.length; i++) {
- // check for the line number
- if (this.pattern_identifier.exec(lines[i])){
- // skip to the next line where the start --> end time code should be
- i++;
- timecode = this.pattern_timecode.exec(lines[i]);
-
- if (timecode && i<lines.length){
- i++;
- // grab all the (possibly multi-line) text that follows
- text = lines[i];
+ webvvt: {
+ // match start "chapter-" (or anythingelse)
+ 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(trackText) {
+ var
+ i = 0,
+ lines = mejs.TrackFormatParser.split2(trackText, /\r?\n/),
+ entries = {text:[], times:[]},
+ timecode,
+ text;
+ for(; i<lines.length; i++) {
+ // check for the line number
+ if (this.pattern_identifier.exec(lines[i])){
+ // skip to the next line where the start --> end time code should be
i++;
- while(lines[i] !== '' && i<lines.length){
- text = text + '\n' + lines[i];
+ timecode = this.pattern_timecode.exec(lines[i]);
+
+ if (timecode && i<lines.length){
i++;
+ // grab all the (possibly multi-line) text that follows
+ text = lines[i];
+ i++;
+ while(lines[i] !== '' && i<lines.length){
+ text = text + '\n' + lines[i];
+ i++;
+ }
+ text = $.trim(text).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
+ // Text is in a different array so I can use .join
+ entries.text.push(text);
+ entries.times.push(
+ {
+ start: (mejs.Utility.convertSMPTEtoSeconds(timecode[1]) == 0) ? 0.200 : mejs.Utility.convertSMPTEtoSeconds(timecode[1]),
+ stop: mejs.Utility.convertSMPTEtoSeconds(timecode[3]),
+ settings: timecode[5]
+ });
}
-
- // Text is in a different array so I can use .join
- entries.text.push(text);
- entries.times.push(
- {
- start: mejs.Utility.timeCodeToSeconds(timecode[1]),
- stop: mejs.Utility.timeCodeToSeconds(timecode[3]),
- settings: timecode[5]
- });
}
}
+ return entries;
}
+ },
+ // Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
+ dfxp: {
+ parse: function(trackText) {
+ trackText = $(trackText).filter("tt");
+ var
+ i = 0,
+ container = trackText.children("div").eq(0),
+ lines = container.find("p"),
+ styleNode = trackText.find("#" + container.attr("style")),
+ styles,
+ begin,
+ end,
+ text,
+ entries = {text:[], times:[]};
+
+
+ if (styleNode.length) {
+ var attributes = styleNode.removeAttr("id").get(0).attributes;
+ if (attributes.length) {
+ styles = {};
+ for (i = 0; i < attributes.length; i++) {
+ styles[attributes[i].name.split(":")[1]] = attributes[i].value;
+ }
+ }
+ }
- return entries;
+ for(i = 0; i<lines.length; i++) {
+ var style;
+ var _temp_times = {
+ start: null,
+ stop: null,
+ style: null
+ };
+ if (lines.eq(i).attr("begin")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("begin"));
+ if (!_temp_times.start && lines.eq(i-1).attr("end")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i-1).attr("end"));
+ if (lines.eq(i).attr("end")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("end"));
+ if (!_temp_times.stop && lines.eq(i+1).attr("begin")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i+1).attr("begin"));
+ if (styles) {
+ style = "";
+ for (var _style in styles) {
+ style += _style + ":" + styles[_style] + ";";
+ }
+ }
+ if (style) _temp_times.style = style;
+ if (_temp_times.start == 0) _temp_times.start = 0.200;
+ entries.times.push(_temp_times);
+ text = $.trim(lines.eq(i).html()).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
+ entries.text.push(text);
+ if (entries.times.start == 0) entries.times.start = 2;
+ }
+ return entries;
+ }
+ },
+ split2: function (text, regex) {
+ // normal version for compliant browsers
+ // see below for IE fix
+ return text.split(regex);
}
};
diff --git a/files_videoviewer/mediaelement/src/js/mep-player.js b/files_videoviewer/mediaelement/src/js/mep-player.js
index cd289e90f..263711a8b 100644
--- a/files_videoviewer/mediaelement/src/js/mep-player.js
+++ b/files_videoviewer/mediaelement/src/js/mep-player.js
@@ -1,1076 +1,1076 @@
-(function ($) {
-
- // default player values
- mejs.MepDefaults = {
- // url to poster (to fix iOS 3.x)
- poster: '',
- // default if the <video width> is not specified
- defaultVideoWidth: 480,
- // default if the <video height> is not specified
- defaultVideoHeight: 270,
- // if set, overrides <video width>
- videoWidth: -1,
- // if set, overrides <video height>
- videoHeight: -1,
- // default if the user doesn't specify
- defaultAudioWidth: 400,
- // default if the user doesn't specify
- defaultAudioHeight: 30,
-
- // default amount to move back when back key is pressed
- defaultSeekBackwardInterval: function(media) {
- return (media.duration * 0.05);
- },
- // default amount to move forward when forward key is pressed
- defaultSeekForwardInterval: function(media) {
- return (media.duration * 0.05);
- },
-
- // width of audio player
- audioWidth: -1,
- // height of audio player
- audioHeight: -1,
- // initial volume when the player starts (overrided by user cookie)
- startVolume: 0.8,
- // useful for <audio> player loops
- loop: false,
- // resize to media dimensions
- enableAutosize: true,
- // forces the hour marker (##:00:00)
- alwaysShowHours: false,
-
- // show framecount in timecode (##:00:00:00)
- showTimecodeFrameCount: false,
- // used when showTimecodeFrameCount is set to true
- framesPerSecond: 25,
-
- // automatically calculate the width of the progress bar based on the sizes of other elements
- autosizeProgress : true,
- // Hide controls when playing and mouse is not over the video
- alwaysShowControls: false,
- // force iPad's native controls
- iPadUseNativeControls: false,
- // force iPhone's native controls
- iPhoneUseNativeControls: false,
- // force Android's native controls
- AndroidUseNativeControls: false,
- // features to show
- features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
- // only for dynamic
- isVideo: true,
-
- // turns keyboard support on and off for this instance
- enableKeyboard: true,
-
- // whenthis player starts, it will pause other players
- pauseOtherPlayers: true,
-
- // array of keyboard actions such as play pause
- keyActions: [
- {
- keys: [
- 32, // SPACE
- 179 // GOOGLE play/pause button
- ],
- action: function(player, media) {
- if (media.paused || media.ended) {
- media.play();
- } else {
- media.pause();
- }
- }
- },
- {
- keys: [38], // UP
- action: function(player, media) {
- var newVolume = Math.min(media.volume + 0.1, 1);
- media.setVolume(newVolume);
- }
- },
- {
- keys: [40], // DOWN
- action: function(player, media) {
- var newVolume = Math.max(media.volume - 0.1, 0);
- media.setVolume(newVolume);
- }
- },
- {
- keys: [
- 37, // LEFT
- 227 // Google TV rewind
- ],
- action: function(player, media) {
- if (!isNaN(media.duration) && media.duration > 0) {
- if (player.isVideo) {
- player.showControls();
- player.startControlsTimer();
- }
-
- // 5%
- var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
- media.setCurrentTime(newTime);
- }
- }
- },
- {
- keys: [
- 39, // RIGHT
- 228 // Google TV forward
- ],
- action: function(player, media) {
- if (!isNaN(media.duration) && media.duration > 0) {
- if (player.isVideo) {
- player.showControls();
- player.startControlsTimer();
- }
-
- // 5%
- var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
- media.setCurrentTime(newTime);
- }
- }
- },
- {
- keys: [70], // f
- action: function(player, media) {
- if (typeof player.enterFullScreen != 'undefined') {
- if (player.isFullScreen) {
- player.exitFullScreen();
- } else {
- player.enterFullScreen();
- }
- }
- }
- }
- ]
- };
-
- mejs.mepIndex = 0;
-
- mejs.players = [];
-
- // wraps a MediaElement object in player controls
- mejs.MediaElementPlayer = function(node, o) {
- // enforce object, even without "new" (via John Resig)
- if ( !(this instanceof mejs.MediaElementPlayer) ) {
- return new mejs.MediaElementPlayer(node, o);
- }
-
- var t = this;
-
- // these will be reset after the MediaElement.success fires
- t.$media = t.$node = $(node);
- t.node = t.media = t.$media[0];
-
- // check for existing player
- if (typeof t.node.player != 'undefined') {
- return t.node.player;
- } else {
- // attach player to DOM node for reference
- t.node.player = t;
- }
-
-
- // try to get options from data-mejsoptions
- if (typeof o == 'undefined') {
- o = t.$node.data('mejsoptions');
- }
-
- // extend default options
- t.options = $.extend({},mejs.MepDefaults,o);
-
- // add to player array (for focus events)
- mejs.players.push(t);
-
- // start up
- t.init();
-
- return t;
- };
-
- // actual player
- mejs.MediaElementPlayer.prototype = {
-
- hasFocus: false,
-
- controlsAreVisible: true,
-
- init: function() {
-
- var
- t = this,
- mf = mejs.MediaFeatures,
- // options for MediaElement (shim)
- meOptions = $.extend(true, {}, t.options, {
- success: function(media, domNode) { t.meReady(media, domNode); },
- error: function(e) { t.handleError(e);}
- }),
- tagName = t.media.tagName.toLowerCase();
-
- t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
-
- if (t.isDynamic) {
- // get video from src or href?
- t.isVideo = t.options.isVideo;
- } else {
- t.isVideo = (tagName !== 'audio' && t.options.isVideo);
- }
-
- // use native controls in iPad, iPhone, and Android
- if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
-
- // add controls and stop
- t.$media.attr('controls', 'controls');
-
- // attempt to fix iOS 3 bug
- //t.$media.removeAttr('poster');
- // no Issue found on iOS3 -ttroxell
-
- // override Apple's autoplay override for iPads
- if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
- t.media.load();
- t.media.play();
- }
-
- } else if (mf.isAndroid && t.AndroidUseNativeControls) {
-
- // leave default player
-
- } else {
-
- // DESKTOP: use MediaElementPlayer controls
-
- // 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">'+
- '<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(t.$media[0].className)
- .insertBefore(t.$media);
-
- // add classes for user and content
- t.container.addClass(
- (mf.isAndroid ? 'mejs-android ' : '') +
- (mf.isiOS ? 'mejs-ios ' : '') +
- (mf.isiPad ? 'mejs-ipad ' : '') +
- (mf.isiPhone ? 'mejs-iphone ' : '') +
- (t.isVideo ? 'mejs-video ' : 'mejs-audio ')
- );
-
-
- // move the <video/video> tag into the right spot
- if (mf.isiOS) {
-
- // sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
- var $newMedia = t.$media.clone();
-
- t.container.find('.mejs-mediaelement').append($newMedia);
-
- t.$media.remove();
- t.$node = t.$media = $newMedia;
- t.node = t.media = $newMedia[0]
-
- } else {
-
- // normal way of moving it into place (doesn't work on iOS)
- t.container.find('.mejs-mediaelement').append(t.$media);
- }
-
- // find parts
- t.controls = t.container.find('.mejs-controls');
- t.layers = t.container.find('.mejs-layers');
-
- // determine the size
-
- /* size priority:
- (1) videoWidth (forced),
- (2) style="width;height;"
- (3) width attribute,
- (4) defaultVideoWidth (for unspecified cases)
- */
-
- var tagType = (t.isVideo ? 'video' : 'audio'),
- capsTagName = tagType.substring(0,1).toUpperCase() + tagType.substring(1);
-
-
- if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
- t.width = t.options[tagType + 'Width'];
- } else if (t.media.style.width !== '' && t.media.style.width !== null) {
- t.width = t.media.style.width;
- } else if (t.media.getAttribute('width') !== null) {
- t.width = t.$media.attr('width');
- } else {
- t.width = t.options['default' + capsTagName + 'Width'];
- }
-
- if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
- t.height = t.options[tagType + 'Height'];
- } else if (t.media.style.height !== '' && t.media.style.height !== null) {
- t.height = t.media.style.height;
- } else if (t.$media[0].getAttribute('height') !== null) {
- t.height = t.$media.attr('height');
- } else {
- t.height = t.options['default' + capsTagName + 'Height'];
- }
-
- // set the size, while we wait for the plugins to load below
- t.setPlayerSize(t.width, t.height);
-
- // create MediaElementShim
- meOptions.pluginWidth = t.height;
- meOptions.pluginHeight = t.width;
- }
-
-
-
- // create MediaElement shim
- mejs.MediaElement(t.$media[0], meOptions);
- },
-
- showControls: function(doAnimation) {
- var t = this;
-
- doAnimation = typeof doAnimation == 'undefined' || doAnimation;
-
- if (t.controlsAreVisible)
- return;
-
- if (doAnimation) {
- t.controls
- .css('visibility','visible')
- .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control')
- .css('visibility','visible')
- .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
-
- } else {
- t.controls
- .css('visibility','visible')
- .css('display','block');
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control')
- .css('visibility','visible')
- .css('display','block');
-
- t.controlsAreVisible = true;
- }
-
- t.setControlsSize();
-
- },
-
- hideControls: function(doAnimation) {
- var t = this;
-
- doAnimation = typeof doAnimation == 'undefined' || doAnimation;
-
- if (!t.controlsAreVisible)
- return;
-
- if (doAnimation) {
- // fade out main controls
- t.controls.stop(true, true).fadeOut(200, function() {
- $(this)
- .css('visibility','hidden')
- .css('display','block');
-
- t.controlsAreVisible = false;
- });
-
- // any additional controls people might add and want to hide
- t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
- $(this)
- .css('visibility','hidden')
- .css('display','block');
- });
- } else {
-
- // hide main controls
- t.controls
- .css('visibility','hidden')
- .css('display','block');
-
- // hide others
- t.container.find('.mejs-control')
- .css('visibility','hidden')
- .css('display','block');
-
- t.controlsAreVisible = false;
- }
- },
-
- controlsTimer: null,
-
- startControlsTimer: function(timeout) {
-
- var t = this;
-
- timeout = typeof timeout != 'undefined' ? timeout : 1500;
-
- t.killControlsTimer('start');
-
- t.controlsTimer = setTimeout(function() {
- //console.log('timer fired');
- t.hideControls();
- t.killControlsTimer('hide');
- }, timeout);
- },
-
- killControlsTimer: function(src) {
-
- var t = this;
-
- if (t.controlsTimer !== null) {
- clearTimeout(t.controlsTimer);
- delete t.controlsTimer;
- t.controlsTimer = null;
- }
- },
-
- controlsEnabled: true,
-
- disableControls: function() {
- var t= this;
-
- t.killControlsTimer();
- t.hideControls(false);
- this.controlsEnabled = false;
- },
-
- enableControls: function() {
- var t= this;
-
- t.showControls(false);
-
- t.controlsEnabled = true;
- },
-
-
- // Sets up all controls and events
- meReady: function(media, domNode) {
-
-
- var t = this,
- mf = mejs.MediaFeatures,
- autoplayAttr = domNode.getAttribute('autoplay'),
- autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
- featureIndex,
- feature;
-
- // make sure it can't create itself again if a plugin reloads
- if (t.created)
- return;
- else
- t.created = true;
-
- t.media = media;
- t.domNode = domNode;
-
- if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
-
- // two built in features
- t.buildposter(t, t.controls, t.layers, t.media);
- t.buildkeyboard(t, t.controls, t.layers, t.media);
- t.buildoverlays(t, t.controls, t.layers, t.media);
-
- // grab for use by features
- t.findTracks();
-
- // add user-defined features/controls
- for (featureIndex in t.options.features) {
- feature = t.options.features[featureIndex];
- if (t['build' + feature]) {
- try {
- t['build' + feature](t, t.controls, t.layers, t.media);
- } catch (e) {
- // TODO: report control error
- //throw e;
- //console.log('error building ' + feature);
- //console.log(e);
- }
- }
- }
-
- t.container.trigger('controlsready');
-
- // reset all layers and controls
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
-
-
- // controls fade
- if (t.isVideo) {
-
- if (mejs.MediaFeatures.hasTouch) {
-
- // for touch devices (iOS, Android)
- // show/hide without animation on touch
-
- t.$media.bind('touchstart', function() {
-
-
- // toggle controls
- if (t.controlsAreVisible) {
- t.hideControls(false);
- } else {
- if (t.controlsEnabled) {
- t.showControls(false);
- }
- }
- });
-
- } else {
- // click controls
- var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
-
- // click to play/pause
- clickElement.click(function() {
- if (media.paused) {
- media.play();
- } else {
- media.pause();
- }
- });
-
-
- // show/hide controls
- t.container
- .bind('mouseenter mouseover', function () {
- if (t.controlsEnabled) {
- if (!t.options.alwaysShowControls) {
- t.killControlsTimer('enter');
- t.showControls();
- t.startControlsTimer(2500);
- }
- }
- })
- .bind('mousemove', function() {
- if (t.controlsEnabled) {
- if (!t.controlsAreVisible) {
- t.showControls();
- }
- //t.killControlsTimer('move');
- if (!t.options.alwaysShowControls) {
- t.startControlsTimer(2500);
- }
- }
- })
- .bind('mouseleave', function () {
- if (t.controlsEnabled) {
- if (!t.media.paused && !t.options.alwaysShowControls) {
- t.startControlsTimer(1000);
- }
- }
- });
- }
-
- // check for autoplay
- if (autoplay && !t.options.alwaysShowControls) {
- t.hideControls();
- }
-
- // resizer
- if (t.options.enableAutosize) {
- t.media.addEventListener('loadedmetadata', function(e) {
- // if the <video height> was not set and the options.videoHeight was not set
- // then resize to the real dimensions
- if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
- t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
- t.setControlsSize();
- t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
- }
- }, false);
- }
- }
-
- // EVENTS
-
- // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
- media.addEventListener('play', function() {
-
- // go through all other players
- for (var i=0, il=mejs.players.length; i<il; i++) {
- var p = mejs.players[i];
- if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
- p.pause();
- }
- p.hasFocus = false;
- }
-
- t.hasFocus = true;
- },false);
-
-
- // ended for all
- t.media.addEventListener('ended', function (e) {
- try{
- t.media.setCurrentTime(0);
- } catch (exp) {
-
- }
- t.media.pause();
-
- if (t.setProgressRail)
- t.setProgressRail();
- if (t.setCurrentRail)
- t.setCurrentRail();
-
- if (t.options.loop) {
- t.media.play();
- } else if (!t.options.alwaysShowControls && t.controlsEnabled) {
- t.showControls();
- }
- }, false);
-
- // resize on the first play
- t.media.addEventListener('loadedmetadata', function(e) {
- if (t.updateDuration) {
- t.updateDuration();
- }
- if (t.updateCurrent) {
- t.updateCurrent();
- }
-
- if (!t.isFullScreen) {
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
- }
- }, false);
-
-
- // webkit has trouble doing this without a delay
- setTimeout(function () {
- t.setPlayerSize(t.width, t.height);
- t.setControlsSize();
- }, 50);
-
- // adjust controls whenever window sizes (used to be in fullscreen only)
- $(window).resize(function() {
-
- // don't resize for fullscreen mode
- if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
- t.setPlayerSize(t.width, t.height);
- }
-
- // always adjust controls
- t.setControlsSize();
- });
-
- // TEMP: needs to be moved somewhere else
- if (t.media.pluginType == 'youtube') {
- t.container.find('.mejs-overlay-play').hide();
- }
- }
-
- // force autoplay for HTML5
- if (autoplay && media.pluginType == 'native') {
- media.load();
- media.play();
- }
-
-
- if (t.options.success) {
-
- if (typeof t.options.success == 'string') {
- window[t.options.success](t.media, t.domNode, t);
- } else {
- t.options.success(t.media, t.domNode, t);
- }
- }
- },
-
- handleError: function(e) {
- var t = this;
-
- t.controls.hide();
-
- // Tell user that the file cannot be played
- if (t.options.error) {
- t.options.error(e);
- }
- },
-
- setPlayerSize: function(width,height) {
- var t = this;
-
- if (typeof width != 'undefined')
- t.width = width;
-
- if (typeof height != 'undefined')
- t.height = height;
-
- // detect 100% mode
- if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width') === '100%') {
-
- // do we have the native dimensions yet?
- var
- nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
- nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
- parentWidth = t.container.parent().width(),
- newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
-
- if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
- parentWidth = $(window).width();
- newHeight = $(window).height();
- }
-
- if ( newHeight != 0 ) {
- // set outer container size
- t.container
- .width(parentWidth)
- .height(newHeight);
-
- // set native <video>
- t.$media
- .width('100%')
- .height('100%');
-
- // set shims
- t.container.find('object, embed, iframe')
- .width('100%')
- .height('100%');
-
- // if shim is ready, send the size to the embeded plugin
- if (t.isVideo) {
- if (t.media.setVideoSize) {
- t.media.setVideoSize(parentWidth, newHeight);
- }
- }
-
- // set the layers
- t.layers.children('.mejs-layer')
- .width('100%')
- .height('100%');
- }
-
-
- } else {
-
- t.container
- .width(t.width)
- .height(t.height);
-
- t.layers.children('.mejs-layer')
- .width(t.width)
- .height(t.height);
-
- }
- },
-
- setControlsSize: function() {
- var t = this,
- usedWidth = 0,
- railWidth = 0,
- rail = t.controls.find('.mejs-time-rail'),
- total = t.controls.find('.mejs-time-total'),
- current = t.controls.find('.mejs-time-current'),
- loaded = t.controls.find('.mejs-time-loaded'),
- others = rail.siblings();
-
-
- // allow the size to come from custom CSS
- if (t.options && !t.options.autosizeProgress) {
- // Also, frontends devs can be more flexible
- // due the opportunity of absolute positioning.
- railWidth = parseInt(rail.css('width'));
- }
-
- // attempt to autosize
- if (railWidth === 0 || !railWidth) {
-
- // find the size of all the other controls besides the rail
- others.each(function() {
- if ($(this).css('position') != 'absolute') {
- usedWidth += $(this).outerWidth(true);
- }
- });
-
- // fit the rail into the remaining space
- railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
- }
-
- // outer area
- rail.width(railWidth);
- // dark space
- total.width(railWidth - (total.outerWidth(true) - total.width()));
-
- if (t.setProgressRail)
- t.setProgressRail();
- if (t.setCurrentRail)
- t.setCurrentRail();
- },
-
-
- buildposter: function(player, controls, layers, media) {
- var t = this,
- poster =
- $('<div class="mejs-poster mejs-layer">' +
- '</div>')
- .appendTo(layers),
- posterUrl = player.$media.attr('poster');
-
- // prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
- if (player.options.poster !== '') {
- posterUrl = player.options.poster;
- }
-
- // second, try the real poster
- if (posterUrl !== '' && posterUrl != null) {
- t.setPoster(posterUrl);
- } else {
- poster.hide();
- }
-
- media.addEventListener('play',function() {
- poster.hide();
- }, false);
- },
-
- setPoster: function(url) {
- var t = this,
- posterDiv = t.container.find('.mejs-poster'),
- posterImg = posterDiv.find('img');
-
- if (posterImg.length == 0) {
- posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
- }
-
- posterImg.attr('src', url);
- },
-
- buildoverlays: function(player, controls, layers, media) {
- if (!player.isVideo)
- return;
-
- var
- loading =
- $('<div class="mejs-overlay mejs-layer">'+
- '<div class="mejs-overlay-loading"><span></span></div>'+
- '</div>')
- .hide() // start out hidden
- .appendTo(layers),
- error =
- $('<div class="mejs-overlay mejs-layer">'+
- '<div class="mejs-overlay-error"></div>'+
- '</div>')
- .hide() // start out hidden
- .appendTo(layers),
- // this needs to come last so it's on top
- bigPlay =
- $('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
- '<div class="mejs-overlay-button"></div>'+
- '</div>')
- .appendTo(layers)
- .click(function() {
- if (media.paused) {
- media.play();
- } else {
- media.pause();
- }
- });
-
- /*
- if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
- bigPlay.remove();
- loading.remove();
- }
- */
-
-
- // show/hide big play button
- media.addEventListener('play',function() {
- bigPlay.hide();
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.hide();
- }, false);
-
- media.addEventListener('playing', function() {
- bigPlay.hide();
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.hide();
- }, false);
-
- media.addEventListener('seeking', function() {
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
-
- media.addEventListener('seeked', function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- }, false);
-
- media.addEventListener('pause',function() {
- if (!mejs.MediaFeatures.isiPhone) {
- bigPlay.show();
- }
- }, false);
-
- media.addEventListener('waiting', function() {
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
-
-
- // show/hide loading
- media.addEventListener('loadeddata',function() {
- // for some reason Chrome is firing this event
- //if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
- // return;
-
- loading.show();
- controls.find('.mejs-time-buffering').show();
- }, false);
- media.addEventListener('canplay',function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- }, false);
-
- // error handling
- media.addEventListener('error',function() {
- loading.hide();
- controls.find('.mejs-time-buffering').hide();
- error.show();
- error.find('mejs-overlay-error').html("Error loading this resource");
- }, false);
- },
-
- buildkeyboard: function(player, controls, layers, media) {
-
- var t = this;
-
- // listen for key presses
- $(document).keydown(function(e) {
-
- if (player.hasFocus && player.options.enableKeyboard) {
-
- // find a matching key
- for (var i=0, il=player.options.keyActions.length; i<il; i++) {
- var keyAction = player.options.keyActions[i];
-
- for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
- if (e.keyCode == keyAction.keys[j]) {
- e.preventDefault();
- keyAction.action(player, media, e.keyCode);
- return false;
- }
- }
- }
- }
-
- return true;
- });
-
- // check if someone clicked outside a player region, then kill its focus
- $(document).click(function(event) {
- if ($(event.target).closest('.mejs-container').length == 0) {
- player.hasFocus = false;
- }
- });
-
- },
-
- findTracks: function() {
- var t = this,
- tracktags = t.$media.find('track');
-
- // store for use by plugins
- t.tracks = [];
- tracktags.each(function(index, track) {
-
- track = $(track);
-
- t.tracks.push({
- srclang: track.attr('srclang').toLowerCase(),
- src: track.attr('src'),
- kind: track.attr('kind'),
- label: track.attr('label') || '',
- entries: [],
- isLoaded: false
- });
- });
- },
- changeSkin: function(className) {
- this.container[0].className = 'mejs-container ' + className;
- 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(muted) {
- this.media.setMuted(muted);
- },
- setCurrentTime: function(time) {
- this.media.setCurrentTime(time);
- },
- getCurrentTime: function() {
- return this.media.currentTime;
- },
- setVolume: function(volume) {
- this.media.setVolume(volume);
- },
- getVolume: function() {
- return this.media.volume;
- },
- setSrc: function(src) {
- this.media.setSrc(src);
- },
- remove: function() {
- var t = this;
-
- if (t.media.pluginType === 'flash') {
- t.media.remove();
- } else if (t.media.pluginType === 'native') {
- t.$media.prop('controls', true);
- }
-
- // grab video and put it back in place
- if (!t.isDynamic) {
- t.$node.insertBefore(t.container)
- }
-
- t.container.remove();
- }
- };
-
- // turn into jQuery plugin
- if (typeof jQuery != 'undefined') {
- jQuery.fn.mediaelementplayer = function (options) {
- return this.each(function () {
- new mejs.MediaElementPlayer(this, options);
- });
- };
- }
-
- $(document).ready(function() {
- // auto enable using JSON attribute
- $('.mejs-player').mediaelementplayer();
- });
-
- // push out to window
- window.MediaElementPlayer = mejs.MediaElementPlayer;
-
-})(mejs.$);
+(function ($) {
+
+ // default player values
+ mejs.MepDefaults = {
+ // url to poster (to fix iOS 3.x)
+ poster: '',
+ // default if the <video width> is not specified
+ defaultVideoWidth: 480,
+ // default if the <video height> is not specified
+ defaultVideoHeight: 270,
+ // if set, overrides <video width>
+ videoWidth: -1,
+ // if set, overrides <video height>
+ videoHeight: -1,
+ // default if the user doesn't specify
+ defaultAudioWidth: 400,
+ // default if the user doesn't specify
+ defaultAudioHeight: 30,
+
+ // default amount to move back when back key is pressed
+ defaultSeekBackwardInterval: function(media) {
+ return (media.duration * 0.05);
+ },
+ // default amount to move forward when forward key is pressed
+ defaultSeekForwardInterval: function(media) {
+ return (media.duration * 0.05);
+ },
+
+ // width of audio player
+ audioWidth: -1,
+ // height of audio player
+ audioHeight: -1,
+ // initial volume when the player starts (overrided by user cookie)
+ startVolume: 0.8,
+ // useful for <audio> player loops
+ loop: false,
+ // resize to media dimensions
+ enableAutosize: true,
+ // forces the hour marker (##:00:00)
+ alwaysShowHours: false,
+
+ // show framecount in timecode (##:00:00:00)
+ showTimecodeFrameCount: false,
+ // used when showTimecodeFrameCount is set to true
+ framesPerSecond: 25,
+
+ // automatically calculate the width of the progress bar based on the sizes of other elements
+ autosizeProgress : true,
+ // Hide controls when playing and mouse is not over the video
+ alwaysShowControls: false,
+ // force iPad's native controls
+ iPadUseNativeControls: false,
+ // force iPhone's native controls
+ iPhoneUseNativeControls: false,
+ // force Android's native controls
+ AndroidUseNativeControls: false,
+ // features to show
+ features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
+ // only for dynamic
+ isVideo: true,
+
+ // turns keyboard support on and off for this instance
+ enableKeyboard: true,
+
+ // whenthis player starts, it will pause other players
+ pauseOtherPlayers: true,
+
+ // array of keyboard actions such as play pause
+ keyActions: [
+ {
+ keys: [
+ 32, // SPACE
+ 179 // GOOGLE play/pause button
+ ],
+ action: function(player, media) {
+ if (media.paused || media.ended) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ }
+ },
+ {
+ keys: [38], // UP
+ action: function(player, media) {
+ var newVolume = Math.min(media.volume + 0.1, 1);
+ media.setVolume(newVolume);
+ }
+ },
+ {
+ keys: [40], // DOWN
+ action: function(player, media) {
+ var newVolume = Math.max(media.volume - 0.1, 0);
+ media.setVolume(newVolume);
+ }
+ },
+ {
+ keys: [
+ 37, // LEFT
+ 227 // Google TV rewind
+ ],
+ action: function(player, media) {
+ if (!isNaN(media.duration) && media.duration > 0) {
+ if (player.isVideo) {
+ player.showControls();
+ player.startControlsTimer();
+ }
+
+ // 5%
+ var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
+ media.setCurrentTime(newTime);
+ }
+ }
+ },
+ {
+ keys: [
+ 39, // RIGHT
+ 228 // Google TV forward
+ ],
+ action: function(player, media) {
+ if (!isNaN(media.duration) && media.duration > 0) {
+ if (player.isVideo) {
+ player.showControls();
+ player.startControlsTimer();
+ }
+
+ // 5%
+ var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
+ media.setCurrentTime(newTime);
+ }
+ }
+ },
+ {
+ keys: [70], // f
+ action: function(player, media) {
+ if (typeof player.enterFullScreen != 'undefined') {
+ if (player.isFullScreen) {
+ player.exitFullScreen();
+ } else {
+ player.enterFullScreen();
+ }
+ }
+ }
+ }
+ ]
+ };
+
+ mejs.mepIndex = 0;
+
+ mejs.players = [];
+
+ // wraps a MediaElement object in player controls
+ mejs.MediaElementPlayer = function(node, o) {
+ // enforce object, even without "new" (via John Resig)
+ if ( !(this instanceof mejs.MediaElementPlayer) ) {
+ return new mejs.MediaElementPlayer(node, o);
+ }
+
+ var t = this;
+
+ // these will be reset after the MediaElement.success fires
+ t.$media = t.$node = $(node);
+ t.node = t.media = t.$media[0];
+
+ // check for existing player
+ if (typeof t.node.player != 'undefined') {
+ return t.node.player;
+ } else {
+ // attach player to DOM node for reference
+ t.node.player = t;
+ }
+
+
+ // try to get options from data-mejsoptions
+ if (typeof o == 'undefined') {
+ o = t.$node.data('mejsoptions');
+ }
+
+ // extend default options
+ t.options = $.extend({},mejs.MepDefaults,o);
+
+ // add to player array (for focus events)
+ mejs.players.push(t);
+
+ // start up
+ t.init();
+
+ return t;
+ };
+
+ // actual player
+ mejs.MediaElementPlayer.prototype = {
+
+ hasFocus: false,
+
+ controlsAreVisible: true,
+
+ init: function() {
+
+ var
+ t = this,
+ mf = mejs.MediaFeatures,
+ // options for MediaElement (shim)
+ meOptions = $.extend(true, {}, t.options, {
+ success: function(media, domNode) { t.meReady(media, domNode); },
+ error: function(e) { t.handleError(e);}
+ }),
+ tagName = t.media.tagName.toLowerCase();
+
+ t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
+
+ if (t.isDynamic) {
+ // get video from src or href?
+ t.isVideo = t.options.isVideo;
+ } else {
+ t.isVideo = (tagName !== 'audio' && t.options.isVideo);
+ }
+
+ // use native controls in iPad, iPhone, and Android
+ if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
+
+ // add controls and stop
+ t.$media.attr('controls', 'controls');
+
+ // attempt to fix iOS 3 bug
+ //t.$media.removeAttr('poster');
+ // no Issue found on iOS3 -ttroxell
+
+ // override Apple's autoplay override for iPads
+ if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
+ t.media.load();
+ t.media.play();
+ }
+
+ } else if (mf.isAndroid && t.AndroidUseNativeControls) {
+
+ // leave default player
+
+ } else {
+
+ // DESKTOP: use MediaElementPlayer controls
+
+ // 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">'+
+ '<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(t.$media[0].className)
+ .insertBefore(t.$media);
+
+ // add classes for user and content
+ t.container.addClass(
+ (mf.isAndroid ? 'mejs-android ' : '') +
+ (mf.isiOS ? 'mejs-ios ' : '') +
+ (mf.isiPad ? 'mejs-ipad ' : '') +
+ (mf.isiPhone ? 'mejs-iphone ' : '') +
+ (t.isVideo ? 'mejs-video ' : 'mejs-audio ')
+ );
+
+
+ // move the <video/video> tag into the right spot
+ if (mf.isiOS) {
+
+ // sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
+ var $newMedia = t.$media.clone();
+
+ t.container.find('.mejs-mediaelement').append($newMedia);
+
+ t.$media.remove();
+ t.$node = t.$media = $newMedia;
+ t.node = t.media = $newMedia[0]
+
+ } else {
+
+ // normal way of moving it into place (doesn't work on iOS)
+ t.container.find('.mejs-mediaelement').append(t.$media);
+ }
+
+ // find parts
+ t.controls = t.container.find('.mejs-controls');
+ t.layers = t.container.find('.mejs-layers');
+
+ // determine the size
+
+ /* size priority:
+ (1) videoWidth (forced),
+ (2) style="width;height;"
+ (3) width attribute,
+ (4) defaultVideoWidth (for unspecified cases)
+ */
+
+ var tagType = (t.isVideo ? 'video' : 'audio'),
+ capsTagName = tagType.substring(0,1).toUpperCase() + tagType.substring(1);
+
+
+ if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
+ t.width = t.options[tagType + 'Width'];
+ } else if (t.media.style.width !== '' && t.media.style.width !== null) {
+ t.width = t.media.style.width;
+ } else if (t.media.getAttribute('width') !== null) {
+ t.width = t.$media.attr('width');
+ } else {
+ t.width = t.options['default' + capsTagName + 'Width'];
+ }
+
+ if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
+ t.height = t.options[tagType + 'Height'];
+ } else if (t.media.style.height !== '' && t.media.style.height !== null) {
+ t.height = t.media.style.height;
+ } else if (t.$media[0].getAttribute('height') !== null) {
+ t.height = t.$media.attr('height');
+ } else {
+ t.height = t.options['default' + capsTagName + 'Height'];
+ }
+
+ // set the size, while we wait for the plugins to load below
+ t.setPlayerSize(t.width, t.height);
+
+ // create MediaElementShim
+ meOptions.pluginWidth = t.height;
+ meOptions.pluginHeight = t.width;
+ }
+
+
+
+ // create MediaElement shim
+ mejs.MediaElement(t.$media[0], meOptions);
+ },
+
+ showControls: function(doAnimation) {
+ var t = this;
+
+ doAnimation = typeof doAnimation == 'undefined' || doAnimation;
+
+ if (t.controlsAreVisible)
+ return;
+
+ if (doAnimation) {
+ t.controls
+ .css('visibility','visible')
+ .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control')
+ .css('visibility','visible')
+ .stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
+
+ } else {
+ t.controls
+ .css('visibility','visible')
+ .css('display','block');
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control')
+ .css('visibility','visible')
+ .css('display','block');
+
+ t.controlsAreVisible = true;
+ }
+
+ t.setControlsSize();
+
+ },
+
+ hideControls: function(doAnimation) {
+ var t = this;
+
+ doAnimation = typeof doAnimation == 'undefined' || doAnimation;
+
+ if (!t.controlsAreVisible)
+ return;
+
+ if (doAnimation) {
+ // fade out main controls
+ t.controls.stop(true, true).fadeOut(200, function() {
+ $(this)
+ .css('visibility','hidden')
+ .css('display','block');
+
+ t.controlsAreVisible = false;
+ });
+
+ // any additional controls people might add and want to hide
+ t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
+ $(this)
+ .css('visibility','hidden')
+ .css('display','block');
+ });
+ } else {
+
+ // hide main controls
+ t.controls
+ .css('visibility','hidden')
+ .css('display','block');
+
+ // hide others
+ t.container.find('.mejs-control')
+ .css('visibility','hidden')
+ .css('display','block');
+
+ t.controlsAreVisible = false;
+ }
+ },
+
+ controlsTimer: null,
+
+ startControlsTimer: function(timeout) {
+
+ var t = this;
+
+ timeout = typeof timeout != 'undefined' ? timeout : 1500;
+
+ t.killControlsTimer('start');
+
+ t.controlsTimer = setTimeout(function() {
+ //console.log('timer fired');
+ t.hideControls();
+ t.killControlsTimer('hide');
+ }, timeout);
+ },
+
+ killControlsTimer: function(src) {
+
+ var t = this;
+
+ if (t.controlsTimer !== null) {
+ clearTimeout(t.controlsTimer);
+ delete t.controlsTimer;
+ t.controlsTimer = null;
+ }
+ },
+
+ controlsEnabled: true,
+
+ disableControls: function() {
+ var t= this;
+
+ t.killControlsTimer();
+ t.hideControls(false);
+ this.controlsEnabled = false;
+ },
+
+ enableControls: function() {
+ var t= this;
+
+ t.showControls(false);
+
+ t.controlsEnabled = true;
+ },
+
+
+ // Sets up all controls and events
+ meReady: function(media, domNode) {
+
+
+ var t = this,
+ mf = mejs.MediaFeatures,
+ autoplayAttr = domNode.getAttribute('autoplay'),
+ autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
+ featureIndex,
+ feature;
+
+ // make sure it can't create itself again if a plugin reloads
+ if (t.created)
+ return;
+ else
+ t.created = true;
+
+ t.media = media;
+ t.domNode = domNode;
+
+ if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
+
+ // two built in features
+ t.buildposter(t, t.controls, t.layers, t.media);
+ t.buildkeyboard(t, t.controls, t.layers, t.media);
+ t.buildoverlays(t, t.controls, t.layers, t.media);
+
+ // grab for use by features
+ t.findTracks();
+
+ // add user-defined features/controls
+ for (featureIndex in t.options.features) {
+ feature = t.options.features[featureIndex];
+ if (t['build' + feature]) {
+ try {
+ t['build' + feature](t, t.controls, t.layers, t.media);
+ } catch (e) {
+ // TODO: report control error
+ //throw e;
+ //console.log('error building ' + feature);
+ //console.log(e);
+ }
+ }
+ }
+
+ t.container.trigger('controlsready');
+
+ // reset all layers and controls
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+
+
+ // controls fade
+ if (t.isVideo) {
+
+ if (mejs.MediaFeatures.hasTouch) {
+
+ // for touch devices (iOS, Android)
+ // show/hide without animation on touch
+
+ t.$media.bind('touchstart', function() {
+
+
+ // toggle controls
+ if (t.controlsAreVisible) {
+ t.hideControls(false);
+ } else {
+ if (t.controlsEnabled) {
+ t.showControls(false);
+ }
+ }
+ });
+
+ } else {
+ // click controls
+ var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
+
+ // click to play/pause
+ clickElement.click(function() {
+ if (media.paused) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ });
+
+
+ // show/hide controls
+ t.container
+ .bind('mouseenter mouseover', function () {
+ if (t.controlsEnabled) {
+ if (!t.options.alwaysShowControls) {
+ t.killControlsTimer('enter');
+ t.showControls();
+ t.startControlsTimer(2500);
+ }
+ }
+ })
+ .bind('mousemove', function() {
+ if (t.controlsEnabled) {
+ if (!t.controlsAreVisible) {
+ t.showControls();
+ }
+ //t.killControlsTimer('move');
+ if (!t.options.alwaysShowControls) {
+ t.startControlsTimer(2500);
+ }
+ }
+ })
+ .bind('mouseleave', function () {
+ if (t.controlsEnabled) {
+ if (!t.media.paused && !t.options.alwaysShowControls) {
+ t.startControlsTimer(1000);
+ }
+ }
+ });
+ }
+
+ // check for autoplay
+ if (autoplay && !t.options.alwaysShowControls) {
+ t.hideControls();
+ }
+
+ // resizer
+ if (t.options.enableAutosize) {
+ t.media.addEventListener('loadedmetadata', function(e) {
+ // if the <video height> was not set and the options.videoHeight was not set
+ // then resize to the real dimensions
+ if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
+ t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
+ t.setControlsSize();
+ t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
+ }
+ }, false);
+ }
+ }
+
+ // EVENTS
+
+ // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
+ media.addEventListener('play', function() {
+
+ // go through all other players
+ for (var i=0, il=mejs.players.length; i<il; i++) {
+ var p = mejs.players[i];
+ if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
+ p.pause();
+ }
+ p.hasFocus = false;
+ }
+
+ t.hasFocus = true;
+ },false);
+
+
+ // ended for all
+ t.media.addEventListener('ended', function (e) {
+ try{
+ t.media.setCurrentTime(0);
+ } catch (exp) {
+
+ }
+ t.media.pause();
+
+ if (t.setProgressRail)
+ t.setProgressRail();
+ if (t.setCurrentRail)
+ t.setCurrentRail();
+
+ if (t.options.loop) {
+ t.media.play();
+ } else if (!t.options.alwaysShowControls && t.controlsEnabled) {
+ t.showControls();
+ }
+ }, false);
+
+ // resize on the first play
+ t.media.addEventListener('loadedmetadata', function(e) {
+ if (t.updateDuration) {
+ t.updateDuration();
+ }
+ if (t.updateCurrent) {
+ t.updateCurrent();
+ }
+
+ if (!t.isFullScreen) {
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+ }
+ }, false);
+
+
+ // webkit has trouble doing this without a delay
+ setTimeout(function () {
+ t.setPlayerSize(t.width, t.height);
+ t.setControlsSize();
+ }, 50);
+
+ // adjust controls whenever window sizes (used to be in fullscreen only)
+ $(window).resize(function() {
+
+ // don't resize for fullscreen mode
+ if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
+ t.setPlayerSize(t.width, t.height);
+ }
+
+ // always adjust controls
+ t.setControlsSize();
+ });
+
+ // TEMP: needs to be moved somewhere else
+ if (t.media.pluginType == 'youtube') {
+ t.container.find('.mejs-overlay-play').hide();
+ }
+ }
+
+ // force autoplay for HTML5
+ if (autoplay && media.pluginType == 'native') {
+ media.load();
+ media.play();
+ }
+
+
+ if (t.options.success) {
+
+ if (typeof t.options.success == 'string') {
+ window[t.options.success](t.media, t.domNode, t);
+ } else {
+ t.options.success(t.media, t.domNode, t);
+ }
+ }
+ },
+
+ handleError: function(e) {
+ var t = this;
+
+ t.controls.hide();
+
+ // Tell user that the file cannot be played
+ if (t.options.error) {
+ t.options.error(e);
+ }
+ },
+
+ setPlayerSize: function(width,height) {
+ var t = this;
+
+ if (typeof width != 'undefined')
+ t.width = width;
+
+ if (typeof height != 'undefined')
+ t.height = height;
+
+ // detect 100% mode
+ if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width') === '100%') {
+
+ // do we have the native dimensions yet?
+ var
+ nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
+ nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
+ parentWidth = t.container.parent().width(),
+ newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
+
+ if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
+ parentWidth = $(window).width();
+ newHeight = $(window).height();
+ }
+
+ if ( newHeight != 0 ) {
+ // set outer container size
+ t.container
+ .width(parentWidth)
+ .height(newHeight);
+
+ // set native <video>
+ t.$media
+ .width('100%')
+ .height('100%');
+
+ // set shims
+ t.container.find('object, embed, iframe')
+ .width('100%')
+ .height('100%');
+
+ // if shim is ready, send the size to the embeded plugin
+ if (t.isVideo) {
+ if (t.media.setVideoSize) {
+ t.media.setVideoSize(parentWidth, newHeight);
+ }
+ }
+
+ // set the layers
+ t.layers.children('.mejs-layer')
+ .width('100%')
+ .height('100%');
+ }
+
+
+ } else {
+
+ t.container
+ .width(t.width)
+ .height(t.height);
+
+ t.layers.children('.mejs-layer')
+ .width(t.width)
+ .height(t.height);
+
+ }
+ },
+
+ setControlsSize: function() {
+ var t = this,
+ usedWidth = 0,
+ railWidth = 0,
+ rail = t.controls.find('.mejs-time-rail'),
+ total = t.controls.find('.mejs-time-total'),
+ current = t.controls.find('.mejs-time-current'),
+ loaded = t.controls.find('.mejs-time-loaded'),
+ others = rail.siblings();
+
+
+ // allow the size to come from custom CSS
+ if (t.options && !t.options.autosizeProgress) {
+ // Also, frontends devs can be more flexible
+ // due the opportunity of absolute positioning.
+ railWidth = parseInt(rail.css('width'));
+ }
+
+ // attempt to autosize
+ if (railWidth === 0 || !railWidth) {
+
+ // find the size of all the other controls besides the rail
+ others.each(function() {
+ if ($(this).css('position') != 'absolute') {
+ usedWidth += $(this).outerWidth(true);
+ }
+ });
+
+ // fit the rail into the remaining space
+ railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
+ }
+
+ // outer area
+ rail.width(railWidth);
+ // dark space
+ total.width(railWidth - (total.outerWidth(true) - total.width()));
+
+ if (t.setProgressRail)
+ t.setProgressRail();
+ if (t.setCurrentRail)
+ t.setCurrentRail();
+ },
+
+
+ buildposter: function(player, controls, layers, media) {
+ var t = this,
+ poster =
+ $('<div class="mejs-poster mejs-layer">' +
+ '</div>')
+ .appendTo(layers),
+ posterUrl = player.$media.attr('poster');
+
+ // prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
+ if (player.options.poster !== '') {
+ posterUrl = player.options.poster;
+ }
+
+ // second, try the real poster
+ if (posterUrl !== '' && posterUrl != null) {
+ t.setPoster(posterUrl);
+ } else {
+ poster.hide();
+ }
+
+ media.addEventListener('play',function() {
+ poster.hide();
+ }, false);
+ },
+
+ setPoster: function(url) {
+ var t = this,
+ posterDiv = t.container.find('.mejs-poster'),
+ posterImg = posterDiv.find('img');
+
+ if (posterImg.length == 0) {
+ posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
+ }
+
+ posterImg.attr('src', url);
+ },
+
+ buildoverlays: function(player, controls, layers, media) {
+ if (!player.isVideo)
+ return;
+
+ var
+ loading =
+ $('<div class="mejs-overlay mejs-layer">'+
+ '<div class="mejs-overlay-loading"><span></span></div>'+
+ '</div>')
+ .hide() // start out hidden
+ .appendTo(layers),
+ error =
+ $('<div class="mejs-overlay mejs-layer">'+
+ '<div class="mejs-overlay-error"></div>'+
+ '</div>')
+ .hide() // start out hidden
+ .appendTo(layers),
+ // this needs to come last so it's on top
+ bigPlay =
+ $('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
+ '<div class="mejs-overlay-button"></div>'+
+ '</div>')
+ .appendTo(layers)
+ .click(function() {
+ if (media.paused) {
+ media.play();
+ } else {
+ media.pause();
+ }
+ });
+
+ /*
+ if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
+ bigPlay.remove();
+ loading.remove();
+ }
+ */
+
+
+ // show/hide big play button
+ media.addEventListener('play',function() {
+ bigPlay.hide();
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.hide();
+ }, false);
+
+ media.addEventListener('playing', function() {
+ bigPlay.hide();
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.hide();
+ }, false);
+
+ media.addEventListener('seeking', function() {
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+
+ media.addEventListener('seeked', function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ }, false);
+
+ media.addEventListener('pause',function() {
+ if (!mejs.MediaFeatures.isiPhone) {
+ bigPlay.show();
+ }
+ }, false);
+
+ media.addEventListener('waiting', function() {
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+
+
+ // show/hide loading
+ media.addEventListener('loadeddata',function() {
+ // for some reason Chrome is firing this event
+ //if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
+ // return;
+
+ loading.show();
+ controls.find('.mejs-time-buffering').show();
+ }, false);
+ media.addEventListener('canplay',function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ }, false);
+
+ // error handling
+ media.addEventListener('error',function() {
+ loading.hide();
+ controls.find('.mejs-time-buffering').hide();
+ error.show();
+ error.find('mejs-overlay-error').html("Error loading this resource");
+ }, false);
+ },
+
+ buildkeyboard: function(player, controls, layers, media) {
+
+ var t = this;
+
+ // listen for key presses
+ $(document).keydown(function(e) {
+
+ if (player.hasFocus && player.options.enableKeyboard) {
+
+ // find a matching key
+ for (var i=0, il=player.options.keyActions.length; i<il; i++) {
+ var keyAction = player.options.keyActions[i];
+
+ for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
+ if (e.keyCode == keyAction.keys[j]) {
+ e.preventDefault();
+ keyAction.action(player, media, e.keyCode);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ });
+
+ // check if someone clicked outside a player region, then kill its focus
+ $(document).click(function(event) {
+ if ($(event.target).closest('.mejs-container').length == 0) {
+ player.hasFocus = false;
+ }
+ });
+
+ },
+
+ findTracks: function() {
+ var t = this,
+ tracktags = t.$media.find('track');
+
+ // store for use by plugins
+ t.tracks = [];
+ tracktags.each(function(index, track) {
+
+ track = $(track);
+
+ t.tracks.push({
+ srclang: track.attr('srclang').toLowerCase(),
+ src: track.attr('src'),
+ kind: track.attr('kind'),
+ label: track.attr('label') || '',
+ entries: [],
+ isLoaded: false
+ });
+ });
+ },
+ changeSkin: function(className) {
+ this.container[0].className = 'mejs-container ' + className;
+ 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(muted) {
+ this.media.setMuted(muted);
+ },
+ setCurrentTime: function(time) {
+ this.media.setCurrentTime(time);
+ },
+ getCurrentTime: function() {
+ return this.media.currentTime;
+ },
+ setVolume: function(volume) {
+ this.media.setVolume(volume);
+ },
+ getVolume: function() {
+ return this.media.volume;
+ },
+ setSrc: function(src) {
+ this.media.setSrc(src);
+ },
+ remove: function() {
+ var t = this;
+
+ if (t.media.pluginType === 'flash') {
+ t.media.remove();
+ } else if (t.media.pluginType === 'native') {
+ t.$media.prop('controls', true);
+ }
+
+ // grab video and put it back in place
+ if (!t.isDynamic) {
+ t.$node.insertBefore(t.container)
+ }
+
+ t.container.remove();
+ }
+ };
+
+ // turn into jQuery plugin
+ if (typeof jQuery != 'undefined') {
+ jQuery.fn.mediaelementplayer = function (options) {
+ return this.each(function () {
+ new mejs.MediaElementPlayer(this, options);
+ });
+ };
+ }
+
+ $(document).ready(function() {
+ // auto enable using JSON attribute
+ $('.mejs-player').mediaelementplayer();
+ });
+
+ // push out to window
+ window.MediaElementPlayer = mejs.MediaElementPlayer;
+
+})(mejs.$);