Вход Регистрация
Файл: media/mediaelement-and-player.min.js
Строк: 6184
<?php
/*!
 *
 * MediaElement.js
 * HTML5 <video> and <audio> shim and player
 * http://mediaelementjs.com/
 *
 * Creates a JavaScript object that mimics HTML5 MediaElement API
 * for browsers that don't understand HTML5 or can't play the provided codec
 * Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3
 *
 * Copyright 2010-2014, John Dyer (http://j.hn)
 * License: MIT
 *
 */
// Namespace
var mejs mejs || {};

// version number
mejs.version '2.16.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/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg''video/youtube''video/x-youtube''application/x-mpegURL']}
        
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
    
],
    
youtube: [
        {
versionnulltypes: ['video/youtube''video/x-youtube''audio/youtube''audio/x-youtube']}
    ],
    
vimeo: [
        {
versionnulltypes: ['video/vimeo''video/x-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
            
0,
            
j,
            
codePath '',
            
testname '',
            
slashPos,
            
filenamePos,
            
scriptUrl,
            
scriptPath,            
            
scriptFilename,
            
scripts document.getElementsByTagName('script'),
            
il scripts.length,
            
jl scriptNames.length;
            
        
// go through all <script> tags
        
for (; ili++) {
            
scriptUrl scripts[i].src;
            
slashPos scriptUrl.lastIndexOf('/');
            if (
slashPos > -1) {
                
scriptFilename scriptUrl.substring(slashPos 1);
                
scriptPath scriptUrl.substring(0slashPos 1);
            } else {
                
scriptFilename scriptUrl;
                
scriptPath '';            
            }
            
            
// see if any <script> tags have a file name that matches the 
            
for (0jlj++) {
                
testname scriptNames[j];
                
filenamePos scriptFilename.indexOf(testname);
                if (
filenamePos > -1) {
                    
codePath scriptPath;
                    break;
                }
            }
            
            
// if we found a path, then break and return it
            
if (codePath !== '') {
                break;
            }
        }
        
        
// send the best path back
        
return codePath;
    },
    
secondsToTimeCode: function(timeforceHoursshowFrameCountfps) {
        
//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_ffforceHoursshowFrameCountfps){
        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 
0SMPTE.lengthi++) {
            
multiplier 1;
            if (
0) {
                
multiplier Math.pow(60i); 
            }
            
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 && /object|embed/i.test(obj.nodeName)) {
            if (
mejs.MediaFeatures.isIE) {
                
obj.style.display "none";
                (function(){
                    if (
obj.readyState == 4) {
                        
mejs.Utility.removeObjectInIE(id);
                    } else {
                        
setTimeout(arguments.callee10);
                    }
                })();
            } 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
mejs.PluginDetector = {

    
// main public function to test a plug version number PluginDetector.hasPluginVersion('flash',[9,0,125]);
    
hasPluginVersion: function(pluginv) {
        var 
pv this.plugins[plugin];
        
v[1] = v[1] || 0;
        
v[2] = v[2] || 0;
        return (
pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true false;
    },

    
// cached values
    
navwindow.navigator,
    
uawindow.navigator.userAgent.toLowerCase(),

    
// stored version numbers
    
plugins: [],

    
// runs detectPlugin() and stores the version number
    
addPlugin: function(ppluginNamemimeTypeactiveXaxDetect) {
        
this.plugins[p] = this.detectPlugin(pluginNamemimeTypeactiveXaxDetect);
    },

    
// get the version number from the mimetype (all but IE) or ActiveX (IE)
    
detectPlugin: function(pluginNamemimeTypeactiveXaxDetect) {

        var 
version = [0,0,0],
            
description,
            
i,
            
ax;

        
// Firefox, Webkit, Opera
        
if (typeof(this.nav.plugins) != 'undefined' && typeof this.nav.plugins[pluginName] == 'object') {
            
description this.nav.plugins[pluginName].description;
            if (
description && !(typeof this.nav.mimeTypes != 'undefined' && this.nav.mimeTypes[mimeType] && !this.nav.mimeTypes[mimeType].enabledPlugin)) {
                
version description.replace(pluginName'').replace(/^s+/,'').replace(/sr/gi,'.').split('.');
                for (
i=0i<version.lengthi++) {
                    
version[i] = parseInt(version[i].match(/d+/), 10);
                }
            }
        
// Internet Explorer / ActiveX
        
} else if (typeof(window.ActiveXObject) != 'undefined') {
            try {
                
ax = new ActiveXObject(activeX);
                if (
ax) {
                    
version axDetect(ax);
                }
            }
            catch (
e) { }
        }
        return 
version;
    }
};

// Add Flash detection
mejs.PluginDetector.addPlugin('flash','Shockwave Flash','application/x-shockwave-flash','ShockwaveFlash.ShockwaveFlash', function(ax) {
    
// adapted from SWFObject
    
var version = [],
        
ax.GetVariable("$version");
    if (
d) {
        
d.split(" ")[1].split(",");
        
version = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
    }
    return 
version;
});

// Add Silverlight detection
mejs.PluginDetector.addPlugin('silverlight','Silverlight Plug-In','application/x-silverlight-2','AgControl.AgControl', function (ax) {
    
// Silverlight cannot report its version number to IE
    // but it does have a isVersionSupported function, so we have to loop through it to get a version number.
    // adapted from http://www.silverlightversion.com/
    
var = [0,0,0,0],
        
loopMatch = function(axvin) {
            while(
ax.isVersionSupported(v[0]+ "."v[1] + "." v[2] + "." v[3])){
                
v[i]+=n;
            }
            
v[i] -= n;
        };
    
loopMatch(axv01);
    
loopMatch(axv11);
    
loopMatch(axv210000); // the third place in the version number is usually 5 digits (4.0.xxxxx)
    
loopMatch(axv21000);
    
loopMatch(axv2100);
    
loopMatch(axv210);
    
loopMatch(axv21);
    
loopMatch(axv31);

    return 
v;
});
// add adobe acrobat
/*
PluginDetector.addPlugin('acrobat','Adobe Acrobat','application/pdf','AcroPDF.PDF', function (ax) {
    var version = [],
        d = ax.GetVersions().split(',')[0].split('=')[1].split('.');

    if (d) {
        version = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
    }
    return version;
});
*/
// necessary detection (fixes for <IE9)
mejs.MediaFeatures = {
    
init: function() {
        var
            
this,
            
document,
            
nav mejs.PluginDetector.nav,
            
ua mejs.PluginDetector.ua.toLowerCase(),
            
i,
            
v,
            
html5Elements = ['source','track','audio','video'];

        
// detect browsers (only the ones that have some kind of quirk we need to work around)
        
t.isiPad = (ua.match(/ipad/i) !== null);
        
t.isiPhone = (ua.match(/iphone/i) !== null);
        
t.isiOS t.isiPhone || t.isiPad;
        
t.isAndroid = (ua.match(/android/i) !== null);
        
t.isBustedAndroid = (ua.match(/android 2.[12]/) !== null);
        
t.isBustedNativeHTTPS = (location.protocol === 'https:' && (ua.match(/android [12]./) !== null || ua.match(/macintosh.* version.* safari/) !== null));
        
t.isIE = (nav.appName.toLowerCase().indexOf("microsoft") != -|| nav.appName.toLowerCase().match(/trident/gi) !== null);
        
t.isChrome = (ua.match(/chrome/gi) !== null);
        
t.isChromium = (ua.match(/chromium/gi) !== null);
        
t.isFirefox = (ua.match(/firefox/gi) !== null);
        
t.isWebkit = (ua.match(/webkit/gi) !== null);
        
t.isGecko = (ua.match(/gecko/gi) !== null) && !t.isWebkit && !t.isIE;
        
t.isOpera = (ua.match(/opera/gi) !== null);
        
t.hasTouch = ('ontouchstart' in window); //  && window.ontouchstart != null); // this breaks iOS 7
        
        // borrowed from Modernizr
        
t.svg = !! document.createElementNS &&
                !! 
document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect;

        
// create HTML5 media elements for IE before 9, get a <video> element for fullscreen detection
        
for (i=0i<html5Elements.lengthi++) {
            
document.createElement(html5Elements[i]);
        }
        
        
t.supportsMediaTag = (typeof v.canPlayType !== 'undefined' || t.isBustedAndroid);

        
// Fix for IE9 on Windows 7N / Windows 7KN (Media Player not installer)
        
try{
            
v.canPlayType("video/mp4");
        }catch(
e){
            
t.supportsMediaTag false;
        }

        
// detect native JavaScript fullscreen (Safari/Firefox only, Chrome still fails)
        
        // iOS
        
t.hasSemiNativeFullScreen = (typeof v.webkitEnterFullscreen !== 'undefined');
        
        
// W3C
        
t.hasNativeFullscreen = (typeof v.requestFullscreen !== 'undefined');
        
        
// webkit/firefox/IE11+
        
t.hasWebkitNativeFullScreen = (typeof v.webkitRequestFullScreen !== 'undefined');
        
t.hasMozNativeFullScreen = (typeof v.mozRequestFullScreen !== 'undefined');
        
t.hasMsNativeFullScreen = (typeof v.msRequestFullscreen !== 'undefined');
        
        
t.hasTrueNativeFullScreen = (t.hasWebkitNativeFullScreen || t.hasMozNativeFullScreen || t.hasMsNativeFullScreen);
        
t.nativeFullScreenEnabled t.hasTrueNativeFullScreen;
        
        
// Enabled?
        
if (t.hasMozNativeFullScreen) {
            
t.nativeFullScreenEnabled document.mozFullScreenEnabled;
        } else if (
t.hasMsNativeFullScreen) {
            
t.nativeFullScreenEnabled document.msFullscreenEnabled;        
        }
        
        if (
t.isChrome) {
            
t.hasSemiNativeFullScreen false;
        }
        
        if (
t.hasTrueNativeFullScreen) {
            
            
t.fullScreenEventName '';
            if (
t.hasWebkitNativeFullScreen) { 
                
t.fullScreenEventName 'webkitfullscreenchange';
                
            } else if (
t.hasMozNativeFullScreen) {
                
t.fullScreenEventName 'mozfullscreenchange';
                
            } else if (
t.hasMsNativeFullScreen) {
                
t.fullScreenEventName 'MSFullscreenChange';
            }
            
            
t.isFullScreen = function() {
                if (
t.hasMozNativeFullScreen) {
                    return 
d.mozFullScreen;
                
                } else if (
t.hasWebkitNativeFullScreen) {
                    return 
d.webkitIsFullScreen;
                
                } else if (
t.hasMsNativeFullScreen) {
                    return 
d.msFullscreenElement !== null;
                }
            }
                    
            
t.requestFullScreen = function(el) {
        
                if (
t.hasWebkitNativeFullScreen) {
                    
el.webkitRequestFullScreen();
                    
                } else if (
t.hasMozNativeFullScreen) {
                    
el.mozRequestFullScreen();

                } else if (
t.hasMsNativeFullScreen) {
                    
el.msRequestFullscreen();

                }
            }
            
            
t.cancelFullScreen = function() {                
                if (
t.hasWebkitNativeFullScreen) {
                    
document.webkitCancelFullScreen();
                    
                } else if (
t.hasMozNativeFullScreen) {
                    
document.mozCancelFullScreen();
                    
                } else if (
t.hasMsNativeFullScreen) {
                    
document.msExitFullscreen();
                    
                }
            }    
            
        }
        
        
        
// OS X 10.5 can't do this even if it says it can :(
        
if (t.hasSemiNativeFullScreen && ua.match(/mac os x 10_5/i)) {
            
t.hasNativeFullScreen false;
            
t.hasSemiNativeFullScreen false;
        }
        
    }
};
mejs.MediaFeatures.init();

/*
extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below)
*/
mejs.HtmlMediaElement = {
    
pluginType'native',
    
isFullScreenfalse,

    
setCurrentTime: function (time) {
        
this.currentTime time;
    },

    
setMuted: function (muted) {
        
this.muted muted;
    },

    
setVolume: function (volume) {
        
this.volume volume;
    },

    
// for parity with the plugin versions
    
stop: function () {
        
this.pause();
    },

    
// This can be a url string
    // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    
setSrc: function (url) {
        
        
// Fix for IE9 which can't set .src when there are <source> elements. Awesome, right?
        
var 
            
existingSources this.getElementsByTagName('source');
        while (
existingSources.length 0){
            
this.removeChild(existingSources[0]);
        }
    
        if (
typeof url == 'string') {
            
this.src url;
        } else {
            var 
imedia;

            for (
i=0i<url.lengthi++) {
                
media url[i];
                if (
this.canPlayType(media.type)) {
                    
this.src media.src;
                    break;
                }
            }
        }
    },

    
setVideoSize: function (widthheight) {
        
this.width width;
        
this.height height;
    }
};

/*
Mimics the <video/audio> element by calling Flash's External Interface or Silverlights [ScriptableMember]
*/
mejs.PluginMediaElement = function (pluginidpluginTypemediaUrl) {
    
this.id pluginid;
    
this.pluginType pluginType;
    
this.src mediaUrl;
    
this.events = {};
    
this.attributes = {};
};

// JavaScript values and ExternalInterface methods that match HTML5 video properties methods
// http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/fl/video/FLVPlayback.html
// http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
mejs.PluginMediaElement.prototype = {

    
// special
    
pluginElementnull,
    
pluginType'',
    
isFullScreenfalse,

    
// not implemented :(
    
playbackRate: -1,
    
defaultPlaybackRate: -1,
    
seekable: [],
    
played: [],

    
// HTML5 read-only properties
    
pausedtrue,
    
endedfalse,
    
seekingfalse,
    
duration0,
    
errornull,
    
tagName'',

    
// HTML5 get/set properties, but only set (updated by event handlers)
    
mutedfalse,
    
volume1,
    
currentTime0,

    
// HTML5 methods
    
play: function () {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                
this.pluginApi.playVideo();
            } else {
                
this.pluginApi.playMedia();
            }
            
this.paused false;
        }
    },
    
load: function () {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
            } else {
                
this.pluginApi.loadMedia();
            }
            
            
this.paused false;
        }
    },
    
pause: function () {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                
this.pluginApi.pauseVideo();
            } else {
                
this.pluginApi.pauseMedia();
            }            
            
            
            
this.paused true;
        }
    },
    
stop: function () {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                
this.pluginApi.stopVideo();
            } else {
                
this.pluginApi.stopMedia();
            }    
            
this.paused true;
        }
    },
    
canPlayType: function(type) {
        var 
i,
            
j,
            
pluginInfo,
            
pluginVersions mejs.plugins[this.pluginType];

        for (
i=0i<pluginVersions.lengthi++) {
            
pluginInfo pluginVersions[i];

            
// test if user has the correct plugin version
            
if (mejs.PluginDetector.hasPluginVersion(this.pluginTypepluginInfo.version)) {

                
// test for plugin playback types
                
for (j=0j<pluginInfo.types.lengthj++) {
                    
// find plugin that can play the type
                    
if (type == pluginInfo.types[j]) {
                        return 
'probably';
                    }
                }
            }
        }

        return 
'';
    },
    
    
positionFullscreenButton: function(x,y,visibleAndAbove) {
        if (
this.pluginApi != null && this.pluginApi.positionFullscreenButton) {
            
this.pluginApi.positionFullscreenButton(Math.floor(x),Math.floor(y),visibleAndAbove);
        }
    },
    
    
hideFullscreenButton: function() {
        if (
this.pluginApi != null && this.pluginApi.hideFullscreenButton) {
            
this.pluginApi.hideFullscreenButton();
        }        
    },    
    

    
// custom methods since not all JavaScript implementations support get/set

    // This can be a url string
    // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    
setSrc: function (url) {
        if (
typeof url == 'string') {
            
this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));
            
this.src mejs.Utility.absolutizeUrl(url);
        } else {
            var 
imedia;

            for (
i=0i<url.lengthi++) {
                
media url[i];
                if (
this.canPlayType(media.type)) {
                    
this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(media.src));
                    
this.src mejs.Utility.absolutizeUrl(url);
                    break;
                }
            }
        }

    },
    
setCurrentTime: function (time) {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                
this.pluginApi.seekTo(time);
            } else {
                
this.pluginApi.setCurrentTime(time);
            }                
            
            
            
            
this.currentTime time;
        }
    },
    
setVolume: function (volume) {
        if (
this.pluginApi != null) {
            
// same on YouTube and MEjs
            
if (this.pluginType == 'youtube') {
                
this.pluginApi.setVolume(volume 100);
            } else {
                
this.pluginApi.setVolume(volume);
            }
            
this.volume volume;
        }
    },
    
