webshims.register('mediaelement-jaris', function($, webshims, window, document, undefined, options){ "use strict"; var mediaelement = webshims.mediaelement; var swfmini = window.swfmini; var support = webshims.support; var hasNative = support.mediaelement; var hasFlash = swfmini.hasFlashPlayerVersion('11.3'); var loadedSwf = 0; var needsLoadPreload = 'ActiveXObject' in window && hasNative; var getProps = { paused: true, ended: false, currentSrc: '', duration: window.NaN, readyState: 0, networkState: 0, videoHeight: 0, videoWidth: 0, seeking: false, error: null, buffered: { start: function(index){ if(index){ webshims.error('buffered index size error'); return; } return 0; }, end: function(index){ if(index){ webshims.error('buffered index size error'); return; } return 0; }, length: 0 } }; var getPropKeys = Object.keys(getProps); var getSetProps = { currentTime: 0, volume: 1, muted: false }; var getSetPropKeys = Object.keys(getSetProps); var playerStateObj = $.extend({ isActive: 'html5', activating: 'html5', wasSwfReady: false, _usermedia: null, _bufferedEnd: 0, _bufferedStart: 0, currentTime: 0, lastCalledTime: -500, _ppFlag: undefined, _calledMeta: false, lastDuration: 0, _timeDif: 0.3 }, getProps, getSetProps); var getSwfDataFromElem = function(elem){ try { (elem.nodeName); } catch(er){ return null; } var data = webshims.data(elem, 'mediaelement'); return (data && data.isActive == 'third') ? data : null; }; var trigger = function(elem, evt){ evt = $.Event(evt); evt.preventDefault(); $.event.trigger(evt, undefined, elem); }; var playerSwfPath = options.playerPath || webshims.cfg.basePath + "swf/" + (options.playerName || 'JarisFLVPlayer.swf'); webshims.extendUNDEFProp(options.params, { allowscriptaccess: 'always', allowfullscreen: 'true', wmode: 'transparent', allowNetworking: 'all' }); webshims.extendUNDEFProp(options.vars, { controltype: '1', jsapi: '1' }); webshims.extendUNDEFProp(options.attrs, { bgcolor: '#000000' }); options.playerPath = playerSwfPath; var setReadyState = function(readyState, data){ if(readyState < 3){ clearTimeout(data._canplaythroughTimer); } if(readyState >= 3 && data.readyState < 3){ data.readyState = readyState; trigger(data._elem, 'canplay'); if(!data.paused){ trigger(data._elem, 'playing'); } clearTimeout(data._canplaythroughTimer); data._canplaythroughTimer = setTimeout(function(){ setReadyState(4, data); }, 4000); } if(readyState >= 4 && data.readyState < 4){ data.readyState = readyState; trigger(data._elem, 'canplaythrough'); } data.readyState = readyState; }; var callSeeked = function(data){ if(data.seeking && Math.abs(data.currentTime - data._lastSeektime) < 2){ data.seeking = false; $(data._elem).triggerHandler('seeked'); } }; mediaelement.jarisEvent = {}; var localConnectionTimer; var onEvent = { onPlayPause: function(jaris, data, override){ var playing, type; var idled = data.paused || data.ended; if(override == null){ try { playing = data.api.api_get("isPlaying"); } catch(e){} } else { playing = override; } if(playing == idled || playing == null){ data.paused = !playing; type = data.paused ? 'pause' : 'play'; data._ppFlag = true; trigger(data._elem, type); if(data.readyState < 3){ setReadyState(3, data); } if(!data.paused){ trigger(data._elem, 'playing'); } } }, onSeek: function(jaris, data){ data._lastSeektime = jaris.seekTime; data.seeking = true; $(data._elem).triggerHandler('seeking'); clearTimeout(data._seekedTimer); data._seekedTimer = setTimeout(function(){ callSeeked(data); data.seeking = false; }, 300); }, onConnectionFailed: function(jaris, data){ mediaelement.setError(data._elem, 'flash connection error'); }, onNotBuffering: function(jaris, data){ setReadyState(3, data); }, onDataInitialized: function(jaris, data){ var oldDur = data.duration; var durDelta; data.duration = jaris.duration; if(oldDur == data.duration || isNaN(data.duration)){return;} if(data._calledMeta && ((durDelta = Math.abs(data.lastDuration - data.duration)) < 2)){return;} data.videoHeight = jaris.height; data.videoWidth = jaris.width; if(!data.networkState){ data.networkState = 2; } if(data.readyState < 1){ setReadyState(1, data); } clearTimeout(data._durationChangeTimer); if(data._calledMeta && data.duration){ data._durationChangeTimer = setTimeout(function(){ data.lastDuration = data.duration; trigger(data._elem, 'durationchange'); }, durDelta > 50 ? 0 : durDelta > 9 ? 9 : 99); } else { data.lastDuration = data.duration; if(data.duration){ trigger(data._elem, 'durationchange'); } if(!data._calledMeta){ trigger(data._elem, 'loadedmetadata'); } if(data.duration > 1 && data.duration < 140){ data._timeDif = 0.2; } else if(data.duration < 600) { data._timeDif = 0.25; } else { data._timeDif = 0.30; } } data._calledMeta = true; }, onBuffering: function(jaris, data){ if(data.ended){ data.ended = false; } setReadyState(1, data); trigger(data._elem, 'waiting'); }, onTimeUpdate: function(jaris, data){ var timeDif = data.currentTime - data.lastCalledTime; if(data.ended){ data.ended = false; } if(data.readyState < 3){ setReadyState(3, data); trigger(data._elem, 'playing'); } if(data.seeking){ callSeeked(data); } if(timeDif > data._timeDif || timeDif < -0.3){ data.lastCalledTime = data.currentTime; $.event.trigger('timeupdate', undefined, data._elem, true); } }, onProgress: function(jaris, data){ if(data.ended){ data.ended = false; } if(!data.duration || isNaN(data.duration)){ return; } var percentage = jaris.loaded / jaris.total; if(percentage > 0.02 && percentage < 0.2){ setReadyState(3, data); } else if(percentage > 0.2){ if(percentage > 0.95){ percentage = 1; data.networkState = 1; } setReadyState(4, data); } if(data._bufferedEnd && (data._bufferedEnd > percentage)){ data._bufferedStart = data.currentTime || 0; } data._bufferedEnd = percentage; data.buffered.length = 1; $.event.trigger('progress', undefined, data._elem, true); }, onPlaybackFinished: function(jaris, data){ if(data.readyState < 4){ setReadyState(4, data); } data.ended = true; trigger(data._elem, 'ended'); }, onVolumeChange: function(jaris, data){ if(data.volume != jaris.volume || data.muted != jaris.mute){ data.volume = jaris.volume; data.muted = jaris.mute; trigger(data._elem, 'volumechange'); } }, ready: (function(){ var testAPI = function(data){ var passed = true; try { data.api.api_get('volume'); } catch(er){ passed = false; } return passed; }; return function(jaris, data){ var i = 0; var doneFn = function(){ if(i > 9){ data.tryedReframeing = 0; return; } i++; data.tryedReframeing++; if(testAPI(data)){ data.wasSwfReady = true; data.tryedReframeing = 0; startAutoPlay(data); workActionQueue(data); } else if(data.tryedReframeing < 6) { if(data.tryedReframeing < 3){ data.reframeTimer = setTimeout(doneFn, 9); data.shadowElem.css({overflow: 'visible'}); setTimeout(function(){ data.shadowElem.css({overflow: 'hidden'}); }, 1); } else { data.shadowElem.css({overflow: 'hidden'}); $(data._elem).mediaLoad(); } } else { clearTimeout(data.reframeTimer); webshims.error("reframing error"); } }; if(!data || !data.api){return;} if(!data.tryedReframeing){ data.tryedReframeing = 0; } clearTimeout(localConnectionTimer); clearTimeout(data.reframeTimer); data.shadowElem.removeClass('flashblocker-assumed'); if(!i){ doneFn(); } else { data.reframeTimer = setTimeout(doneFn, 9); } }; })() }; onEvent.onMute = onEvent.onVolumeChange; mediaelement.onEvent = onEvent; var workActionQueue = function(data){ var actionLen = data.actionQueue.length; var i = 0; var operation; if(actionLen && data.isActive == 'third'){ while(data.actionQueue.length && actionLen > i){ i++; operation = data.actionQueue.shift(); try{ data.api[operation.fn].apply(data.api, operation.args); } catch(er){ webshims.warn(er); } } } if(data.actionQueue.length){ data.actionQueue = []; } }; var startAutoPlay = function(data){ if(!data){return;} if( (data._ppFlag === undefined && ($.prop(data._elem, 'autoplay')) || !data.paused)){ setTimeout(function(){ if(data.isActive == 'third' && (data._ppFlag === undefined || !data.paused)){ try { $(data._elem).play(); data._ppFlag = true; } catch(er){} } }, 1); } if(data.muted){ $.prop(data._elem, 'muted', true); } if(data.volume != 1){ $.prop(data._elem, 'volume', data.volume); } }; var addMediaToStopEvents = $.noop; if(hasNative){ var stopEvents = { play: 1, playing: 1 }; var hideEvtArray = ['play', 'pause', 'playing', 'loadstart', 'canplay', 'progress', 'waiting', 'ended', 'loadedmetadata', 'durationchange', 'emptied']; var hidevents = hideEvtArray.map(function(evt){ return evt +'.webshimspolyfill'; }).join(' '); var hidePlayerEvents = function(event){ var data = webshims.data(event.target, 'mediaelement'); if(!data){return;} var isNativeHTML5 = ( event.originalEvent && event.originalEvent.type === event.type ); if( isNativeHTML5 == (data.activating == 'third') ){ event.stopImmediatePropagation(); if(stopEvents[event.type]){ if(data.isActive != data.activating){ $(event.target).pause(); } else if(isNativeHTML5){ ($.prop(event.target, 'pause')._supvalue || $.noop).apply(event.target); } } } }; addMediaToStopEvents = function(elem){ $(elem) .off(hidevents) .on(hidevents, hidePlayerEvents) ; hideEvtArray.forEach(function(evt){ webshims.moveToFirstEvent(elem, evt); }); }; addMediaToStopEvents(document); } mediaelement.setActive = function(elem, type, data){ if(!data){ data = webshims.data(elem, 'mediaelement'); } if(!data || data.isActive == type){return;} if(type != 'html5' && type != 'third'){ webshims.warn('wrong type for mediaelement activating: '+ type); } var shadowData = webshims.data(elem, 'shadowData'); data.activating = type; $(elem).pause(); data.isActive = type; if(type == 'third'){ shadowData.shadowElement = shadowData.shadowFocusElement = data.shadowElem[0]; $(elem).addClass('swf-api-active nonnative-api-active').hide().getShadowElement().show(); } else { $(elem).removeClass('swf-api-active nonnative-api-active').show().getShadowElement().hide(); shadowData.shadowElement = shadowData.shadowFocusElement = false; } $(elem).trigger('mediaelementapichange'); }; var resetSwfProps = (function(){ var resetProtoProps = ['_calledMeta', 'lastDuration', '_bufferedEnd', 'lastCalledTime', '_usermedia', '_bufferedStart', '_ppFlag', 'currentSrc', 'currentTime', 'duration', 'ended', 'networkState', 'paused', 'seeking', 'videoHeight', 'videoWidth']; var len = resetProtoProps.length; return function(data){ if(!data){return;} clearTimeout(data._seekedTimer); var lenI = len; var networkState = data.networkState; setReadyState(0, data); clearTimeout(data._durationChangeTimer); while(--lenI > -1){ delete data[resetProtoProps[lenI]]; } data.actionQueue = []; data.buffered.length = 0; if(networkState){ trigger(data._elem, 'emptied'); } }; })(); var getComputedDimension = (function(){ var dimCache = {}; var getVideoDims = function(data){ var ret, poster, img; if(dimCache[data.currentSrc]){ ret = dimCache[data.currentSrc]; } else if(data.videoHeight && data.videoWidth){ dimCache[data.currentSrc] = { width: data.videoWidth, height: data.videoHeight }; ret = dimCache[data.currentSrc]; } else if((poster = $.attr(data._elem, 'poster'))){ ret = dimCache[poster]; if(!ret){ img = document.createElement('img'); img.onload = function(){ dimCache[poster] = { width: this.width, height: this.height }; if(dimCache[poster].height && dimCache[poster].width){ setElementDimension(data, $.prop(data._elem, 'controls')); } else { delete dimCache[poster]; } img.onload = null; }; img.src = poster; if(img.complete && img.onload){ img.onload(); } } } return ret || {width: 300, height: data._elemNodeName == 'video' ? 150 : 50}; }; var getCssStyle = function(elem, style){ return elem.style[style] || (elem.currentStyle && elem.currentStyle[style]) || (window.getComputedStyle && (window.getComputedStyle( elem, null ) || {} )[style]) || ''; }; var minMaxProps = ['minWidth', 'maxWidth', 'minHeight', 'maxHeight']; var addMinMax = function(elem, ret){ var i, prop; var hasMinMax = false; for (i = 0; i < 4; i++) { prop = getCssStyle(elem, minMaxProps[i]); if(parseFloat(prop, 10)){ hasMinMax = true; ret[minMaxProps[i]] = prop; } } return hasMinMax; }; var retFn = function(data){ var videoDims, ratio; var elem = data._elem; var autos = { width: getCssStyle(elem, 'width') == 'auto', height: getCssStyle(elem, 'height') == 'auto' }; var ret = { width: !autos.width && $(elem).width(), height: !autos.height && $(elem).height() }; if(autos.width || autos.height){ videoDims = getVideoDims(data); ratio = videoDims.width / videoDims.height; if(autos.width && autos.height){ ret.width = videoDims.width; ret.height = videoDims.height; } else if(autos.width){ ret.width = ret.height * ratio; } else if(autos.height){ ret.height = ret.width / ratio; } if(addMinMax(elem, ret)){ data.shadowElem.css(ret); if(autos.width){ ret.width = data.shadowElem.height() * ratio; } if(autos.height){ ret.height = ((autos.width) ? ret.width : data.shadowElem.width()) / ratio; } if(autos.width && autos.height){ data.shadowElem.css(ret); ret.height = data.shadowElem.width() / ratio; ret.width = ret.height * ratio; data.shadowElem.css(ret); ret.width = data.shadowElem.height() * ratio; ret.height = ret.width / ratio; } if(!webshims.support.mediaelement){ ret.width = data.shadowElem.width(); ret.height = data.shadowElem.height(); } } } return ret; }; return retFn; })(); var setElementDimension = function(data, hasControls){ var dims; var box = data.shadowElem; $(data._elem)[hasControls ? 'addClass' : 'removeClass']('webshims-controls'); if(data.isActive == 'third' || data.activating == 'third'){ if(data._elemNodeName == 'audio' && !hasControls){ box.css({width: 0, height: 0}); } else { data._elem.style.display = ''; dims = getComputedDimension(data); data._elem.style.display = 'none'; box.css(dims); } } }; var bufferSrc = (function(){ var preloads = { '': 1, 'auto': 1 }; return function(elem){ var preload = $.attr(elem, 'preload'); if(preload == null || preload == 'none' || $.prop(elem, 'autoplay')){ return false; } preload = $.prop(elem, 'preload'); return !!(preloads[preload] || (preload == 'metadata' && $(elem).is('.preload-in-doubt, video:not([poster])'))); }; })(); var regs = { A: /&/g, a: /&/g, e: /\=/g, q: /\?/g }, replaceVar = function(val){ return (val.replace) ? val.replace(regs.A, '%26').replace(regs.a, '%26').replace(regs.e, '%3D').replace(regs.q, '%3F') : val; }; if('matchMedia' in window){ var allowMediaSorting = false; try { allowMediaSorting = window.matchMedia('only all').matches; } catch(er){} if(allowMediaSorting){ mediaelement.sortMedia = function(src1, src2){ try { src1 = !src1.media || matchMedia( src1.media ).matches; src2 = !src2.media || matchMedia( src2.media ).matches; } catch(er){ return 0; } return src1 == src2 ? 0 : src1 ? -1 : 1; }; } } mediaelement.resetSwfProps = resetSwfProps; mediaelement.createSWF = function( elem, canPlaySrc, data ){ if(!hasFlash){ setTimeout(function(){ $(elem).mediaLoad(); //<- this should produce a mediaerror }, 1); return; } var attrStyle = {}; if(loadedSwf < 1){ loadedSwf = 1; } else { loadedSwf++; } if(!data){ data = webshims.data(elem, 'mediaelement'); } if((attrStyle.height = $.attr(elem, 'height') || '') || (attrStyle.width = $.attr(elem, 'width') || '')){ $(elem).css(attrStyle); webshims.warn("width or height content attributes used. Webshims prefers the usage of CSS (computed styles or inline styles) to detect size of a video/audio. It's really more powerfull."); } var box; var streamRequest = canPlaySrc.streamrequest; var isStream = canPlaySrc.type == 'jarisplayer/stream'; var hasControls = $.prop(elem, 'controls'); var elemId = 'jarisplayer-'+ webshims.getID(elem); var elemNodeName = elem.nodeName.toLowerCase(); var setDimension = function(){ if(data.isActive == 'third'){ setElementDimension(data, $.prop(elem, 'controls')); } }; if(isStream && !streamRequest){ webshim.usermedia.attach(elem, canPlaySrc, data); return; } if(data && data.swfCreated){ mediaelement.setActive(elem, 'third', data); data.currentSrc = ''; data.shadowElem.html('