[SPIP] ~spip v3.2.0-->v3.2.1
[lhc/web/www.git] / www / plugins-dist / medias / lib / mejs / mediaelement.js
index 42f5afd..c10caa0 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'],
@@ -1305,12 +1329,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);
@@ -1385,25 +1409,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);
                                        });
                                }
                        }
@@ -1561,6 +1581,7 @@ var FlashMediaElementRenderer = {
        create: function create(mediaElement, options, mediaFiles) {
 
                var flash = {};
+               var isActive = false;
 
                flash.options = options;
                flash.id = mediaElement.id + '_' + flash.options.prefix;
@@ -1628,21 +1649,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
-                                       });
                                }
                        };
                };
@@ -1714,16 +1737,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;"');
@@ -1732,10 +1767,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(' ') + '>';
@@ -1744,11 +1782,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 = '';
                        }
@@ -1813,7 +1853,11 @@ if (hasFlash) {
 
                        pseudoStreamingStartQueryParam: 'start',
 
-                       pseudoStreamingType: 'byte'
+                       pseudoStreamingType: 'byte',
+
+                       proxyType: '',
+
+                       streamDelimiter: ''
                },
 
                canPlayType: function canPlayType(type) {
@@ -1923,7 +1967,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 () {
@@ -1937,7 +1981,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;
        }
@@ -1948,7 +1992,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
@@ -1971,12 +2015,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);
@@ -1996,6 +2040,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++) {
@@ -2003,6 +2048,7 @@ var FlvNativeRenderer = {
                                                        }
                                                        flvPlayer = NativeFlv._createPlayer({
                                                                options: _flvOptions,
+                                                               configs: _flvConfigs,
                                                                id: id
                                                        });
                                                        flvPlayer.attachMediaElement(node);
@@ -2043,9 +2089,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);
                                }
                        };
 
@@ -2087,6 +2133,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';
@@ -2118,6 +2165,7 @@ var FlvNativeRenderer = {
 
                mediaElement.promises.push(NativeFlv.load({
                        options: flvOptions,
+                       configs: flvConfigs,
                        id: id
                }));
 
@@ -2168,7 +2216,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 () {
@@ -2191,7 +2239,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
@@ -2210,19 +2258,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);
@@ -2237,7 +2287,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({
@@ -2254,7 +2304,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]);
                }
 
@@ -2272,7 +2322,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]);
                        }
 
@@ -2280,7 +2330,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) {
@@ -2295,15 +2346,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();
@@ -2311,9 +2374,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);
                                }
                        };
 
@@ -2334,10 +2397,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;
                                }
                        }
@@ -2450,6 +2513,7 @@ var HtmlMediaElement = {
        create: function create(mediaElement, options, mediaFiles) {
 
                var id = mediaElement.id + '_' + options.prefix;
+               var isActive = false;
 
                var node = null;
 
@@ -2477,19 +2541,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]);
                }
 
@@ -2500,26 +2568,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);
 
@@ -2828,6 +2912,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;
 
@@ -2855,9 +2962,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,
@@ -2887,7 +2991,7 @@ var YouTubeIframeRenderer = {
 
                                        youTubeIframe = youTubeApi.getIframe();
 
-                                       if (mediaElement.originalNode.getAttribute('muted')) {
+                                       if (mediaElement.originalNode.muted) {
                                                youTubeApi.mute();
                                        }
 
@@ -2954,25 +3058,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) {
@@ -3042,7 +3150,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);
 
@@ -3089,6 +3197,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;
 
@@ -3195,6 +3317,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;
@@ -3357,7 +3480,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) {
@@ -3815,9 +3941,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;
        };
 }