setMuted: function (muted) {
        if (
this.pluginApi != null) {
            if (
this.pluginType == 'youtube') {
                if (
muted) {
                    
this.pluginApi.mute();
                } else {
                    
this.pluginApi.unMute();
                }
                
this.muted muted;
                
this.dispatchEvent('volumechange');
            } else {
                
this.pluginApi.setMuted(muted);
            }
            
this.muted muted;
        }
    },

    
// additional non-HTML5 methods
    
setVideoSize: function (widthheight) {
        
        
//if (this.pluginType == 'flash' || this.pluginType == 'silverlight') {
            
if (this.pluginElement && this.pluginElement.style) {
                
this.pluginElement.style.width width 'px';
                
this.pluginElement.style.height height 'px';
            }
            if (
this.pluginApi != null && this.pluginApi.setVideoSize) {
                
this.pluginApi.setVideoSize(widthheight);
            }
        
//}
    
},

    
setFullscreen: function (fullscreen) {
        if (
this.pluginApi != null && this.pluginApi.setFullscreen) {
            
this.pluginApi.setFullscreen(fullscreen);
        }
    },
    
    
enterFullScreen: function() {
        if (
this.pluginApi != null && this.pluginApi.setFullscreen) {
            
this.setFullscreen(true);
        }        
        
    },
    
    
exitFullScreen: function() {
        if (
this.pluginApi != null && this.pluginApi.setFullscreen) {
            
this.setFullscreen(false);
        }
    },    

    
// start: fake events
    
addEventListener: function (eventNamecallbackbubble) {
        
this.events[eventName] = this.events[eventName] || [];
        
this.events[eventName].push(callback);
    },
    
removeEventListener: function (eventNamecallback) {
        if (!
eventName) { this.events = {}; return true; }
        var 
callbacks this.events[eventName];
        if (!
callbacks) return true;
        if (!
callback) { this.events[eventName] = []; return true; }
        for (var 
0callbacks.lengthi++) {
            if (
callbacks[i] === callback) {
                
this.events[eventName].splice(i1);
                return 
true;
            }
        }
        return 
false;
    },    
    
dispatchEvent: function (eventName) {
        var 
i,
            
args,
            
callbacks this.events[eventName];

        if (
callbacks) {
            
args = Array.prototype.slice.call(arguments1);
            for (
0callbacks.lengthi++) {
                
callbacks[i].apply(thisargs);
            }
        }
    },
    
// end: fake events
    
    // fake DOM attribute methods
    
hasAttribute: function(name){
        return (
name in this.attributes);  
    },
    
removeAttribute: function(name){
        
delete this.attributes[name];
    },
    
getAttribute: function(name){
        if (
this.hasAttribute(name)) {
            return 
this.attributes[name];
        }
        return 
'';
    },
    
setAttribute: function(namevalue){
        
this.attributes[name] = value;
    },

    
remove: function() {
        
mejs.Utility.removeSwf(this.pluginElement.id);
        
mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
    }
};

// Handles calls from Flash/Silverlight and reports them as native <video/audio> events and properties
mejs.MediaPluginBridge = {

    
pluginMediaElements:{},
    
htmlMediaElements:{},

    
registerPluginElement: function (idpluginMediaElementhtmlMediaElement) {
        
this.pluginMediaElements[id] = pluginMediaElement;
        
this.htmlMediaElements[id] = htmlMediaElement;
    },

    
unregisterPluginElement: function (id) {
        
delete this.pluginMediaElements[id];
        
delete this.htmlMediaElements[id];
    },

    
// when Flash/Silverlight is ready, it calls out to this method
    
initPlugin: function (id) {

        var 
pluginMediaElement this.pluginMediaElements[id],
            
htmlMediaElement this.htmlMediaElements[id];

        if (
pluginMediaElement) {
            
// find the javascript bridge
            
switch (pluginMediaElement.pluginType) {
                case 
"flash":
                    
pluginMediaElement.pluginElement pluginMediaElement.pluginApi document.getElementById(id);
                    break;
                case 
"silverlight":
                    
pluginMediaElement.pluginElement document.getElementById(pluginMediaElement.id);
                    
pluginMediaElement.pluginApi pluginMediaElement.pluginElement.Content.MediaElementJS;
                    break;
            }
    
            if (
pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
                
pluginMediaElement.success(pluginMediaElementhtmlMediaElement);
            }
        }
    },

    
// receives events from Flash/Silverlight and sends them out as HTML5 media events
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
    
fireEvent: function (ideventNamevalues) {

        var
            
e,
            
i,
            
bufferedTime,
            
pluginMediaElement this.pluginMediaElements[id];

        if(!
pluginMediaElement){
            return;
        }
        
        
// fake event object to mimic real HTML media event.
        
= {
            
typeeventName,
            
targetpluginMediaElement
        
};

        
// attach all values to element and event object
        
for (i in values) {
            
pluginMediaElement[i] = values[i];
            
e[i] = values[i];
        }

        
// fake the newer W3C buffered TimeRange (loaded and total have been removed)
        
bufferedTime values.bufferedTime || 0;

        
e.target.buffered e.buffered = {
            
start: function(index) {
                return 
0;
            },
            
end: function (index) {
                return 
bufferedTime;
            },
            
length1
        
};

        
pluginMediaElement.dispatchEvent(e.typee);
    }
};

/*
Default options
*/
mejs.MediaElementDefaults = {
    
// allows testing on HTML5, flash, silverlight
    // auto: attempts to detect what the browser can do
    // auto_plugin: prefer plugins and then attempt native HTML5
    // native: forces HTML5 playback
    // shim: disallows HTML5, will attempt either Flash or Silverlight
    // none: forces fallback view
    
mode'auto',
    
// remove or reorder to change plugin priority and availability
    
plugins: ['flash','silverlight','youtube','vimeo'],
    
// shows debug errors on screen
    
enablePluginDebugfalse,
    
// use plugin for browsers that have trouble with Basic Authentication on HTTPS sites
    
httpsBasicAuthSitefalse,
    
// overrides the type specified, useful for dynamic instantiation
    
type'',
    
// path to Flash and Silverlight plugins
    
pluginPathmejs.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
    
enablePluginSmoothingfalse,
    
// enabled pseudo-streaming (seek) on .mp4 files
    
enablePseudoStreamingfalse,
    
// start query parameter sent to server for pseudo-streaming
    
pseudoStreamingStartQueryParam'start',
    
// name of silverlight file
    
silverlightName'silverlightmediaelement.xap',
    
// default if the <video width> is not specified
    
defaultVideoWidth480,
    
// default if the <video height> is not specified
    
defaultVideoHeight270,
    
// overrides <video width>
    
pluginWidth: -1,
    
// overrides <video height>
    
pluginHeight: -1,
    
// additional plugin variables in 'key=value' form
    
pluginVars: [],    
    
// rate in milliseconds for Flash and Silverlight to fire the timeupdate event
    // larger number is less accurate, but less strain on plugin->JavaScript bridge
    
timerRate250,
    
// initial volume for player
    
startVolume0.8,
    
success: function () { },
    
error: function () { }
};

/*
Determines if a browser supports the <video> or <audio> element
and returns either the native element or a Flash/Silverlight version that
mimics HTML5 MediaElement
*/
mejs.MediaElement = function (elo) {
    return 
mejs.HtmlMediaElementShim.create(el,o);
};

mejs.HtmlMediaElementShim = {

    
create: function(elo) {
        var
            
options mejs.MediaElementDefaults,
            
htmlMediaElement = (typeof(el) == 'string') ? document.getElementById(el) : el,
            
tagName htmlMediaElement.tagName.toLowerCase(),
            
isMediaTag = (tagName === 'audio' || tagName === 'video'),
            
src = (isMediaTag) ? htmlMediaElement.getAttribute('src') : htmlMediaElement.getAttribute('href'),
            
poster htmlMediaElement.getAttribute('poster'),
            
autoplay =  htmlMediaElement.getAttribute('autoplay'),
            
preload =  htmlMediaElement.getAttribute('preload'),
            
controls =  htmlMediaElement.getAttribute('controls'),
            
playback,
            
prop;

        
// extend options
        
for (prop in o) {
            
options[prop] = o[prop];
        }

        
// clean up attributes
        
src =         (typeof src == 'undefined'     || src === null || src == '') ? null src;        
        
poster =    (typeof poster == 'undefined'     || poster === null) ? '' poster;
        
preload =     (typeof preload == 'undefined'     || preload === null || preload === 'false') ? 'none' preload;
        
autoplay =     !(typeof autoplay == 'undefined' || autoplay === null || autoplay === 'false');
        
controls =     !(typeof controls == 'undefined' || controls === null || controls === 'false');

        
// test for HTML5 and plugin capabilities
        
playback this.determinePlayback(htmlMediaElementoptionsmejs.MediaFeatures.supportsMediaTagisMediaTagsrc);
        
playback.url = (playback.url !== null) ? mejs.Utility.absolutizeUrl(playback.url) : '';

        if (
playback.method == 'native') {
            
// second fix for android
            
if (mejs.MediaFeatures.isBustedAndroid) {
                
htmlMediaElement.src playback.url;
                
htmlMediaElement.addEventListener('click', function() {
                    
htmlMediaElement.play();
                }, 
false);
            }
        
            
// add methods to native HTMLMediaElement
            
return this.updateNative(playbackoptionsautoplaypreload);
        } else if (
playback.method !== '') {
            
// create plugin to mimic HTMLMediaElement
            
            
return this.createPluginplayback,  optionsposterautoplaypreloadcontrols);
        } else {
            
// boo, no HTML5, no Flash, no Silverlight.
            
this.createErrorMessageplaybackoptionsposter );
            
            return 
this;
        }
    },
    
    
determinePlayback: function(htmlMediaElementoptionssupportsMediaTagisMediaTagsrc) {
        var
            
mediaFiles = [],
            
i,
            
j,
            
k,
            
l,
            
n,
            
type,
            
result = { method''url''htmlMediaElementhtmlMediaElementisVideo: (htmlMediaElement.tagName.toLowerCase() != 'audio')},
            
pluginName,
            
pluginVersions,
            
pluginInfo,
            
dummy,
            
media;
            
        
// STEP 1: Get URL and type from <video src> or <source src>

        // supplied type overrides <video type> and <source type>
        
if (typeof options.type != 'undefined' && options.type !== '') {
            
            
// accept either string or array of types
            
if (typeof options.type == 'string') {
                
mediaFiles.push({type:options.typeurl:src});
            } else {
                
                for (
i=0i<options.type.lengthi++) {
                    
mediaFiles.push({type:options.type[i], url:src});
                }
            }

        
// test for src attribute first
        
} else if (src !== null) {
            
type this.formatType(srchtmlMediaElement.getAttribute('type'));
            
mediaFiles.push({type:typeurl:src});

        
// then test for <source> elements
        
} else {
            
// test <source> types to see if they are usable
            
for (0htmlMediaElement.childNodes.lengthi++) {
                
htmlMediaElement.childNodes[i];
                if (
n.nodeType == && n.tagName.toLowerCase() == 'source') {
                    
src n.getAttribute('src');
                    
type this.formatType(srcn.getAttribute('type'));
                    
media n.getAttribute('media');

                    if (!
media || !window.matchMedia || (window.matchMedia && window.matchMedia(media).matches)) {
                        
mediaFiles.push({type:typeurl:src});
                    }
                }
            }
        }
        
        
// in the case of dynamicly created players
        // check for audio types
        
if (!isMediaTag && mediaFiles.length && mediaFiles[0].url !== null && this.getTypeFromFile(mediaFiles[0].url).indexOf('audio') > -1) {
            
result.isVideo false;
        }
        

        
// STEP 2: Test for playback method
        
        // special case for Android which sadly doesn't implement the canPlayType function (always returns '')
        
if (mejs.MediaFeatures.isBustedAndroid) {
            
htmlMediaElement.canPlayType = function(type) {
                return (
type.match(/video/(mp4|m4v)/gi) !== null) ? 'maybe' '';
            };
        }        
        
        
// special case for Chromium to specify natively supported video codecs (i.e. WebM and Theora) 
        
if (mejs.MediaFeatures.isChromium) { 
            
htmlMediaElement.canPlayType = function(type) { 
                return (
type.match(/video/(webm|ogv|ogg)/gi) !== null) ? 'maybe' ''
            }; 
        }

        
// test for native playback first
        
if (supportsMediaTag && (options.mode === 'auto' || options.mode === 'auto_plugin' || options.mode === 'native')  && !(mejs.MediaFeatures.isBustedNativeHTTPS && options.httpsBasicAuthSite === true)) {
                        
            if (!
isMediaTag) {

                
// create a real HTML5 Media Element 
                
dummy document.createElementresult.isVideo 'video' 'audio');            
                
htmlMediaElement.parentNode.insertBefore(dummyhtmlMediaElement);
                
htmlMediaElement.style.display 'none';
                
                
// use this one from now on
                
result.htmlMediaElement htmlMediaElement dummy;
            }
                
            for (
i=0i<mediaFiles.lengthi++) {
                
// normal check
                
if (mediaFiles[i].type == "video/m3u8" || htmlMediaElement.canPlayType(mediaFiles[i].type).replace(/no/, '') !== ''
                    
// special case for Mac/Safari 5.0.3 which answers '' to canPlayType('audio/mp3') but 'maybe' to canPlayType('audio/mpeg')
                    
|| htmlMediaElement.canPlayType(mediaFiles[i].type.replace(/mp3/,'mpeg')).replace(/no/, '') !== ''
                    
// special case for m4a supported by detecting mp4 support
                    
|| htmlMediaElement.canPlayType(mediaFiles[i].type.replace(/m4a/,'mp4')).replace(/no/, '') !== '') {
                    
result.method 'native';
                    
result.url mediaFiles[i].url;
                    break;
                }
            }            
            
            if (
result.method === 'native') {
                if (
result.url !== null) {
                    
htmlMediaElement.src result.url;
                }
            
                
// if `auto_plugin` mode, then cache the native result but try plugins.
                
if (options.mode !== 'auto_plugin') {
                    return 
result;
                }
            }
        }

        
// if native playback didn't work, then test plugins
        
if (options.mode === 'auto' || options.mode === 'auto_plugin' || options.mode === 'shim') {
            for (
i=0i<mediaFiles.lengthi++) {
                
type mediaFiles[i].type;

                
// test all plugins in order of preference [silverlight, flash]
                
for (j=0j<options.plugins.lengthj++) {

                    
pluginName options.plugins[j];
            
                    
// test version of plugin (for future features)
                    
pluginVersions mejs.plugins[pluginName];                
                    
                    for (
k=0k<pluginVersions.lengthk++) {
                        
pluginInfo pluginVersions[k];
                    
                        
// test if user has the correct plugin version
                        
                        // for youtube/vimeo
                        
if (pluginInfo.version == null || 
                            
                            
mejs.PluginDetector.hasPluginVersion(pluginNamepluginInfo.version)) {

                            
// test for plugin playback types
                            
for (l=0l<pluginInfo.types.lengthl++) {
                                
// find plugin that can play the type
                                
if (type == pluginInfo.types[l]) {
                                    
result.method pluginName;
                                    
result.url mediaFiles[i].url;
                                    return 
result;
                                }
                            }
                        }
                    }
                }
            }
        }
        
        
// at this point, being in 'auto_plugin' mode implies that we tried plugins but failed.
        // if we have native support then return that.
        
if (options.mode === 'auto_plugin' && result.method === 'native') {
            return 
result;
        }

        
// what if there's nothing to play? just grab the first available
        
if (result.method === '' && mediaFiles.length 0) {
            
result.url mediaFiles[0].url;
        }

        return 
result;
    },

    
formatType: function(urltype) {
        var 
ext;

        
// if no type is supplied, fake it with the extension
        
if (url && !type) {        
            return 
this.getTypeFromFile(url);
        } else {
            
// only return the mime part of the type in case the attribute contains the codec
            // see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-source-element
            // `video/mp4; codecs="avc1.42E01E, mp4a.40.2"` becomes `video/mp4`
            
            
if (type && ~type.indexOf(';')) {
                return 
type.substr(0type.indexOf(';')); 
            } else {
                return 
type;
            }
        }
    },
    
    
