[SPIP] ~spip v3.2.0-->v3.2.1
[lhc/web/www.git] / www / plugins-dist / medias / lib / mejs / mediaelement-and-player.js
index e9d3a85..506ced4 100644 (file)
@@ -315,8 +315,8 @@ i18n.language = function () {
                        throw new TypeError('Language code must be a string value');
                }
 
-               if (!/^[a-z]{2}(\-[a-z]{2})?$/i.test(args[0])) {
-                       throw new TypeError('Language code must have format `xx` or `xx-xx`');
+               if (!/^[a-z]{2,3}((\-|_)[a-z]{2})?$/i.test(args[0])) {
+                       throw new TypeError('Language code must have format 2-3 letters and. optionally, hyphen, underscore followed by 2 more letters');
                }
 
                i18n.lang = args[0];
@@ -864,9 +864,23 @@ var MediaElement = function MediaElement(idOrNode, options, sources) {
            triggerAction = function triggerAction(methodName, args) {
                try {
                        if (methodName === 'play' && t.mediaElement.rendererName === 'native_dash') {
-                               setTimeout(function () {
-                                       t.mediaElement.renderer[methodName](args);
-                               }, 100);
+                               var response = t.mediaElement.renderer[methodName](args);
+                               if (response && typeof response.then === 'function') {
+                                       response.catch(function () {
+                                               if (t.mediaElement.paused) {
+                                                       setTimeout(function () {
+                                                               var tmpResponse = t.mediaElement.renderer.play();
+                                                               if (tmpResponse !== undefined) {
+                                                                       tmpResponse.catch(function () {
+                                                                               if (!t.mediaElement.renderer.paused) {
+                                                                                       t.mediaElement.renderer.pause();
+                                                                               }
+                                                                       });
+                                                               }
+                                                       }, 150);
+                                               }
+                                       });
+                               }
                        } else {
                                t.mediaElement.renderer[methodName](args);
                        }
@@ -947,6 +961,15 @@ var MediaElement = function MediaElement(idOrNode, options, sources) {
                }
        };
 
+       t.mediaElement.destroy = function () {
+               var mediaElement = t.mediaElement.originalNode.cloneNode(true);
+               var wrapper = t.mediaElement.parentElement;
+               mediaElement.removeAttribute('id');
+               mediaElement.remove();
+               t.mediaElement.remove();
+               wrapper.append(mediaElement);
+       };
+
        if (mediaFiles.length) {
                t.mediaElement.src = mediaFiles;
        }
@@ -975,6 +998,7 @@ var MediaElement = function MediaElement(idOrNode, options, sources) {
 };
 
 _window2.default.MediaElement = MediaElement;
+_mejs2.default.MediaElement = MediaElement;
 
 exports.default = MediaElement;
 
@@ -993,7 +1017,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
 
 var mejs = {};
 
-mejs.version = '4.2.5';
+mejs.version = '4.2.7';
 
 mejs.html5media = {
        properties: ['volume', 'src', 'currentTime', 'muted', 'duration', 'paused', 'ended', 'buffered', 'error', 'networkState', 'readyState', 'seeking', 'seekable', 'currentSrc', 'preload', 'bufferedBytes', 'bufferedTime', 'initialTime', 'startOffsetTime', 'defaultPlaybackRate', 'playbackRate', 'played', 'autoplay', 'loop', 'controls'],
@@ -1207,6 +1231,21 @@ Object.assign(_player2.default.prototype, {
 
                player.fullscreenBtn = fullscreenBtn;
 
+               t.options.keyActions.push({
+                       keys: [70],
+                       action: function action(player, media, key, event) {
+                               if (!event.ctrlKey) {
+                                       if (typeof player.enterFullScreen !== 'undefined') {
+                                               if (player.isFullScreen) {
+                                                       player.exitFullScreen();
+                                               } else {
+                                                       player.enterFullScreen();
+                                               }
+                                       }
+                               }
+                       }
+               });
+
                t.exitFullscreenCallback = function (e) {
                        var key = e.which || e.keyCode || 0;
                        if (key === 27 && (Features.HAS_TRUE_NATIVE_FULLSCREEN && Features.IS_FULLSCREEN || t.isFullScreen)) {
@@ -1261,7 +1300,7 @@ Object.assign(_player2.default.prototype, {
        enterFullScreen: function enterFullScreen() {
                var t = this,
                    isNative = t.media.rendererName !== null && /(html5|native)/i.test(t.media.rendererName),
-                   containerStyles = getComputedStyle(t.container);
+                   containerStyles = getComputedStyle(t.getElement(t.container));
 
                if (t.options.useFakeFullscreen === false && Features.IS_IOS && Features.HAS_IOS_FULLSCREEN && typeof t.media.originalNode.webkitEnterFullscreen === 'function' && t.media.originalNode.canPlayType((0, _media.getTypeFromFile)(t.media.getSrc()))) {
                        t.media.originalNode.webkitEnterFullscreen();
@@ -1269,13 +1308,13 @@ Object.assign(_player2.default.prototype, {
                }
 
                (0, _dom.addClass)(_document2.default.documentElement, t.options.classPrefix + 'fullscreen');
-               (0, _dom.addClass)(t.container, t.options.classPrefix + 'container-fullscreen');
+               (0, _dom.addClass)(t.getElement(t.container), t.options.classPrefix + 'container-fullscreen');
 
                t.normalHeight = parseFloat(containerStyles.height);
                t.normalWidth = parseFloat(containerStyles.width);
 
                if (t.fullscreenMode === 'native-native' || t.fullscreenMode === 'plugin-native') {
-                       Features.requestFullScreen(t.container);
+                       Features.requestFullScreen(t.getElement(t.container));
 
                        if (t.isInIframe) {
                                setTimeout(function checkFullscreen() {
@@ -1297,12 +1336,12 @@ Object.assign(_player2.default.prototype, {
                        }
                }
 
-               t.container.style.width = '100%';
-               t.container.style.height = '100%';
+               t.getElement(t.container).style.width = '100%';
+               t.getElement(t.container).style.height = '100%';
 
                t.containerSizeTimeout = setTimeout(function () {
-                       t.container.style.width = '100%';
-                       t.container.style.height = '100%';
+                       t.getElement(t.container).style.width = '100%';
+                       t.getElement(t.container).style.height = '100%';
                        t.setControlsSize();
                }, 500);
 
@@ -1310,7 +1349,7 @@ Object.assign(_player2.default.prototype, {
                        t.node.style.width = '100%';
                        t.node.style.height = '100%';
                } else {
-                       var elements = t.container.querySelectorAll('embed, object, video'),
+                       var elements = t.getElement(t.container).querySelectorAll('embed, object, video'),
                            _total = elements.length;
                        for (var i = 0; i < _total; i++) {
                                elements[i].style.width = '100%';
@@ -1322,7 +1361,7 @@ Object.assign(_player2.default.prototype, {
                        t.media.setSize(screen.width, screen.height);
                }
 
-               var layers = t.layers.children,
+               var layers = t.getElement(t.layers).children,
                    total = layers.length;
                for (var _i = 0; _i < total; _i++) {
                        layers[_i].style.width = '100%';
@@ -1338,14 +1377,14 @@ Object.assign(_player2.default.prototype, {
                t.isFullScreen = true;
 
                var zoomFactor = Math.min(screen.width / t.width, screen.height / t.height),
-                   captionText = t.container.querySelector('.' + t.options.classPrefix + 'captions-text');
+                   captionText = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'captions-text');
                if (captionText) {
                        captionText.style.fontSize = zoomFactor * 100 + '%';
                        captionText.style.lineHeight = 'normal';
-                       t.container.querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = '45px';
+                       t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = (screen.height - t.normalHeight) / 2 - t.getElement(t.controls).offsetHeight / 2 + zoomFactor + 15 + 'px';
                }
-               var event = (0, _general.createEvent)('enteredfullscreen', t.container);
-               t.container.dispatchEvent(event);
+               var event = (0, _general.createEvent)('enteredfullscreen', t.getElement(t.container));
+               t.getElement(t.container).dispatchEvent(event);
        },
        exitFullScreen: function exitFullScreen() {
                var t = this,
@@ -1358,17 +1397,17 @@ Object.assign(_player2.default.prototype, {
                }
 
                (0, _dom.removeClass)(_document2.default.documentElement, t.options.classPrefix + 'fullscreen');
-               (0, _dom.removeClass)(t.container, t.options.classPrefix + 'container-fullscreen');
+               (0, _dom.removeClass)(t.getElement(t.container), t.options.classPrefix + 'container-fullscreen');
 
                if (t.options.setDimensions) {
-                       t.container.style.width = t.normalWidth + 'px';
-                       t.container.style.height = t.normalHeight + 'px';
+                       t.getElement(t.container).style.width = t.normalWidth + 'px';
+                       t.getElement(t.container).style.height = t.normalHeight + 'px';
 
                        if (isNative) {
                                t.node.style.width = t.normalWidth + 'px';
                                t.node.style.height = t.normalHeight + 'px';
                        } else {
-                               var elements = t.container.querySelectorAll('embed, object, video'),
+                               var elements = t.getElement(t.container).querySelectorAll('embed, object, video'),
                                    _total2 = elements.length;
                                for (var i = 0; i < _total2; i++) {
                                        elements[i].style.width = t.normalWidth + 'px';
@@ -1380,7 +1419,7 @@ Object.assign(_player2.default.prototype, {
                                t.media.setSize(t.normalWidth, t.normalHeight);
                        }
 
-                       var layers = t.layers.children,
+                       var layers = t.getElement(t.layers).children,
                            total = layers.length;
                        for (var _i2 = 0; _i2 < total; _i2++) {
                                layers[_i2].style.width = t.normalWidth + 'px';
@@ -1396,14 +1435,14 @@ Object.assign(_player2.default.prototype, {
                t.setControlsSize();
                t.isFullScreen = false;
 
-               var captionText = t.container.querySelector('.' + t.options.classPrefix + 'captions-text');
+               var captionText = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'captions-text');
                if (captionText) {
                        captionText.style.fontSize = '';
                        captionText.style.lineHeight = '';
-                       t.container.querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = '';
+                       t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = '';
                }
-               var event = (0, _general.createEvent)('exitedfullscreen', t.container);
-               t.container.dispatchEvent(event);
+               var event = (0, _general.createEvent)('exitedfullscreen', t.getElement(t.container));
+               t.getElement(t.container).dispatchEvent(event);
        }
 });
 
@@ -1548,7 +1587,38 @@ Object.assign(_player2.default.prototype, {
 
                t.addControlElement(rail, 'progress');
 
-               controls.querySelector('.' + t.options.classPrefix + 'time-buffering').style.display = 'none';
+               t.options.keyActions.push({
+                       keys: [37, 227],
+                       action: function action(player) {
+                               if (!isNaN(player.duration) && player.duration > 0) {
+                                       if (player.isVideo) {
+                                               player.showControls();
+                                               player.startControlsTimer();
+                                       }
+
+                                       player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'time-total').focus();
+
+                                       var newTime = Math.max(player.currentTime - player.options.defaultSeekBackwardInterval(player), 0);
+                                       player.setCurrentTime(newTime);
+                               }
+                       }
+               }, {
+                       keys: [39, 228],
+                       action: function action(player) {
+
+                               if (!isNaN(player.duration) && player.duration > 0) {
+                                       if (player.isVideo) {
+                                               player.showControls();
+                                               player.startControlsTimer();
+                                       }
+
+                                       player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'time-total').focus();
+
+                                       var newTime = Math.min(player.currentTime + player.options.defaultSeekForwardInterval(player), player.duration);
+                                       player.setCurrentTime(newTime);
+                               }
+                       }
+               });
 
                t.rail = controls.querySelector('.' + t.options.classPrefix + 'time-rail');
                t.total = controls.querySelector('.' + t.options.classPrefix + 'time-total');
@@ -1559,6 +1629,7 @@ Object.assign(_player2.default.prototype, {
                t.timefloatcurrent = controls.querySelector('.' + t.options.classPrefix + 'time-float-current');
                t.slider = controls.querySelector('.' + t.options.classPrefix + 'time-slider');
                t.hovered = controls.querySelector('.' + t.options.classPrefix + 'time-hovered');
+               t.buffer = controls.querySelector('.' + t.options.classPrefix + 'time-buffering');
                t.newTime = 0;
                t.forcedHandlePause = false;
                t.setTransformStyle = function (element, value) {
@@ -1569,6 +1640,8 @@ Object.assign(_player2.default.prototype, {
                        element.style.OTransform = value;
                };
 
+               t.buffer.style.display = 'none';
+
                var handleMouseMove = function handleMouseMove(e) {
                        var totalStyles = getComputedStyle(t.total),
                            offsetStyles = (0, _dom.offset)(t.total),
@@ -1625,7 +1698,7 @@ Object.assign(_player2.default.prototype, {
                                        t.updateCurrent(t.newTime);
                                }
 
-                               if (!_constants.IS_IOS && !_constants.IS_ANDROID && t.timefloat) {
+                               if (!_constants.IS_IOS && !_constants.IS_ANDROID) {
                                        if (pos < 0) {
                                                pos = 0;
                                        }
@@ -1645,21 +1718,30 @@ Object.assign(_player2.default.prototype, {
                                                }
                                        }
 
-                                       var half = t.timefloat.offsetWidth / 2;
-                                       if (x <= t.timefloat.offsetWidth + half) {
-                                               leftPos = half;
-                                       } else if (x >= t.container.offsetWidth - half) {
-                                               leftPos = t.total.offsetWidth - half;
-                                       } else {
-                                               leftPos = pos;
-                                       }
+                                       if (t.timefloat) {
+                                               var half = t.timefloat.offsetWidth / 2,
+                                                   offsetContainer = mejs.Utils.offset(t.getElement(t.container)),
+                                                   tooltipStyles = getComputedStyle(t.timefloat);
+
+                                               if (x - offsetContainer.left < t.timefloat.offsetWidth) {
+                                                       leftPos = half;
+                                               } else if (x - offsetContainer.left >= t.getElement(t.container).offsetWidth - half) {
+                                                       leftPos = t.total.offsetWidth - half;
+                                               } else {
+                                                       leftPos = pos;
+                                               }
 
-                                       t.timefloat.style.left = leftPos + 'px';
-                                       t.timefloatcurrent.innerHTML = (0, _time.secondsToTimeCode)(t.newTime, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength);
-                                       t.timefloat.style.display = 'block';
+                                               if ((0, _dom.hasClass)(t.getElement(t.container), t.options.classPrefix + 'long-video')) {
+                                                       leftPos += parseFloat(tooltipStyles.marginLeft) / 2 + t.timefloat.offsetWidth / 2;
+                                               }
+
+                                               t.timefloat.style.left = leftPos + 'px';
+                                               t.timefloatcurrent.innerHTML = (0, _time.secondsToTimeCode)(t.newTime, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength, player.options.timeFormat);
+                                               t.timefloat.style.display = 'block';
+                                       }
                                }
                        } else if (!_constants.IS_IOS && !_constants.IS_ANDROID && t.timefloat) {
-                               leftPos = t.timefloat.offsetWidth + width >= t.container.offsetWidth ? t.timefloat.offsetWidth / 2 : 0;
+                               leftPos = t.timefloat.offsetWidth + width >= t.getElement(t.container).offsetWidth ? t.timefloat.offsetWidth / 2 : 0;
                                t.timefloat.style.left = leftPos + 'px';
                                t.timefloat.style.left = leftPos + 'px';
                                t.timefloat.style.display = 'block';
@@ -1668,7 +1750,7 @@ Object.assign(_player2.default.prototype, {
                    updateSlider = function updateSlider() {
                        var seconds = t.getCurrentTime(),
                            timeSliderText = _i18n2.default.t('mejs.time-slider'),
-                           time = (0, _time.secondsToTimeCode)(seconds, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength),
+                           time = (0, _time.secondsToTimeCode)(seconds, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength, player.options.timeFormat),
                            duration = t.getDuration();
 
                        t.slider.setAttribute('role', 'slider');
@@ -1725,16 +1807,35 @@ Object.assign(_player2.default.prototype, {
                                    seekBackward = player.options.defaultSeekBackwardInterval(media);
 
                                var seekTime = t.getCurrentTime();
+                               var volume = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-slider');
+
+                               if (keyCode === 38 || keyCode === 40) {
+                                       if (volume) {
+                                               volume.style.display = 'block';
+                                       }
+                                       if (t.isVideo) {
+                                               t.showControls();
+                                               t.startControlsTimer();
+                                       }
+
+                                       var newVolume = keyCode === 38 ? Math.min(t.volume + 0.1, 1) : Math.max(t.volume - 0.1, 0),
+                                           mutePlayer = newVolume <= 0;
+                                       t.setVolume(newVolume);
+                                       t.setMuted(mutePlayer);
+                                       return;
+                               } else {
+                                       if (volume) {
+                                               volume.style.display = 'none';
+                                       }
+                               }
 
                                switch (keyCode) {
                                        case 37:
-                                       case 40:
                                                if (t.getDuration() !== Infinity) {
                                                        seekTime -= seekBackward;
                                                }
                                                break;
                                        case 39:
-                                       case 38:
                                                if (t.getDuration() !== Infinity) {
                                                        seekTime += seekForward;
                                                }
@@ -1745,8 +1846,9 @@ Object.assign(_player2.default.prototype, {
                                        case 35:
                                                seekTime = duration;
                                                break;
+                                       case 13:
                                        case 32:
-                                               if (!_constants.IS_FIREFOX) {
+                                               if (_constants.IS_FIREFOX) {
                                                        if (t.paused) {
                                                                t.play();
                                                        } else {
@@ -1754,13 +1856,6 @@ Object.assign(_player2.default.prototype, {
                                                        }
                                                }
                                                return;
-                                       case 13:
-                                               if (t.paused) {
-                                                       t.play();
-                                               } else {
-                                                       t.pause();
-                                               }
-                                               return;
                                        default:
                                                return;
                                }
@@ -1776,6 +1871,7 @@ Object.assign(_player2.default.prototype, {
                                }
 
                                t.setCurrentTime(seekTime);
+                               player.showControls();
 
                                e.preventDefault();
                                e.stopPropagation();
@@ -1803,7 +1899,7 @@ Object.assign(_player2.default.prototype, {
                                                var endEvents = ['mouseup', 'touchend'];
 
                                                for (var j = 0, totalEvents = endEvents.length; j < totalEvents; j++) {
-                                                       t.container.addEventListener(endEvents[j], function (event) {
+                                                       t.getElement(t.container).addEventListener(endEvents[j], function (event) {
                                                                var target = event.target;
                                                                if (target === t.slider || target.closest('.' + t.options.classPrefix + 'time-slider')) {
                                                                        handleMouseMove(event);
@@ -1819,11 +1915,11 @@ Object.assign(_player2.default.prototype, {
                                                });
                                        }
                                }
-                       });
+                       }, _constants.SUPPORT_PASSIVE_EVENT && events[i] === 'touchstart' ? { passive: true } : false);
                }
                t.slider.addEventListener('mouseenter', function (e) {
                        if (e.target === t.slider && t.getDuration() !== Infinity) {
-                               t.container.addEventListener('mousemove', function (event) {
+                               t.getElement(t.container).addEventListener('mousemove', function (event) {
                                        var target = event.target;
                                        if (target === t.slider || target.closest('.' + t.options.classPrefix + 'time-slider')) {
                                                handleMouseMove(event);
@@ -1874,8 +1970,35 @@ Object.assign(_player2.default.prototype, {
 
                media.addEventListener('progress', t.broadcastCallback);
                media.addEventListener('timeupdate', t.broadcastCallback);
+               media.addEventListener('play', function () {
+                       t.buffer.style.display = 'none';
+               });
+               media.addEventListener('playing', function () {
+                       t.buffer.style.display = 'none';
+               });
+               media.addEventListener('seeking', function () {
+                       t.buffer.style.display = '';
+               });
+               media.addEventListener('seeked', function () {
+                       t.buffer.style.display = 'none';
+               });
+               media.addEventListener('pause', function () {
+                       t.buffer.style.display = 'none';
+               });
+               media.addEventListener('waiting', function () {
+                       t.buffer.style.display = '';
+               });
+               media.addEventListener('loadeddata', function () {
+                       t.buffer.style.display = '';
+               });
+               media.addEventListener('canplay', function () {
+                       t.buffer.style.display = 'none';
+               });
+               media.addEventListener('error', function () {
+                       t.buffer.style.display = 'none';
+               });
 
-               t.container.addEventListener('controlsresize', function (e) {
+               t.getElement(t.container).addEventListener('controlsresize', function (e) {
                        if (t.getDuration() !== Infinity) {
                                player.setProgressRail(e);
                                if (!t.forcedHandlePause) {
@@ -1936,7 +2059,7 @@ Object.assign(_player2.default.prototype, {
                                t.setTransformStyle(t.handle, 'translateX(' + handlePos + 'px)');
 
                                if (t.options.useSmoothHover && !(0, _dom.hasClass)(t.hovered, 'no-hover')) {
-                                       var pos = parseInt(t.hovered.getAttribute('pos'));
+                                       var pos = parseInt(t.hovered.getAttribute('pos'), 10);
                                        pos = isNaN(pos) ? 0 : pos;
 
                                        var hoverScaleX = pos / tW - handlePos / tW;
@@ -1986,9 +2109,10 @@ Object.assign(_player2.default.prototype, {
                time.className = t.options.classPrefix + 'time';
                time.setAttribute('role', 'timer');
                time.setAttribute('aria-live', 'off');
-               time.innerHTML = '<span class="' + t.options.classPrefix + 'currenttime">' + (0, _time.secondsToTimeCode)(0, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength) + '</span>';
+               time.innerHTML = '<span class="' + t.options.classPrefix + 'currenttime">' + (0, _time.secondsToTimeCode)(0, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength, player.options.timeFormat) + '</span>';
 
                t.addControlElement(time, 'current');
+               player.updateCurrent();
                t.updateTimeCallback = function () {
                        if (t.controlsAreVisible) {
                                player.updateCurrent();
@@ -2004,7 +2128,7 @@ Object.assign(_player2.default.prototype, {
                    currTime = controls.lastChild.querySelector('.' + t.options.classPrefix + 'currenttime');
 
                if (currTime) {
-                       controls.querySelector('.' + t.options.classPrefix + 'time').innerHTML += t.options.timeAndDurationSeparator + '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength) + '</span>');
+                       controls.querySelector('.' + t.options.classPrefix + 'time').innerHTML += t.options.timeAndDurationSeparator + '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength, t.options.timeFormat) + '</span>');
                } else {
                        if (controls.querySelector('.' + t.options.classPrefix + 'currenttime')) {
                                (0, _dom.addClass)(controls.querySelector('.' + t.options.classPrefix + 'currenttime').parentNode, t.options.classPrefix + 'currenttime-container');
@@ -2012,15 +2136,21 @@ Object.assign(_player2.default.prototype, {
 
                        var duration = _document2.default.createElement('div');
                        duration.className = t.options.classPrefix + 'time ' + t.options.classPrefix + 'duration-container';
-                       duration.innerHTML = '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength) + '</span>');
+                       duration.innerHTML = '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength, t.options.timeFormat) + '</span>');
 
                        t.addControlElement(duration, 'duration');
                }
 
-               media.addEventListener('timeupdate', t.updateTimeCallback);
+               t.updateDurationCallback = function () {
+                       if (t.controlsAreVisible) {
+                               player.updateDuration();
+                       }
+               };
+
+               media.addEventListener('timeupdate', t.updateDurationCallback);
        },
        cleanduration: function cleanduration(player, controls, layers, media) {
-               media.removeEventListener('timeupdate', player.updateTimeCallback);
+               media.removeEventListener('timeupdate', player.updateDurationCallback);
        },
        updateCurrent: function updateCurrent() {
                var t = this;
@@ -2031,16 +2161,16 @@ Object.assign(_player2.default.prototype, {
                        currentTime = 0;
                }
 
-               var timecode = (0, _time.secondsToTimeCode)(currentTime, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength);
+               var timecode = (0, _time.secondsToTimeCode)(currentTime, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength, t.options.timeFormat);
 
                if (timecode.length > 5) {
-                       (0, _dom.addClass)(t.container, t.options.classPrefix + 'long-video');
+                       (0, _dom.addClass)(t.getElement(t.container), t.options.classPrefix + 'long-video');
                } else {
-                       (0, _dom.removeClass)(t.container, t.options.classPrefix + 'long-video');
+                       (0, _dom.removeClass)(t.getElement(t.container), t.options.classPrefix + 'long-video');
                }
 
-               if (t.controls.querySelector('.' + t.options.classPrefix + 'currenttime')) {
-                       t.controls.querySelector('.' + t.options.classPrefix + 'currenttime').innerText = timecode;
+               if (t.getElement(t.controls).querySelector('.' + t.options.classPrefix + 'currenttime')) {
+                       t.getElement(t.controls).querySelector('.' + t.options.classPrefix + 'currenttime').innerText = timecode;
                }
        },
        updateDuration: function updateDuration() {
@@ -2056,16 +2186,16 @@ Object.assign(_player2.default.prototype, {
                        duration = t.options.duration;
                }
 
-               var timecode = (0, _time.secondsToTimeCode)(duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength);
+               var timecode = (0, _time.secondsToTimeCode)(duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength, t.options.timeFormat);
 
                if (timecode.length > 5) {
-                       (0, _dom.addClass)(t.container, t.options.classPrefix + 'long-video');
+                       (0, _dom.addClass)(t.getElement(t.container), t.options.classPrefix + 'long-video');
                } else {
-                       (0, _dom.removeClass)(t.container, t.options.classPrefix + 'long-video');
+                       (0, _dom.removeClass)(t.getElement(t.container), t.options.classPrefix + 'long-video');
                }
 
-               if (t.controls.querySelector('.' + t.options.classPrefix + 'duration') && duration > 0) {
-                       t.controls.querySelector('.' + t.options.classPrefix + 'duration').innerHTML = timecode;
+               if (t.getElement(t.controls).querySelector('.' + t.options.classPrefix + 'duration') && duration > 0) {
+                       t.getElement(t.controls).querySelector('.' + t.options.classPrefix + 'duration').innerHTML = timecode;
                }
        }
 });
@@ -2118,6 +2248,8 @@ Object.assign(_player2.default.prototype, {
 
        buildtracks: function buildtracks(player, controls, layers, media) {
 
+               this.findTracks();
+
                if (!player.tracks.length && (!player.trackFiles || !player.trackFiles.length === 0)) {
                        return;
                }
@@ -2187,12 +2319,13 @@ Object.assign(_player2.default.prototype, {
                    outEvents = ['mouseleave', 'focusout'];
 
                if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitleCount === 1) {
-                       player.captionsButton.addEventListener('click', function () {
+                       player.captionsButton.addEventListener('click', function (e) {
                                var trackId = 'none';
                                if (player.selectedTrack === null) {
                                        trackId = player.tracks[0].trackId;
                                }
-                               player.setTrack(trackId);
+                               var keyboard = e.keyCode || e.which;
+                               player.setTrack(trackId, typeof keyboard !== 'undefined');
                        });
                } else {
                        var labels = player.captionsButton.querySelectorAll('.' + t.options.classPrefix + 'captions-selector-label'),
@@ -2211,18 +2344,20 @@ Object.assign(_player2.default.prototype, {
                        }
 
                        for (var _i5 = 0, _total3 = captions.length; _i5 < _total3; _i5++) {
-                               captions[_i5].addEventListener('click', function () {
-                                       player.setTrack(this.value);
+                               captions[_i5].addEventListener('click', function (e) {
+                                       var keyboard = e.keyCode || e.which;
+                                       player.setTrack(this.value, typeof keyboard !== 'undefined');
                                });
                        }
 
                        for (var _i6 = 0, _total4 = labels.length; _i6 < _total4; _i6++) {
-                               labels[_i6].addEventListener('click', function () {
+                               labels[_i6].addEventListener('click', function (e) {
                                        var radio = (0, _dom.siblings)(this, function (el) {
                                                return el.tagName === 'INPUT';
                                        })[0],
                                            event = (0, _general.createEvent)('click', radio);
                                        radio.dispatchEvent(event);
+                                       e.preventDefault();
                                });
                        }
 
@@ -2250,17 +2385,17 @@ Object.assign(_player2.default.prototype, {
                });
 
                if (!player.options.alwaysShowControls) {
-                       player.container.addEventListener('controlsshown', function () {
-                               (0, _dom.addClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
+                       player.getElement(player.container).addEventListener('controlsshown', function () {
+                               (0, _dom.addClass)(player.getElement(player.container).querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
                        });
 
-                       player.container.addEventListener('controlshidden', function () {
+                       player.getElement(player.container).addEventListener('controlshidden', function () {
                                if (!media.paused) {
-                                       (0, _dom.removeClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
+                                       (0, _dom.removeClass)(player.getElement(player.container).querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
                                }
                        });
                } else {
-                       (0, _dom.addClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
+                       (0, _dom.addClass)(player.getElement(player.container).querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
                }
 
                media.addEventListener('timeupdate', function () {
@@ -2297,7 +2432,7 @@ Object.assign(_player2.default.prototype, {
        rebuildtracks: function rebuildtracks() {
                var t = this;
                t.findTracks();
-               t.buildtracks(t, t.controls, t.layers, t.media);
+               t.buildtracks(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
        },
        findTracks: function findTracks() {
                var t = this,
@@ -2320,7 +2455,7 @@ Object.assign(_player2.default.prototype, {
                        });
                }
        },
-       setTrack: function setTrack(trackId) {
+       setTrack: function setTrack(trackId, setByKeyboard) {
 
                var t = this,
                    radios = t.captionsButton.querySelectorAll('input[type="radio"]'),
@@ -2364,6 +2499,12 @@ Object.assign(_player2.default.prototype, {
                var event = (0, _general.createEvent)('captionschange', t.media);
                event.detail.caption = t.selectedTrack;
                t.media.dispatchEvent(event);
+
+               if (!setByKeyboard) {
+                       setTimeout(function () {
+                               t.getElement(t.container).focus();
+                       }, 500);
+               }
        },
        loadNextTrack: function loadNextTrack() {
                var t = this;
@@ -2590,7 +2731,7 @@ Object.assign(_player2.default.prototype, {
                for (var _i13 = 0, _total10 = radios.length; _i13 < _total10; _i13++) {
                        radios[_i13].disabled = false;
                        radios[_i13].checked = false;
-                       radios[_i13].addEventListener('click', function () {
+                       radios[_i13].addEventListener('click', function (e) {
                                var self = this,
                                    listItems = t.chaptersButton.querySelectorAll('li'),
                                    label = (0, _dom.siblings)(self, function (el) {
@@ -2606,6 +2747,13 @@ Object.assign(_player2.default.prototype, {
                                        listItems[_i14].setAttribute('aria-checked', false);
                                }
 
+                               var keyboard = e.keyCode || e.which;
+                               if (typeof keyboard === 'undefined') {
+                                       setTimeout(function () {
+                                               t.getElement(t.container).focus();
+                                       }, 500);
+                               }
+
                                t.media.setCurrentTime(parseFloat(self.value));
                                if (t.media.paused) {
                                        t.media.play();
@@ -2614,12 +2762,13 @@ Object.assign(_player2.default.prototype, {
                }
 
                for (var _i15 = 0, _total12 = labels.length; _i15 < _total12; _i15++) {
-                       labels[_i15].addEventListener('click', function () {
+                       labels[_i15].addEventListener('click', function (e) {
                                var radio = (0, _dom.siblings)(this, function (el) {
                                        return el.tagName === 'INPUT';
                                })[0],
                                    event = (0, _general.createEvent)('click', radio);
                                radio.dispatchEvent(event);
+                               e.preventDefault();
                        });
                }
        },
@@ -2870,6 +3019,60 @@ Object.assign(_player2.default.prototype, {
 
                t.addControlElement(mute, 'volume');
 
+               t.options.keyActions.push({
+                       keys: [38],
+                       action: function action(player) {
+                               var volumeSlider = player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'volume-slider');
+                               if (volumeSlider || player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'volume-slider').matches(':focus')) {
+                                       volumeSlider.style.display = 'block';
+                               }
+                               if (player.isVideo) {
+                                       player.showControls();
+                                       player.startControlsTimer();
+                               }
+
+                               var newVolume = Math.min(player.volume + 0.1, 1);
+                               player.setVolume(newVolume);
+                               if (newVolume > 0) {
+                                       player.setMuted(false);
+                               }
+                       }
+               }, {
+                       keys: [40],
+                       action: function action(player) {
+                               var volumeSlider = player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'volume-slider');
+                               if (volumeSlider) {
+                                       volumeSlider.style.display = 'block';
+                               }
+
+                               if (player.isVideo) {
+                                       player.showControls();
+                                       player.startControlsTimer();
+                               }
+
+                               var newVolume = Math.max(player.volume - 0.1, 0);
+                               player.setVolume(newVolume);
+
+                               if (newVolume <= 0.1) {
+                                       player.setMuted(true);
+                               }
+                       }
+               }, {
+                       keys: [77],
+                       action: function action(player) {
+                               player.getElement(player.container).querySelector('.' + _player.config.classPrefix + 'volume-slider').style.display = 'block';
+                               if (player.isVideo) {
+                                       player.showControls();
+                                       player.startControlsTimer();
+                               }
+                               if (player.media.muted) {
+                                       player.setMuted(false);
+                               } else {
+                                       player.setMuted(true);
+                               }
+                       }
+               });
+
                if (mode === 'horizontal') {
                        var anchor = _document2.default.createElement('a');
                        anchor.className = t.options.classPrefix + 'horizontal-volume-slider';
@@ -2891,10 +3094,10 @@ Object.assign(_player2.default.prototype, {
                        volumeSlider.setAttribute('aria-valuetext', volume + '%');
                };
 
-               var volumeSlider = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-slider') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-slider'),
-                   volumeTotal = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-total') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-total'),
-                   volumeCurrent = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-current') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-current'),
-                   volumeHandle = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-handle') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-handle'),
+               var volumeSlider = mode === 'vertical' ? t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-slider') : t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'horizontal-volume-slider'),
+                   volumeTotal = mode === 'vertical' ? t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-total') : t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'horizontal-volume-total'),
+                   volumeCurrent = mode === 'vertical' ? t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-current') : t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'horizontal-volume-current'),
+                   volumeHandle = mode === 'vertical' ? t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'volume-handle') : t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'horizontal-volume-handle'),
                    positionVolumeHandle = function positionVolumeHandle(volume) {
 
                        if (volume === null || isNaN(volume) || volume === undefined) {
@@ -2980,6 +3183,13 @@ Object.assign(_player2.default.prototype, {
                        }
                };
 
+               player.getElement(player.container).addEventListener('keydown', function (e) {
+                       var hasFocus = !!e.target.closest('.' + t.options.classPrefix + 'container');
+                       if (!hasFocus && mode === 'vertical') {
+                               volumeSlider.style.display = 'none';
+                       }
+               });
+
                mute.addEventListener('mouseenter', function (e) {
                        if (e.target === mute) {
                                volumeSlider.style.display = 'block';
@@ -3100,7 +3310,6 @@ Object.assign(_player2.default.prototype, {
                                if (!modified && !rendered) {
                                        if (player.options.startVolume === 0 || media.originalNode.muted) {
                                                media.setMuted(true);
-                                               player.options.startVolume = 0;
                                        }
                                        media.setVolume(player.options.startVolume);
                                        t.setControlsSize();
@@ -3115,7 +3324,7 @@ Object.assign(_player2.default.prototype, {
                        toggleMute();
                }
 
-               t.container.addEventListener('controlsresize', function () {
+               t.getElement(t.container).addEventListener('controlsresize', function () {
                        toggleMute();
                });
        }
@@ -3366,99 +3575,6 @@ var config = exports.config = {
                                }
                        }
                }
-       }, {
-               keys: [38],
-               action: function action(player) {
-
-                       if (player.container.querySelector('.' + config.classPrefix + 'volume-button>button').matches(':focus') || player.container.querySelector('.' + config.classPrefix + 'volume-slider').matches(':focus')) {
-                               player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
-                       }
-                       if (player.isVideo) {
-                               player.showControls();
-                               player.startControlsTimer();
-                       }
-
-                       var newVolume = Math.min(player.volume + 0.1, 1);
-                       player.setVolume(newVolume);
-                       if (newVolume > 0) {
-                               player.setMuted(false);
-                       }
-               }
-       }, {
-               keys: [40],
-               action: function action(player) {
-
-                       if (player.container.querySelector('.' + config.classPrefix + 'volume-button>button').matches(':focus') || player.container.querySelector('.' + config.classPrefix + 'volume-slider').matches(':focus')) {
-                               player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
-                       }
-
-                       if (player.isVideo) {
-                               player.showControls();
-                               player.startControlsTimer();
-                       }
-
-                       var newVolume = Math.max(player.volume - 0.1, 0);
-                       player.setVolume(newVolume);
-
-                       if (newVolume <= 0.1) {
-                               player.setMuted(true);
-                       }
-               }
-       }, {
-               keys: [37, 227],
-               action: function action(player) {
-                       if (!isNaN(player.duration) && player.duration > 0) {
-                               if (player.isVideo) {
-                                       player.showControls();
-                                       player.startControlsTimer();
-                               }
-
-                               var newTime = Math.max(player.currentTime - player.options.defaultSeekBackwardInterval(player), 0);
-                               player.setCurrentTime(newTime);
-                       }
-               }
-       }, {
-               keys: [39, 228],
-               action: function action(player) {
-
-                       if (!isNaN(player.duration) && player.duration > 0) {
-                               if (player.isVideo) {
-                                       player.showControls();
-                                       player.startControlsTimer();
-                               }
-
-                               var newTime = Math.min(player.currentTime + player.options.defaultSeekForwardInterval(player), player.duration);
-                               player.setCurrentTime(newTime);
-                       }
-               }
-       }, {
-               keys: [70],
-               action: function action(player, media, key, event) {
-                       if (!event.ctrlKey) {
-                               if (typeof player.enterFullScreen !== 'undefined') {
-                                       if (player.isFullScreen) {
-                                               player.exitFullScreen();
-                                       } else {
-                                               player.enterFullScreen();
-                                       }
-                               }
-                       }
-               }
-       }, {
-               keys: [77],
-               action: function action(player) {
-
-                       player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
-                       if (player.isVideo) {
-                               player.showControls();
-                               player.startControlsTimer();
-                       }
-                       if (player.media.muted) {
-                               player.setMuted(false);
-                       } else {
-                               player.setMuted(true);
-                       }
-               }
        }]
 };
 
@@ -3527,180 +3643,191 @@ var MediaElementPlayer = function () {
 
                _mejs2.default.players[t.id] = t;
 
-               var playerOptions = Object.assign({}, t.options, {
-                       success: function success(media, domNode) {
-                               t._meReady(media, domNode);
-                       },
-                       error: function error(e) {
-                               t._handleError(e);
-                       }
-               }),
-                   tagName = t.node.tagName.toLowerCase();
-
-               t.isDynamic = tagName !== 'audio' && tagName !== 'video' && tagName !== 'iframe';
-               t.isVideo = t.isDynamic ? t.options.isVideo : tagName !== 'audio' && t.options.isVideo;
-               t.mediaFiles = null;
-               t.trackFiles = null;
-
-               if (_constants.IS_IPAD && t.options.iPadUseNativeControls || _constants.IS_IPHONE && t.options.iPhoneUseNativeControls) {
-                       t.node.setAttribute('controls', true);
+               t.init();
 
-                       if (_constants.IS_IPAD && t.node.getAttribute('autoplay')) {
-                               t.play();
-                       }
-               } else if ((t.isVideo || !t.isVideo && (t.options.features.length || t.options.useDefaultControls)) && !(_constants.IS_ANDROID && t.options.AndroidUseNativeControls)) {
-                       t.node.removeAttribute('controls');
-                       var videoPlayerTitle = t.isVideo ? _i18n2.default.t('mejs.video-player') : _i18n2.default.t('mejs.audio-player');
+               return t;
+       }
 
-                       var offscreen = _document2.default.createElement('span');
-                       offscreen.className = t.options.classPrefix + 'offscreen';
-                       offscreen.innerText = videoPlayerTitle;
-                       t.media.parentNode.insertBefore(offscreen, t.media);
+       _createClass(MediaElementPlayer, [{
+               key: 'getElement',
+               value: function getElement(element) {
+                       return element;
+               }
+       }, {
+               key: 'init',
+               value: function init() {
+                       var t = this,
+                           playerOptions = Object.assign({}, t.options, {
+                               success: function success(media, domNode) {
+                                       t._meReady(media, domNode);
+                               },
+                               error: function error(e) {
+                                       t._handleError(e);
+                               }
+                       }),
+                           tagName = t.node.tagName.toLowerCase();
+
+                       t.isDynamic = tagName !== 'audio' && tagName !== 'video' && tagName !== 'iframe';
+                       t.isVideo = t.isDynamic ? t.options.isVideo : tagName !== 'audio' && t.options.isVideo;
+                       t.mediaFiles = null;
+                       t.trackFiles = null;
+
+                       if (_constants.IS_IPAD && t.options.iPadUseNativeControls || _constants.IS_IPHONE && t.options.iPhoneUseNativeControls) {
+                               t.node.setAttribute('controls', true);
+
+                               if (_constants.IS_IPAD && t.node.getAttribute('autoplay')) {
+                                       t.play();
+                               }
+                       } else if ((t.isVideo || !t.isVideo && (t.options.features.length || t.options.useDefaultControls)) && !(_constants.IS_ANDROID && t.options.AndroidUseNativeControls)) {
+                               t.node.removeAttribute('controls');
+                               var videoPlayerTitle = t.isVideo ? _i18n2.default.t('mejs.video-player') : _i18n2.default.t('mejs.audio-player');
+
+                               var offscreen = _document2.default.createElement('span');
+                               offscreen.className = t.options.classPrefix + 'offscreen';
+                               offscreen.innerText = videoPlayerTitle;
+                               t.media.parentNode.insertBefore(offscreen, t.media);
+
+                               t.container = _document2.default.createElement('div');
+                               t.getElement(t.container).id = t.id;
+                               t.getElement(t.container).className = t.options.classPrefix + 'container ' + t.options.classPrefix + 'container-keyboard-inactive ' + t.media.className;
+                               t.getElement(t.container).tabIndex = 0;
+                               t.getElement(t.container).setAttribute('role', 'application');
+                               t.getElement(t.container).setAttribute('aria-label', videoPlayerTitle);
+                               t.getElement(t.container).innerHTML = '<div class="' + t.options.classPrefix + 'inner">' + ('<div class="' + t.options.classPrefix + 'mediaelement"></div>') + ('<div class="' + t.options.classPrefix + 'layers"></div>') + ('<div class="' + t.options.classPrefix + 'controls"></div>') + '</div>';
+                               t.getElement(t.container).addEventListener('focus', function (e) {
+                                       if (!t.controlsAreVisible && !t.hasFocus && t.controlsEnabled) {
+                                               t.showControls(true);
+
+                                               var btnSelector = (0, _general.isNodeAfter)(e.relatedTarget, t.getElement(t.container)) ? '.' + t.options.classPrefix + 'controls .' + t.options.classPrefix + 'button:last-child > button' : '.' + t.options.classPrefix + 'playpause-button > button',
+                                                   button = t.getElement(t.container).querySelector(btnSelector);
+
+                                               button.focus();
+                                       }
+                               });
+                               t.node.parentNode.insertBefore(t.getElement(t.container), t.node);
 
-                       t.container = _document2.default.createElement('div');
-                       t.container.id = t.id;
-                       t.container.className = t.options.classPrefix + 'container ' + t.options.classPrefix + 'container-keyboard-inactive ' + t.media.className;
-                       t.container.tabIndex = 0;
-                       t.container.setAttribute('role', 'application');
-                       t.container.setAttribute('aria-label', videoPlayerTitle);
-                       t.container.innerHTML = '<div class="' + t.options.classPrefix + 'inner">' + ('<div class="' + t.options.classPrefix + 'mediaelement"></div>') + ('<div class="' + t.options.classPrefix + 'layers"></div>') + ('<div class="' + t.options.classPrefix + 'controls"></div>') + '</div>';
-                       t.container.addEventListener('focus', function (e) {
-                               if (!t.controlsAreVisible && !t.hasFocus && t.controlsEnabled) {
-                                       t.showControls(true);
+                               if (!t.options.features.length && !t.options.useDefaultControls) {
+                                       t.getElement(t.container).style.background = 'transparent';
+                                       t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'controls').style.display = 'none';
+                               }
 
-                                       var btnSelector = (0, _general.isNodeAfter)(e.relatedTarget, t.container) ? '.' + t.options.classPrefix + 'controls .' + t.options.classPrefix + 'button:last-child > button' : '.' + t.options.classPrefix + 'playpause-button > button',
-                                           button = t.container.querySelector(btnSelector);
+                               if (t.isVideo && t.options.stretching === 'fill' && !dom.hasClass(t.getElement(t.container).parentNode, t.options.classPrefix + 'fill-container')) {
+                                       t.outerContainer = t.media.parentNode;
 
-                                       button.focus();
+                                       var wrapper = _document2.default.createElement('div');
+                                       wrapper.className = t.options.classPrefix + 'fill-container';
+                                       t.getElement(t.container).parentNode.insertBefore(wrapper, t.getElement(t.container));
+                                       wrapper.appendChild(t.getElement(t.container));
                                }
-                       });
-                       t.node.parentNode.insertBefore(t.container, t.node);
 
-                       if (!t.options.features.length && !t.options.useDefaultControls) {
-                               t.container.style.background = 'transparent';
-                               t.container.querySelector('.' + t.options.classPrefix + 'controls').style.display = 'none';
-                       }
+                               if (_constants.IS_ANDROID) {
+                                       dom.addClass(t.getElement(t.container), t.options.classPrefix + 'android');
+                               }
+                               if (_constants.IS_IOS) {
+                                       dom.addClass(t.getElement(t.container), t.options.classPrefix + 'ios');
+                               }
+                               if (_constants.IS_IPAD) {
+                                       dom.addClass(t.getElement(t.container), t.options.classPrefix + 'ipad');
+                               }
+                               if (_constants.IS_IPHONE) {
+                                       dom.addClass(t.getElement(t.container), t.options.classPrefix + 'iphone');
+                               }
+                               dom.addClass(t.getElement(t.container), t.isVideo ? t.options.classPrefix + 'video' : t.options.classPrefix + 'audio');
+
+                               if (_constants.IS_SAFARI && !_constants.IS_IOS) {
+
+                                       dom.addClass(t.getElement(t.container), t.options.classPrefix + 'hide-cues');
+
+                                       var cloneNode = t.node.cloneNode(),
+                                           children = t.node.children,
+                                           mediaFiles = [],
+                                           tracks = [];
+
+                                       for (var i = 0, total = children.length; i < total; i++) {
+                                               var childNode = children[i];
+
+                                               (function () {
+                                                       switch (childNode.tagName.toLowerCase()) {
+                                                               case 'source':
+                                                                       var elements = {};
+                                                                       Array.prototype.slice.call(childNode.attributes).forEach(function (item) {
+                                                                               elements[item.name] = item.value;
+                                                                       });
+                                                                       elements.type = (0, _media.formatType)(elements.src, elements.type);
+                                                                       mediaFiles.push(elements);
+                                                                       break;
+                                                               case 'track':
+                                                                       childNode.mode = 'hidden';
+                                                                       tracks.push(childNode);
+                                                                       break;
+                                                               default:
+                                                                       cloneNode.appendChild(childNode);
+                                                                       break;
+                                                       }
+                                               })();
+                                       }
 
-                       if (t.isVideo && t.options.stretching === 'fill' && !dom.hasClass(t.container.parentNode, t.options.classPrefix + 'fill-container')) {
-                               t.outerContainer = t.media.parentNode;
+                                       t.node.remove();
+                                       t.node = t.media = cloneNode;
 
-                               var wrapper = _document2.default.createElement('div');
-                               wrapper.className = t.options.classPrefix + 'fill-container';
-                               t.container.parentNode.insertBefore(wrapper, t.container);
-                               wrapper.appendChild(t.container);
-                       }
+                                       if (mediaFiles.length) {
+                                               t.mediaFiles = mediaFiles;
+                                       }
+                                       if (tracks.length) {
+                                               t.trackFiles = tracks;
+                                       }
+                               }
 
-                       if (_constants.IS_ANDROID) {
-                               dom.addClass(t.container, t.options.classPrefix + 'android');
-                       }
-                       if (_constants.IS_IOS) {
-                               dom.addClass(t.container, t.options.classPrefix + 'ios');
-                       }
-                       if (_constants.IS_IPAD) {
-                               dom.addClass(t.container, t.options.classPrefix + 'ipad');
-                       }
-                       if (_constants.IS_IPHONE) {
-                               dom.addClass(t.container, t.options.classPrefix + 'iphone');
-                       }
-                       dom.addClass(t.container, t.isVideo ? t.options.classPrefix + 'video' : t.options.classPrefix + 'audio');
+                               t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'mediaelement').appendChild(t.node);
 
-                       if (_constants.IS_SAFARI && !_constants.IS_IOS) {
+                               t.media.player = t;
 
-                               dom.addClass(t.container, t.options.classPrefix + 'hide-cues');
+                               t.controls = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'controls');
+                               t.layers = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'layers');
 
-                               var cloneNode = t.node.cloneNode(),
-                                   children = t.node.children,
-                                   mediaFiles = [],
-                                   tracks = [];
+                               var tagType = t.isVideo ? 'video' : 'audio',
+                                   capsTagName = tagType.substring(0, 1).toUpperCase() + tagType.substring(1);
 
-                               for (var i = 0, total = children.length; i < total; i++) {
-                                       var childNode = children[i];
-
-                                       (function () {
-                                               switch (childNode.tagName.toLowerCase()) {
-                                                       case 'source':
-                                                               var elements = {};
-                                                               Array.prototype.slice.call(childNode.attributes).forEach(function (item) {
-                                                                       elements[item.name] = item.value;
-                                                               });
-                                                               elements.type = (0, _media.formatType)(elements.src, elements.type);
-                                                               mediaFiles.push(elements);
-                                                               break;
-                                                       case 'track':
-                                                               childNode.mode = 'hidden';
-                                                               tracks.push(childNode);
-                                                               break;
-                                                       default:
-                                                               cloneNode.appendChild(childNode);
-                                                               break;
-                                               }
-                                       })();
+                               if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
+                                       t.width = t.options[tagType + 'Width'];
+                               } else if (t.node.style.width !== '' && t.node.style.width !== null) {
+                                       t.width = t.node.style.width;
+                               } else if (t.node.getAttribute('width')) {
+                                       t.width = t.node.getAttribute('width');
+                               } else {
+                                       t.width = t.options['default' + capsTagName + 'Width'];
                                }
 
-                               t.node.remove();
-                               t.node = t.media = cloneNode;
-
-                               if (mediaFiles.length) {
-                                       t.mediaFiles = mediaFiles;
-                               }
-                               if (tracks.length) {
-                                       t.trackFiles = tracks;
+                               if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
+                                       t.height = t.options[tagType + 'Height'];
+                               } else if (t.node.style.height !== '' && t.node.style.height !== null) {
+                                       t.height = t.node.style.height;
+                               } else if (t.node.getAttribute('height')) {
+                                       t.height = t.node.getAttribute('height');
+                               } else {
+                                       t.height = t.options['default' + capsTagName + 'Height'];
                                }
-                       }
-
-                       t.container.querySelector('.' + t.options.classPrefix + 'mediaelement').appendChild(t.node);
 
-                       t.media.player = t;
+                               t.initialAspectRatio = t.height >= t.width ? t.width / t.height : t.height / t.width;
 
-                       t.controls = t.container.querySelector('.' + t.options.classPrefix + 'controls');
-                       t.layers = t.container.querySelector('.' + t.options.classPrefix + 'layers');
-
-                       var tagType = t.isVideo ? 'video' : 'audio',
-                           capsTagName = tagType.substring(0, 1).toUpperCase() + tagType.substring(1);
-
-                       if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
-                               t.width = t.options[tagType + 'Width'];
-                       } else if (t.node.style.width !== '' && t.node.style.width !== null) {
-                               t.width = t.node.style.width;
-                       } else if (t.node.getAttribute('width')) {
-                               t.width = t.node.getAttribute('width');
-                       } else {
-                               t.width = t.options['default' + capsTagName + 'Width'];
-                       }
+                               t.setPlayerSize(t.width, t.height);
 
-                       if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
-                               t.height = t.options[tagType + 'Height'];
-                       } else if (t.node.style.height !== '' && t.node.style.height !== null) {
-                               t.height = t.node.style.height;
-                       } else if (t.node.getAttribute('height')) {
-                               t.height = t.node.getAttribute('height');
-                       } else {
-                               t.height = t.options['default' + capsTagName + 'Height'];
-                       }
+                               playerOptions.pluginWidth = t.width;
+                               playerOptions.pluginHeight = t.height;
+                       } else if (!t.isVideo && !t.options.features.length && !t.options.useDefaultControls) {
+                                       t.node.style.display = 'none';
+                               }
 
-                       t.initialAspectRatio = t.height >= t.width ? t.width / t.height : t.height / t.width;
+                       _mejs2.default.MepDefaults = playerOptions;
 
-                       t.setPlayerSize(t.width, t.height);
+                       new _mediaelement2.default(t.media, playerOptions, t.mediaFiles);
 
-                       playerOptions.pluginWidth = t.width;
-                       playerOptions.pluginHeight = t.height;
-               } else if (!t.isVideo && !t.options.features.length && !t.options.useDefaultControls) {
-                               t.node.style.display = 'none';
+                       if (t.getElement(t.container) !== undefined && t.options.features.length && t.controlsAreVisible && !t.options.hideVideoControlsOnLoad) {
+                               var event = (0, _general.createEvent)('controlsshown', t.getElement(t.container));
+                               t.getElement(t.container).dispatchEvent(event);
                        }
-
-               _mejs2.default.MepDefaults = playerOptions;
-
-               new _mediaelement2.default(t.media, playerOptions, t.mediaFiles);
-
-               if (t.container !== undefined && t.options.features.length && t.controlsAreVisible && !t.options.hideVideoControlsOnLoad) {
-                       var event = (0, _general.createEvent)('controlsshown', t.container);
-                       t.container.dispatchEvent(event);
                }
-
-               return t;
-       }
-
-       _createClass(MediaElementPlayer, [{
+       }, {
                key: 'showControls',
                value: function showControls(doAnimation) {
                        var t = this;
@@ -3713,13 +3840,13 @@ var MediaElementPlayer = function () {
 
                        if (doAnimation) {
                                (function () {
-                                       dom.fadeIn(t.controls, 200, function () {
-                                               dom.removeClass(t.controls, t.options.classPrefix + 'offscreen');
-                                               var event = (0, _general.createEvent)('controlsshown', t.container);
-                                               t.container.dispatchEvent(event);
+                                       dom.fadeIn(t.getElement(t.controls), 200, function () {
+                                               dom.removeClass(t.getElement(t.controls), t.options.classPrefix + 'offscreen');
+                                               var event = (0, _general.createEvent)('controlsshown', t.getElement(t.container));
+                                               t.getElement(t.container).dispatchEvent(event);
                                        });
 
-                                       var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
+                                       var controls = t.getElement(t.container).querySelectorAll('.' + t.options.classPrefix + 'control');
 
                                        var _loop = function _loop(i, total) {
                                                dom.fadeIn(controls[i], 200, function () {
@@ -3732,18 +3859,18 @@ var MediaElementPlayer = function () {
                                        }
                                })();
                        } else {
-                               dom.removeClass(t.controls, t.options.classPrefix + 'offscreen');
-                               t.controls.style.display = '';
-                               t.controls.style.opacity = 1;
+                               dom.removeClass(t.getElement(t.controls), t.options.classPrefix + 'offscreen');
+                               t.getElement(t.controls).style.display = '';
+                               t.getElement(t.controls).style.opacity = 1;
 
-                               var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
+                               var controls = t.getElement(t.container).querySelectorAll('.' + t.options.classPrefix + 'control');
                                for (var i = 0, total = controls.length; i < total; i++) {
                                        dom.removeClass(controls[i], t.options.classPrefix + 'offscreen');
                                        controls[i].style.display = '';
                                }
 
-                               var event = (0, _general.createEvent)('controlsshown', t.container);
-                               t.container.dispatchEvent(event);
+                               var event = (0, _general.createEvent)('controlsshown', t.getElement(t.container));
+                               t.getElement(t.container).dispatchEvent(event);
                        }
 
                        t.controlsAreVisible = true;
@@ -3762,14 +3889,14 @@ var MediaElementPlayer = function () {
 
                        if (doAnimation) {
                                (function () {
-                                       dom.fadeOut(t.controls, 200, function () {
-                                               dom.addClass(t.controls, t.options.classPrefix + 'offscreen');
-                                               t.controls.style.display = '';
-                                               var event = (0, _general.createEvent)('controlshidden', t.container);
-                                               t.container.dispatchEvent(event);
+                                       dom.fadeOut(t.getElement(t.controls), 200, function () {
+                                               dom.addClass(t.getElement(t.controls), t.options.classPrefix + 'offscreen');
+                                               t.getElement(t.controls).style.display = '';
+                                               var event = (0, _general.createEvent)('controlshidden', t.getElement(t.container));
+                                               t.getElement(t.container).dispatchEvent(event);
                                        });
 
-                                       var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
+                                       var controls = t.getElement(t.container).querySelectorAll('.' + t.options.classPrefix + 'control');
 
                                        var _loop2 = function _loop2(i, total) {
                                                dom.fadeOut(controls[i], 200, function () {
@@ -3783,18 +3910,18 @@ var MediaElementPlayer = function () {
                                        }
                                })();
                        } else {
-                               dom.addClass(t.controls, t.options.classPrefix + 'offscreen');
-                               t.controls.style.display = '';
-                               t.controls.style.opacity = 0;
+                               dom.addClass(t.getElement(t.controls), t.options.classPrefix + 'offscreen');
+                               t.getElement(t.controls).style.display = '';
+                               t.getElement(t.controls).style.opacity = 0;
 
-                               var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
+                               var controls = t.getElement(t.container).querySelectorAll('.' + t.options.classPrefix + 'control');
                                for (var i = 0, total = controls.length; i < total; i++) {
                                        dom.addClass(controls[i], t.options.classPrefix + 'offscreen');
                                        controls[i].style.display = '';
                                }
 
-                               var event = (0, _general.createEvent)('controlshidden', t.container);
-                               t.container.dispatchEvent(event);
+                               var event = (0, _general.createEvent)('controlshidden', t.getElement(t.container));
+                               t.getElement(t.container).dispatchEvent(event);
                        }
 
                        t.controlsAreVisible = false;
@@ -3866,12 +3993,12 @@ var MediaElementPlayer = function () {
                            autoplay = !(autoplayAttr === undefined || autoplayAttr === null || autoplayAttr === 'false'),
                            isNative = media.rendererName !== null && /(native|html5)/i.test(t.media.rendererName);
 
-                       if (t.controls) {
+                       if (t.getElement(t.controls)) {
                                t.enableControls();
                        }
 
-                       if (t.container && t.container.querySelector('.' + t.options.classPrefix + 'overlay-play')) {
-                               t.container.querySelector('.' + t.options.classPrefix + 'overlay-play').style.display = '';
+                       if (t.getElement(t.container) && t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'overlay-play')) {
+                               t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'overlay-play').style.display = '';
                        }
 
                        if (t.created) {
@@ -3900,12 +4027,14 @@ var MediaElementPlayer = function () {
                                        return;
                                }
 
-                               t.findTracks();
-
                                t.featurePosition = {};
 
                                t._setDefaultPlayer();
 
+                               t.buildposter(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
+                               t.buildkeyboard(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
+                               t.buildoverlays(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
+
                                if (t.options.useDefaultControls) {
                                        var defaultControls = ['playpause', 'current', 'progress', 'duration', 'tracks', 'volume', 'fullscreen'];
                                        t.options.features = defaultControls.concat(t.options.features.filter(function (item) {
@@ -3913,23 +4042,10 @@ var MediaElementPlayer = function () {
                                        }));
                                }
 
-                               for (var i = 0, total = t.options.features.length; i < total; i++) {
-                                       var feature = t.options.features[i];
-                                       if (t['build' + feature]) {
-                                               try {
-                                                       t['build' + feature](t, t.controls, t.layers, t.media);
-                                               } catch (e) {
-                                                       console.error('error building ' + feature, e);
-                                               }
-                                       }
-                               }
-
-                               t.buildposter(t, t.controls, t.layers, t.media);
-                               t.buildkeyboard(t, t.controls, t.layers, t.media);
-                               t.buildoverlays(t, t.controls, t.layers, t.media);
+                               t.buildfeatures(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
 
-                               var event = (0, _general.createEvent)('controlsready', t.container);
-                               t.container.dispatchEvent(event);
+                               var event = (0, _general.createEvent)('controlsready', t.getElement(t.container));
+                               t.getElement(t.container).dispatchEvent(event);
 
                                t.setPlayerSize(t.width, t.height);
                                t.setControlsSize();
@@ -3938,7 +4054,7 @@ var MediaElementPlayer = function () {
                                        t.clickToPlayPauseCallback = function () {
 
                                                if (t.options.clickToPlayPause) {
-                                                       var button = t.container.querySelector('.' + t.options.classPrefix + 'overlay-button'),
+                                                       var button = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'overlay-button'),
                                                            pressed = button.getAttribute('aria-pressed');
 
                                                        if (t.paused && pressed) {
@@ -3950,7 +4066,7 @@ var MediaElementPlayer = function () {
                                                        }
 
                                                        button.setAttribute('aria-pressed', !pressed);
-                                                       t.container.focus();
+                                                       t.getElement(t.container).focus();
                                                }
                                        };
 
@@ -3967,9 +4083,9 @@ var MediaElementPlayer = function () {
                                                                        t.showControls(false);
                                                                }
                                                        }
-                                               });
+                                               }, _constants.SUPPORT_PASSIVE_EVENT ? { passive: true } : false);
                                        } else {
-                                               t.container.addEventListener('mouseenter', function () {
+                                               t.getElement(t.container).addEventListener('mouseenter', function () {
                                                        if (t.controlsEnabled) {
                                                                if (!t.options.alwaysShowControls) {
                                                                        t.killControlsTimer('enter');
@@ -3978,7 +4094,7 @@ var MediaElementPlayer = function () {
                                                                }
                                                        }
                                                });
-                                               t.container.addEventListener('mousemove', function () {
+                                               t.getElement(t.container).addEventListener('mousemove', function () {
                                                        if (t.controlsEnabled) {
                                                                if (!t.controlsAreVisible) {
                                                                        t.showControls();
@@ -3988,7 +4104,7 @@ var MediaElementPlayer = function () {
                                                                }
                                                        }
                                                });
-                                               t.container.addEventListener('mouseleave', function () {
+                                               t.getElement(t.container).addEventListener('mouseleave', function () {
                                                        if (t.controlsEnabled) {
                                                                if (!t.paused && !t.options.alwaysShowControls) {
                                                                        t.startControlsTimer(t.options.controlsTimeoutMouseLeave);
@@ -4004,7 +4120,7 @@ var MediaElementPlayer = function () {
                                        if (t.options.enableAutosize) {
                                                t.media.addEventListener('loadedmetadata', function (e) {
                                                        var target = e !== undefined ? e.detail.target || e.target : t.media;
-                                                       if (t.options.videoHeight <= 0 && !t.domNode.getAttribute('height') && target !== null && !isNaN(target.videoHeight)) {
+                                                       if (t.options.videoHeight <= 0 && !t.domNode.getAttribute('height') && !t.domNode.style.height && target !== null && !isNaN(target.videoHeight)) {
                                                                t.setPlayerSize(target.videoWidth, target.videoHeight);
                                                                t.setControlsSize();
                                                                t.media.setSize(target.videoWidth, target.videoHeight);
@@ -4038,7 +4154,7 @@ var MediaElementPlayer = function () {
                                                        t.setCurrentTime(0);
 
                                                        setTimeout(function () {
-                                                               var loadingElement = t.container.querySelector('.' + t.options.classPrefix + 'overlay-loading');
+                                                               var loadingElement = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'overlay-loading');
                                                                if (loadingElement && loadingElement.parentNode) {
                                                                        loadingElement.parentNode.style.display = 'none';
                                                                }
@@ -4102,11 +4218,11 @@ var MediaElementPlayer = function () {
                                        }
                                });
 
-                               t.container.addEventListener('click', function (e) {
+                               t.getElement(t.container).addEventListener('click', function (e) {
                                        dom.addClass(e.currentTarget, t.options.classPrefix + 'container-keyboard-inactive');
                                });
 
-                               t.container.addEventListener('focusin', function (e) {
+                               t.getElement(t.container).addEventListener('focusin', function (e) {
                                        dom.removeClass(e.currentTarget, t.options.classPrefix + 'container-keyboard-inactive');
                                        if (t.isVideo && !_constants.IS_ANDROID && !_constants.IS_IOS && t.controlsEnabled && !t.options.alwaysShowControls) {
                                                t.killControlsTimer('enter');
@@ -4115,7 +4231,7 @@ var MediaElementPlayer = function () {
                                        }
                                });
 
-                               t.container.addEventListener('focusout', function (e) {
+                               t.getElement(t.container).addEventListener('focusout', function (e) {
                                        setTimeout(function () {
                                                if (e.relatedTarget) {
                                                        if (t.keyboardAction && !e.relatedTarget.closest('.' + t.options.classPrefix + 'container')) {
@@ -4160,7 +4276,7 @@ var MediaElementPlayer = function () {
                key: '_handleError',
                value: function _handleError(e, media, node) {
                        var t = this,
-                           play = t.layers.querySelector('.' + t.options.classPrefix + 'overlay-play');
+                           play = t.getElement(t.layers).querySelector('.' + t.options.classPrefix + 'overlay-play');
 
                        if (play) {
                                play.style.display = 'none';
@@ -4170,8 +4286,8 @@ var MediaElementPlayer = function () {
                                t.options.error(e, media, node);
                        }
 
-                       if (t.container.querySelector('.' + t.options.classPrefix + 'cannotplay')) {
-                               t.container.querySelector('.' + t.options.classPrefix + 'cannotplay').remove();
+                       if (t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'cannotplay')) {
+                               t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'cannotplay').remove();
                        }
 
                        var errorContainer = _document2.default.createElement('div');
@@ -4182,14 +4298,14 @@ var MediaElementPlayer = function () {
                        var errorContent = typeof t.options.customError === 'function' ? t.options.customError(t.media, t.media.originalNode) : t.options.customError,
                            imgError = '';
 
-                       if (errorContent) {
+                       if (!errorContent) {
                                var poster = t.media.originalNode.getAttribute('poster');
                                if (poster) {
                                        imgError = '<img src="' + poster + '" alt="' + _mejs2.default.i18n.t('mejs.download-file') + '">';
                                }
 
                                if (e.message) {
-                                       errorContent += '<p>' + e.message + '</p>';
+                                       errorContent = '<p>' + e.message + '</p>';
                                }
 
                                if (e.urls) {
@@ -4200,10 +4316,14 @@ var MediaElementPlayer = function () {
                                }
                        }
 
-                       if (errorContent && t.layers.querySelector('.' + t.options.classPrefix + 'overlay-error')) {
+                       if (errorContent && t.getElement(t.layers).querySelector('.' + t.options.classPrefix + 'overlay-error')) {
                                errorContainer.innerHTML = errorContent;
-                               t.layers.querySelector('.' + t.options.classPrefix + 'overlay-error').innerHTML = '' + imgError + errorContainer.outerHTML;
-                               t.layers.querySelector('.' + t.options.classPrefix + 'overlay-error').parentNode.style.display = 'block';
+                               t.getElement(t.layers).querySelector('.' + t.options.classPrefix + 'overlay-error').innerHTML = '' + imgError + errorContainer.outerHTML;
+                               t.getElement(t.layers).querySelector('.' + t.options.classPrefix + 'overlay-error').parentNode.style.display = 'block';
+                       }
+
+                       if (t.controlsEnabled) {
+                               t.disableControls();
                        }
                }
        }, {
@@ -4261,7 +4381,7 @@ var MediaElementPlayer = function () {
                            parent = function () {
 
                                var parentEl = void 0,
-                                   el = t.container;
+                                   el = t.getElement(t.container);
 
                                while (el) {
                                        try {
@@ -4285,8 +4405,8 @@ var MediaElementPlayer = function () {
                            parentStyles = parent ? getComputedStyle(parent, null) : getComputedStyle(_document2.default.body, null),
                            nativeWidth = function () {
                                if (t.isVideo) {
-                                       if (t.media.videoWidth && t.media.videoWidth > 0) {
-                                               return t.media.videoWidth;
+                                       if (t.node.videoWidth && t.node.videoWidth > 0) {
+                                               return t.node.videoWidth;
                                        } else if (t.node.getAttribute('width')) {
                                                return t.node.getAttribute('width');
                                        } else {
@@ -4298,8 +4418,8 @@ var MediaElementPlayer = function () {
                        }(),
                            nativeHeight = function () {
                                if (t.isVideo) {
-                                       if (t.media.videoHeight && t.media.videoHeight > 0) {
-                                               return t.media.videoHeight;
+                                       if (t.node.videoHeight && t.node.videoHeight > 0) {
+                                               return t.node.videoHeight;
                                        } else if (t.node.getAttribute('height')) {
                                                return t.node.getAttribute('height');
                                        } else {
@@ -4315,8 +4435,8 @@ var MediaElementPlayer = function () {
                                        return ratio;
                                }
 
-                               if (t.media.videoWidth && t.media.videoWidth > 0 && t.media.videoHeight && t.media.videoHeight > 0) {
-                                       ratio = t.height >= t.width ? t.media.videoWidth / t.media.videoHeight : t.media.videoHeight / t.media.videoWidth;
+                               if (t.node.videoWidth && t.node.videoWidth > 0 && t.node.videoHeight && t.node.videoHeight > 0) {
+                                       ratio = t.height >= t.width ? t.node.videoWidth / t.node.videoHeight : t.node.videoHeight / t.node.videoWidth;
                                } else {
                                        ratio = t.initialAspectRatio;
                                }
@@ -4346,14 +4466,14 @@ var MediaElementPlayer = function () {
                                newHeight = parentHeight;
                        }
 
-                       if (t.container.parentNode.length > 0 && t.container.parentNode.tagName.toLowerCase() === 'body') {
+                       if (t.getElement(t.container).parentNode.length > 0 && t.getElement(t.container).parentNode.tagName.toLowerCase() === 'body') {
                                parentWidth = _window2.default.innerWidth || _document2.default.documentElement.clientWidth || _document2.default.body.clientWidth;
                                newHeight = _window2.default.innerHeight || _document2.default.documentElement.clientHeight || _document2.default.body.clientHeight;
                        }
 
                        if (newHeight && parentWidth) {
-                               t.container.style.width = parentWidth + 'px';
-                               t.container.style.height = newHeight + 'px';
+                               t.getElement(t.container).style.width = parentWidth + 'px';
+                               t.getElement(t.container).style.height = newHeight + 'px';
 
                                t.node.style.width = '100%';
                                t.node.style.height = '100%';
@@ -4362,7 +4482,7 @@ var MediaElementPlayer = function () {
                                        t.media.setSize(parentWidth, newHeight);
                                }
 
-                               var layerChildren = t.layers.children;
+                               var layerChildren = t.getElement(t.layers).children;
                                for (var i = 0, total = layerChildren.length; i < total; i++) {
                                        layerChildren[i].style.width = '100%';
                                        layerChildren[i].style.height = '100%';
@@ -4373,22 +4493,31 @@ var MediaElementPlayer = function () {
                key: 'setFillMode',
                value: function setFillMode() {
                        var t = this;
+                       var isIframe = _window2.default.self !== _window2.default.top && _window2.default.frameElement !== null;
+                       var parent = function () {
+                               var parentEl = void 0,
+                                   el = t.getElement(t.container);
 
-                       var parent = void 0,
-                           isIframe = false;
+                               while (el) {
+                                       try {
+                                               if (_constants.IS_FIREFOX && el.tagName.toLowerCase() === 'html' && _window2.default.self !== _window2.default.top && _window2.default.frameElement !== null) {
+                                                       return _window2.default.frameElement;
+                                               } else {
+                                                       parentEl = el.parentElement;
+                                               }
+                                       } catch (e) {
+                                               parentEl = el.parentElement;
+                                       }
 
-                       try {
-                               if (_window2.default.self !== _window2.default.top) {
-                                       isIframe = true;
-                                       parent = _window2.default.frameElement;
-                               } else {
-                                       parent = t.outerContainer;
+                                       if (parentEl && dom.visible(parentEl)) {
+                                               return parentEl;
+                                       }
+                                       el = parentEl;
                                }
-                       } catch (e) {
-                               parent = t.outerContainer;
-                       }
 
-                       var parentStyles = getComputedStyle(parent);
+                               return null;
+                       }();
+                       var parentStyles = parent ? getComputedStyle(parent, null) : getComputedStyle(_document2.default.body, null);
 
                        if (t.node.style.height !== 'none' && t.node.style.height !== t.height) {
                                t.node.style.height = 'auto';
@@ -4428,12 +4557,12 @@ var MediaElementPlayer = function () {
 
                        t.setDimensions('100%', '100%');
 
-                       var poster = t.container.querySelector('.' + t.options.classPrefix + 'poster>img');
+                       var poster = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'poster>img');
                        if (poster) {
                                poster.style.display = '';
                        }
 
-                       var targetElement = t.container.querySelectorAll('object, embed, iframe, video'),
+                       var targetElement = t.getElement(t.container).querySelectorAll('object, embed, iframe, video'),
                            initHeight = t.height,
                            initWidth = t.width,
                            scaleX1 = parentWidth,
@@ -4465,10 +4594,10 @@ var MediaElementPlayer = function () {
                        width = (0, _general.isString)(width) && width.indexOf('%') > -1 ? width : parseFloat(width) + 'px';
                        height = (0, _general.isString)(height) && height.indexOf('%') > -1 ? height : parseFloat(height) + 'px';
 
-                       t.container.style.width = width;
-                       t.container.style.height = height;
+                       t.getElement(t.container).style.width = width;
+                       t.getElement(t.container).style.height = height;
 
-                       var layers = t.layers.children;
+                       var layers = t.getElement(t.layers).children;
                        for (var i = 0, total = layers.length; i < total; i++) {
                                layers[i].style.width = width;
                                layers[i].style.height = height;
@@ -4479,7 +4608,7 @@ var MediaElementPlayer = function () {
                value: function setControlsSize() {
                        var t = this;
 
-                       if (!dom.visible(t.container)) {
+                       if (!dom.visible(t.getElement(t.container))) {
                                return;
                        }
 
@@ -4501,19 +4630,19 @@ var MediaElementPlayer = function () {
 
                                siblingsWidth += totalMargin + (totalMargin === 0 ? railMargin * 2 : railMargin) + 1;
 
-                               t.container.style.minWidth = siblingsWidth + 'px';
+                               t.getElement(t.container).style.minWidth = siblingsWidth + 'px';
 
-                               var event = (0, _general.createEvent)('controlsresize', t.container);
-                               t.container.dispatchEvent(event);
+                               var event = (0, _general.createEvent)('controlsresize', t.getElement(t.container));
+                               t.getElement(t.container).dispatchEvent(event);
                        } else {
-                               var children = t.controls.children;
+                               var children = t.getElement(t.controls).children;
                                var minWidth = 0;
 
                                for (var _i = 0, _total = children.length; _i < _total; _i++) {
                                        minWidth += children[_i].offsetWidth;
                                }
 
-                               t.container.style.minWidth = minWidth + 'px';
+                               t.getElement(t.container).style.minWidth = minWidth + 'px';
                        }
                }
        }, {
@@ -4523,11 +4652,11 @@ var MediaElementPlayer = function () {
                        var t = this;
 
                        if (t.featurePosition[key] !== undefined) {
-                               var child = t.controls.children[t.featurePosition[key] - 1];
+                               var child = t.getElement(t.controls).children[t.featurePosition[key] - 1];
                                child.parentNode.insertBefore(element, child.nextSibling);
                        } else {
-                               t.controls.appendChild(element);
-                               var children = t.controls.children;
+                               t.getElement(t.controls).appendChild(element);
+                               var children = t.getElement(t.controls).children;
                                for (var i = 0, total = children.length; i < total; i++) {
                                        if (element === children[i]) {
                                                t.featurePosition[key] = i;
@@ -4579,35 +4708,39 @@ var MediaElementPlayer = function () {
                value: function setPoster(url) {
                        var t = this;
 
-                       var posterDiv = t.container.querySelector('.' + t.options.classPrefix + 'poster');
+                       if (t.getElement(t.container)) {
+                               var posterDiv = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'poster');
 
-                       if (!posterDiv) {
-                               posterDiv = _document2.default.createElement('div');
-                               posterDiv.className = t.options.classPrefix + 'poster ' + t.options.classPrefix + 'layer';
-                               t.layers.appendChild(posterDiv);
-                       }
+                               if (!posterDiv) {
+                                       posterDiv = _document2.default.createElement('div');
+                                       posterDiv.className = t.options.classPrefix + 'poster ' + t.options.classPrefix + 'layer';
+                                       t.getElement(t.layers).appendChild(posterDiv);
+                               }
 
-                       var posterImg = posterDiv.querySelector('img');
+                               var posterImg = posterDiv.querySelector('img');
 
-                       if (!posterImg && url) {
-                               posterImg = _document2.default.createElement('img');
-                               posterImg.className = t.options.classPrefix + 'poster-img';
-                               posterImg.width = '100%';
-                               posterImg.height = '100%';
-                               posterDiv.style.display = '';
-                               posterDiv.appendChild(posterImg);
-                       }
+                               if (!posterImg && url) {
+                                       posterImg = _document2.default.createElement('img');
+                                       posterImg.className = t.options.classPrefix + 'poster-img';
+                                       posterImg.width = '100%';
+                                       posterImg.height = '100%';
+                                       posterDiv.style.display = '';
+                                       posterDiv.appendChild(posterImg);
+                               }
 
-                       if (url) {
-                               posterImg.setAttribute('src', url);
-                               posterDiv.style.backgroundImage = 'url("' + url + '")';
-                               posterDiv.style.display = '';
-                       } else if (posterImg) {
-                               posterDiv.style.backgroundImage = 'none';
-                               posterDiv.style.display = 'none';
-                               posterImg.remove();
-                       } else {
-                               posterDiv.style.display = 'none';
+                               if (url) {
+                                       posterImg.setAttribute('src', url);
+                                       posterDiv.style.backgroundImage = 'url("' + url + '")';
+                                       posterDiv.style.display = '';
+                               } else if (posterImg) {
+                                       posterDiv.style.backgroundImage = 'none';
+                                       posterDiv.style.display = 'none';
+                                       posterImg.remove();
+                               } else {
+                                       posterDiv.style.display = 'none';
+                               }
+                       } else if (_constants.IS_IPAD && t.options.iPadUseNativeControls || _constants.IS_IPHONE && t.options.iPhoneUseNativeControls || _constants.IS_ANDROID && t.options.AndroidUseNativeControls) {
+                               t.media.originalNode.poster = url;
                        }
                }
        }, {
@@ -4615,7 +4748,7 @@ var MediaElementPlayer = function () {
                value: function changeSkin(className) {
                        var t = this;
 
-                       t.container.className = t.options.classPrefix + 'container ' + className;
+                       t.getElement(t.container).className = t.options.classPrefix + 'container ' + className;
                        t.setPlayerSize(t.width, t.height);
                        t.setControlsSize();
                }
@@ -4671,6 +4804,22 @@ var MediaElementPlayer = function () {
                                }
                        }
                }
+       }, {
+               key: 'buildfeatures',
+               value: function buildfeatures(player, controls, layers, media) {
+                       var t = this;
+
+                       for (var i = 0, total = t.options.features.length; i < total; i++) {
+                               var feature = t.options.features[i];
+                               if (t['build' + feature]) {
+                                       try {
+                                               t['build' + feature](player, controls, layers, media);
+                                       } catch (e) {
+                                               console.error('error building ' + feature, e);
+                                       }
+                               }
+                       }
+               }
        }, {
                key: 'buildposter',
                value: function buildposter(player, controls, layers, media) {
@@ -4682,8 +4831,10 @@ var MediaElementPlayer = function () {
 
                        var posterUrl = media.originalNode.getAttribute('poster');
 
-                       if (player.options.poster !== '' && posterUrl && _constants.IS_IOS) {
-                               media.originalNode.removeAttribute('poster');
+                       if (player.options.poster !== '') {
+                               if (posterUrl && _constants.IS_IOS) {
+                                       media.originalNode.removeAttribute('poster');
+                               }
                                posterUrl = player.options.poster;
                        }
 
@@ -4732,8 +4883,7 @@ var MediaElementPlayer = function () {
                        var t = this,
                            loading = _document2.default.createElement('div'),
                            error = _document2.default.createElement('div'),
-                           bigPlay = _document2.default.createElement('div'),
-                           buffer = controls.querySelector('.' + t.options.classPrefix + 'time-buffering');
+                           bigPlay = _document2.default.createElement('div');
 
                        loading.style.display = 'none';
                        loading.className = t.options.classPrefix + 'overlay ' + t.options.classPrefix + 'layer';
@@ -4750,7 +4900,7 @@ var MediaElementPlayer = function () {
                        bigPlay.addEventListener('click', function () {
                                if (t.options.clickToPlayPause) {
 
-                                       var button = t.container.querySelector('.' + t.options.classPrefix + 'overlay-button'),
+                                       var button = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'overlay-button'),
                                            pressed = button.getAttribute('aria-pressed');
 
                                        if (t.paused) {
@@ -4760,7 +4910,7 @@ var MediaElementPlayer = function () {
                                        }
 
                                        button.setAttribute('aria-pressed', !!pressed);
-                                       t.container.focus();
+                                       t.getElement(t.container).focus();
                                }
                        });
 
@@ -4785,35 +4935,23 @@ var MediaElementPlayer = function () {
                        media.addEventListener('play', function () {
                                bigPlay.style.display = 'none';
                                loading.style.display = 'none';
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
                                error.style.display = 'none';
                                hasError = false;
                        });
                        media.addEventListener('playing', function () {
                                bigPlay.style.display = 'none';
                                loading.style.display = 'none';
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
                                error.style.display = 'none';
                                hasError = false;
                        });
                        media.addEventListener('seeking', function () {
                                bigPlay.style.display = 'none';
                                loading.style.display = '';
-                               if (buffer !== null) {
-                                       buffer.style.display = '';
-                               }
                                hasError = false;
                        });
                        media.addEventListener('seeked', function () {
                                bigPlay.style.display = t.paused && !_constants.IS_STOCK_ANDROID ? '' : 'none';
                                loading.style.display = 'none';
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
                                hasError = false;
                        });
                        media.addEventListener('pause', function () {
@@ -4821,24 +4959,15 @@ var MediaElementPlayer = function () {
                                if (!_constants.IS_STOCK_ANDROID && !hasError) {
                                        bigPlay.style.display = '';
                                }
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
                                hasError = false;
                        });
                        media.addEventListener('waiting', function () {
                                loading.style.display = '';
-                               if (buffer !== null) {
-                                       buffer.style.display = '';
-                               }
                                hasError = false;
                        });
 
                        media.addEventListener('loadeddata', function () {
                                loading.style.display = '';
-                               if (buffer !== null) {
-                                       buffer.style.display = '';
-                               }
 
                                if (_constants.IS_ANDROID) {
                                        media.canplayTimeout = setTimeout(function () {
@@ -4853,9 +4982,6 @@ var MediaElementPlayer = function () {
                        });
                        media.addEventListener('canplay', function () {
                                loading.style.display = 'none';
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
 
                                clearTimeout(media.canplayTimeout);
                                hasError = false;
@@ -4865,12 +4991,15 @@ var MediaElementPlayer = function () {
                                t._handleError(e, t.media, t.node);
                                loading.style.display = 'none';
                                bigPlay.style.display = 'none';
-                               if (buffer !== null) {
-                                       buffer.style.display = 'none';
-                               }
                                hasError = true;
                        });
 
+                       media.addEventListener('loadedmetadata', function () {
+                               if (!t.controlsEnabled) {
+                                       t.enableControls();
+                               }
+                       });
+
                        media.addEventListener('keydown', function (e) {
                                t.onkeydown(player, media, e);
                                hasError = false;
@@ -4882,7 +5011,7 @@ var MediaElementPlayer = function () {
 
                        var t = this;
 
-                       t.container.addEventListener('keydown', function () {
+                       t.getElement(t.container).addEventListener('keydown', function () {
                                t.keyboardAction = true;
                        });
 
@@ -4914,6 +5043,7 @@ var MediaElementPlayer = function () {
                                                        keyAction.action(player, media, e.keyCode, e);
                                                        e.preventDefault();
                                                        e.stopPropagation();
+                                                       return;
                                                }
                                        }
                                }
@@ -4995,7 +5125,7 @@ var MediaElementPlayer = function () {
                                var feature = t.options.features[featureIndex];
                                if (t['clean' + feature]) {
                                        try {
-                                               t['clean' + feature](t, t.layers, t.controls, t.media);
+                                               t['clean' + feature](t, t.getElement(t.layers), t.getElement(t.controls), t.media);
                                        } catch (e) {
                                                console.error('error cleaning ' + feature, e);
                                        }
@@ -5024,11 +5154,13 @@ var MediaElementPlayer = function () {
                        t.node.style.width = nativeWidth;
                        t.node.style.height = nativeHeight;
 
+                       t.setPlayerSize(0, 0);
+
                        if (!t.isDynamic) {
                                (function () {
                                        t.node.setAttribute('controls', true);
                                        t.node.setAttribute('id', t.node.getAttribute('id').replace('_' + rendererName, '').replace('_from_mejs', ''));
-                                       var poster = t.container.querySelector('.' + t.options.classPrefix + 'poster>img');
+                                       var poster = t.getElement(t.container).querySelector('.' + t.options.classPrefix + 'poster>img');
                                        if (poster) {
                                                t.node.setAttribute('poster', poster.src);
                                        }
@@ -5046,7 +5178,7 @@ var MediaElementPlayer = function () {
 
                                        var node = t.node.cloneNode();
                                        node.style.display = '';
-                                       t.container.parentNode.insertBefore(node, t.container);
+                                       t.getElement(t.container).parentNode.insertBefore(node, t.getElement(t.container));
                                        t.node.remove();
 
                                        if (t.mediaFiles) {
@@ -5083,7 +5215,7 @@ var MediaElementPlayer = function () {
                                        delete t.trackFiles;
                                })();
                        } else {
-                               t.container.parentNode.insertBefore(t.node, t.container);
+                               t.getElement(t.container).parentNode.insertBefore(t.node, t.getElement(t.container));
                        }
 
                        if (typeof t.media.renderer.destroy === 'function') {
@@ -5092,10 +5224,10 @@ var MediaElementPlayer = function () {
 
                        delete _mejs2.default.players[t.id];
 
-                       if (_typeof(t.container) === 'object') {
-                               var offscreen = t.container.parentNode.querySelector('.' + t.options.classPrefix + 'offscreen');
+                       if (_typeof(t.getElement(t.container)) === 'object') {
+                               var offscreen = t.getElement(t.container).parentNode.querySelector('.' + t.options.classPrefix + 'offscreen');
                                offscreen.remove();
-                               t.container.remove();
+                               t.getElement(t.container).remove();
                        }
                        t.globalUnbind('resize', t.globalResizeCallback);
                        t.globalUnbind('keydown', t.globalKeydownCallback);
@@ -5161,6 +5293,7 @@ var MediaElementPlayer = function () {
 }();
 
 _window2.default.MediaElementPlayer = MediaElementPlayer;
+_mejs2.default.MediaElementPlayer = MediaElementPlayer;
 
 exports.default = MediaElementPlayer;
 
@@ -5477,12 +5610,12 @@ var DashNativeRenderer = {
                options = Object.assign(options, mediaElement.options);
 
                var props = _mejs2.default.html5media.properties,
-                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']),
+                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']).filter(function (e) {
+                       return e !== 'error';
+               }),
                    attachNativeEvents = function attachNativeEvents(e) {
-                       if (e.type !== 'error') {
-                               var _event = (0, _general.createEvent)(e.type, mediaElement);
-                               mediaElement.dispatchEvent(_event);
-                       }
+                       var event = (0, _general.createEvent)(e.type, mediaElement);
+                       mediaElement.dispatchEvent(event);
                },
                    assignGettersSetters = function assignGettersSetters(propName) {
                        var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
@@ -5557,25 +5690,21 @@ var DashNativeRenderer = {
                                assignEvents(events[_i3]);
                        }
 
-                       var assignMdashEvents = function assignMdashEvents(name, data) {
-                               if (name.toLowerCase() === 'error') {
-                                       mediaElement.generateError(data.message, node.src);
-                                       console.error(data);
+                       var assignMdashEvents = function assignMdashEvents(e) {
+                               if (e.type.toLowerCase() === 'error') {
+                                       mediaElement.generateError(e.message, node.src);
+                                       console.error(e);
                                } else {
-                                       var _event2 = (0, _general.createEvent)(name, mediaElement);
-                                       _event2.data = data;
-                                       mediaElement.dispatchEvent(_event2);
+                                       var _event = (0, _general.createEvent)(e.type, mediaElement);
+                                       _event.data = e;
+                                       mediaElement.dispatchEvent(_event);
                                }
                        };
 
                        for (var eventType in dashEvents) {
                                if (dashEvents.hasOwnProperty(eventType)) {
                                        dashPlayer.on(dashEvents[eventType], function (e) {
-                                               for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
-                                                       args[_key - 1] = arguments[_key];
-                                               }
-
-                                               return assignMdashEvents(e.type, args);
+                                               return assignMdashEvents(e);
                                        });
                                }
                        }
@@ -5733,6 +5862,7 @@ var FlashMediaElementRenderer = {
        create: function create(mediaElement, options, mediaFiles) {
 
                var flash = {};
+               var isActive = false;
 
                flash.options = options;
                flash.id = mediaElement.id + '_' + flash.options.prefix;
@@ -5800,21 +5930,23 @@ var FlashMediaElementRenderer = {
                var methods = _mejs2.default.html5media.methods,
                    assignMethods = function assignMethods(methodName) {
                        flash[methodName] = function () {
-                               if (flash.flashApi !== null) {
-                                       if (flash.flashApi['fire_' + methodName]) {
-                                               try {
-                                                       flash.flashApi['fire_' + methodName]();
-                                               } catch (e) {
+                               if (isActive) {
+                                       if (flash.flashApi !== null) {
+                                               if (flash.flashApi['fire_' + methodName]) {
+                                                       try {
+                                                               flash.flashApi['fire_' + methodName]();
+                                                       } catch (e) {
+                                                               
+                                                       }
+                                               } else {
                                                        
                                                }
                                        } else {
-                                               
+                                               flash.flashApiStack.push({
+                                                       type: 'call',
+                                                       methodName: methodName
+                                               });
                                        }
-                               } else {
-                                       flash.flashApiStack.push({
-                                               type: 'call',
-                                               methodName: methodName
-                                       });
                                }
                        };
                };
@@ -5886,16 +6018,28 @@ var FlashMediaElementRenderer = {
                        flashVars.push('pseudostreamtype=' + flash.options.pseudoStreamingType);
                }
 
+               if (flash.options.streamDelimiter) {
+                       flashVars.push('streamdelimiter=' + encodeURIComponent(flash.options.streamDelimiter));
+               }
+
+               if (flash.options.proxyType) {
+                       flashVars.push('proxytype=' + flash.options.proxyType);
+               }
+
                mediaElement.appendChild(flash.flashWrapper);
                mediaElement.originalNode.style.display = 'none';
 
                var settings = [];
 
-               if (_constants.IS_IE) {
+               if (_constants.IS_IE || _constants.IS_EDGE) {
                        var specialIEContainer = _document2.default.createElement('div');
                        flash.flashWrapper.appendChild(specialIEContainer);
 
-                       settings = ['classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"', 'codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"', 'id="__' + flash.id + '"', 'width="' + flashWidth + '"', 'height="' + flashHeight + '"'];
+                       if (_constants.IS_EDGE) {
+                               settings = ['type="application/x-shockwave-flash"', 'data="' + flash.options.pluginPath + flash.options.filename + '"', 'id="__' + flash.id + '"', 'width="' + flashWidth + '"', 'height="' + flashHeight + '\'"'];
+                       } else {
+                               settings = ['classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"', 'codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"', 'id="__' + flash.id + '"', 'width="' + flashWidth + '"', 'height="' + flashHeight + '"'];
+                       }
 
                        if (!isVideo) {
                                settings.push('style="clip: rect(0 0 0 0); position: absolute;"');
@@ -5904,10 +6048,13 @@ var FlashMediaElementRenderer = {
                        specialIEContainer.outerHTML = '<object ' + settings.join(' ') + '>' + ('<param name="movie" value="' + flash.options.pluginPath + flash.options.filename + '?x=' + new Date() + '" />') + ('<param name="flashvars" value="' + flashVars.join('&amp;') + '" />') + '<param name="quality" value="high" />' + '<param name="bgcolor" value="#000000" />' + '<param name="wmode" value="transparent" />' + ('<param name="allowScriptAccess" value="' + flash.options.shimScriptAccess + '" />') + '<param name="allowFullScreen" value="true" />' + ('<div>' + _i18n2.default.t('mejs.install-flash') + '</div>') + '</object>';
                } else {
 
-                       settings = ['id="__' + flash.id + '"', 'name="__' + flash.id + '"', 'play="true"', 'loop="false"', 'quality="high"', 'bgcolor="#000000"', 'wmode="transparent"', 'allowScriptAccess="' + flash.options.shimScriptAccess + '"', 'allowFullScreen="true"', 'type="application/x-shockwave-flash"', 'pluginspage="//www.macromedia.com/go/getflashplayer"', 'src="' + flash.options.pluginPath + flash.options.filename + '"', 'flashvars="' + flashVars.join('&') + '"', 'width="' + flashWidth + '"', 'height="' + flashHeight + '"'];
+                       settings = ['id="__' + flash.id + '"', 'name="__' + flash.id + '"', 'play="true"', 'loop="false"', 'quality="high"', 'bgcolor="#000000"', 'wmode="transparent"', 'allowScriptAccess="' + flash.options.shimScriptAccess + '"', 'allowFullScreen="true"', 'type="application/x-shockwave-flash"', 'pluginspage="//www.macromedia.com/go/getflashplayer"', 'src="' + flash.options.pluginPath + flash.options.filename + '"', 'flashvars="' + flashVars.join('&') + '"'];
 
-                       if (!isVideo) {
-                               settings.push('style="clip: rect(0 0 0 0); position: absolute;"');
+                       if (isVideo) {
+                               settings.push('width="' + flashWidth + '"');
+                               settings.push('height="' + flashHeight + '"');
+                       } else {
+                               settings.push('style="position: fixed; left: -9999em; top: -9999em;"');
                        }
 
                        flash.flashWrapper.innerHTML = '<embed ' + settings.join(' ') + '>';
@@ -5916,11 +6063,13 @@ var FlashMediaElementRenderer = {
                flash.flashNode = flash.flashWrapper.lastChild;
 
                flash.hide = function () {
+                       isActive = false;
                        if (isVideo) {
                                flash.flashNode.style.display = 'none';
                        }
                };
                flash.show = function () {
+                       isActive = true;
                        if (isVideo) {
                                flash.flashNode.style.display = '';
                        }
@@ -5985,7 +6134,11 @@ if (hasFlash) {
 
                        pseudoStreamingStartQueryParam: 'start',
 
-                       pseudoStreamingType: 'byte'
+                       pseudoStreamingType: 'byte',
+
+                       proxyType: '',
+
+                       streamDelimiter: ''
                },
 
                canPlayType: function canPlayType(type) {
@@ -6095,7 +6248,7 @@ var NativeFlv = {
                                NativeFlv._createPlayer(settings);
                        });
                } else {
-                       settings.options.path = typeof settings.options.path === 'string' ? settings.options.path : 'https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.3.2/flv.min.js';
+                       settings.options.path = typeof settings.options.path === 'string' ? settings.options.path : 'https://cdn.jsdelivr.net/npm/flv.js@latest';
 
                        NativeFlv.promise = NativeFlv.promise || (0, _dom.loadScript)(settings.options.path);
                        NativeFlv.promise.then(function () {
@@ -6109,7 +6262,7 @@ var NativeFlv = {
        _createPlayer: function _createPlayer(settings) {
                flvjs.LoggingControl.enableDebug = settings.options.debug;
                flvjs.LoggingControl.enableVerbose = settings.options.debug;
-               var player = flvjs.createPlayer(settings.options);
+               var player = flvjs.createPlayer(settings.options, settings.configs);
                _window2.default['__ready__' + settings.id](player);
                return player;
        }
@@ -6120,7 +6273,7 @@ var FlvNativeRenderer = {
        options: {
                prefix: 'native_flv',
                flv: {
-                       path: 'https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.3.2/flv.min.js',
+                       path: 'https://cdn.jsdelivr.net/npm/flv.js@latest',
 
                        cors: true,
                        debug: false
@@ -6143,12 +6296,12 @@ var FlvNativeRenderer = {
                options = Object.assign(options, mediaElement.options);
 
                var props = _mejs2.default.html5media.properties,
-                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']),
+                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']).filter(function (e) {
+                       return e !== 'error';
+               }),
                    attachNativeEvents = function attachNativeEvents(e) {
-                       if (e.type !== 'error') {
-                               var _event = (0, _general.createEvent)(e.type, mediaElement);
-                               mediaElement.dispatchEvent(_event);
-                       }
+                       var event = (0, _general.createEvent)(e.type, mediaElement);
+                       mediaElement.dispatchEvent(event);
                },
                    assignGettersSetters = function assignGettersSetters(propName) {
                        var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
@@ -6168,6 +6321,7 @@ var FlvNativeRenderer = {
                                                        _flvOptions.cors = options.flv.cors;
                                                        _flvOptions.debug = options.flv.debug;
                                                        _flvOptions.path = options.flv.path;
+                                                       var _flvConfigs = options.flv.configs;
 
                                                        flvPlayer.destroy();
                                                        for (var i = 0, total = events.length; i < total; i++) {
@@ -6175,6 +6329,7 @@ var FlvNativeRenderer = {
                                                        }
                                                        flvPlayer = NativeFlv._createPlayer({
                                                                options: _flvOptions,
+                                                               configs: _flvConfigs,
                                                                id: id
                                                        });
                                                        flvPlayer.attachMediaElement(node);
@@ -6215,9 +6370,9 @@ var FlvNativeRenderer = {
                                        var message = data[0] + ': ' + data[1] + ' ' + data[2].msg;
                                        mediaElement.generateError(message, node.src);
                                } else {
-                                       var _event2 = (0, _general.createEvent)(name, mediaElement);
-                                       _event2.data = data;
-                                       mediaElement.dispatchEvent(_event2);
+                                       var _event = (0, _general.createEvent)(name, mediaElement);
+                                       _event.data = data;
+                                       mediaElement.dispatchEvent(_event);
                                }
                        };
 
@@ -6259,6 +6414,7 @@ var FlvNativeRenderer = {
                flvOptions.cors = options.flv.cors;
                flvOptions.debug = options.flv.debug;
                flvOptions.path = options.flv.path;
+               var flvConfigs = options.flv.configs;
 
                node.setSize = function (width, height) {
                        node.style.width = width + 'px';
@@ -6290,6 +6446,7 @@ var FlvNativeRenderer = {
 
                mediaElement.promises.push(NativeFlv.load({
                        options: flvOptions,
+                       configs: flvConfigs,
                        id: id
                }));
 
@@ -6340,7 +6497,7 @@ var NativeHls = {
                                NativeHls._createPlayer(settings);
                        });
                } else {
-                       settings.options.path = typeof settings.options.path === 'string' ? settings.options.path : 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/0.7.11/hls.min.js';
+                       settings.options.path = typeof settings.options.path === 'string' ? settings.options.path : 'https://cdn.jsdelivr.net/npm/hls.js@latest';
 
                        NativeHls.promise = NativeHls.promise || (0, _dom.loadScript)(settings.options.path);
                        NativeHls.promise.then(function () {
@@ -6363,7 +6520,7 @@ var HlsNativeRenderer = {
        options: {
                prefix: 'native_hls',
                hls: {
-                       path: 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/0.7.11/hls.min.js',
+                       path: 'https://cdn.jsdelivr.net/npm/hls.js@latest',
 
                        autoStartLoad: false,
                        debug: false
@@ -6382,19 +6539,21 @@ var HlsNativeRenderer = {
                    autoplay = originalNode.autoplay;
 
                var hlsPlayer = null,
-                   node = null;
+                   node = null,
+                   index = 0,
+                   total = mediaFiles.length;
 
                node = originalNode.cloneNode(true);
                options = Object.assign(options, mediaElement.options);
                options.hls.autoStartLoad = preload && preload !== 'none' || autoplay;
 
                var props = _mejs2.default.html5media.properties,
-                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']),
+                   events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']).filter(function (e) {
+                       return e !== 'error';
+               }),
                    attachNativeEvents = function attachNativeEvents(e) {
-                       if (e.type !== 'error') {
-                               var _event = (0, _general.createEvent)(e.type, mediaElement);
-                               mediaElement.dispatchEvent(_event);
-                       }
+                       var event = (0, _general.createEvent)(e.type, mediaElement);
+                       mediaElement.dispatchEvent(event);
                },
                    assignGettersSetters = function assignGettersSetters(propName) {
                        var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
@@ -6409,7 +6568,7 @@ var HlsNativeRenderer = {
                                                node[propName] = (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value.src ? value.src : value;
                                                if (hlsPlayer !== null) {
                                                        hlsPlayer.destroy();
-                                                       for (var i = 0, total = events.length; i < total; i++) {
+                                                       for (var i = 0, _total = events.length; i < _total; i++) {
                                                                node.removeEventListener(events[i], attachNativeEvents);
                                                        }
                                                        hlsPlayer = NativeHls._createPlayer({
@@ -6426,7 +6585,7 @@ var HlsNativeRenderer = {
                        };
                };
 
-               for (var i = 0, total = props.length; i < total; i++) {
+               for (var i = 0, _total2 = props.length; i < _total2; i++) {
                        assignGettersSetters(props[i]);
                }
 
@@ -6444,7 +6603,7 @@ var HlsNativeRenderer = {
                                node.addEventListener(eventName, attachNativeEvents);
                        };
 
-                       for (var _i = 0, _total = events.length; _i < _total; _i++) {
+                       for (var _i = 0, _total3 = events.length; _i < _total3; _i++) {
                                assignEvents(events[_i]);
                        }
 
@@ -6452,7 +6611,8 @@ var HlsNativeRenderer = {
                            recoverSwapAudioCodecDate = void 0;
                        var assignHlsEvents = function assignHlsEvents(name, data) {
                                if (name === 'hlsError') {
-                                       console.warn(name, data);
+                                       console.warn(data);
+                                       data = data[1];
 
                                        if (data.fatal) {
                                                switch (data.type) {
@@ -6467,15 +6627,27 @@ var HlsNativeRenderer = {
                                                                        hlsPlayer.swapAudioCodec();
                                                                        hlsPlayer.recoverMediaError();
                                                                } else {
-                                                                       var _message = 'Cannot recover, last media error recovery failed';
-                                                                       mediaElement.generateError(_message, node.src);
-                                                                       console.error(_message);
+                                                                       var message = 'Cannot recover, last media error recovery failed';
+                                                                       mediaElement.generateError(message, node.src);
+                                                                       console.error(message);
                                                                }
                                                                break;
                                                        case 'networkError':
-                                                               var message = 'Network error';
-                                                               mediaElement.generateError(message, node.src);
-                                                               console.error(message);
+                                                               if (data.details === 'manifestLoadError') {
+                                                                       if (index < total && mediaFiles[index + 1] !== undefined) {
+                                                                               node.setSrc(mediaFiles[index++].src);
+                                                                               node.load();
+                                                                               node.play();
+                                                                       } else {
+                                                                               var _message = 'Network error';
+                                                                               mediaElement.generateError(_message, mediaFiles);
+                                                                               console.error(_message);
+                                                                       }
+                                                               } else {
+                                                                       var _message2 = 'Network error';
+                                                                       mediaElement.generateError(_message2, mediaFiles);
+                                                                       console.error(_message2);
+                                                               }
                                                                break;
                                                        default:
                                                                hlsPlayer.destroy();
@@ -6483,9 +6655,9 @@ var HlsNativeRenderer = {
                                                }
                                        }
                                } else {
-                                       var _event2 = (0, _general.createEvent)(name, mediaElement);
-                                       _event2.data = data;
-                                       mediaElement.dispatchEvent(_event2);
+                                       var _event = (0, _general.createEvent)(name, mediaElement);
+                                       _event.data = data;
+                                       mediaElement.dispatchEvent(_event);
                                }
                        };
 
@@ -6506,10 +6678,10 @@ var HlsNativeRenderer = {
                        }
                };
 
-               if (mediaFiles && mediaFiles.length > 0) {
-                       for (var _i2 = 0, _total2 = mediaFiles.length; _i2 < _total2; _i2++) {
-                               if (_renderer.renderer.renderers[options.prefix].canPlayType(mediaFiles[_i2].type)) {
-                                       node.setAttribute('src', mediaFiles[_i2].src);
+               if (total > 0) {
+                       for (; index < total; index++) {
+                               if (_renderer.renderer.renderers[options.prefix].canPlayType(mediaFiles[index].type)) {
+                                       node.setAttribute('src', mediaFiles[index].src);
                                        break;
                                }
                        }
@@ -6622,6 +6794,7 @@ var HtmlMediaElement = {
        create: function create(mediaElement, options, mediaFiles) {
 
                var id = mediaElement.id + '_' + options.prefix;
+               var isActive = false;
 
                var node = null;
 
@@ -6649,19 +6822,23 @@ var HtmlMediaElement = {
                        };
                };
 
-               for (var i = 0, total = props.length; i < total; i++) {
+               for (var i = 0, _total = props.length; i < _total; i++) {
                        assignGettersSetters(props[i]);
                }
 
-               var events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']),
+               var events = _mejs2.default.html5media.events.concat(['click', 'mouseover', 'mouseout']).filter(function (e) {
+                       return e !== 'error';
+               }),
                    assignEvents = function assignEvents(eventName) {
                        node.addEventListener(eventName, function (e) {
-                               var event = (0, _general.createEvent)(e.type, mediaElement);
-                               mediaElement.dispatchEvent(event);
+                               if (isActive) {
+                                       var _event = (0, _general.createEvent)(e.type, e.target);
+                                       mediaElement.dispatchEvent(_event);
+                               }
                        });
                };
 
-               for (var _i = 0, _total = events.length; _i < _total; _i++) {
+               for (var _i = 0, _total2 = events.length; _i < _total2; _i++) {
                        assignEvents(events[_i]);
                }
 
@@ -6672,26 +6849,42 @@ var HtmlMediaElement = {
                };
 
                node.hide = function () {
+                       isActive = false;
                        node.style.display = 'none';
 
                        return node;
                };
 
                node.show = function () {
+                       isActive = true;
                        node.style.display = '';
 
                        return node;
                };
 
-               if (mediaFiles && mediaFiles.length > 0) {
-                       for (var _i2 = 0, _total2 = mediaFiles.length; _i2 < _total2; _i2++) {
-                               if (_renderer.renderer.renderers[options.prefix].canPlayType(mediaFiles[_i2].type)) {
-                                       node.setAttribute('src', mediaFiles[_i2].src);
+               var index = 0,
+                   total = mediaFiles.length;
+               if (total > 0) {
+                       for (; index < total; index++) {
+                               if (_renderer.renderer.renderers[options.prefix].canPlayType(mediaFiles[index].type)) {
+                                       node.setAttribute('src', mediaFiles[index].src);
                                        break;
                                }
                        }
                }
 
+               node.addEventListener('error', function (e) {
+                       if (e.target.error.code === 4 && isActive) {
+                               if (index < total && mediaFiles[index + 1] !== undefined) {
+                                       node.src = mediaFiles[index++].src;
+                                       node.load();
+                                       node.play();
+                               } else {
+                                       mediaElement.generateError('Media error: Format(s) not supported or source(s) not found', mediaFiles);
+                               }
+                       }
+               });
+
                var event = (0, _general.createEvent)('rendererready', node);
                mediaElement.dispatchEvent(event);
 
@@ -7000,6 +7193,29 @@ var YouTubeIframeRenderer = {
                        assignMethods(methods[_i]);
                }
 
+               var errorHandler = function errorHandler(error) {
+                       var message = '';
+                       switch (error.data) {
+                               case 2:
+                                       message = 'The request contains an invalid parameter value. Verify that video ID has 11 characters and that contains no invalid characters, such as exclamation points or asterisks.';
+                                       break;
+                               case 5:
+                                       message = 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.';
+                                       break;
+                               case 100:
+                                       message = 'The video requested was not found. Either video has been removed or has been marked as private.';
+                                       break;
+                               case 101:
+                               case 105:
+                                       message = 'The owner of the requested video does not allow it to be played in embedded players.';
+                                       break;
+                               default:
+                                       message = 'Unknown error.';
+                                       break;
+                       }
+                       mediaElement.generateError('Code ' + error.data + ': ' + message, mediaFiles);
+               };
+
                var youtubeContainer = _document2.default.createElement('div');
                youtubeContainer.id = youtube.id;
 
@@ -7027,9 +7243,6 @@ var YouTubeIframeRenderer = {
                                showinfo: 0,
                                modestbranding: 0,
                                html5: 1,
-                               playsinline: 0,
-                               start: 0,
-                               end: 0,
                                iv_load_policy: 3
                        }, youtube.options.youtube),
                        origin: _window2.default.location.host,
@@ -7059,7 +7272,7 @@ var YouTubeIframeRenderer = {
 
                                        youTubeIframe = youTubeApi.getIframe();
 
-                                       if (mediaElement.originalNode.getAttribute('muted')) {
+                                       if (mediaElement.originalNode.muted) {
                                                youTubeApi.mute();
                                        }
 
@@ -7126,25 +7339,29 @@ var YouTubeIframeRenderer = {
                                        }
                                },
                                onError: function onError(e) {
-                                       var event = (0, _general.createEvent)('error', youtube);
-                                       event.data = e.data;
-                                       mediaElement.dispatchEvent(event);
+                                       return errorHandler(e);
                                }
                        }
                };
 
-               if (isAudio) {
+               if (isAudio || mediaElement.originalNode.hasAttribute('playsinline')) {
                        youtubeSettings.playerVars.playsinline = 1;
                }
 
+               if (mediaElement.originalNode.controls) {
+                       youtubeSettings.playerVars.controls = 1;
+               }
                if (mediaElement.originalNode.autoplay) {
                        youtubeSettings.playerVars.autoplay = 1;
                }
-
                if (mediaElement.originalNode.loop) {
                        youtubeSettings.playerVars.loop = 1;
                }
 
+               if ((youtubeSettings.playerVars.loop && parseInt(youtubeSettings.playerVars.loop, 10) === 1 || mediaElement.originalNode.src.indexOf('loop=') > -1) && !youtubeSettings.playerVars.playlist && mediaElement.originalNode.src.indexOf('playlist=') === -1) {
+                       youtubeSettings.playerVars.playlist = YouTubeApi.getYouTubeId(mediaElement.originalNode.src);
+               }
+
                YouTubeApi.enqueueIframe(youtubeSettings);
 
                youtube.onEvent = function (eventName, player, _youTubeState) {
@@ -7214,7 +7431,7 @@ _renderer.renderer.add(YouTubeIframeRenderer);
 Object.defineProperty(exports, "__esModule", {
        value: true
 });
-exports.cancelFullScreen = exports.requestFullScreen = exports.isFullScreen = exports.FULLSCREEN_EVENT_NAME = exports.HAS_NATIVE_FULLSCREEN_ENABLED = exports.HAS_TRUE_NATIVE_FULLSCREEN = exports.HAS_IOS_FULLSCREEN = exports.HAS_MS_NATIVE_FULLSCREEN = exports.HAS_MOZ_NATIVE_FULLSCREEN = exports.HAS_WEBKIT_NATIVE_FULLSCREEN = exports.HAS_NATIVE_FULLSCREEN = exports.SUPPORTS_NATIVE_HLS = exports.SUPPORT_POINTER_EVENTS = exports.HAS_MSE = exports.IS_STOCK_ANDROID = exports.IS_SAFARI = exports.IS_FIREFOX = exports.IS_CHROME = exports.IS_EDGE = exports.IS_IE = exports.IS_ANDROID = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = exports.UA = exports.NAV = undefined;
+exports.cancelFullScreen = exports.requestFullScreen = exports.isFullScreen = exports.FULLSCREEN_EVENT_NAME = exports.HAS_NATIVE_FULLSCREEN_ENABLED = exports.HAS_TRUE_NATIVE_FULLSCREEN = exports.HAS_IOS_FULLSCREEN = exports.HAS_MS_NATIVE_FULLSCREEN = exports.HAS_MOZ_NATIVE_FULLSCREEN = exports.HAS_WEBKIT_NATIVE_FULLSCREEN = exports.HAS_NATIVE_FULLSCREEN = exports.SUPPORTS_NATIVE_HLS = exports.SUPPORT_PASSIVE_EVENT = exports.SUPPORT_POINTER_EVENTS = exports.HAS_MSE = exports.IS_STOCK_ANDROID = exports.IS_SAFARI = exports.IS_FIREFOX = exports.IS_CHROME = exports.IS_EDGE = exports.IS_IE = exports.IS_ANDROID = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = exports.UA = exports.NAV = undefined;
 
 var _window = _dereq_(3);
 
@@ -7261,6 +7478,20 @@ var SUPPORT_POINTER_EVENTS = exports.SUPPORT_POINTER_EVENTS = function () {
        return !!supports;
 }();
 
+var SUPPORT_PASSIVE_EVENT = exports.SUPPORT_PASSIVE_EVENT = function () {
+       var supportsPassive = false;
+       try {
+               var opts = Object.defineProperty({}, 'passive', {
+                       get: function get() {
+                               supportsPassive = true;
+                       }
+               });
+               _window2.default.addEventListener('test', null, opts);
+       } catch (e) {}
+
+       return supportsPassive;
+}();
+
 var html5Elements = ['source', 'track', 'audio', 'video'];
 var video = void 0;
 
@@ -7367,6 +7598,7 @@ _mejs2.default.Features.isStockAndroid = IS_STOCK_ANDROID;
 _mejs2.default.Features.hasMSE = HAS_MSE;
 _mejs2.default.Features.supportsNativeHLS = SUPPORTS_NATIVE_HLS;
 _mejs2.default.Features.supportsPointerEvents = SUPPORT_POINTER_EVENTS;
+_mejs2.default.Features.supportsPassiveEvent = SUPPORT_PASSIVE_EVENT;
 _mejs2.default.Features.hasiOSFullScreen = HAS_IOS_FULLSCREEN;
 _mejs2.default.Features.hasNativeFullscreen = HAS_NATIVE_FULLSCREEN;
 _mejs2.default.Features.hasWebkitNativeFullScreen = HAS_WEBKIT_NATIVE_FULLSCREEN;
@@ -7529,7 +7761,10 @@ function siblings(el, filter) {
 }
 
 function visible(elem) {
-       return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
+       if (elem.getClientRects !== undefined && elem.getClientRects === 'function') {
+               return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
+       }
+       return !!(elem.offsetWidth || elem.offsetHeight);
 }
 
 function ajax(url, dataType, success, error) {
@@ -7987,9 +8222,9 @@ if (window.Element && !Element.prototype.closest) {
 })();
 
 if (/firefox/i.test(navigator.userAgent)) {
-       window.mediaElementJsOldGetComputedStyle = window.getComputedStyle;
+       var getComputedStyle = window.getComputedStyle;
        window.getComputedStyle = function (el, pseudoEl) {
-               var t = window.mediaElementJsOldGetComputedStyle(el, pseudoEl);
+               var t = getComputedStyle(el, pseudoEl);
                return t === null ? { getPropertyValue: function getPropertyValue() {} } : t;
        };
 }
@@ -8045,6 +8280,7 @@ function secondsToTimeCode(time) {
        var showFrameCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
        var fps = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 25;
        var secondsDecimalLength = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+       var timeFormat = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'hh:mm:ss';
 
 
        time = !time || typeof time !== 'number' || time < 0 ? 0 : time;
@@ -8083,7 +8319,7 @@ function secondsToTimeCode(time) {
                if (showFrameCount) {
                        seconds = timeBaseDivision % 60;
                } else {
-                       seconds = (f / timeBase % 60).toFixed(secondsDecimalLength);
+                       seconds = Math.floor(f / timeBase % 60).toFixed(secondsDecimalLength);
                }
        } else {
                hours = Math.floor(time / 3600) % 24;
@@ -8091,21 +8327,38 @@ function secondsToTimeCode(time) {
                if (showFrameCount) {
                        seconds = Math.floor(time % 60);
                } else {
-                       seconds = (time % 60).toFixed(secondsDecimalLength);
+                       seconds = Math.floor(time % 60).toFixed(secondsDecimalLength);
                }
        }
        hours = hours <= 0 ? 0 : hours;
        minutes = minutes <= 0 ? 0 : minutes;
        seconds = seconds <= 0 ? 0 : seconds;
 
-       var result = forceHours || hours > 0 ? (hours < 10 ? '0' + hours : hours) + ':' : '';
-       result += (minutes < 10 ? '0' + minutes : minutes) + ':';
-       result += '' + (seconds < 10 ? '0' + seconds : seconds);
+       seconds = seconds === 60 ? 0 : seconds;
+       minutes = minutes === 60 ? 0 : minutes;
+
+       var timeFormatFrags = timeFormat.split(':');
+       var timeFormatSettings = {};
+       for (var i = 0, total = timeFormatFrags.length; i < total; ++i) {
+               var unique = '';
+               for (var j = 0, t = timeFormatFrags[i].length; j < t; j++) {
+                       if (unique.indexOf(timeFormatFrags[i][j]) < 0) {
+                               unique += timeFormatFrags[i][j];
+                       }
+               }
+               if (~['f', 's', 'm', 'h'].indexOf(unique)) {
+                       timeFormatSettings[unique] = timeFormatFrags[i].length;
+               }
+       }
+
+       var result = forceHours || hours > 0 ? (hours < 10 && timeFormatSettings.h > 1 ? '0' + hours : hours) + ':' : '';
+       result += (minutes < 10 && timeFormatSettings.m > 1 ? '0' + minutes : minutes) + ':';
+       result += '' + (seconds < 10 && timeFormatSettings.s > 1 ? '0' + seconds : seconds);
 
        if (showFrameCount) {
                frames = (f % timeBase).toFixed(0);
                frames = frames <= 0 ? 0 : frames;
-               result += frames < 10 ? frameSep + '0' + frames : '' + frameSep + frames;
+               result += frames < 10 && timeFormatSettings.f ? frameSep + '0' + frames : '' + frameSep + frames;
        }
 
        return result;
@@ -8218,7 +8471,7 @@ function calculateTimeFormat(time, options) {
                }
        }
 
-       options.currentTimeFormat = format;
+       options.timeFormat = format;
 }
 
 function convertSMPTEtoSeconds(SMPTE) {