0) {
+ result.url = mediaFiles[0].url;
+ }
+
+ return result;
+ },
+
+ formatType: function(url, type) {
+ 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(0, type.indexOf(';'));
+ } else {
+ return type;
+ }
+ }
+ },
+
+ getTypeFromFile: function(url) {
+ url = url.split('?')[0];
+ var ext = url.substring(url.lastIndexOf('.') + 1);
+ return (/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext);
+ },
+
+ getTypeFromExtension: function(ext) {
+
+ switch (ext) {
+ case 'mp4':
+ case 'm4v':
+ return 'mp4';
+ case 'webm':
+ case 'webma':
+ case 'webmv':
+ return 'webm';
+ case 'ogg':
+ case 'oga':
+ case 'ogv':
+ return 'ogg';
+ default:
+ return ext;
+ }
+ },
+
+ createErrorMessage: function(playback, options, poster) {
+ 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) {}
+
+ errorContainer.innerHTML = (poster !== '') ?
+ '' :
+ '' + mejs.i18n.t('Download File') + '';
+
+ htmlMediaElement.parentNode.insertBefore(errorContainer, htmlMediaElement);
+ htmlMediaElement.style.display = 'none';
+
+ options.error(htmlMediaElement);
+ },
+
+ createPlugin:function(playback, options, poster, autoplay, preload, controls) {
+ var
+ htmlMediaElement = playback.htmlMediaElement,
+ width = 1,
+ height = 1,
+ pluginid = 'me_' + playback.method + '_' + (mejs.meIndex++),
+ pluginMediaElement = new mejs.PluginMediaElement(pluginid, playback.method, playback.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 i = 0; i < htmlMediaElement.attributes.length; i++) {
+ var attribute = htmlMediaElement.attributes[i];
+ if (attribute.specified == true) {
+ pluginMediaElement.setAttribute(attribute.name, attribute.value);
+ }
+ }
+
+ // check for placement inside a tag (sometimes WYSIWYG editors do this)
+ node = htmlMediaElement.parentNode;
+ while (node !== null && node.tagName.toLowerCase() != 'body') {
+ if (node.parentNode.tagName.toLowerCase() == 'p') {
+ node.parentNode.parentNode.insertBefore(node, node.parentNode);
+ break;
+ }
+ node = node.parentNode;
+ }
+
+ if (playback.isVideo) {
+ width = (options.videoWidth > 0) ? options.videoWidth : (htmlMediaElement.getAttribute('width') !== null) ? htmlMediaElement.getAttribute('width') : options.defaultVideoWidth;
+ height = (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(pluginid, pluginMediaElement, htmlMediaElement);
+
+ // 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(container, htmlMediaElement);
+ } else {
+ document.body.insertBefore(container, document.body.childNodes[0]);
+ }
+
+ // flash/silverlight vars
+ initVars = [
+ 'id=' + pluginid,
+ 'isvideo=' + ((playback.isVideo) ? "true" : "false"),
+ 'autoplay=' + ((autoplay) ? "true" : "false"),
+ 'preload=' + preload,
+ 'width=' + width,
+ 'startvolume=' + options.startVolume,
+ 'timerrate=' + options.timerRate,
+ 'flashstreamer=' + options.flashStreamer,
+ 'height=' + height];
+
+ 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 (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 =
+'';
+ break;
+
+ case 'flash':
+
+ if (mejs.MediaFeatures.isIE) {
+ specialIEContainer = document.createElement('div');
+ container.appendChild(specialIEContainer);
+ specialIEContainer.outerHTML =
+'';
+
+ } else {
+
+ container.innerHTML =
+'';
+ }
+ break;
+
+ case 'youtube':
+
+
+ var
+ videoId = playback.url.substr(playback.url.lastIndexOf('=')+1);
+ youtubeSettings = {
+ container: container,
+ containerId: container.id,
+ pluginMediaElement: pluginMediaElement,
+ pluginId: pluginid,
+ videoId: videoId,
+ height: height,
+ width: width
+ };
+
+ 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':
+ //console.log('vimeoid');
+
+ pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1);
+
+ container.innerHTML ='';
+
+ /*
+ container.innerHTML =
+ '';
+ */
+
+ break;
+ }
+ // hide original element
+ htmlMediaElement.style.display = 'none';
+
+ // FYI: options.success will be fired by the MediaPluginBridge
+
+ return pluginMediaElement;
+ },
+
+ updateNative: function(playback, options, autoplay, preload) {
+
+ 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(htmlMediaElement, htmlMediaElement);
+
+ 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 = {
+ isIframeStarted: false,
+ isIframeLoaded: false,
+ loadIframeApi: function() {
+ if (!this.isIframeStarted) {
+ var tag = document.createElement('script');
+ tag.src = "http://www.youtube.com/player_api";
+ var firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+ 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, {
+ height: settings.height,
+ width: settings.width,
+ videoId: settings.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(player, pluginMediaElement, 'timeupdate');
+ }, 250);
+ },
+ 'onStateChange': function(e) {
+
+ mejs.YouTubeApi.handleStateChange(e.data, player, pluginMediaElement);
+
+ }
+ }
+ });
+ },
+
+ createEvent: function (player, pluginMediaElement, eventName) {
+ var obj = {
+ type: eventName,
+ target: pluginMediaElement
+ };
+
+ 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;
+ },
+ length: 1
+ };
+
+ }
+
+ // send event up the chain
+ pluginMediaElement.dispatchEvent(obj.type, obj);
+ },
+
+ 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 =
+ '';
+ */
+
+ var specialIEContainer,
+ youtubeUrl = 'http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid=' + settings.pluginId + '&version=3&autoplay=0&controls=0&modestbranding=1&loop=0';
+
+ if (mejs.MediaFeatures.isIE) {
+
+ specialIEContainer = document.createElement('div');
+ settings.container.appendChild(specialIEContainer);
+ specialIEContainer.outerHTML = '';
+ } else {
+ settings.container.innerHTML =
+ '';
+ }
+
+ },
+
+ 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(e, player, pluginMediaElement);
+ }
+
+ player.addEventListener('onStateChange', callbackName);
+
+ setInterval(function() {
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'timeupdate');
+ }, 250);
+ },
+
+ handleStateChange: function(youTubeState, player, pluginMediaElement) {
+ switch (youTubeState) {
+ case -1: // not started
+ pluginMediaElement.paused = true;
+ pluginMediaElement.ended = true;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'loadedmetadata');
+ //createYouTubeEvent(player, pluginMediaElement, 'loadeddata');
+ break;
+ case 0:
+ pluginMediaElement.paused = false;
+ pluginMediaElement.ended = true;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'ended');
+ break;
+ case 1:
+ pluginMediaElement.paused = false;
+ pluginMediaElement.ended = false;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'play');
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'playing');
+ break;
+ case 2:
+ pluginMediaElement.paused = true;
+ pluginMediaElement.ended = false;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'pause');
+ break;
+ case 3: // buffering
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, '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 objects.
+ *
+ * What is the concept beyond i18n?
+ * http://en.wikipedia.org/wiki/Internationalization_and_localization
+ *
+ *
+ * This file both i18n methods and locale which is used to translate
+ * strings into other languages.
+ *
+ * Default translations are not available, you have to add them
+ * through locale objects which are named exactly as the langcode
+ * they stand for. The default language is always english (en).
+ *
+ *
+ * Wrapper built to be able to attach the i18n object to
+ * other objects without changing more than one line.
+ *
+ *
+ * LICENSE:
+ *
+ * The i18n file uses methods from the Drupal project (drupal.js):
+ * - i18n.methods.t() (modified)
+ * - i18n.methods.checkPlain() (full copy)
+ * - i18n.methods.formatString() (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)
+ *
+ * @see
+ * me-i18n-locale.js
+ *
+ * @params
+ * - $ - zepto || jQuery ..
+ * - context - document, iframe ..
+ * - exports - CommonJS, window ..
+ *
+ */
+;(function($, context, exports, undefined) {
+ "use strict";
+ var i18n = {
+ "locale": {
+ "strings" : {}
+ },
+ "methods" : {}
+ };
+// start i18n
+
+
+ /**
+ * Get the current browser's language
+ *
+ * @see: i18n.methods.t()
+ */
+ i18n.locale.getLanguage = function () {
+ return {
+ "language" : navigator.language
+ };
+ };
+
+ /**
+ * Store the language the locale object was initialized with
+ */
+ i18n.locale.INIT_LANGUAGE = i18n.locale.getLanguage();
+
+
+ /**
+ * Encode special characters in a plain-text string for display as HTML.
+ */
+ i18n.methods.checkPlain = function (str) {
+ var character, regex,
+ replace = {
+ '&': '&',
+ '"': '"',
+ '<': '<',
+ '>': '>'
+ };
+ str = String(str);
+ for (character in replace) {
+ if (replace.hasOwnProperty(character)) {
+ regex = new RegExp(character, 'g');
+ str = str.replace(regex, replace[character]);
+ }
+ }
+ return str;
+ };
+
+ /**
+ * Replace placeholders with sanitized values in a string.
+ *
+ * @param str
+ * A string with placeholders.
+ * @param args
+ * An object of replacements pairs to make. Incidences of any key in this
+ * array are replaced with the corresponding value. Based on the first
+ * character of the key, the value is escaped and/or themed:
+ * - !variable: inserted as is
+ * - @variable: escape plain text to HTML (i18n.methods.checkPlain)
+ * - %variable: escape text and theme as a placeholder for user-submitted
+ * content (checkPlain + )
+ *
+ * @see i18n.methods.t()
+ */
+ i18n.methods.formatString = function(str, args) {
+ // Transform arguments before inserting them.
+ for (var key in args) {
+ switch (key.charAt(0)) {
+ // Escaped only.
+ case '@':
+ args[key] = i18n.methods.checkPlain(args[key]);
+ break;
+ // Pass-through.
+ case '!':
+ break;
+ // Escaped and placeholder.
+ case '%':
+ default:
+ args[key] = '' + i18n.methods.checkPlain(args[key]) + '';
+ break;
+ }
+ str = str.replace(key, args[key]);
+ }
+ return str;
+ };
+
+ /**
+ * Translate strings to the page language or a given language.
+ *
+ * See the documentation of the server-side t() function for further details.
+ *
+ * @param str
+ * A string containing the English string to translate.
+ * @param args
+ * An object of replacements pairs to make after translation. Incidences
+ * of any key in this array are replaced with the corresponding value.
+ * See i18n.methods.formatString().
+ *
+ * @param options
+ * - 'context' (defaults to the default context): The context the source string
+ * belongs to.
+ *
+ * @return
+ * The translated string.
+ */
+ i18n.methods.t = function (str, args, options) {
+
+ // 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];
+ }
+
+ if (args) {
+ str = i18n.methods.formatString(str, args);
+ }
+ return str;
+ };
+
+
+ /**
+ * Wrapper for i18n.methods.t()
+ *
+ * @see i18n.methods.t()
+ * @throws InvalidArgumentException
+ */
+ i18n.t = function(str, args, options) {
+
+ if (typeof str === 'string' && str.length > 0) {
+
+ // check every time due languge can change for
+ // different reasons (translation, lang switcher ..)
+ var lang = i18n.locale.getLanguage();
+
+ options = options || {
+ "context" : lang.language
+ };
+
+ return i18n.methods.t(str, args, options);
+ }
+ else {
+ throw {
+ "name" : 'InvalidArgumentException',
+ "message" : 'First argument is either not a string or empty.'
+ }
+ }
+ };
+
+// end i18n
+ exports.i18n = i18n;
+}(jQuery, document, mejs));
+/*!
+ * This is a i18n.locale language object.
+ *
+ * German translation by Tim Latz, latz.tim@gmail.com
+ *
+ * @author
+ * Tim Latz (latz.tim@gmail.com)
+ *
+ * @see
+ * me-i18n.js
+ *
+ * @params
+ * - exports - CommonJS, window ..
+ */
+;(function(exports, undefined) {
+
+ "use strict";
+
+ exports.de = {
+ "Fullscreen" : "Vollbild",
+ "Go Fullscreen" : "Vollbild an",
+ "Turn off Fullscreen" : "Vollbild aus",
+ "Close" : "Schließen"
+ };
+
+}(mejs.i18n.locale.strings));
+
+/*!
+ * MediaElementPlayer
+ * http://mediaelementjs.com/
+ *
+ * Creates a controller bar for HTML5