getTypeFromFile: function(url) {
        
url url.split('?')[0];
        var 
ext url.substring(url.lastIndexOf('.') + 1).toLowerCase();
        return (/(
mp4|m4v|ogg|ogv|m3u8|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' 'audio') + '/' this.getTypeFromExtension(ext);
    },
    
    
getTypeFromExtension: function(ext) {
        
        switch (
ext) {
            case 
'mp4':
            case 
'm4v':
            case 
'm4a':
                return 
'mp4';
            case 
'webm':
            case 
'webma':
            case 
'webmv':    
                return 
'webm';
            case 
'ogg':
            case 
'oga':
            case 
'ogv':    
                return 
'ogg';
            default:
                return 
ext;
        }
    },

    
createErrorMessage: function(playbackoptionsposter) {
        var 
            
htmlMediaElement playback.htmlMediaElement,
            
errorContainer document.createElement('div');
            
        
errorContainer.className 'me-cannotplay';

        try {
            
errorContainer.style.width htmlMediaElement.width 'px';
            
errorContainer.style.height htmlMediaElement.height 'px';
        } catch (
e) {}

    if (
options.customError) {
      
errorContainer.innerHTML options.customError;
    } else {
      
errorContainer.innerHTML = (poster !== '') ?
        
'<a href="' playback.url '"><img src="' poster '" width="100%" height="100%" /></a>' :
        
'<a href="' playback.url '"><span>' mejs.i18n.t('Download File') + '</span></a>';
    }

        
htmlMediaElement.parentNode.insertBefore(errorContainerhtmlMediaElement);
        
htmlMediaElement.style.display 'none';

        
options.error(htmlMediaElement);
    },

    
createPlugin:function(playbackoptionsposterautoplaypreloadcontrols) {
        var 
            
htmlMediaElement playback.htmlMediaElement,
            
width 1,
            
height 1,
            
pluginid 'me_' playback.method '_' + (mejs.meIndex++),
            
pluginMediaElement = new mejs.PluginMediaElement(pluginidplayback.methodplayback.url),
            
container document.createElement('div'),
            
specialIEContainer,
            
node,
            
initVars;

        
// copy tagName from html media element
        
pluginMediaElement.tagName htmlMediaElement.tagName

        
// copy attributes from html media element to plugin media element
        
for (var 0htmlMediaElement.attributes.lengthi++) {
            var 
attribute htmlMediaElement.attributes[i];
            if (
attribute.specified == true) {
                
pluginMediaElement.setAttribute(attribute.nameattribute.value);
            }
        }

        
// check for placement inside a <p> tag (sometimes WYSIWYG editors do this)
        
node htmlMediaElement.parentNode;
        while (
node !== null && node.tagName.toLowerCase() !== 'body' && node.parentNode != null) {
            if (
node.parentNode.tagName.toLowerCase() === 'p') {
                
node.parentNode.parentNode.insertBefore(nodenode.parentNode);
                break;
            }
            
node node.parentNode;
        }

        if (
playback.isVideo) {
            
width = (options.pluginWidth 0) ? options.pluginWidth : (options.videoWidth 0) ? options.videoWidth : (htmlMediaElement.getAttribute('width') !== null) ? htmlMediaElement.getAttribute('width') : options.defaultVideoWidth;
            
height = (options.pluginHeight 0) ? options.pluginHeight : (options.videoHeight 0) ? options.videoHeight : (htmlMediaElement.getAttribute('height') !== null) ? htmlMediaElement.getAttribute('height') : options.defaultVideoHeight;
        
            
// in case of '%' make sure it's encoded
            
width mejs.Utility.encodeUrl(width);
            
height mejs.Utility.encodeUrl(height);
        
        } else {
            if (
options.enablePluginDebug) {
                
width 320;
                
height 240;
            }
        }

        
// register plugin
        
pluginMediaElement.success options.success;
        
mejs.MediaPluginBridge.registerPluginElement(pluginidpluginMediaElementhtmlMediaElement);

        
// add container (must be added to DOM before inserting HTML for IE)
        
container.className 'me-plugin';
        
container.id pluginid '_container';
        
        if (
playback.isVideo) {
                
htmlMediaElement.parentNode.insertBefore(containerhtmlMediaElement);
        } else {
                
document.body.insertBefore(containerdocument.body.childNodes[0]);
        }

        
// flash/silverlight vars
        
initVars = [
            
'id=' pluginid,
            
'jsinitfunction=' "mejs.MediaPluginBridge.initPlugin",
            
'jscallbackfunction=' "mejs.MediaPluginBridge.fireEvent",
            
'isvideo=' + ((playback.isVideo) ? "true" "false"),
            
'autoplay=' + ((autoplay) ? "true" "false"),
            
'preload=' preload,
            
'width=' width,
            
'startvolume=' options.startVolume,
            
'timerrate=' options.timerRate,
            
'flashstreamer=' options.flashStreamer,
            
'height=' height,
            
'pseudostreamstart=' options.pseudoStreamingStartQueryParam];

        if (
playback.url !== null) {
            if (
playback.method == 'flash') {
                
initVars.push('file=' mejs.Utility.encodeUrl(playback.url));
            } else {
                
initVars.push('file=' playback.url);
            }
        }
        if (
options.enablePluginDebug) {
            
initVars.push('debug=true');
        }
        if (
options.enablePluginSmoothing) {
            
initVars.push('smoothing=true');
        }
    if (
options.enablePseudoStreaming) {
      
initVars.push('pseudostreaming=true');
    }
        if (
controls) {
            
initVars.push('controls=true'); // shows controls in the plugin if desired
        
}
        if (
options.pluginVars) {
            
initVars initVars.concat(options.pluginVars);
        }        

        switch (
playback.method) {
            case 
'silverlight':
                
container.innerHTML =
'<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="' pluginid '" name="' pluginid '" width="' width '" height="' height '" class="mejs-shim">' +
'<param name="initParams" value="' initVars.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="' options.pluginPath options.silverlightName '" />' +
'</object>';
                    break;

            case 
'flash':

                if (
mejs.MediaFeatures.isIE) {
                    
specialIEContainer document.createElement('div');
                    
container.appendChild(specialIEContainer);
                    
specialIEContainer.outerHTML =
'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
'id="' pluginid '" width="' width '" height="' height '" class="mejs-shim">' +
'<param name="movie" value="' options.pluginPath options.flashName '?x=' + (new Date()) + '" />' +
'<param name="flashvars" value="' initVars.join('&amp;') + '" />' +
'<param name="quality" value="high" />' +
'<param name="bgcolor" value="#000000" />' +
'<param name="wmode" value="transparent" />' +
'<param name="allowScriptAccess" value="always" />' +
'<param name="allowFullScreen" value="true" />' +
'<param name="scale" value="default" />' 
'</object>';

                } else {

                    
container.innerHTML =
'<embed id="' pluginid '" name="' pluginid '" ' +
'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="' options.pluginPath options.flashName '" ' +
'flashvars="' initVars.join('&') + '" ' +
'width="' width '" ' +
'height="' height '" ' +
'scale="default"' 
'class="mejs-shim"></embed>';
                }
                break;
            
            case 
'youtube':
            
                
                var 
videoId;
                
// youtu.be url from share button
                
if (playback.url.lastIndexOf("youtu.be") != -1) {
                    
videoId playback.url.substr(playback.url.lastIndexOf('/')+1);
                    if (
videoId.indexOf('?') != -1) {
                        
videoId videoId.substr(0videoId.indexOf('?'));
                    }
                }
                else {
                    
videoId playback.url.substr(playback.url.lastIndexOf('=')+1);
                }
                
youtubeSettings = {
                        
containercontainer,
                        
containerIdcontainer.id,
                        
pluginMediaElementpluginMediaElement,
                        
pluginIdpluginid,
                        
videoIdvideoId,
                        
heightheight,
                        
widthwidth    
                    
};                
                
                if (
mejs.PluginDetector.hasPluginVersion('flash', [10,0,0]) ) {
                    
mejs.YouTubeApi.createFlash(youtubeSettings);
                } else {
                    
mejs.YouTubeApi.enqueueIframe(youtubeSettings);        
                }
                
                break;
            
            
// DEMO Code. Does NOT work.
            
case 'vimeo':
                var 
player_id pluginid "_player";
                
pluginMediaElement.vimeoid playback.url.substr(playback.url.lastIndexOf('/')+1);
                
                
container.innerHTML ='<iframe src="//player.vimeo.com/video/' pluginMediaElement.vimeoid '?api=1&portrait=0&byline=0&title=0&player_id=' player_id '" width="' width +'" height="' height +'" frameborder="0" class="mejs-shim" id="' player_id '" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
                if (
typeof($f) == 'function') { // froogaloop available
                    
var player $f(container.childNodes[0]);
                    
player.addEvent('ready', function() {
                        $.
extendplayer, {
                            
playVideo: function() {
                                
player.api'play' );
                            }, 
                            
stopVideo: function() {
                                
player.api'unload' );
                            }, 
                            
pauseVideo: function() {
                                
player.api'pause' );
                            }, 
                            
seekTo: function( seconds ) {
                                
player.api'seekTo'seconds );
                            }, 
                            
setVolume: function( volume ) {
                                
player.api'setVolume'volume );
                            }, 
                            
setMuted: function( muted ) {
                                if( 
muted ) {
                                    
player.lastVolume player.api'getVolume' );
                                    
player.api'setVolume');
                                } else {
                                    
player.api'setVolume'player.lastVolume );
                                    
delete player.lastVolume;
                                }
                            }
                        });

                        function 
createEvent(playerpluginMediaElementeventNamee) {
                            var 
obj = {
                                
typeeventName,
                                
targetpluginMediaElement
                            
};
                            if (
eventName == 'timeupdate') {
                                
pluginMediaElement.currentTime obj.currentTime e.seconds;
                                
pluginMediaElement.duration obj.duration e.duration;
                            }
                            
pluginMediaElement.dispatchEvent(obj.typeobj);
                        }

                        
player.addEvent('play', function() {
                            
createEvent(playerpluginMediaElement'play');
                            
createEvent(playerpluginMediaElement'playing');
                        });

                        
player.addEvent('pause', function() {
                            
createEvent(playerpluginMediaElement'pause');
                        });

                        
player.addEvent('finish', function() {
                            
createEvent(playerpluginMediaElement'ended');
                        });

                        
player.addEvent('playProgress', function(e) {
                            
createEvent(playerpluginMediaElement'timeupdate'e);
                        });

                        
pluginMediaElement.pluginElement container;
                        
pluginMediaElement.pluginApi player;

                        
// init mejs
                        
mejs.MediaPluginBridge.initPlugin(pluginid);
                    });
                }
                else {
                    
console.warn("You need to include froogaloop for vimeo to work");
                }
                break;            
        }
        
// hide original element
        
htmlMediaElement.style.display 'none';
        
// prevent browser from autoplaying when using a plugin
        
htmlMediaElement.removeAttribute('autoplay');

        
// FYI: options.success will be fired by the MediaPluginBridge
        
        
return pluginMediaElement;
    },

    
updateNative: function(playbackoptionsautoplaypreload) {
        
        var 
htmlMediaElement playback.htmlMediaElement,
            
m;
        
        
        
// add methods to video object to bring it into parity with Flash Object
        
for (m in mejs.HtmlMediaElement) {
            
htmlMediaElement[m] = mejs.HtmlMediaElement[m];
        }

        
/*
        Chrome now supports preload="none"
        if (mejs.MediaFeatures.isChrome) {
        
            // special case to enforce preload attribute (Chrome doesn't respect this)
            if (preload === 'none' && !autoplay) {
            
                // forces the browser to stop loading (note: fails in IE9)
                htmlMediaElement.src = '';
                htmlMediaElement.load();
                htmlMediaElement.canceledPreload = true;

                htmlMediaElement.addEventListener('play',function() {
                    if (htmlMediaElement.canceledPreload) {
                        htmlMediaElement.src = playback.url;
                        htmlMediaElement.load();
                        htmlMediaElement.play();
                        htmlMediaElement.canceledPreload = false;
                    }
                }, false);
            // for some reason Chrome forgets how to autoplay sometimes.
            } else if (autoplay) {
                htmlMediaElement.load();
                htmlMediaElement.play();
            }
        }
        */

        // fire success code
        
options.success(htmlMediaElementhtmlMediaElement);
        
        return 
htmlMediaElement;
    }
};

/*
 - test on IE (object vs. embed)
 - determine when to use iframe (Firefox, Safari, Mobile) vs. Flash (Chrome, IE)
 - fullscreen?
*/

// YouTube Flash and Iframe API
mejs.YouTubeApi = {
    
isIframeStartedfalse,
    
isIframeLoadedfalse,
    
loadIframeApi: function() {
        if (!
this.isIframeStarted) {
            var 
tag document.createElement('script');
            
tag.src "//www.youtube.com/player_api";
            var 
firstScriptTag document.getElementsByTagName('script')[0];
            
firstScriptTag.parentNode.insertBefore(tagfirstScriptTag);
            
this.isIframeStarted true;
        }
    },
    
iframeQueue: [],
    
enqueueIframe: function(yt) {
        
        if (
this.isLoaded) {
            
this.createIframe(yt);
        } else {
            
this.loadIframeApi();
            
this.iframeQueue.push(yt);
        }
    },
    
createIframe: function(settings) {
        
        var
        
pluginMediaElement settings.pluginMediaElement,    
        
player = new YT.Player(settings.containerId, {
            
heightsettings.height,
            
widthsettings.width,
            
videoIdsettings.videoId,
            
playerVars: {controls:0},
            
events: {
                
'onReady': function() {
                    
                    
// hook up iframe object to MEjs
                    
settings.pluginMediaElement.pluginApi player;
                    
                    
// init mejs
                    
mejs.MediaPluginBridge.initPlugin(settings.pluginId);
                    
                    
// create timer
                    
setInterval(function() {
                        
mejs.YouTubeApi.createEvent(playerpluginMediaElement'timeupdate');
                    }, 
250);                    
                },
                
'onStateChange': function(e) {
                    
                    
mejs.YouTubeApi.handleStateChange(e.dataplayerpluginMediaElement);
                    
                }
            }
        });
    },
    
    
createEvent: function (playerpluginMediaElementeventName) {
        var 
obj = {
            
typeeventName,
            
targetpluginMediaElement
        
};

        if (
player && player.getDuration) {
            
            
// time 
            
pluginMediaElement.currentTime obj.currentTime player.getCurrentTime();
            
pluginMediaElement.duration obj.duration player.getDuration();
            
            
// state
            
obj.paused pluginMediaElement.paused;
            
obj.ended pluginMediaElement.ended;            
            
            
// sound
            
obj.muted player.isMuted();
            
obj.volume player.getVolume() / 100;
            
            
// progress
            
obj.bytesTotal player.getVideoBytesTotal();
            
obj.bufferedBytes player.getVideoBytesLoaded();
            
            
// fake the W3C buffered TimeRange
            
var bufferedTime obj.bufferedBytes obj.bytesTotal obj.duration;
            
            
obj.target.buffered obj.buffered = {
                
start: function(index) {
                    return 
0;
                },
                
end: function (index) {
                    return 
bufferedTime;
                },
                
length1
            
};

        }
        
        
// send event up the chain
        
pluginMediaElement.dispatchEvent(obj.typeobj);
    },    
    
    
iFrameReady: function() {
        
        
this.isLoaded true;
        
this.isIframeLoaded true;
        
        while (
this.iframeQueue.length 0) {
            var 
settings this.iframeQueue.pop();
            
this.createIframe(settings);
        }    
    },
    
    
// FLASH!
    
flashPlayers: {},
    
createFlash: function(settings) {
        
        
this.flashPlayers[settings.pluginId] = settings;
        
        
/*
        settings.container.innerHTML =
            '<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="//www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=' + settings.pluginId  + '&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0" ' +
                'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; " class="mejs-shim">' +
                '<param name="allowScriptAccess" value="always">' +
                '<param name="wmode" value="transparent">' +
            '</object>';
        */

        
var specialIEContainer,
            
youtubeUrl '//www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=' settings.pluginId  '&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0';
            
        if (
mejs.MediaFeatures.isIE) {
            
            
specialIEContainer document.createElement('div');
            
settings.container.appendChild(specialIEContainer);
            
specialIEContainer.outerHTML '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
'id="' settings.pluginId '" width="' settings.width '" height="' settings.height '" class="mejs-shim">' +
    
'<param name="movie" value="' youtubeUrl '" />' +
    
'<param name="wmode" value="transparent" />' +
    
'<param name="allowScriptAccess" value="always" />' +
    
'<param name="allowFullScreen" value="true" />' +
'</object>';
        } else {
        
settings.container.innerHTML =
            
'<object type="application/x-shockwave-flash" id="' settings.pluginId '" data="' youtubeUrl '" ' +
                
'width="' settings.width '" height="' settings.height '" style="visibility: visible; " class="mejs-shim">' +
                
'<param name="allowScriptAccess" value="always">' +
                
'<param name="wmode" value="transparent">' +
            
'</object>';
        }        
        
    },
    
    
flashReady: function(id) {
        var
            
settings this.flashPlayers[id],
            
player document.getElementById(id),
            
pluginMediaElement settings.pluginMediaElement;
        
        
// hook up and return to MediaELementPlayer.success    
        
pluginMediaElement.pluginApi 
        
pluginMediaElement.pluginElement player;
        
mejs.MediaPluginBridge.initPlugin(id);
        
        
// load the youtube video
        
player.cueVideoById(settings.videoId);
        
        var 
callbackName settings.containerId '_callback';
        
        
window[callbackName] = function(e) {
            
mejs.YouTubeApi.handleStateChange(eplayerpluginMediaElement);
        }
        
        
player.addEventListener('onStateChange'callbackName);
        
        
setInterval(function() {
            
mejs.YouTubeApi.createEvent(playerpluginMediaElement'timeupdate');
        }, 
250);
        
        
mejs.YouTubeApi.createEvent(playerpluginMediaElement'canplay');
    },
    
    
handleStateChange: function(youTubeStateplayerpluginMediaElement) {
        switch (
youTubeState) {
            case -
1// not started
                
pluginMediaElement.paused true;
                
pluginMediaElement.ended true;
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'loadedmetadata');
                
//createYouTubeEvent(player, pluginMediaElement, 'loadeddata');
                
break;
            case 
0:
                
pluginMediaElement.paused false;
                
pluginMediaElement.ended true;
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'ended');
                break;
            case 
1:
                
pluginMediaElement.paused false;
                
pluginMediaElement.ended false;                
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'play');
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'playing');
                break;
            case 
