(function(webshims){ "use strict"; var support = webshims.support; var hasNative = support.mediaelement; var supportsLoop = false; var bugs = webshims.bugs; var swfType = 'mediaelement-jaris'; var loadSwf = function(){ webshims.ready(swfType, function(){ if(!webshims.mediaelement.createSWF){ webshims.mediaelement.loadSwf = true; webshims.reTest([swfType], hasNative); } }); }; var wsCfg = webshims.cfg; var options = wsCfg.mediaelement; var isIE = navigator.userAgent.indexOf('MSIE') != -1; if(!options){ webshims.error("mediaelement wasn't implemented but loaded"); return; } if(hasNative){ var videoElem = document.createElement('video'); support.videoBuffered = ('buffered' in videoElem); support.mediaDefaultMuted = ('defaultMuted' in videoElem); supportsLoop = ('loop' in videoElem); support.mediaLoop = supportsLoop; webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']); if( !support.videoBuffered || !supportsLoop || (!support.mediaDefaultMuted && isIE && 'ActiveXObject' in window) ){ webshims.addPolyfill('mediaelement-native-fix', { d: ['dom-support'] }); webshims.loader.loadList(['mediaelement-native-fix']); } } if(support.track && !bugs.track){ (function(){ if(!bugs.track){ if(window.VTTCue && !window.TextTrackCue){ window.TextTrackCue = window.VTTCue; } else if(!window.VTTCue){ window.VTTCue = window.TextTrackCue; } try { new VTTCue(2, 3, ''); } catch(e){ bugs.track = true; } } })(); } webshims.register('mediaelement-core', function($, webshims, window, document, undefined, options){ var hasSwf = swfmini.hasFlashPlayerVersion('10.0.3'); var mediaelement = webshims.mediaelement; mediaelement.parseRtmp = function(data){ var src = data.src.split('://'); var paths = src[1].split('/'); var i, len, found; data.server = src[0]+'://'+paths[0]+'/'; data.streamId = []; for(i = 1, len = paths.length; i < len; i++){ if(!found && paths[i].indexOf(':') !== -1){ paths[i] = paths[i].split(':')[1]; found = true; } if(!found){ data.server += paths[i]+'/'; } else { data.streamId.push(paths[i]); } } if(!data.streamId.length){ webshims.error('Could not parse rtmp url'); } data.streamId = data.streamId.join('/'); }; var getSrcObj = function(elem, nodeName){ elem = $(elem); var src = {src: elem.attr('src') || '', elem: elem, srcProp: elem.prop('src')}; var tmp; if(!src.src){return src;} tmp = elem.attr('data-server'); if(tmp != null){ src.server = tmp; } tmp = elem.attr('type') || elem.attr('data-type'); if(tmp){ src.type = tmp; src.container = $.trim(tmp.split(';')[0]); } else { if(!nodeName){ nodeName = elem[0].nodeName.toLowerCase(); if(nodeName == 'source'){ nodeName = (elem.closest('video, audio')[0] || {nodeName: 'video'}).nodeName.toLowerCase(); } } if(src.server){ src.type = nodeName+'/rtmp'; src.container = nodeName+'/rtmp'; } else { tmp = mediaelement.getTypeForSrc( src.src, nodeName, src ); if(tmp){ src.type = tmp; src.container = tmp; } } } tmp = elem.attr('media'); if(tmp){ src.media = tmp; } if(src.type == 'audio/rtmp' || src.type == 'video/rtmp'){ if(src.server){ src.streamId = src.src; } else { mediaelement.parseRtmp(src); } } return src; }; var hasYt = !hasSwf && ('postMessage' in window) && hasNative; var loadTrackUi = function(){ if(loadTrackUi.loaded){return;} loadTrackUi.loaded = true; if(!options.noAutoTrack){ webshims.ready('WINDOWLOAD', function(){ loadThird(); webshims.loader.loadList(['track-ui']); }); } }; var loadYt = (function(){ var loaded; return function(){ if(loaded || !hasYt){return;} loaded = true; webshims.loader.loadScript("https://www.youtube.com/player_api"); $(function(){ webshims._polyfill(["mediaelement-yt"]); }); }; })(); var loadThird = function(){ if(hasSwf){ loadSwf(); } else { loadYt(); } }; webshims.addPolyfill('mediaelement-yt', { test: !hasYt, d: ['dom-support'] }); mediaelement.mimeTypes = { audio: { //ogm shouldn´t be used! 'audio/ogg': ['ogg','oga', 'ogm'], 'audio/ogg;codecs="opus"': 'opus', 'audio/mpeg': ['mp2','mp3','mpga','mpega'], 'audio/mp4': ['mp4','mpg4', 'm4r', 'm4a', 'm4p', 'm4b', 'aac'], 'audio/wav': ['wav'], 'audio/3gpp': ['3gp','3gpp'], 'audio/webm': ['webm'], 'audio/fla': ['flv', 'f4a', 'fla'], 'application/x-mpegURL': ['m3u8', 'm3u'] }, video: { //ogm shouldn´t be used! 'video/ogg': ['ogg','ogv', 'ogm'], 'video/mpeg': ['mpg','mpeg','mpe'], 'video/mp4': ['mp4','mpg4', 'm4v'], 'video/quicktime': ['mov','qt'], 'video/x-msvideo': ['avi'], 'video/x-ms-asf': ['asf', 'asx'], 'video/flv': ['flv', 'f4v'], 'video/3gpp': ['3gp','3gpp'], 'video/webm': ['webm'], 'application/x-mpegURL': ['m3u8', 'm3u'], 'video/MP2T': ['ts'] } } ; mediaelement.mimeTypes.source = $.extend({}, mediaelement.mimeTypes.audio, mediaelement.mimeTypes.video); mediaelement.getTypeForSrc = function(src, nodeName){ if(src.indexOf('youtube.com/watch?') != -1 || src.indexOf('youtube.com/v/') != -1){ return 'video/youtube'; } if(src.indexOf('rtmp') === 0){ return nodeName+'/rtmp'; } src = src.split('?')[0].split('#')[0].split('.'); src = src[src.length - 1]; var mt; $.each(mediaelement.mimeTypes[nodeName], function(mimeType, exts){ if(exts.indexOf(src) !== -1){ mt = mimeType; return false; } }); return mt; }; mediaelement.srces = function(mediaElem, srces){ mediaElem = $(mediaElem); if(!srces){ srces = []; var nodeName = mediaElem[0].nodeName.toLowerCase(); var src = getSrcObj(mediaElem, nodeName); if(!src.src){ $('source', mediaElem).each(function(){ src = getSrcObj(this, nodeName); if(src.src){srces.push(src);} }); } else { srces.push(src); } return srces; } else { webshims.error('setting sources was removed.'); } }; mediaelement.swfMimeTypes = ['video/3gpp', 'video/x-msvideo', 'video/quicktime', 'video/x-m4v', 'video/mp4', 'video/m4p', 'video/x-flv', 'video/flv', 'audio/mpeg', 'audio/aac', 'audio/mp4', 'audio/x-m4a', 'audio/m4a', 'audio/mp3', 'audio/x-fla', 'audio/fla', 'youtube/flv', 'video/jarisplayer', 'jarisplayer/jarisplayer', 'video/youtube', 'video/rtmp', 'audio/rtmp']; mediaelement.canThirdPlaySrces = function(mediaElem, srces){ var ret = ''; if(hasSwf || hasYt){ mediaElem = $(mediaElem); srces = srces || mediaelement.srces(mediaElem); $.each(srces, function(i, src){ if(src.container && src.src && ((hasSwf && mediaelement.swfMimeTypes.indexOf(src.container) != -1) || (hasYt && src.container == 'video/youtube'))){ ret = src; return false; } }); } return ret; }; var nativeCanPlayType = {}; mediaelement.canNativePlaySrces = function(mediaElem, srces){ var ret = ''; if(hasNative){ mediaElem = $(mediaElem); var nodeName = (mediaElem[0].nodeName || '').toLowerCase(); var nativeCanPlay = (nativeCanPlayType[nodeName] || {prop: {_supvalue: false}}).prop._supvalue || mediaElem[0].canPlayType; if(!nativeCanPlay){return ret;} srces = srces || mediaelement.srces(mediaElem); $.each(srces, function(i, src){ if(src.type && nativeCanPlay.call(mediaElem[0], src.type) ){ ret = src; return false; } }); } return ret; }; var emptyType = (/^\s*application\/octet\-stream\s*$/i); var getRemoveEmptyType = function(){ var ret = emptyType.test($.attr(this, 'type') || ''); if(ret){ $(this).removeAttr('type'); } return ret; }; mediaelement.setError = function(elem, message){ if($('source', elem).filter(getRemoveEmptyType).length){ webshims.error('"application/octet-stream" is a useless mimetype for audio/video. Please change this attribute.'); try { $(elem).mediaLoad(); } catch(er){} } else { if(!message){ message = "can't play sources"; } $(elem).pause().data('mediaerror', message); webshims.error('mediaelementError: '+ message +'. Run the following line in your console to get more info: webshim.mediaelement.loadDebugger();'); setTimeout(function(){ if($(elem).data('mediaerror')){ $(elem).addClass('media-error').trigger('mediaerror'); } }, 1); } }; var handleThird = (function(){ var requested; var readyType = hasSwf ? swfType : 'mediaelement-yt'; return function( mediaElem, ret, data ){ //readd to ready webshims.ready(readyType, function(){ if(mediaelement.createSWF && $(mediaElem).parent()[0]){ mediaelement.createSWF( mediaElem, ret, data ); } else if(!requested) { requested = true; loadThird(); handleThird( mediaElem, ret, data ); } }); if(!requested && hasYt && !mediaelement.createSWF){ loadYt(); } }; })(); var activate = { native: function(elem, src, data){ if(data && data.isActive == 'third') { mediaelement.setActive(elem, 'html5', data); } }, third: handleThird }; var stepSources = function(elem, data, srces){ var i, src; var testOrder = [{test: 'canNativePlaySrces', activate: 'native'}, {test: 'canThirdPlaySrces', activate: 'third'}]; if(options.preferFlash || (data && data.isActive == 'third') ){ testOrder.reverse(); } for(i = 0; i < 2; i++){ src = mediaelement[testOrder[i].test](elem, srces); if(src){ activate[testOrder[i].activate](elem, src, data); break; } } if(!src){ mediaelement.setError(elem, false); if(data && data.isActive == 'third') { mediaelement.setActive(elem, 'html5', data); } } }; var stopParent = /^(?:embed|object|datalist|picture)$/i; var selectSource = function(elem, data){ var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); var _srces = mediaelement.srces(elem); var parent = elem.parentNode; clearTimeout(baseData.loadTimer); $(elem).removeClass('media-error'); $.data(elem, 'mediaerror', false); if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;} data = data || webshims.data(elem, 'mediaelement'); if(mediaelement.sortMedia){ _srces.sort(mediaelement.sortMedia); } stepSources(elem, data, _srces); }; mediaelement.selectSource = selectSource; $(document).on('ended', function(e){ var data = webshims.data(e.target, 'mediaelement'); if( supportsLoop && (!data || data.isActive == 'html5') && !$.prop(e.target, 'loop')){return;} setTimeout(function(){ if( $.prop(e.target, 'paused') || !$.prop(e.target, 'loop') ){return;} $(e.target).prop('currentTime', 0).play(); }); }); var handleMedia = false; var initMediaElements = function(){ var testFixMedia = function(){ if(webshims.implement(this, 'mediaelement')){ selectSource(this); if(!support.mediaDefaultMuted && $.attr(this, 'muted') != null){ $.prop(this, 'muted', true); } } }; webshims.ready('dom-support', function(){ handleMedia = true; if(!supportsLoop){ webshims.defineNodeNamesBooleanProperty(['audio', 'video'], 'loop'); } ['audio', 'video'].forEach(function(nodeName){ var supLoad; supLoad = webshims.defineNodeNameProperty(nodeName, 'load', { prop: { value: function(){ var data = webshims.data(this, 'mediaelement'); selectSource(this, data); if(hasNative && (!data || data.isActive == 'html5') && supLoad.prop._supvalue){ supLoad.prop._supvalue.apply(this, arguments); } if(!loadTrackUi.loaded && this.querySelector('track')){ loadTrackUi(); } $(this).triggerHandler('wsmediareload'); } } }); nativeCanPlayType[nodeName] = webshims.defineNodeNameProperty(nodeName, 'canPlayType', { prop: { value: function(type){ var ret = ''; if(hasNative && nativeCanPlayType[nodeName].prop._supvalue){ ret = nativeCanPlayType[nodeName].prop._supvalue.call(this, type); if(ret == 'no'){ ret = ''; } } if(!ret && hasSwf){ type = $.trim((type || '').split(';')[0]); if(mediaelement.swfMimeTypes.indexOf(type) != -1){ ret = 'maybe'; } } if(!ret && hasYt && type == 'video/youtube'){ ret = 'maybe'; } return ret; } } }); }); webshims.onNodeNamesPropertyModify(['audio', 'video'], ['src', 'poster'], { set: function(){ var elem = this; var baseData = webshims.data(elem, 'mediaelementBase') || webshims.data(elem, 'mediaelementBase', {}); clearTimeout(baseData.loadTimer); baseData.loadTimer = setTimeout(function(){ selectSource(elem); elem = null; }, 9); } }); webshims.addReady(function(context, insertedElement){ var media = $('video, audio', context) .add(insertedElement.filter('video, audio')) .each(testFixMedia) ; if(!loadTrackUi.loaded && $('track', media).length){ loadTrackUi(); } media = null; }); }); if(hasNative && !handleMedia){ webshims.addReady(function(context, insertedElement){ if(!handleMedia){ $('video, audio', context) .add(insertedElement.filter('video, audio')) .each(function(){ if(!mediaelement.canNativePlaySrces(this)){ loadThird(); handleMedia = true; return false; } }) ; } }); } }; mediaelement.loadDebugger = function(){ webshims.ready('dom-support', function(){ webshims.loader.loadScript('mediaelement-debug'); }); }; if(({noCombo: 1, media: 1})[webshims.cfg.debug]){ $(document).on('mediaerror', function(e){ mediaelement.loadDebugger(); }); } //set native implementation ready, before swf api is retested if(hasNative){ webshims.isReady('mediaelement-core', true); initMediaElements(); webshims.ready('WINDOWLOAD mediaelement', loadThird); } else { webshims.ready(swfType, initMediaElements); } webshims.ready('track', loadTrackUi); if(document.readyState == 'complete'){ webshims.isReady('WINDOWLOAD', true); } }); })(webshims);