Вход Регистрация
Файл: contao-3.5.8/assets/jquery/mediaelement/2.19.0.1/js/mediaelement.js
Строк: 2453
<?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.19.0.1';


// 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/dailymotion''video/x-dailymotion''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;
    },
    
/*
     * Calculate the time format to use. We have a default format set in the
     * options but it can be imcomplete. We ajust it according to the media
     * duration.
     *
     * We support format like 'hh:mm:ss:ff'.
     */
    
calculateTimeFormat: function(timeoptionsfps) {
        if (
time 0) {
            
time 0;
        }

        if(
typeof fps == 'undefined') {
            
fps 25;
        }

        var 
format options.timeFormat,
            
firstChar format[0],
            
firstTwoPlaces = (format[1] == format[0]),
            
separatorIndex firstTwoPlaces21,
            
separator ':',
            
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)),
            
lis = [
                [
frames'f'],
                [
seconds's'],
                [
minutes'm'],
                [
hours'h']
            ];

        
// Try to get the separator from the format
        
if (format.length separatorIndex) {
            
separator format[separatorIndex];
        }

        var 
required false;

        for (var 
i=0len=lis.lengthleni++) {
            if (
format.indexOf(lis[i][1]) !== -1) {
                
required=true;
            }
            else if (
required) {
                var 
hasNextValue false;
                for (var 
j=ilenj++) {
                    if (
lis[j][0] > 0) {
                        
hasNextValue true;
                        break;
                    }
                }

                if (! 
hasNextValue) {
                    break;
                }

                if (!
firstTwoPlaces) {
                    
format firstChar format;
                }
                
format lis[i][1] + separator format;
                if (
firstTwoPlaces) {
                    
format lis[i][1] + format;
                }
                
firstChar lis[i][1];
            }
        }
        
options.currentTimeFormat format;
    },
    
/*
     * Prefix the given number by zero if it is lower than 10.
     */
    
twoDigitsString: function(n) {
        if (
10) {
            return 
'0' n;
        }
        return 
String(n);
    },
    
secondsToTimeCode: function(timeoptions) {
        if (
time 0) {
            
time 0;
        }

        
// Maintain backward compatibility with method signature before v2.18.
        
if (typeof options !== 'object') {
            var 
format 'm:ss';
            
format arguments[1] ? 'hh:mm:ss' format// forceHours
            
format arguments[2] ? format ':ff' format// showFrameCount

            
options = {
                
currentTimeFormatformat,
                
framesPerSecondarguments[3] || 25
            
};
        }

        var 
fps options.framesPerSecond;
        if(
typeof fps === 'undefined') {
            
fps 25;
        }

        var 
format options.currentTimeFormat,
            
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));
            
lis = [
                [
frames'f'],
                [
seconds's'],
                [
minutes'm'],
                [
hours'h']
            ];

        var 
res format;
        for (
i=0,len=lis.lengthleni++) {
            
res res.replace(lis[i][1]+lis[i][1], this.twoDigitsString(lis[i][0]));
            
res res.replace(lis[i][1], lis[i][0]);
        }
        return 
res;
    },
    
    
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.svgasimg`, sources:
        // - https://github.com/Modernizr/Modernizr/issues/687
        // - https://github.com/Modernizr/Modernizr/pull/1209/files
        
t.svgAsImg = !!document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image''1.1');

        
// 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(media.src);
                    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({type:'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 (event) {
        var 
i,
            
args,
            
callbacks this.events[event.type];

        if (
callbacks) {
            for (
0callbacks.lengthi++) {
                
callbacks[i].apply(this, [event]);
            }
        }
    },
    
// 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);
    }
};

/*
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'',
    
// set to 'always' for CDN version
    
flashScriptAccess'sameDomain',    
    
// 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 = {},
            
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 mejs.MediaElementDefaults) {
            
options[prop] = mejs.MediaElementDefaults[prop];
        }
        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.toLowerCase() == pluginInfo.types[l].toLowerCase()) {
                                    
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) {
        
// 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(),
            
av = /(mp4|m4v|ogg|ogv|m3u8|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video/' 'audio/';
        return 
this.getTypeFromExtension(extav);
    },
    
    
getTypeFromExtension: function(extav) {
        
av av || '';
        
        switch (
ext) {
            case 
'mp4':
            case 
'm4v':
            case 
'm4a':
            case 
'f4v':
            case 
'f4a':
                return 
av 'mp4';
            case 
'flv':
                return 
av 'x-flv';
            case 
'webm':
            case 
'webma':
            case 
'webmv':    
                return 
av 'webm';
            case 
'ogg':
            case 
'oga':
            case 
'ogv':    
                return 
av 'ogg';
            case 
'm3u8':
                return 
'application/x-mpegurl';
            case 
'ts':
                return 
av 'mp2t';
            default:
                return 
av ext;
        }
    },

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

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

        if (!
errorContent) {
            
errorContent '<a href="' playback.url '">';

            if (
poster !== '') {
                
errorContent += '<img src="' poster '" width="100%" height="100%" alt="" />';
            }

            
errorContent += '<span>' mejs.i18n.t('Download File') + '</span></a>';
        }

        
errorContainer.innerHTML errorContent;

        
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) {
                
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 != null && node.tagName.toLowerCase() !== 'body' && 
                
node.parentNode != null && node.parentNode.tagName != null && node.parentNode.constructor != null && node.parentNode.constructor.name === "ShadowRoot") {
            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="' options.flashScriptAccess '" />' +
'<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="' options.flashScriptAccess '" ' +
'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]) ) {
                
// favor iframe version of YouTube
                
if (window.postMessage) {
                    
mejs.YouTubeApi.enqueueIframe(youtubeSettings);
                } else if (
mejs.PluginDetector.hasPluginVersion('flash', [10,0,0]) ) {
                    
mejs.YouTubeApi.createFlash(youtubeSettingsoptions);
                }
                
                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() {
                        
                        
player.playVideo = function() {
                            
player.api'play' );
                        } 
                        
player.stopVideo = function() {
                            
player.api'unload' );
                        } 
                        
player.pauseVideo = function() {
                            
player.api'pause' );
                        } 
                        
player.seekTo = function( seconds ) {
                            
player.api'seekTo'seconds );
                        }
                        
player.setVolume = function( volume ) {
                            
player.api'setVolume'volume );
                        }
                        
player.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 
event = {
                                
typeeventName,
                                
targetpluginMediaElement
                            
};
                            if (
eventName == 'timeupdate') {
                                
pluginMediaElement.currentTime event.currentTime e.seconds;
                                
pluginMediaElement.duration event.duration e.duration;
                            }
                            
pluginMediaElement.dispatchEvent(event);
                        }

                        
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 
event = {
            
typeeventName,
            
targetpluginMediaElement
        
};

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

        }
        
        
// send event up the chain
        
pluginMediaElement.dispatchEvent(event);
    },    
    
    
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="sameDomain">' +
                '<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="' options.flashScriptAccess '" />' +
    
'<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="' options.flashScriptAccess '">' +
                
'<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
window.onYouTubePlayerAPIReady = function() {
    
mejs.YouTubeApi.iFrameReady();
};
// FLASH
window.onYouTubePlayerReady = function(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));
?>
Онлайн: 0
Реклама