2:
                
pluginMediaElement.paused true;
                
pluginMediaElement.ended false;                
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'pause');
                break;
            case 
3// buffering
                
mejs.YouTubeApi.createEvent(playerpluginMediaElement'progress');
                break;
            case 
5:
                
// cued?
                
break;                        
            
        }            
        
    }
}
// IFRAME
function onYouTubePlayerAPIReady() {
    
mejs.YouTubeApi.iFrameReady();
}
// FLASH
function onYouTubePlayerReady(id) {
    
mejs.YouTubeApi.flashReady(id);
}

window.mejs mejs;
window.MediaElement mejs.MediaElement;

/*
 * Adds Internationalization and localization to mediaelement.
 *
 * This file does not contain translations, you have to add them manually.
 * The schema is always the same: me-i18n-locale-[IETF-language-tag].js
 *
 * Examples are provided both for german and chinese translation.
 *
 *
 * What is the concept beyond i18n?
 *   http://en.wikipedia.org/wiki/Internationalization_and_localization
 *
 * What langcode should i use?
 *   http://en.wikipedia.org/wiki/IETF_language_tag
 *   https://tools.ietf.org/html/rfc5646
 *
 *
 * License?
 *
 *   The i18n file uses methods from the Drupal project (drupal.js):
 *     - i18n.methods.t() (modified)
 *     - i18n.methods.checkPlain() (full copy)
 *
 *   The Drupal project is (like mediaelementjs) licensed under GPLv2.
 *    - http://drupal.org/licensing/faq/#q1
 *    - https://github.com/johndyer/mediaelement
 *    - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *
 *
 * @author
 *   Tim Latz (latz.tim@gmail.com)
 *
 *
 * @params
 *  - context - document, iframe ..
 *  - exports - CommonJS, window ..
 *
 */
;(function(contextexportsundefined) {
    
"use strict";

    var 
i18n = {
        
"locale": {
            
// Ensure previous values aren't overwritten.
            
"language" : (exports.i18n && exports.i18n.locale.language) || '',
            
"strings" : (exports.i18n && exports.i18n.locale.strings) || {}
        },
        
"ietf_lang_regex" : /^(x-)?[a-z]{2,}(-w{2,})?(-w{2,})?$/,
        
"methods" : {}
    };
// start i18n


    /**
     * Get language, fallback to browser's language if empty
     *
     * IETF: RFC 5646, https://tools.ietf.org/html/rfc5646
     * Examples: en, zh-CN, cmn-Hans-CN, sr-Latn-RS, es-419, x-private
     */
    
i18n.getLanguage = function () {
        var 
language i18n.locale.language || window.navigator.userLanguage || window.navigator.language;
        return 
i18n.ietf_lang_regex.exec(language) ? language null;

        
//(WAS: convert to iso 639-1 (2-letters, lower case))
        //return language.substr(0, 2).toLowerCase();
    
};

    
// i18n fixes for compatibility with WordPress
    
if ( typeof mejsL10n != 'undefined' ) {
        
i18n.locale.language mejsL10n.language;
    }



    
/**
     * Encode special characters in a plain-text string for display as HTML.
     */
    
i18n.methods.checkPlain = function (str) {
        var 
characterregex,
        
replace = {
            
'&''&amp;',
            
'"''&quot;',
            
'<''&lt;',
            
'>''&gt;'
        
};
        
str String(str);
        for (
character in replace) {
            if (
replace.hasOwnProperty(character)) {
                
regex = new RegExp(character'g');
                
str str.replace(regexreplace[character]);
            }
        }
        return 
str;
    };

    
/**
     * Translate strings to the page language or a given language.
     *
     *
     * @param str
     *   A string containing the English string to translate.
     *
     * @param options
     *   - 'context' (defaults to the default context): The context the source string
     *     belongs to.
     *
     * @return
     *   The translated string, escaped via i18n.methods.checkPlain()
     */
    
i18n.methods.= function (stroptions) {

        
// Fetch the localized version of the string.
        
if (i18n.locale.strings && i18n.locale.strings[options.context] && i18n.locale.strings[options.context][str]) {
            
str i18n.locale.strings[options.context][str];
        }

        return 
i18n.methods.checkPlain(str);
    };


    
/**
     * Wrapper for i18n.methods.t()
     *
     * @see i18n.methods.t()
     * @throws InvalidArgumentException
     */
    
i18n.= function(stroptions) {

        if (
typeof str === 'string' && str.length 0) {

            
// check every time due language can change for
            // different reasons (translation, lang switcher ..)
            
var language i18n.getLanguage();

            
options options || {
                
"context" language
            
};

            return 
i18n.methods.t(stroptions);
        }
        else {
            throw {
                
"name" 'InvalidArgumentException',
                
"message" 'First argument is either not a string or empty.'
            
};
        }
    };

// end i18n
    
exports.i18n i18n;
}(
documentmejs));

// i18n fixes for compatibility with WordPress
;(function(exportsundefined) {

    
"use strict";

    if ( 
typeof mejsL10n != 'undefined' ) {
        
exports[mejsL10n.language] = mejsL10n.strings;
    }

}(
mejs.i18n.locale.strings));

/*!
 *
 * MediaElementPlayer
 * http://mediaelementjs.com/
 *
 * Creates a controller bar for HTML5 <video> add <audio> tags
 * using jQuery and MediaElement.js (HTML5 Flash/Silverlight wrapper)
 *
 * Copyright 2010-2013, John Dyer (http://j.hn/)
 * License: MIT
 *
 */
if (typeof jQuery != 'undefined') {
    
mejs.$ = jQuery;
} else if (
typeof ender != 'undefined') {
    
mejs.$ = ender;
}
(function ($) {

    
// default player values
    
mejs.MepDefaults = {
        
// url to poster (to fix iOS 3.x)
        
poster'',
        
// When the video is ended, we can show the poster.
        
showPosterWhenEndedfalse,
        
// default if the <video width> is not specified
        
defaultVideoWidth480,
        
// default if the <video height> is not specified
        
defaultVideoHeight270,
        
// if set, overrides <video width>
        
videoWidth: -1,
        
// if set, overrides <video height>
        
videoHeight: -1,
        
// default if the user doesn't specify
        
defaultAudioWidth400,
        
// default if the user doesn't specify
        
defaultAudioHeight30,

        
// 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);
        },

        
// set dimensions via JS instead of CSS
        
setDimensionstrue,

        
// width of audio player
        
audioWidth: -1,
        
// height of audio player
        
audioHeight: -1,
        
// initial volume when the player starts (overrided by user cookie)
        
startVolume0.8,
        
// useful for <audio> player loops
        
loopfalse,
        
// rewind to beginning when media ends
                
autoRewindtrue,
        
// resize to media dimensions
        
enableAutosizetrue,
        
// forces the hour marker (##:00:00)
        
alwaysShowHoursfalse,

        
// show framecount in timecode (##:00:00:00)
        
showTimecodeFrameCountfalse,
        
// used when showTimecodeFrameCount is set to true
        
framesPerSecond25,

        
// 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
        
alwaysShowControlsfalse,
        
// Display the video control
        
hideVideoControlsOnLoadfalse,
        
// Enable click video element to toggle play/pause
        
clickToPlayPausetrue,
        
// force iPad's native controls
        
iPadUseNativeControlsfalse,
        
// force iPhone's native controls
        
iPhoneUseNativeControlsfalse,
        
// force Android's native controls
        
AndroidUseNativeControlsfalse,
        
// features to show
        
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
        
// only for dynamic
        
isVideotrue,

        
// turns keyboard support on and off for this instance
        
enableKeyboardtrue,

        
// whenthis player starts, it will pause other players
        
pauseOtherPlayerstrue,

        
// array of keyboard actions such as play pause
        
keyActions: [
                {
                        
keys: [
                                
32// SPACE
                                
179 // GOOGLE play/pause button
                              
],
                        
action: function(playermedia) {
                                if (
media.paused || media.ended) {
                                        
player.play();
                                } else {
                                        
player.pause();
                                }
                        }
                },
                {
                        
keys: [38], // UP
                        
action: function(playermedia) {
                                
player.container.find('.mejs-volume-slider').css('display','block');
                                if (
player.isVideo) {
                                        
player.showControls();
                                        
player.startControlsTimer();
                                }

                                var 
newVolume Math.min(media.volume 0.11);
                                
media.setVolume(newVolume);
                        }
                },
                {
                        
keys: [40], // DOWN
                        
action: function(playermedia) {
                                
player.container.find('.mejs-volume-slider').css('display','block');
                                if (
player.isVideo) {
                                        
player.showControls();
                                        
player.startControlsTimer();
                                }

                                var 
newVolume Math.max(media.volume 0.10);
                                
media.setVolume(newVolume);
                        }
                },
                {
                        
keys: [
                                
37// LEFT
                                
227 // Google TV rewind
                        
],
                        
action: function(playermedia) {
                                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(playermedia) {
                                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(playermedia) {
                                if (
typeof player.enterFullScreen != 'undefined') {
                                        if (
player.isFullScreen) {
                                                
player.exitFullScreen();
                                        } else {
                                                
player.enterFullScreen();
                                        }
                                }
                        }
                },
                {
                        
keys: [77], // M
                        
action: function(playermedia) {
                                
player.container.find('.mejs-volume-slider').css('display','block');
                                if (
player.isVideo) {
                                        
player.showControls();
                                        
player.startControlsTimer();
                                }
                                if (
player.media.muted) {
                                        
player.setMuted(false);
                                } else {
                                        
player.setMuted(true);
                                }
                        }
                }
        ]
    };

    
mejs.mepIndex 0;

    
mejs.players = {};

    
// wraps a MediaElement object in player controls
    
mejs.MediaElementPlayer = function(nodeo) {
        
// enforce object, even without "new" (via John Resig)
        
if ( !(this instanceof mejs.MediaElementPlayer) ) {
            return new 
mejs.MediaElementPlayer(nodeo);
        }

        var 
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') {
            
t.$node.data('mejsoptions');
        }

        
// extend default options
        
t.options = $.extend({},mejs.MepDefaults,o);

        
// unique ID
        
t.id 'mep_' mejs.mepIndex++;

        
// add to player array (for focus events)
        
mejs.players[t.id] = t;

        
// start up
        
t.init();

        return 
t;
    };

    
// actual player
    
mejs.MediaElementPlayer.prototype = {

        
hasFocusfalse,

        
controlsAreVisibletrue,

        
init: function() {

            var
                
this,
                
mf mejs.MediaFeatures,
                
// options for MediaElement (shim)
                
meOptions = $.extend(true, {}, t.options, {
                    
success: function(mediadomNode) { t.meReady(mediadomNode); },
                    
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.play();
                }

            } else if (
mf.isAndroid && t.options.AndroidUseNativeControls) {

                
// leave default player

            
} else {

                
// DESKTOP: use MediaElementPlayer controls

                // remove native controls
                
t.$media.removeAttr('controls');
                var 
videoPlayerTitle t.isVideo ?
                    
mejs.i18n.t('Video Player') : mejs.i18n.t('Audio Player');
                
// insert description for screen readers
                
$('<span class="mejs-offscreen">' videoPlayerTitle '</span>').insertBefore(t.$media);
                
// build container
                
t.container =
                    $(
'<div id="' t.id '" class="mejs-container ' + (mejs.MediaFeatures.svg 'svg' 'no-svg') +
                      
'" tabindex="0" role="application" aria-label="' videoPlayerTitle '">'+
                        
'<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)
                    .
focus(function ( ) {
                        if( !
t.controlsAreVisible ) {
                            
t.showControls(true);
                            var 
playButton t.container.find('.mejs-playpause-button > button');
                            
playButton.focus();
                        }
                    });

                
// 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'] > || 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'] > || 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.widtht.height);

                
// create MediaElementShim
                
meOptions.pluginWidth t.width;
                
meOptions.pluginHeight t.height;
            }

            
// create MediaElement shim
            
mejs.MediaElement(t.$media[0], meOptions);

            if (
typeof(t.container) != 'undefined' && t.controlsAreVisible){
                
// controls are shown when loaded
                
t.container.trigger('controlsshown');
            }
        },

        
showControls: function(doAnimation) {
            var 
this;

            
doAnimation typeof doAnimation == 'undefined' || doAnimation;

            if (
t.controlsAreVisible)
                return;

            if (
doAnimation) {
                
t.controls
                    
.css('visibility','visible')
                    .
stop(truetrue).fadeIn(200, function() {
                        
t.controlsAreVisible true;
                        
t.container.trigger('controlsshown');
                    });

                
// any additional controls people might add and want to hide
                
t.container.find('.mejs-control')
                    .
css('visibility','visible')
                    .
stop(truetrue).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.container.trigger('controlsshown');
            }

            
t.setControlsSize();

        },

        
hideControls: function(doAnimation) {
            var 
this;

            
doAnimation typeof doAnimation == 'undefined' || doAnimation;

            if (!
t.controlsAreVisible || t.options.alwaysShowControls || t.keyboardAction)
                return;

            if (
doAnimation) {
                
// fade out main controls
                
t.controls.stop(truetrue).fadeOut(200, function() {
                    $(
this)
                        .
css('visibility','hidden')
                        .
css('display','block');

                    
t.controlsAreVisible false;
                    
t.container.trigger('controlshidden');
                });

                
// any additional controls people might add and want to hide
                
t.container.find('.mejs-control').stop(truetrue).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;
                
t.container.trigger('controlshidden');
            }
        },

        
controlsTimernull,

        
startControlsTimer: function(timeout) {

            var 
this;

            
timeout typeof timeout != 'undefined' timeout 1500;

            
t.killControlsTimer('start');

            
t.controlsTimer setTimeout(function() {
                
//
                
t.hideControls();
                
t.killControlsTimer('hide');
            }, 
timeout);
        },

        
killControlsTimer: function(src) {

            var 
this;

            if (
t.controlsTimer !== null) {
                
clearTimeout(t.controlsTimer);
                
delete t.controlsTimer;
                
t.controlsTimer null;
            }
        },

        
controlsEnabledtrue,

        
disableControls: function() {
            var 
tthis;

            
t.killControlsTimer();
            
t.hideControls(false);
            
this.controlsEnabled false;
        },

        
enableControls: function() {
            var 
tthis;

            
t.showControls(false);

            
t.controlsEnabled true;
        },


        
// Sets up all controls and events
        
meReady: function(mediadomNode) {


            var 
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(tt.controlst.layerst.media);
                
t.buildkeyboard(tt.controlst.layerst.media);
                
t.buildoverlays(tt.controlst.layerst.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](tt.controlst.layerst.media);
                        } catch (
e) {
                            
// TODO: report control error
                            //throw e;
                            
                            
                        
}
                    }
                }

                
t.container.trigger('controlsready');

                
// reset all layers and controls
                
t.setPlayerSize(t.widtht.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 {

                        
// create callback here since it needs access to current
                        // MediaElement object
                        
t.clickToPlayPauseCallback = function() {
                            
//

                            
if (t.options.clickToPlayPause) {
                                if (
t.media.paused) {
                                    
t.play();
                                } else {
                                    
t.pause();
                                }
                            }
                        };

                        
// click to play/pause
                        
t.media.addEventListener('click't.clickToPlayPauseCallbackfalse);

                        
// 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();
                                    }
                                    if (!
t.options.alwaysShowControls) {
                                        
t.startControlsTimer(2500);
                                    }
                                }
                            })
                            .
bind('mouseleave', function () {
                                if (
t.controlsEnabled) {
                                    if (!
t.media.paused && !t.options.alwaysShowControls) {
                                        
t.startControlsTimer(1000);
                                    }
                                }
                            });
                    }

                    if(
t.options.hideVideoControlsOnLoad) {
                        
t.hideControls(false);
                    }

                    
// 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 <= && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
                                
t.setPlayerSize(e.target.videoWidthe.target.videoHeight);
                                
t.setControlsSize();
                                
t.media.setVideoSize(e.target.videoWidthe.target.videoHeight);
                            }
                        }, 
false);
                    }
                }

                
// EVENTS

                // FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
                
media.addEventListener('play', function() {
                    var 
playerIndex;

                    
// go through all other players
                    
for (playerIndex in mejs.players) {
                        var 
mejs.players[playerIndex];
                        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) {
                    if(
t.options.autoRewind) {
                        try{
                            
t.media.setCurrentTime(0);
                            
// Fixing an Android stock browser bug, where "seeked" isn't fired correctly after ending the video and jumping to the beginning
                            
window.setTimeout(function(){
                                $(
t.container).find('.mejs-overlay-loading').parent().hide();
                            }, 
20);
                        } catch (
exp) {

                        }
                    }
                    
t.media.pause();

                    if (
t.setProgressRail) {
                        
t.setProgressRail();
                    }
                    if (
t.setCurrentRail) {
                        
t.setCurrentRail();
                    }

                    if (
t.options.loop) {
                        
t.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.widtht.height);
                        
t.setControlsSize();
                    }
                }, 
false);

                
t.container.focusout(function (e) {
                    if( 
e.relatedTarget ) { //FF is working on supporting focusout https://bugzilla.mozilla.org/show_bug.cgi?id=687787
                        
var $target = $(e.relatedTarget);
                        if (
t.keyboardAction && $target.parents('.mejs-container').length === 0) {
                            
t.keyboardAction false;
                            
t.hideControls(true);
                        }
                    }
                });

                
// webkit has trouble doing this without a delay
                
setTimeout(function () {
                    
t.setPlayerSize(t.widtht.height);
                    
t.setControlsSize();
                }, 
50);

                
// adjust controls whenever window sizes (used to be in fullscreen only)
                
t.globalBind('resize', function() {

                    
// don't resize for fullscreen mode
                    
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
                        
t.setPlayerSize(t.widtht.height);
                    }

                    
// always adjust controls
                    
t.setControlsSize();
                });

                
// This is a work-around for a bug in the YouTube iFrame player, which means
                //  we can't use the play() API for the initial playback on iOS or Android;
                //  user has to start playback directly by tapping on the iFrame.
                
if (t.media.pluginType == 'youtube' && ( mf.isiOS || mf.isAndroid ) ) {
                    
t.container.find('.mejs-overlay-play').hide();
                }
            }

            
// force autoplay for HTML5
            
if (autoplay && media.pluginType == 'native') {
                
t.play();
            }


            if (
t.options.success) {

                if (
typeof t.options.success == 'string') {
                    
window[t.options.success](t.mediat.domNodet);
                } else {
                    
t.options.success(t.mediat.domNodet);
                }
            }
        },

        
handleError: function(e) {
            var 
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 
this;

            if( !
t.options.setDimensions ) {
                return 
false;
            }

            if (
typeof width != 'undefined') {
                
t.width width;
            }

            if (
typeof height != 'undefined') {
                
t.height height;
            }

            
// detect 100% mode - use currentStyle for IE since css() doesn't return percentages
            
if (t.height.toString().indexOf('%') > || t.$node.css('max-width') === '100%' || (t.$node[0].currentStyle && t.$node[0].currentStyle.maxWidth === '100%')) {

                
// do we have the native dimensions yet?
                
var nativeWidth = (function() {
                    if (
t.isVideo) {
                        if (
t.media.videoWidth && t.media.videoWidth 0) {
                            return 
t.media.videoWidth;
                        } else if (
t.media.getAttribute('width') !== null) {
                            return 
t.media.getAttribute('width');
                        } else {
                            return 
t.options.defaultVideoWidth;
                        }
                    } else {
                        return 
t.options.defaultAudioWidth;
                    }
                })();

                var 
nativeHeight = (function() {
                    if (
t.isVideo) {
                        if (
t.media.videoHeight && t.media.videoHeight 0) {
                            return 
t.media.videoHeight;
                        } else if (
t.media.getAttribute('height') !== null) {
                            return 
t.media.getAttribute('height');
                        } else {
                            return 
t.options.defaultVideoHeight;
                        }
                    } else {
                        return 
t.options.defaultAudioHeight;
                    }
                })();

                var
                    
parentWidth t.container.parent().closest(':visible').width(),
                    
parentHeight t.container.parent().closest(':visible').height(),
                    
newHeight t.isVideo || !t.options.autosizeProgress parseInt(parentWidth nativeHeight/nativeWidth10) : nativeHeight;

                
// When we use percent, the newHeight can't be calculated so we get the container height
                
if (isNaN(newHeight)) {
                    
newHeight parentHeight;
                }

                if (
t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
                    
parentWidth = $(window).width();
                    
newHeight = $(window).height();
                }

                if ( 
newHeight && parentWidth ) {

                    
// set outer container size
                    
t.container
                        
.width(parentWidth)
                        .
height(newHeight);

                    
// set native <video> or <audio> and shims
                    
t.$media.add(t.container.find('.mejs-shim'))
                        .
width('100%')
                        .
height('100%');

                    
// if shim is ready, send the size to the embeded plugin
                    
if (t.isVideo) {
                        if (
t.media.setVideoSize) {
                            
t.media.setVideoSize(parentWidthnewHeight);
                        }
                    }

                    
// 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);

            }

            
// special case for big play button so it doesn't go over the controls area
            
var playLayer t.layers.find('.mejs-overlay-play'),
                
playButton playLayer.find('.mejs-overlay-button');

            
playLayer.height(t.container.height() - t.controls.height());
            
playButton.css('margin-top''-' + (playButton.height()/t.controls.height()/2).toString() + 'px'  );

        },

        
setControlsSize: function() {
            var 
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(),
                
lastControl others.last(),
                
lastControlPosition null;

            
// skip calculation if hidden
            
if (!t.container.is(':visible') || !rail.length || !rail.is(':visible')) {
                return;
            }


            
// 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'), 10);
            }

            
// attempt to autosize
            
if (railWidth === || !railWidth) {

                
// find the size of all the other controls besides the rail
                
others.each(function() {
                    var 
$this = $(this);
                    if (
$this.css('position') != 'absolute' && $this.is(':visible')) {
                        
usedWidth += $(this).outerWidth(true);
                    }
                });

                
// fit the rail into the remaining space
                
railWidth t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
            }

            
// resize the rail,
            // but then check if the last control (say, the fullscreen button) got pushed down
            // this often happens when zoomed
            
do {
                
// outer area
                
rail.width(railWidth);
                
// dark space
                
total.width(railWidth - (total.outerWidth(true) - total.width()));

                if (
lastControl.css('position') != 'absolute') {
                    
lastControlPosition lastControl.position();
                    
railWidth--;
                }
            } while (
lastControlPosition !== null && lastControlPosition.top && railWidth 0);

            if (
t.setProgressRail)
                
t.setProgressRail();
            if (
t.setCurrentRail)
                
t.setCurrentRail();
        },


        
buildposter: function(playercontrolslayersmedia) {
            var 
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 ) {
                
t.setPoster(posterUrl);
            } else {
                
poster.hide();
            }

            
media.addEventListener('play',function() {
                
poster.hide();
            }, 
false);

            if(
player.options.showPosterWhenEnded && player.options.autoRewind){
                
media.addEventListener('ended',function() {
                    
poster.show();
                }, 
false);
            }
        },

        
setPoster: function(url) {
            var 
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);
            
posterDiv.css({'background-image' 'url(' url ')'});
        },

        
buildoverlays: function(playercontrolslayersmedia) {
            var 
this;
            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)
                .
bind('click', function() {  // Removed 'touchstart' due issues on Samsung Android devices where a tap on bigPlay started and immediately stopped the video
                    
if (t.options.clickToPlayPause) {
                        if (
media.paused) {
                            
media.play();
                        }
                    }
                });

            
/*
            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();
                
// Firing the 'canplay' event after a timeout which isn't getting fired on some Android 4.1 devices (https://github.com/johndyer/mediaelement/issues/1305)
                
if (mejs.MediaFeatures.isAndroid) {
                    
media.canplayTimeout window.setTimeout(
                        function() {
                            if (
document.createEvent) {
                                var 
evt document.createEvent('HTMLEvents');
                                
evt.initEvent('canplay'truetrue);
                                return 
media.dispatchEvent(evt);
                            }
                        }, 
300
                    
);
                }
            }, 
false);
            
media.addEventListener('canplay',function() {
                
loading.hide();
                
controls.find('.mejs-time-buffering').hide();
                
clearTimeout(media.canplayTimeout); // Clear timeout inside 'loadeddata' to prevent 'canplay' to fire twice
            
}, 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);

            
media.addEventListener('keydown', function(e) {
                
t.onkeydown(playermediae);
            }, 
false);
        },

        
buildkeyboard: function(playercontrolslayersmedia) {

                var 
this;

                
t.container.keydown(function () {
                    
t.keyboardAction true;
                });

                
// listen for key presses
                
t.globalBind('keydown', function(e) {
                    return 
t.onkeydown(playermediae);
                });


                
// check if someone clicked outside a player region, then kill its focus
                
t.globalBind('click', function(event) {
                    
player.hasFocus = $(event.target).closest('.mejs-container').length !== 0;
                });

        },
        
onkeydown: function(playermediae) {
            if (
player.hasFocus && player.options.enableKeyboard) {
                
// find a matching key
                
for (var 0il player.options.keyActions.lengthili++) {
                    var 
keyAction player.options.keyActions[i];

                    for (var 
0jl keyAction.keys.lengthjlj++) {
                        if (
e.keyCode == keyAction.keys[j]) {
                            if (
typeof(e.preventDefault) == "function"e.preventDefault();
                            
keyAction.action(playermediae.keyCode);
                            return 
false;
                        }
                    }
                }
            }

            return 
true;
        },

        
findTracks: function() {
            var 
this,
                
tracktags t.$media.find('track');

            
// store for use by plugins
            
t.tracks = [];
            
tracktags.each(function(indextrack) {

                
track = $(track);

                
t.tracks.push({
                    
srclang: (track.attr('srclang')) ? track.attr('srclang').toLowerCase() : '',
                    
srctrack.attr('src'),
                    
kindtrack.attr('kind'),
                    
labeltrack.attr('label') || '',
                    
entries: [],
                    
isLoadedfalse
                
});
            });
        },
        
changeSkin: function(className) {
            
this.container[0].className 'mejs-container ' className;
            
this.setPlayerSize(this.widththis.height);
            
this.setControlsSize();
        },
        
play: function() {
            
this.load();
            
this.media.play();
        },
        
pause: function() {
            try {
                
this.media.pause();
            } catch (
e) {}
        },
        
load: function() {
            if (!
this.isLoaded) {
                
this.media.load();
            }

            
this.isLoaded true;
        },
        
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 
thisfeatureIndexfeature;

            
// invoke features cleanup
            
for (featureIndex in t.options.features) {
                
feature t.options.features[featureIndex];
                if (
t['clean' feature]) {
                    try {
                        
t['clean' feature](t);
                    } catch (
e) {
                        
// TODO: report control error
                        //throw e;
                        //
                        //
                    
}
                }
            }

            
// grab video and put it back in place
            
if (!t.isDynamic) {
                
t.$media.prop('controls'true);
                
// detach events from the video
                // TODO: detach event listeners better than this;
                //       also detach ONLY the events attached by this plugin!
                
t.$node.clone().insertBefore(t.container).show();
                
t.$node.remove();
            } else {
                
t.$node.insertBefore(t.container);
            }

            if (
t.media.pluginType !== 'native') {
                
t.media.remove();
            }

            
// Remove the player from the mejs.players object so that pauseOtherPlayers doesn't blow up when trying to pause a non existance flash api.
            
delete mejs.players[t.id];

            if (
typeof t.container == 'object') {
                
t.container.remove();
            }
            
t.globalUnbind();
            
delete t.node.player;
        }
    };

    (function(){
        var 
rwindow = /^((after|before)print|(before)?unload|hashchange|message|o(ff|n)line|page(hide|show)|popstate|resize|storage)b/;

        function 
splitEvents(eventsid) {
            
// add player ID as an event namespace so it's easier to unbind them all later
            
var ret = {d: [], w: []};
            $.
each((events || '').split(' '), function(kv){
                var 
eventname '.' id;
                if (
eventname.indexOf('.') === 0) {
                    
ret.d.push(eventname);
                    
ret.w.push(eventname);
                }
                else {
                    
ret[rwindow.test(v) ? 'w' 'd'].push(eventname);
                }
            });
            
ret.ret.d.join(' ');
            
ret.ret.w.join(' ');
            return 
ret;
        }

        
mejs.MediaElementPlayer.prototype.globalBind = function(eventsdatacallback) {
            var 
this;
            
events splitEvents(eventst.id);
            if (
events.d) $(document).bind(events.ddatacallback);
            if (
events.w) $(window).bind(events.wdatacallback);
        };

        
mejs.MediaElementPlayer.prototype.globalUnbind = function(eventscallback) {
            var 
this;
            
events splitEvents(eventst.id);
            if (
events.d) $(document).unbind(events.dcallback);
            if (
events.w) $(window).unbind(events.wcallback);
        };
    })();

    
// turn into jQuery plugin
    
if (typeof $ != 'undefined') {
        $.fn.
mediaelementplayer = function (options) {
            if (
options === false) {
                
this.each(function () {
                    var 
player = $(this).data('mediaelementplayer');
                    if (
player) {
                        
player.remove();
                    }
                    $(
this).removeData('mediaelementplayer');
                });
            }
            else {
                
this.each(function () {
                    $(
this).data('mediaelementplayer', new mejs.MediaElementPlayer(thisoptions));
                });
            }
            return 
this;
        };


        $(
document).ready(function() {
            
// auto enable using JSON attribute
            
$('.mejs-player').mediaelementplayer();
        });
    }

    
// push out to window
    
window.MediaElementPlayer mejs.MediaElementPlayer;

})(
mejs.$);

(function($) {

    $.
extend(mejs.MepDefaults, {
        
playTextmejs.i18n.t('Play'),
        
pauseTextmejs.i18n.t('Pause')
    });

    
// PLAY/pause BUTTON
    
$.extend(MediaElementPlayer.prototype, {
        
buildplaypause: function(playercontrolslayersmedia) {
            var 
                
this,
                
op t.options,
                
play 
                $(
'<div class="mejs-button mejs-playpause-button mejs-play" >' +
                    
'<button type="button" aria-controls="' t.id '" title="' op.playText '" aria-label="' op.playText '"></button>' +
                
'</div>')
                .
appendTo(controls)
                .
click(function(e) {
                    
e.preventDefault();
                
                    if (
media.paused) {
                        
media.play();
                    } else {
                        
media.pause();
                    }
                    
                    return 
false;
                }),
                
play_btn play.find('button');


            function 
togglePlayPause(which) {
                if (
'play' === which) {
                    
play.removeClass('mejs-play').addClass('mejs-pause');
                    
play_btn.attr({
                        
'title'op.pauseText,
                        
'aria-label'op.pauseText
                    
});
                } else {
                    
play.removeClass('mejs-pause').addClass('mejs-play');
                    
play_btn.attr({
                        
'title'op.playText,
                        
'aria-label'op.playText
                    
});
                }
            };
            
togglePlayPause('pse');


            
media.addEventListener('play',function() {
                
togglePlayPause('play');
            }, 
false);
            
media.addEventListener('playing',function() {
                
togglePlayPause('play');
            }, 
false);


            
media.addEventListener('pause',function() {
                
togglePlayPause('pse');
            }, 
false);
            
media.addEventListener('paused',function() {
                
togglePlayPause('pse');
            }, 
false);
        }
    });
    
})(
mejs.$);

(function($) {

    $.
extend(mejs.MepDefaults, {
        
stopText'Stop'
    
});

    
// STOP BUTTON
    
$.extend(MediaElementPlayer.prototype, {
        
buildstop: function(playercontrolslayersmedia) {
            var 
this,
                
stop 
                $(
'<div class="mejs-button mejs-stop-button mejs-stop">' +
                    
'<button type="button" aria-controls="' t.id '" title="' t.options.stopText '" aria-label="' t.options.stopText '"></button>' +
                
'</div>')
                .
appendTo(controls)
                .
click(function() {
                    if (!
media.paused) {
                        
media.pause();
                    }
                    if (
media.currentTime 0) {
                        
media.setCurrentTime(0);
                        
media.pause();
                        
controls.find('.mejs-time-current').width('0px');
                        
controls.find('.mejs-time-handle').css('left''0px');
                        
controls.find('.mejs-time-float-current').htmlmejs.Utility.secondsToTimeCode(0) );
                        
controls.find('.mejs-currenttime').htmlmejs.Utility.secondsToTimeCode(0) );                    
                        
layers.find('.mejs-poster').show();
                    }
                });
        }
    });
    
})(
mejs.$);

(function($) {

    $.
extend(mejs.MepDefaults, {
        
progessHelpTextmejs.i18n.t(
        
'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.')
    });

    
// progress/loaded bar
    
$.extend(MediaElementPlayer.prototype, {
        
buildprogress: function(playercontrolslayersmedia) {

            $(
'<div class="mejs-time-rail">' +
                
'<a href="javascript:void(0);" class="mejs-time-total mejs-time-slider">' +
                
'<span class="mejs-offscreen">' this.options.progessHelpText '</span>' +
                
'<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>' +
                
'</a>' +
                
'</div>')
                .
appendTo(controls);
            
controls.find('.mejs-time-buffering').hide();

            var 
                
this,
                
total controls.find('.mejs-time-total'),
                
loaded  controls.find('.mejs-time-loaded'),
                
current  controls.find('.mejs-time-current'),
                
handle  controls.find('.mejs-time-handle'),
                
timefloat  controls.find('.mejs-time-float'),
                
timefloatcurrent  controls.find('.mejs-time-float-current'),
                
slider controls.find('.mejs-time-slider'),
                
handleMouseMove = function (e) {
                    
                    var 
offset total.offset(),
                        
width total.outerWidth(true),
                        
percentage 0,
                        
newTime 0,
                        
pos 0,
                        
x;
                    
                    
// mouse or touch position relative to the object
                    
if (e.originalEvent.changedTouches) {
                        
e.originalEvent.changedTouches[0].pageX;
                    }else{
                        
e.pageX;
                    }

                    if (
media.duration) {
                        if (
offset.left) {
                            
offset.left;
                        } else if (
width offset.left) {
                            
width offset.left;
                        }
                        
                        
pos offset.left;
                        
percentage = (pos width);
                        
newTime = (percentage <= 0.02) ? percentage media.duration;

                        
// seek to where the mouse is
                        
if (mouseIsDown && newTime !== media.currentTime) {
                            
media.setCurrentTime(newTime);
                        }

                        
// position floating time box
                        
if (!mejs.MediaFeatures.hasTouch) {
                                
timefloat.css('left'pos);
                                
timefloatcurrent.htmlmejs.Utility.secondsToTimeCode(newTime) );
                                
timefloat.show();
                        }
                    }
                },
                
mouseIsDown false,
                
mouseIsOver false,
                
lastKeyPressTime 0,
                
startedPaused false,
                
autoRewindInitial player.options.autoRewind;
            
// Accessibility for slider
            
var updateSlider = function (e) {

                var 
seconds media.currentTime,
                    
timeSliderText mejs.i18n.t('Time Slider'),
                    
time mejs.Utility.secondsToTimeCode(seconds),
                    
duration media.duration;

                
slider.attr({
                    
'aria-label'timeSliderText,
                    
'aria-valuemin'0,
                    
'aria-valuemax'duration,
                    
'aria-valuenow'seconds,
                    
'aria-valuetext'time,
                    
'role''slider',
                    
'tabindex'0
                
});

            };
            
            var 
restartPlayer = function () {
                var 
now = new Date();
                if (
now lastKeyPressTime >= 1000) {
                    
media.play();
                }
            };

            
slider.bind('focus', function (e) {
                
player.options.autoRewind false;
            });

            
slider.bind('blur', function (e) {
                
player.options.autoRewind autoRewindInitial;
            });

            
slider.bind('keydown', function (e) {

                if ((new 
Date() - lastKeyPressTime) >= 1000) {
                    
startedPaused media.paused;
                }

                var 
keyCode e.keyCode,
                    
duration media.duration,
                    
seekTime media.currentTime;

                switch (
keyCode) {
                case 
37// left
                    
seekTime -= 1;
                    break;
                case 
39// Right
                    
seekTime += 1;
                    break;
                case 
38// Up
                    
seekTime += Math.floor(duration 0.1);
                    break;
                case 
40// Down
                    
seekTime -= Math.floor(duration 0.1);
                    break;
                case 
36// Home
                    
seekTime 0;
                    break;
                case 
35// end
                    
seekTime duration;
                    break;
                case 
10// enter
                    
media.paused media.play() : media.pause();
                    return;
                case 
13// space
                    
media.paused media.play() : media.pause();
                    return;
                default:
                    return;
                }

                
seekTime seekTime : (seekTime >= duration duration Math.floor(seekTime));
                
lastKeyPressTime = new Date();
                if (!
startedPaused) {
                    
media.pause();
                }

                if (
seekTime media.duration && !startedPaused) {
                    
setTimeout(restartPlayer1100);
                }

                
media.setCurrentTime(seekTime);

                
e.preventDefault();
                
e.stopPropagation();
                return 
false;
            });


            
// handle clicks
            //controls.find('.mejs-time-rail').delegate('span', 'click', handleMouseMove);
            
total
                
.bind('mousedown touchstart', function (e) {
                    
// only handle left clicks or touch
                    
if (e.which === || e.which === 0) {
                        
mouseIsDown true;
                        
handleMouseMove(e);
                        
t.globalBind('mousemove.dur touchmove.dur', function(e) {
                            
handleMouseMove(e);
                        });
                        
t.globalBind('mouseup.dur touchend.dur', function (e) {
                            
mouseIsDown false;
                            
timefloat.hide();
                            
t.globalUnbind('.dur');
                        });
                    }
                })
                .
bind('mouseenter', function(e) {
                    
mouseIsOver true;
                    
t.globalBind('mousemove.dur', function(e) {
                        
handleMouseMove(e);
                    });
                    if (!
mejs.MediaFeatures.hasTouch) {
                        
timefloat.show();
                    }
                })
                .
bind('mouseleave',function(e) {
                    
mouseIsOver false;
                    if (!
mouseIsDown) {
                        
t.globalUnbind('.dur');
                        
timefloat.hide();
                    }
                });

            
// loading
            
media.addEventListener('progress', function (e) {
                
player.setProgressRail(e);
                
player.setCurrentRail(e);
            }, 
false);

            
// current time
            
media.addEventListener('timeupdate', function(e) {
                
player.setProgressRail(e);
                
player.setCurrentRail(e);
                
updateSlider(e);
            }, 
false);
            
            
            
// store for later use
            
t.loaded loaded;
            
t.total total;
            
t.current current;
            
t.handle handle;
        },
        
setProgressRail: function(e) {

            var
                
this,
                
target = (!== undefined) ? e.target t.media,
                
percent null;

            
// newest HTML5 spec has buffered array (FF4, Webkit)
            
if (target && target.buffered && target.buffered.length && target.buffered.end && target.duration) {
                
// TODO: account for a real array with multiple values (only Firefox 4 has this so far) 
                
percent target.buffered.end(0) / target.duration;
            } 
            
// Some browsers (e.g., FF3.6 and Safari 5) cannot calculate target.bufferered.end()
            // to be anything other than 0. If the byte count is available we use this instead.
            // Browsers that support the else if do not seem to have the bufferedBytes value and
            // should skip to there. Tested in Safari 5, Webkit head, FF3.6, Chrome 6, IE 7/8.
            
else if (target && target.bytesTotal !== undefined && target.bytesTotal && target.bufferedBytes !== undefined) {
                
percent target.bufferedBytes target.bytesTotal;
            }
            
// Firefox 3 with an Ogg file seems to go this way
            
else if (&& e.lengthComputable && e.total !== 0) {
                
percent e.loaded e.total;
            }

            
// finally update the progress bar
            
if (percent !== null) {
                
percent Math.min(1Math.max(0percent));
                
// update loaded bar
                
if (t.loaded && t.total) {
                    
t.loaded.width(t.total.width() * percent);
                }
            }
        },
        
setCurrentRail: function() {

            var 
this;
        
            if (
t.media.currentTime !== undefined && t.media.duration) {

                
// update bar and handle
                
if (t.total && t.handle) {
                    var 
                        
newWidth Math.round(t.total.width() * t.media.currentTime t.media.duration),
                        
handlePos newWidth Math.round(t.handle.outerWidth(true) / 2);

                    
t.current.width(newWidth);
                    
t.handle.css('left'handlePos);
                }
            }

        }
    });
})(
mejs.$);
(function($) {
    
    
// options
    
$.extend(mejs.MepDefaults, {
        
duration: -1,
        
timeAndDurationSeparator'<span> | </span>'
    
});


    
// current and duration 00:00 / 00:00
    
$.extend(MediaElementPlayer.prototype, {
        
buildcurrent: function(playercontrolslayersmedia) {
            var 
this;
            
            $(
'<div class="mejs-time" role="timer" aria-live="off">' +
                    
'<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(playercontrolslayersmedia) {
            var 
this;
            
            if (
controls.children().last().find('.mejs-currenttime').length 0) {
                $(
t.options.timeAndDurationSeparator +
                    
'<span class="mejs-duration">' 
                        (
t.options.duration 
                            
mejs.Utility.secondsToTimeCode(t.options.durationt.options.alwaysShowHours || t.media.duration 3600t.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 
                            
mejs.Utility.secondsToTimeCode(t.options.durationt.options.alwaysShowHours || t.media.duration 3600t.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 
this;

            if (
t.currenttime) {
                
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTimet.options.alwaysShowHours || t.media.duration 3600t.options.showTimecodeFrameCount,  t.options.framesPerSecond || 25));
            }
        },
        
        
updateDuration: function() {
            var 
this;

            
//Toggle the long video class if the video is longer than an hour.
            
t.container.toggleClass("mejs-long-video"t.media.duration 3600);
            
            if (
t.durationD && (t.options.duration || t.media.duration)) {
                
t.durationD.html(mejs.Utility.secondsToTimeCode(t.options.duration t.options.duration t.media.durationt.options.alwaysShowHourst.options.showTimecodeFrameCountt.options.framesPerSecond || 25));
            }        
        }
    });

})(
mejs.$);

(function($) {

    $.
extend(mejs.MepDefaults, {
        
muteTextmejs.i18n.t('Mute Toggle'),
        
allyVolumeControlTextmejs.i18n.t('Use Up/Down Arrow keys to increase or decrease volume.'),
        
hideVolumeOnTouchDevicestrue,
        
audioVolume'horizontal',
        
videoVolume'horizontal'}); ///vertical

    
$.extend(MediaElementPlayer.prototype, {
        
buildvolume: function(playercontrolslayersmedia) {
                
            
// Android and iOS don't support volume controls
            
if ((mejs.MediaFeatures.isAndroid || mejs.MediaFeatures.isiOS) && this.options.hideVolumeOnTouchDevices)
                return;
            
            var 
this,
                
mode = (t.isVideo) ? t.options.videoVolume t.options.audioVolume,
                
mute = (mode == 'horizontal') ?
                
                
// horizontal version
                
$('<div class="mejs-button mejs-volume-button mejs-mute">' +
                    
'<button type="button" aria-controls="' t.id 
                        
'" title="' t.options.muteText 
                        
'" aria-label="' t.options.muteText +
                    
'"></button>'+
                
'</div>' +
                  
'<a href="javascript:void(0);" class="mejs-horizontal-volume-slider">' // outer background
                    
'<span class="mejs-offscreen">' t.options.allyVolumeControlText '</span>' +
                    
'<div class="mejs-horizontal-volume-total"></div>'// line background
                    
'<div class="mejs-horizontal-volume-current"></div>'// current volume
                    
'<div class="mejs-horizontal-volume-handle"></div>'// handle
                
'</a>'
                
)
                    .
appendTo(controls) :
                
                
// vertical version
                
$('<div class="mejs-button mejs-volume-button mejs-mute">'+
                    
'<button type="button" aria-controls="' t.id 
                        
'" title="' t.options.muteText 
                        
'" aria-label="' t.options.muteText 
                    
'"></button>'+
                    
'<a href="javascript:void(0);" class="mejs-volume-slider">'// outer background
                        
'<span class="mejs-offscreen">' t.options.allyVolumeControlText '</span>' +                  
                        
'<div class="mejs-volume-total"></div>'// line background
                        
'<div class="mejs-volume-current"></div>'// current volume
                        
'<div class="mejs-volume-handle"></div>'// handle
                    
'</a>'+
                
'</div>')
                    .
appendTo(controls),
            
volumeSlider t.container.find('.mejs-volume-slider, .mejs-horizontal-volume-slider'),
            
volumeTotal t.container.find('.mejs-volume-total, .mejs-horizontal-volume-total'),
            
volumeCurrent t.container.find('.mejs-volume-current, .mejs-horizontal-volume-current'),
            
volumeHandle t.container.find('.mejs-volume-handle, .mejs-horizontal-volume-handle'),

            
positionVolumeHandle = function(volumesecondTry) {

                if (!
volumeSlider.is(':visible') && typeof secondTry == 'undefined') {
                    
volumeSlider.show();
                    
positionVolumeHandle(volumetrue);
                    
volumeSlider.hide();
                    return;
                }

                
// correct to 0-1
                
volume Math.max(0,volume);
                
volume Math.min(volume,1);

                
// ajust mute button style
                
if (volume === 0) {
                    
mute.removeClass('mejs-mute').addClass('mejs-unmute');
                } else {
                    
mute.removeClass('mejs-unmute').addClass('mejs-mute');
                }

                
// top/left of full size volume slider background
                
var totalPosition volumeTotal.position();
                
// position slider 
                
if (mode == 'vertical') {
                    var
                    
// height of the full size volume slider background
                        
totalHeight volumeTotal.height(),

                        
// the new top position based on the current volume
                        // 70% volume on 100px height == top:30px
                        
newTop totalHeight - (totalHeight volume);
    
                    
// handle
                    
volumeHandle.css('top'Math.round(totalPosition.top newTop - (volumeHandle.height() / 2)));
    
                    
// show the current visibility
                    
volumeCurrent.height(totalHeight newTop );
                    
volumeCurrent.css('top'totalPosition.top newTop);
                } else {
                    var
                        
// height of the full size volume slider background
                        
totalWidth volumeTotal.width(),
                        
                        
// the new left position based on the current volume
                        
newLeft totalWidth volume;
    
                    
// handle
                    
volumeHandle.css('left'Math.round(totalPosition.left newLeft - (volumeHandle.width() / 2)));
    
                    
// rezize the current part of the volume bar
                    
volumeCurrent.widthMath.round(newLeft) );
                }
            },
            
handleVolumeMove = function(e) {
                
                var 
volume null,
                    
totalOffset volumeTotal.offset();
                
                
// calculate the new volume based on the moust position
                
if (mode === 'vertical') {
                
                    var
                        
railHeight volumeTotal.height(),
                        
totalTop parseInt(volumeTotal.css('top').replace(/px/,''),10),
                        
newY e.pageY totalOffset.top;
                        
                    
volume = (railHeight newY) / railHeight;
                        
                    
// the controls just hide themselves (usually when mouse moves too far up)
                    
if (totalOffset.top === || totalOffset.left === 0) {
                        return;
                    }
                    
                } else {
                    var
                        
railWidth volumeTotal.width(),
                        
newX e.pageX totalOffset.left;
                        
                    
volume newX railWidth;
                }
                
                
// ensure the volume isn't outside 0-1
                
volume Math.max(0,volume);
                
volume Math.min(volume,1);
                
                
// position the slider and handle
                
positionVolumeHandle(volume);
                
                
// set the media object (this will trigger the volumechanged event)
                
if (volume === 0) {
                    
media.setMuted(true);
                } else {
                    
media.setMuted(false);
                }
                
media.setVolume(volume);
            },
            
mouseIsDown false,
            
mouseIsOver false;

            
// SLIDER
            
            
mute
                
.hover(function() {
                    
volumeSlider.show();
                    
mouseIsOver true;
                }, function() {
                    
mouseIsOver false;
                        
                    if (!
mouseIsDown && mode == 'vertical')    {
                        
volumeSlider.hide();
                    }
                });
            
            var 
updateVolumeSlider = function (e) {

                var 
volume Math.floor(media.volume*100);

                
volumeSlider.attr({
                    
'aria-label'mejs.i18n.t('volumeSlider'),
                    
'aria-valuemin'0,
                    
'aria-valuemax'100,
                    
'aria-valuenow'volume,
                    
'aria-valuetext'volume+'%',
                    
'role''slider',
                    
'tabindex'0
                
});

            };
            
            
volumeSlider
                
.bind('mouseover', function() {
                    
mouseIsOver true;    
                })
                .
bind('mousedown', function (e) {
                    
handleVolumeMove(e);
                    
t.globalBind('mousemove.vol', function(e) {
                        
handleVolumeMove(e);
                    });
                    
t.globalBind('mouseup.vol', function () {
                        
mouseIsDown false;
                        
t.globalUnbind('.vol');

                        if (!
mouseIsOver && mode == 'vertical') {
                            
volumeSlider.hide();
                        }
                    });
                    
mouseIsDown true;
                        
                    return 
false;
                })
                .
bind('keydown', function (e) {
                    var 
keyCode e.keyCode;
                    var 
volume media.volume;
                    switch (
keyCode) {
                        case 
38// Up
                            
volume += 0.1;
                            break;
                        case 
40// Down
                            
volume volume 0.1;
                            break;
                        default:
                            return 
true;
                    }

                    
mouseIsDown false;
                    
positionVolumeHandle(volume);
                    
media.setVolume(volume);
                    return 
false;
                })
                .
bind('blur', function () {
                    
volumeSlider.hide();
                });

            
// MUTE button
            
mute.find('button').click(function() {
                
media.setMuted( !media.muted );
            });
            
            
//Keyboard input
            
mute.find('button').bind('focus', function () {
                
volumeSlider.show();
            });

            
// listen for volume change events from other sources
            
media.addEventListener('volumechange', function(e) {
                if (!
mouseIsDown) {
                    if (
media.muted) {
                        
positionVolumeHandle(0);
                        
mute.removeClass('mejs-mute').addClass('mejs-unmute');
                    } else {
                        
positionVolumeHandle(media.volume);
                        
mute.removeClass('mejs-unmute').addClass('mejs-mute');
                    }
                }
                
updateVolumeSlider(e);
            }, 
false);

            if (
t.container.is(':visible')) {
                
// set initial volume
                
positionVolumeHandle(player.options.startVolume);

                
// mutes the media and sets the volume icon muted if the initial volume is set to 0
                
if (player.options.startVolume === 0) {
                    
media.setMuted(true);
                }

                
// shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
                
if (media.pluginType === 'native') {
                    
media.setVolume(player.options.startVolume);
                }
            }
        }
    });
    
})(
mejs.$);
(function($) {

    $.
extend(mejs.MepDefaults, {
        
usePluginFullScreentrue,
        
newWindowCallback: function() { return '';},
        
fullscreenTextmejs.i18n.t('Fullscreen')
    });

    $.
extend(MediaElementPlayer.prototype, {

        
isFullScreenfalse,

        
isNativeFullScreenfalse,

        
isInIframefalse,

        
buildfullscreen: function(playercontrolslayersmedia) {

            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 func = function(e) {
                    if (
player.isFullScreen) {
                        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();
                        }
                    }
                };

                
player.globalBind(mejs.MediaFeatures.fullScreenEventNamefunc);
            }

            var 
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 '" aria-label="' 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;
                        })();

                    
//

                    
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
                                    
for (var i in hoverDivs) {
                                        
hoverDivs[i].hide();
                                    }

                                    
// restore the control bar
                                    
fullscreenBtn.css('pointer-events''');
                                    
t.controls.css('pointer-events''');

                                    
// prevent clicks from pausing video
                                    
t.media.removeEventListener('click't.clickToPlayPauseCallback);

                                    
// store for later
                                    
fullscreenIsDisabled false;
                                }
                            },
                            
hoverDivs = {},
                            
hoverDivNames = ['top''left''right''bottom'],
                            
ilen,
                            
positionHoverDivs = function() {
                                var 
fullScreenBtnOffsetLeft fullscreenBtn.offset().left t.container.offset().left,
                                    
fullScreenBtnOffsetTop fullscreenBtn.offset().top t.container.offset().top,
                                    
fullScreenBtnWidth fullscreenBtn.outerWidth(true),
                                    
fullScreenBtnHeight fullscreenBtn.outerHeight(true),
                                    
containerWidth t.container.width(),
                                    
containerHeight t.container.height();

                                for (
i in hoverDivs) {
                                    
hoverDivs[i].css({position'absolute'top0left0}); //, backgroundColor: '#f00'});
                                
}

                                
// over video, but not controls
                                
hoverDivs['top']
                                    .
widthcontainerWidth )
                                    .
heightfullScreenBtnOffsetTop );

                                
// over controls, but not the fullscreen button
                                
hoverDivs['left']
                                    .
widthfullScreenBtnOffsetLeft )
                                    .
heightfullScreenBtnHeight )
                                    .
css({topfullScreenBtnOffsetTop});

                                
// after the fullscreen button
                                
hoverDivs['right']
                                    .
widthcontainerWidth fullScreenBtnOffsetLeft fullScreenBtnWidth )
                                    .
heightfullScreenBtnHeight )
                                    .
css({topfullScreenBtnOffsetTop,
                                         
leftfullScreenBtnOffsetLeft fullScreenBtnWidth});

                                
// under the fullscreen button
                                
hoverDivs['bottom']
                                    .
widthcontainerWidth )
                                    .
heightcontainerHeight fullScreenBtnHeight fullScreenBtnOffsetTop )
                                    .
css({topfullScreenBtnOffsetTop fullScreenBtnHeight});
                            };

                        
t.globalBind('resize', function() {
                            
positionHoverDivs();
                        });

                        for (
0len hoverDivNames.lengthleni++) {
                            
hoverDivs[hoverDivNames[i]] = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls).hide();
                        }

                        
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
                        
fullscreenBtn.on('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.leftbuttonPos.top containerPos.topfalse);

                                
// allows click through
                                
fullscreenBtn.css('pointer-events''none');
                                
t.controls.css('pointer-events''none');

                                
// restore click-to-play
                                
t.media.addEventListener('click't.clickToPlayPauseCallback);

                                
// show the divs that will restore things
                                
for (i in hoverDivs) {
                                    
hoverDivs[i].show();
                                }

                                
positionHoverDivs();

                                
fullscreenIsDisabled true;
                            }

                        });

                        
// restore controls anytime the user enters or leaves fullscreen
                        
media.addEventListener('fullscreenchange', function(e) {
                            
t.isFullScreen = !t.isFullScreen;
                            
// don't allow plugin click to pause video - messes with
                            // plugin's controls
                            
if (t.isFullScreen) {
                                
t.media.removeEventListener('click't.clickToPlayPauseCallback);
                            } else {
                                
t.media.addEventListener('click't.clickToPlayPauseCallback);
                            }
                            
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

                        
t.globalBind('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
                            
.on('mouseover', function() {

                                if (
hideTimeout !== null) {
                                    
clearTimeout(hideTimeout);
                                    
delete hideTimeout;
                                }

                                var 
buttonPos fullscreenBtn.offset(),
                                    
containerPos player.container.offset();

                                
media.positionFullscreenButton(buttonPos.left containerPos.leftbuttonPos.top containerPos.toptrue);

                            })
                            .
on('mouseout', function() {

                                if (
hideTimeout !== null) {
                                    
clearTimeout(hideTimeout);
                                    
delete hideTimeout;
                                }

                                
hideTimeout setTimeout(function() {
                                    
media.hideFullscreenButton();
                                }, 
1500);


                            });
                    }
                }

            
player.fullscreenBtn fullscreenBtn;

            
t.globalBind('keydown',function (e) {
                if (((
mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
                    
player.exitFullScreen();
                }
            });

        },

        
cleanfullscreen: function(player) {
            
player.exitFullScreen();
        },

        
containerSizeTimeoutnull,

        
enterFullScreen: function() {

            var 
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;
            }

            
// set it to not show scroll bars so 100% will work
            
$(document.documentElement).addClass('mejs-fullscreen');

            
// 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) {
                                var 
zoomMultiplier window["devicePixelRatio"] || 1;
                                
// Use a percent error margin since devicePixelRatio is a float and not exact.
                                
var percentErrorMargin 0.002// 0.2%
                                
var windowWidth zoomMultiplier * $(window).width();
                                var 
screenWidth screen.width;
                                var 
absDiff Math.abs(screenWidth windowWidth);
                                var 
marginError screenWidth percentErrorMargin;

                                
// check if the video is suddenly not really fullscreen
                                
if (absDiff marginError) {
                                    
// manually exit
                                    
t.exitFullScreen();
                                } else {
                                    
// test again
                                    
setTimeout(checkFullscreen500);
                                }
                            }


                        }, 
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(urlt.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(urlt.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) {
                
t.containerSizeTimeout setTimeout(function() {
                    
t.container.css({width'100%'height'100%'});
                    
t.setControlsSize();
                }, 
500);
            
//}

            
if (t.media.pluginType === 'native') {
                
t.$media
                    
.width('100%')
                    .
height('100%');
            } else {
                
t.container.find('.mejs-shim')
                    .
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;

            
t.container.find('.mejs-captions-text').css('font-size'screen.width t.width 1.00 100 '%');
            
t.container.find('.mejs-captions-position').css('bottom''45px');
        },

        
exitFullScreen: function() {

            var 
this;

            
// Prevent container from attempting to stretch a second time
            
clearTimeout(t.containerSizeTimeout);

            
// firefox can't adjust plugins
            
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
                
t.media.setFullscreen(false);
                
//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).removeClass('mejs-fullscreen');

            
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.media.pluginType === 'native') {
                
t.$media
                    
.width(normalWidth)
                    .
height(normalHeight);
            } else {
                
t.container.find('.mejs-shim')
                    .
width(normalWidth)
                    .
height(normalHeight);

                
t.media.setVideoSize(normalWidthnormalHeight);
            }

            
t.layers.children('div')
                .
width(normalWidth)
                .
height(normalHeight);

            
t.fullscreenBtn
                
.removeClass('mejs-unfullscreen')
                .
addClass('mejs-fullscreen');

            
t.setControlsSize();
            
t.isFullScreen false;

            
t.container.find('.mejs-captions-text').css('font-size','');
            
t.container.find('.mejs-captions-position').css('bottom''');
        }
    });

})(
mejs.$);

(function($) {

    
// Speed
    
$.extend(mejs.MepDefaults, {

        
speeds: ['2.00''1.50''1.25''1.00''0.75'],

        
defaultSpeed'1.00',
        
        
speedChar'x'

    
});

    $.
extend(MediaElementPlayer.prototype, {

        
buildspeed: function(playercontrolslayersmedia) {
            var 
this;

            if (
t.media.pluginType == 'native') {
                var 
                    
speedButton null,
                    
speedSelector null,
                    
playbackSpeed null,
                    
html '<div class="mejs-button mejs-speed-button">' 
                                
'<button type="button">' t.options.defaultSpeed t.options.speedChar '</button>' 
                                
'<div class="mejs-speed-selector">' 
                                
'<ul>';
                
                if ($.
inArray(t.options.defaultSpeedt.options.speeds) === -1) {
                    
t.options.speeds.push(t.options.defaultSpeed);
                }

                
t.options.speeds.sort(function(ab) {
                    return 
parseFloat(b) - parseFloat(a);
                });

                for (var 
0il t.options.speeds.lengthi<ili++) {
                    
html += '<li>' 
                                
'<input type="radio" name="speed" ' 
                                            
'value="' t.options.speeds[i] + '" ' 
                                            
'id="' t.options.speeds[i] + '" ' +
                                            (
t.options.speeds[i] == t.options.defaultSpeed ' checked' '') + 
                                            
' />' +
                                
'<label for="' t.options.speeds[i] + '" ' 
                                            (
t.options.speeds[i] == t.options.defaultSpeed ' class="mejs-speed-selected"' '') +
                                            
'>' t.options.speeds[i] + t.options.speedChar '</label>' 
                            
'</li>';
                }
                
html += '</ul></div></div>';

                
speedButton = $(html).appendTo(controls);
                
speedSelector speedButton.find('.mejs-speed-selector');                

                
playbackspeed t.options.defaultSpeed;

                
speedSelector
                    
.on('click''input[type="radio"]', function() {
                        var 
newSpeed = $(this).attr('value');
                        
playbackspeed newSpeed;
                        
media.playbackRate parseFloat(newSpeed);
                        
speedButton.find('button').html('test' newSpeed t.options.speedChar);
                        
speedButton.find('.mejs-speed-selected').removeClass('mejs-speed-selected');
                        
speedButton.find('input[type="radio"]:checked').next().addClass('mejs-speed-selected');
                    });

                
speedSelector
                    
.height(
                        
speedButton.find('.mejs-speed-selector ul').outerHeight(true) + 
                        
speedButton.find('.mejs-speed-translations').outerHeight(true))
                    .
css('top', (-speedSelector.height()) + 'px');
            }
        }
    });

})(
mejs.$);

(function($) {

    
// add extra default options
    
$.extend(mejs.MepDefaults, {
        
// this will automatically turn on a <track>
        
startLanguage'',

        
tracksTextmejs.i18n.t('Captions/Subtitles'),

        
// option to remove the [cc] button when no <track kind="subtitles"> are present
        
hideCaptionsButtonWhenEmptytrue,

        
// If true and we only have one track, change captions to popup
        
toggleCaptionsButtonWhenOnlyOnefalse,

        
// #id or .class
        
slidesSelector''
    
});

    $.
extend(MediaElementPlayer.prototype, {

        
hasChaptersfalse,

        
buildtracks: function(playercontrolslayersmedia) {
            if (
player.tracks.length === 0)
                return;

            var 
this,
                
i,
                
options '';

            if (
t.domNode.textTracks) { // if browser will do native captions, prefer mejs captions, loop through tracks and hide
                
for (t.domNode.textTracks.length 1>= 0i--) {
                    
t.domNode.textTracks[i].mode "hidden";
                }
            }
            
player.chapters =
                    $(
'<div class="mejs-chapters mejs-layer"></div>')
                        .
prependTo(layers).hide();
            
player.captions =
                    $(
'<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position mejs-captions-position-hover" role="log" aria-live="assertive" aria-atomic="false"><span class="mejs-captions-text"></span></div></div>')
                        .
prependTo(layers).hide();
            
player.captionsText player.captions.find('.mejs-captions-text');
            
player.captionsButton =
                    $(
'<div class="mejs-button mejs-captions-button">'+
                        
'<button type="button" aria-controls="' t.id '" title="' t.options.tracksText '" aria-label="' t.options.tracksText '"></button>'+
                        
'<div class="mejs-captions-selector">'+
                            
'<ul>'+
                                
'<li>'+
                                    
'<input type="radio" name="' player.id '_captions" id="' player.id '_captions_none" value="none" checked="checked" />' +
                                    
'<label for="' player.id '_captions_none">' mejs.i18n.t('None') +'</label>'+
                                
'</li>'    +
                            
'</ul>'+
                        
'</div>'+
                    
'</div>')
                        .
appendTo(controls);


            var 
subtitleCount 0;
            for (
i=0i<player.tracks.lengthi++) {
                if (
player.tracks[i].kind == 'subtitles') {
                    
subtitleCount++;
                }
            }

            
// if only one language then just make the button a toggle
            
if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitleCount == 1){
                
// click
                
player.captionsButton.on('click',function() {
                    if (
player.selectedTrack === null) {
                        
lang player.tracks[0].srclang;
                    } else {
                        
lang 'none';
                    }
                    
player.setTrack(lang);
                });
            } else {
                
// hover or keyboard focus
                
player.captionsButton.on'mouseenter focusin', function() {
                    $(
this).find('.mejs-captions-selector').css('visibility','visible');
                })

                
// handle clicks to the language radio buttons
                
.on('click','input[type=radio]',function() {
                    
lang this.value;
                    
player.setTrack(lang);
                });

                
player.captionsButton.on'mouseleave focusout', function() {
                    $(
this).find(".mejs-captions-selector").css("visibility","hidden");
                });

            }

            if (!
player.options.alwaysShowControls) {
                
// move with controls
                
player.container
                    
.bind('controlsshown', function () {
                        
// push captions above controls
                        
player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');

                    })
                    .
bind('controlshidden', function () {
                        if (!
media.paused) {
                            
// move back to normal place
                            
player.container.find('.mejs-captions-position').removeClass('mejs-captions-position-hover');
                        }
                    });
            } else {
                
player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');
            }

            
player.trackToLoad = -1;
            
player.selectedTrack null;
            
player.isLoadingTrack false;

            
// add to list
            
for (i=0i<player.tracks.lengthi++) {
                if (
player.tracks[i].kind == 'subtitles') {
                    
player.addTrackButton(player.tracks[i].srclangplayer.tracks[i].label);
                }
            }

            
// start loading tracks
            
player.loadNextTrack();

            
media.addEventListener('timeupdate',function(e) {
                
player.displayCaptions();
            }, 
false);

            if (
player.options.slidesSelector !== '') {
                
player.slidesContainer = $(player.options.slidesSelector);

                
media.addEventListener('timeupdate',function(e) {
                    
player.displaySlides();
                }, 
false);

            }

            
media.addEventListener('loadedmetadata', function(e) {
                
player.displayChapters();
            }, 
false);

            
player.container.hover(
                function () {
                    
// chapters
                    
if (player.hasChapters) {
                        
player.chapters.css('visibility','visible');
                        
player.chapters.fadeIn(200).height(player.chapters.find('.mejs-chapter').outerHeight());
                    }
                },
                function () {
                    if (
player.hasChapters && !media.paused) {
                        
player.chapters.fadeOut(200, function() {
                            $(
this).css('visibility','hidden');
                            $(
this).css('display','block');
                        });
                    }
                });

            
// check for autoplay
            
if (player.node.getAttribute('autoplay') !== null) {
                
player.chapters.css('visibility','hidden');
            }
        },

        
setTrack: function(lang){

            var 
this,
                
i;

            if (
lang == 'none') {
                
t.selectedTrack null;
                
t.captionsButton.removeClass('mejs-captions-enabled');
            } else {
                for (
i=0i<t.tracks.lengthi++) {
                    if (
t.tracks[i].srclang == lang) {
                        if (
t.selectedTrack === null)
                            
t.captionsButton.addClass('mejs-captions-enabled');
                        
t.selectedTrack t.tracks[i];
                        
t.captions.attr('lang't.selectedTrack.srclang);
                        
t.displayCaptions();
                        break;
                    }
                }
            }
        },

        
loadNextTrack: function() {
            var 
this;

            
t.trackToLoad++;
            if (
t.trackToLoad t.tracks.length) {
                
t.isLoadingTrack true;
                
t.loadTrack(t.trackToLoad);
            } else {
                
// add done?
                
t.isLoadingTrack false;

                
t.checkForTracks();
            }
        },

        
loadTrack: function(index){
            var
                
this,
                
track t.tracks[index],
                
after = function() {

                    
track.isLoaded true;

                    
// create button
                    //t.addTrackButton(track.srclang);
                    
t.enableTrackButton(track.srclangtrack.label);

                    
t.loadNextTrack();

                };


            $.
ajax({
                
urltrack.src,
                
dataType"text",
                
success: function(d) {

                    
// parse the loaded file
                    
if (typeof d == "string" && (/<tts+xml/ig).exec(d)) {
                        
track.entries mejs.TrackFormatParser.dfxp.parse(d);
                    } else {
                        
track.entries mejs.TrackFormatParser.webvtt.parse(d);
                    }

                    
after();

                    if (
track.kind == 'chapters') {
                        
t.media.addEventListener('play', function(e) {
                            if (
t.media.duration 0) {
                                
t.displayChapters(track);
                            }
                        }, 
false);
                    }

                    if (
track.kind == 'slides') {
                        
t.setupSlides(track);
                    }
                },
                
error: function() {
                    
t.loadNextTrack();
                }
            });
        },

        
enableTrackButton: function(langlabel) {
            var 
this;

            if (
label === '') {
                
label mejs.language.codes[lang] || lang;
            }

            
t.captionsButton
                
.find('input[value=' lang ']')
                    .
prop('disabled',false)
                .
siblings('label')
                    .
htmllabel );

            
// auto select
            
if (t.options.startLanguage == lang) {
                $(
'#' t.id '_captions_' lang).prop('checked'true).trigger('click');
            }

            
t.adjustLanguageBox();
        },

        
addTrackButton: function(langlabel) {
            var 
this;
            if (
label === '') {
                
label mejs.language.codes[lang] || lang;
            }

            
t.captionsButton.find('ul').append(
                $(
'<li>'+
                    
'<input type="radio" name="' t.id '_captions" id="' t.id '_captions_' lang '" value="' lang '" disabled="disabled" />' +
                    
'<label for="' t.id '_captions_' lang '">' label ' (loading)' '</label>'+
                
'</li>')
            );

            
t.adjustLanguageBox();

            
// remove this from the dropdownlist (if it exists)
            
t.container.find('.mejs-captions-translations option[value=' lang ']').remove();
        },

        
adjustLanguageBox:function() {
            var 
this;
            
// adjust the size of the outer box
            
t.captionsButton.find('.mejs-captions-selector').height(
                
t.captionsButton.find('.mejs-captions-selector ul').outerHeight(true) +
                
t.captionsButton.find('.mejs-captions-translations').outerHeight(true)
            );
        },

        
checkForTracks: function() {
            var
                
this,
                
hasSubtitles false;

            
// check if any subtitles
            
if (t.options.hideCaptionsButtonWhenEmpty) {
                for (
i=0i<t.tracks.lengthi++) {
                    if (
t.tracks[i].kind == 'subtitles') {
                        
hasSubtitles true;
                        break;
                    }
                }

                if (!
hasSubtitles) {
                    
t.captionsButton.hide();
                    
t.setControlsSize();
                }
            }
        },

        
displayCaptions: function() {

            if (
typeof this.tracks == 'undefined')
                return;

            var
                
this,
                
i,
                
track t.selectedTrack;

            if (
track !== null && track.isLoaded) {
                for (
i=0i<track.entries.times.lengthi++) {
                    if (
t.media.currentTime >= track.entries.times[i].start && t.media.currentTime <= track.entries.times[i].stop) {
                        
// Set the line before the timecode as a class so the cue can be targeted if needed
                        
t.captionsText.html(track.entries.text[i]).attr('class''mejs-captions-text ' + (track.entries.times[i].identifier || ''));
                        
t.captions.show().height(0);
                        return; 
// exit out if one is visible;
                    
}
                }
                
t.captions.hide();
            } else {
                
t.captions.hide();
            }
        },

        
setupSlides: function(track) {
            var 
this;

            
t.slides track;
            
t.slides.entries.imgs = [t.slides.entries.text.length];
            
t.showSlide(0);

        },

        
showSlide: function(index) {
            if (
typeof this.tracks == 'undefined' || typeof this.slidesContainer == 'undefined') {
                return;
            }

            var 
this,
                
url t.slides.entries.text[index],
                
img t.slides.entries.imgs[index];

            if (
typeof img == 'undefined' || typeof img.fadeIn == 'undefined') {

                
t.slides.entries.imgs[index] = img = $('<img src="' url '">')
                        .
on('load', function() {
                            
img.appendTo(t.slidesContainer)
                                .
hide()
                                .
fadeIn()
                                .
siblings(':visible')
                                    .
fadeOut();

                        });

            } else {

                if (!
img.is(':visible') && !img.is(':animated')) {

                    
//

                    
img.fadeIn()
                        .
siblings(':visible')
                            .
fadeOut();
                }
            }

        },

        
displaySlides: function() {

            if (
typeof this.slides == 'undefined')
                return;

            var
                
this,
                
slides t.slides,
                
i;

            for (
i=0i<slides.entries.times.lengthi++) {
                if (
t.media.currentTime >= slides.entries.times[i].start && t.media.currentTime <= slides.entries.times[i].stop){

                    
t.showSlide(i);

                    return; 
// exit out if one is visible;
                
}
            }
        },

        
displayChapters: function() {
            var
                
this,
                
i;

            for (
i=0i<t.tracks.lengthi++) {
                if (
t.tracks[i].kind == 'chapters' && t.tracks[i].isLoaded) {
                    
t.drawChapters(t.tracks[i]);
                    
t.hasChapters true;
                    break;
                }
            }
        },

        
drawChapters: function(chapters) {
            var
                
this,
                
i,
                
dur,
                
//width,
                //left,
                
percent 0,
                
usedPercent 0;

            
t.chapters.empty();

            for (
i=0i<chapters.entries.times.lengthi++) {
                
dur chapters.entries.times[i].stop chapters.entries.times[i].start;
                
percent Math.floor(dur t.media.duration 100);
                if (
percent usedPercent 100 || // too large
                    
== chapters.entries.times.length-&& percent usedPercent 100// not going to fill it in
                    
{
                    
percent 100 usedPercent;
                }
                
//width = Math.floor(t.width * dur / t.media.duration);
                //left = Math.floor(t.width * chapters.entries.times[i].start / t.media.duration);
                //if (left + width > t.width) {
                //    width = t.width - left;
                //}

                
t.chapters.append( $(
                    
'<div class="mejs-chapter" rel="' chapters.entries.times[i].start '" style="left: ' usedPercent.toString() + '%;width: ' percent.toString() + '%;">' +
                        
'<div class="mejs-chapter-block' + ((i==chapters.entries.times.length-1) ? ' mejs-chapter-block-last' '') + '">' +
                            
'<span class="ch-title">' chapters.entries.text[i] + '</span>' +
                            
'<span class="ch-time">' mejs.Utility.secondsToTimeCode(chapters.entries.times[i].start) + '&ndash;' mejs.Utility.secondsToTimeCode(chapters.entries.times[i].stop) + '</span>' +
                        
'</div>' +
                    
'</div>'));
                
usedPercent += percent;
            }

            
t.chapters.find('div.mejs-chapter').click(function() {
                
t.media.setCurrentTimeparseFloat( $(this).attr('rel') ) );
                if (
t.media.paused) {
                    
t.media.play();
                }
            });

            
t.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',
            
fl:'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',
            
// 'pt-pt':'Portuguese (Portugal)',
            
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'
        
}
    };

    
/*
    Parses WebVTT format which should be formatted as
    ================================
    WEBVTT

    1
    00:00:01,1 --> 00:00:05,000
    A line of text

    2
    00:01:15,1 --> 00:02:05,000
    A second line of text

    ===============================

    Adapted from: http://www.delphiki.com/html5/playr
    */
    
mejs.TrackFormatParser = {
        
webvtt: {
            
pattern_timecode: /^((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --> ((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,

            
parse: function(trackText) {
                var
                    
0,
                    
lines mejs.TrackFormatParser.split2(trackText, /r?n/),
                    
entries = {text:[], times:[]},
                    
timecode,
                    
text,
                    
identifier;
                for(; 
i<lines.lengthi++) {
                    
timecode this.pattern_timecode.exec(lines[i]);

                    if (
timecode && i<lines.length) {
                        if ((
1) >= && lines[1] !== '') {
                            
identifier lines[1];
                        }
                        
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(
                        {
                            
identifieridentifier,
                            
start: (mejs.Utility.convertSMPTEtoSeconds(timecode[1]) === 0) ? 0.200 mejs.Utility.convertSMPTEtoSeconds(timecode[1]),
                            
stopmejs.Utility.convertSMPTEtoSeconds(timecode[3]),
                            
settingstimecode[5]
                        });
                    }
                    
identifier '';
                }
                return 
entries;
            }
        },
        
// Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
        
dfxp: {
            
parse: function(trackText) {
                
trackText = $(trackText).filter("tt");
                var
                    
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 (
0attributes.lengthi++) {
                            
styles[attributes[i].name.split(":")[1]] = attributes[i].value;
                        }
                    }
                }

                for(
0i<lines.lengthi++) {
                    var 
style;
                    var 
_temp_times = {
                        
startnull,
                        
stopnull,
                        
stylenull
                    
};
                    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 === 0entries.times.start 2;
                }
                return 
entries;
            }
        },
        
split2: function (textregex) {
            
// normal version for compliant browsers
            // see below for IE fix
            
return text.split(regex);
        }
    };

    
// test for browsers with bad String.split method.
    
if ('xnny'.split(/n/gi).length != 3) {
        
// add super slow IE8 and below version
        
mejs.TrackFormatParser.split2 = function(textregex) {
            var
                
parts = [],
                
chunk '',
                
i;

            for (
i=0i<text.lengthi++) {
                
chunk += text.substring(i,i+1);
                if (
regex.test(chunk)) {
                    
parts.push(chunk.replace(regex''));
                    
chunk '';
                }
            }
            
parts.push(chunk);
            return 
parts;
        };
    }

})(
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 
mejs.i18n.t('Turn off Fullscreen');
                } else {
                    return 
mejs.i18n.t('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 
mejs.i18n.t('Unmute');
                } else {
                    return 
mejs.i18n.t('Mute');
                }
            },
            
click: function(player) {
                if (
player.media.muted) {
                    
player.setMuted(false);
                } else {
                    
player.setMuted(true);
                }
            }
        },
        
// separator
        
{
            
isSeparatortrue
        
}
        ,
        
// demo of simple download video
        

            
render: function(player) {
                return 
mejs.i18n.t('Download Video');
            },
            
click: function(player) {
                
window.location.href player.media.currentSrc;
            }
        }    
    ]}
);


    $.
extend(MediaElementPlayer.prototype, {
        
buildcontextmenu: function(playercontrolslayersmedia) {
            
            
// 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-1e.clientY-1);
                    return 
false;
                }
            });
            
player.container.bind('click', function() {
                
player.contextMenu.hide();
            });    
            
player.contextMenu.bind('mouseleave', function() {

                
//
                
player.startContextMenuTimer();
                
            });        
        },

        
cleancontextmenu: function(player) {
            
player.contextMenu.remove();
        },
        
        
isContextMenuEnabledtrue,
        
enableContextMenu: function() {
            
this.isContextMenuEnabled true;
        },
        
disableContextMenu: function() {
            
this.isContextMenuEnabled false;
        },
        
        
contextMenuTimeoutnull,
        
startContextMenuTimer: function() {
            
//
            
            
var this;
            
            
t.killContextMenuTimer();
            
            
t.contextMenuTimer setTimeout(function() {
                
t.hideContextMenu();
                
t.killContextMenuTimer();
            }, 
750);
        },
        
killContextMenuTimer: function() {
            var 
timer this.contextMenuTimer;
            
            
//
            
            
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 this,
                
html '',
                
items t.options.contextMenuItems;
            
            for (var 
i=0il=items.lengthi<ili++) {
                
                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="' '" id="element-' + (Math.random()*1000000) + '">' rendered '</div>';
                    }
                }
            }
            
            
// position and show the context menu
            
t.contextMenu
                
.empty()
                .
append($(html))
                .
css({top:yleft: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.$);
/**
 * Postroll plugin
 */
(function($) {

    $.
extend(mejs.MepDefaults, {
        
postrollCloseTextmejs.i18n.t('Close')
    });

    
// Postroll
    
$.extend(MediaElementPlayer.prototype, {
        
buildpostroll: function(playercontrolslayersmedia) {
            var
                
this,
                
postrollLink t.container.find('link[rel="postroll"]').attr('href');

            if (
typeof postrollLink !== 'undefined') {
                
player.postroll =
                    $(
'<div class="mejs-postroll-layer mejs-layer"><a class="mejs-postroll-close" onclick="$(this).parent().hide();return false;">' t.options.postrollCloseText '</a><div class="mejs-postroll-layer-content"></div></div>').prependTo(layers).hide();

                
t.media.addEventListener('ended', function (e) {
                    $.
ajax({
                        
dataType'html',
                        
urlpostrollLink,
                        
success: function (datatextStatus) {
                            
layers.find('.mejs-postroll-layer-content').html(data);
                        }
                    });
                    
player.postroll.show();
                }, 
false);
            }
        }
    });

})(
mejs.$);
?>
Онлайн: 0
Реклама