var mvpjq = jQuery; (function (window){ var MVPUtils = function(){}; MVPUtils.test = document.createElement("div"); MVPUtils.isEmpty = function(str){ return str.replace(/^\s+|\s+$/g, '').length == 0; } MVPUtils.strip = function(str){ return str.replace(/^\s+|\s+$/g,""); } MVPUtils.isNumber = function(n){ return !isNaN(parseFloat(n)) && isFinite(n); } MVPUtils.isMobile = function(){ return (/Android|webOS|iPhone|iPad|iPod|sony|BlackBerry/i.test(navigator.userAgent)); } MVPUtils.isIE = function(){ var ie_check = MVPUtils.getInternetExplorerVersion(); if (ie_check != -1)return true; else return false; } MVPUtils.isChrome = function(){ var t = navigator.userAgent.toLowerCase(); if(t.match(/browser/ig)) return; return t.match(/chrome/ig); } MVPUtils.isSafari = function() { return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && navigator.userAgent.indexOf('CriOS') == -1 && navigator.userAgent.indexOf('FxiOS') == -1; } MVPUtils.hasLocalStorage = function() { try{ return 'localStorage' in window && window['localStorage'] !== null; }catch(e){ return false; } } MVPUtils.getInternetExplorerVersion = function(){ var rv = -1; if(navigator.appName == 'Microsoft Internet Explorer'){ var ua = navigator.userAgent; var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if(re.exec(ua) != null)rv = parseFloat( RegExp.$1 ); }else if(navigator.appName == 'Netscape'){ var ua = navigator.userAgent; var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})"); if(re.exec(ua) != null)rv = parseFloat( RegExp.$1 ); } return rv; } MVPUtils.isIOS = function(){ return navigator.userAgent.match(/(iPad|iPhone|iPod)/g); } MVPUtils.isiPhoneIpod = function() { var agent = navigator.userAgent; return agent.indexOf('iPhone') > -1 || agent.indexOf('iPod') > -1; } MVPUtils.isAndroid = function() { return navigator.userAgent.indexOf("Android") > -1; } MVPUtils.hasHistory = function() { return !!(window.history && history.pushState); } MVPUtils.hasDownloadSupport = function(){ return ("download" in document.createElement("a")); } MVPUtils.b64DecodeUnicode = function(str) { // Going backwards: from bytestream, to percent-encoding, to original string. return decodeURIComponent(atob(str).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); }; MVPUtils.volumeCanBeSet = function() { var audio = document.createElement("audio"); if(!audio) return false; audio.volume = 0; return audio.volume == 0 ? true : false; }; MVPUtils.supportsWebGL = function() { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } }; MVPUtils.canPlayMp4 = function() { var v = document.createElement('video'); return !!(v.canPlayType && v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, '')); } MVPUtils.canPlayMp3 = function() { var a = document.createElement('audio'); return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, '')); } MVPUtils.canPlayWav = function() { var a = document.createElement('audio'); return !!(a.canPlayType && a.canPlayType('audio/wav;').replace(/no/, '')); } MVPUtils.relativePath = function(s){ //https://stackoverflow.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative var r = new RegExp('^(?:[a-z]+:)?//', 'i'); return r.test(s); } MVPUtils.qualifyURL = function(url) { var a = document.createElement('a'); a.href = url; return a.href; } MVPUtils.hasFullscreen = function(){ return MVPUtils.test.requestFullscreen || MVPUtils.test.mozRequestFullScreen || MVPUtils.test.msRequestFullscreen || MVPUtils.test.oRequestFullscreen || MVPUtils.test.webkitRequestFullScreen; }; MVPUtils.selectText = function(element) { var doc = document, text = element, range, selection; if (doc.body.createTextRange) { //ms range = doc.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { //all others selection = window.getSelection(); range = doc.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); } } MVPUtils.randomiseArray = function(num) { var arr = [], randomArr = [], i, j, randomIndex; for(i = 0; i < num; i++){ arr[i] = i; } for(j = 0; j < num; j++){ randomIndex = Math.round(Math.random()*(arr.length-1)); randomArr[j] = arr[randomIndex]; arr.splice(randomIndex, 1); } return randomArr; } MVPUtils.shuffleArray = function(a) { var j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; } MVPUtils.sortArray = function(arr, sortArr) { var i, len = arr.length, result = []; for(i=0; i -1)return true; } return false; } MVPUtils.regroupArray = function(arr){ var result = arr.reduce((r, { key, value }) => { let [, i, k] = key.split('-'); r[i] = r[i] || []; value.forEach((v, j) => (r[i][j] = r[i][j] || {})[k] = v); return r; }, []); return result; } MVPUtils.keysrt = function(arr, key, reverse) { var sortOrder = 1; if(reverse)sortOrder = -1; return arr.sort(function(a, b) { var x = a[key]; var y = b[key]; return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0)); }); } MVPUtils.keysrt2 = function(arr, prop, key, reverse) { var sortOrder = 1; if(reverse)sortOrder = -1; return arr.sort(function(a, b) { var x = a[prop][key]; var y = b[prop][key]; return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0)); }); } MVPUtils.formatTime = function(seconds) { var sec_num = parseInt(seconds, 10); var hours = Math.floor(sec_num / 3600); var minutes = Math.floor((sec_num - (hours * 3600)) / 60); var seconds = sec_num - (hours * 3600) - (minutes * 60); if(hours > 0){ if (hours < 10) {hours = "0"+hours;} if (minutes < 10) {minutes = "0"+minutes;} if (seconds < 10) {seconds = "0"+seconds;} return hours+':'+minutes+':'+seconds; }else{ if (minutes < 10) {minutes = "0"+minutes;} if (seconds < 10) {seconds = "0"+seconds;} return minutes+':'+seconds; } } MVPUtils.toSeconds = function(n){ var a = n.split(/[\.:,]+/), seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]); return Number(seconds); } MVPUtils.getViewportSize = function(isMobile){ if(isMobile) return {w:window.innerWidth, h:window.innerHeight}; else return {w:document.documentElement.clientWidth || window.innerWidth, h:document.documentElement.clientHeight || window.innerHeight}; }; MVPUtils.isScrolledIntoView = function(el){ var rect = el.getBoundingClientRect(); var elemTop = rect.top; var elemBottom = rect.bottom; var isVisible = (elemTop + rect.height/2 >= 0) && (elemBottom - rect.height/2 <= window.innerHeight); return isVisible; } MVPUtils.getElementOffsetTop = function(el) { var boundingClientRect = el.getBoundingClientRect(); var bodyEl = document.body; var docEl = document.documentElement; var scrollTop = window.pageYOffset || docEl.scrollTop || bodyEl.scrollTop; var clientTop = docEl.clientTop || bodyEl.clientTop || 0; return Math.round(boundingClientRect.bottom - 100 + scrollTop - clientTop); } MVPUtils.getScrollTop = function(el) { var docEl = document.documentElement; return (window.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0); } MVPUtils.rgbToHex = function(color) { var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); if(isHex){ return color; } else{ color = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); return (color && color.length === 4) ? "#" + ("0" + parseInt(color[1],10).toString(16)).slice(-2) + ("0" + parseInt(color[2],10).toString(16)).slice(-2) + ("0" + parseInt(color[3],10).toString(16)).slice(-2) : ''; } } MVPUtils.getUrlParameter = function(k) { var p={}; window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(s,k,v){p[k]=v}) return k?p[k]:p; }; MVPUtils.checkCssExist = function(url){ var ss = document.styleSheets; for (var i = 0, max = ss.length; i < max; i++) { if (ss[i].href == url) return; } var link = document.createElement("link"); link.rel = "stylesheet"; link.href = url; document.getElementsByTagName("head")[0].appendChild(link); } window.MVPUtils = MVPUtils; }(window)); (function (window, $){ "use strict" var MVPImageSlideshow = function (data){ var self = this, holder = data.holder, timeoutID, poster, aspectRatio = data.settings.aspectRatio, timeout, duration = data.settings.slideshowDuration ? parseInt(data.settings.slideshowDuration,10) : 10, isRandom = data.settings.slideshowRandom, transitionDuration, transitionEnded, mediaArr = [], counter, pathArr = [], currImage, playing, startTime, autoPlay = data.settings.autoPlay this.initMedia = function() { if(holder.children().length>0){//previous image currImage = holder.children().eq(0); } console.log('initMedia') counter++; if(counter > mediaArr.length - 1)counter = 0; var url = mediaArr[counter] $(new Image()).css({ display: 'block' }).addClass('mvp-media mvp-media-img').appendTo(holder) .on('load',function() { poster = $(this); self.resize(); if(currImage){//cross fade currImage.removeClass('mvp-slideshow-visible'); } transitionEnded = false; poster.one("transitionend", function(){ checkNext() }).addClass('mvp-slideshow-visible'); transitionDuration = parseFloat(poster.css('transition-duration'),10) setTimeout(function(){//backup checkNext() },transitionDuration*1000); }).attr('src', url); } function checkNext(){ if(!transitionEnded){ transitionEnded = true; if(currImage){ currImage.remove(); currImage = null; } timeout = duration * 1000; if(autoPlay)self.play(); } } this.pause = function(){ if(timeoutID)clearTimeout(timeoutID); var reduction = (new Date().getTime() - startTime); timeout -= reduction; if(timeout < 0)timeout = 0; playing = false; } this.play = function(){ autoPlay = true; if(timeoutID)clearTimeout(timeoutID); startTime = new Date().getTime(); timeoutID = setTimeout(self.ended, timeout); playing = true; } this.ended = function(){ self.initMedia() } this.dispose = function(){ if(timeoutID)clearTimeout(timeoutID); holder.empty() poster = null; } this.resize = function(){ //if(poster)MVPAspectRatio.resizeMedia('image', aspectRatio, holder, poster); } this.setData = function(data){ counter = -1; mediaArr = data.slideshowImages; if(isRandom){ MVPUtils.shuffleArray(mediaArr) } self.initMedia() } }; window.MVPImageSlideshow = MVPImageSlideshow; }(window,jQuery)); (function (window, $){ "use strict" var MVPPlaylistManager = function (data){ var self = this, loopingOn = data.loopingOn, randomPlay = data.randomPlay, playlistItems, lastInOrder = false, counter = -1, lastPlayedFromPlaylistClick,//last played on click. lastRandomCounter,//last played random media in random playlist. randomPaused = false,//when random is playing and we interrupt it by click on the playlist. randomArr = [], nextRandomArr, playlistSelect = false;//prevent geting counter from randomArr on playlist click (get 'normal' counter instead) setTimeout(function(){ clearTimeout(this); $(self).trigger('MVPPlaylistManager.RANDOM_CHANGE', randomPlay); $(self).trigger('MVPPlaylistManager.LOOP_CHANGE', loopingOn); },50) //set counter to specific number or add it to the currect counter value this.setCounter = function(value, _add) { if (typeof _add === 'undefined') _add = true; if(_add){ counter += parseInt(value, 10); }else{ counter = parseInt(value, 10); } checkCounter(); } this.getCounter = function() { var i; if(randomPlay){ if(!playlistSelect){ i = randomArr[counter]; }else{ i = counter; } }else{ i = counter; } return i; } this.getNextCounter = function(v) {//next or previous counter var c = counter + v; //check counter lastInOrder = false;//reset if(loopingOn){ if(randomPlay){ if(c > playlistItems - 1){//moving fowards c = randomArr[ playlistItems - 1];//remember counter for comparison nextRandomArr = MVPUtils.randomiseArray(playlistItems); _firstIndexCheck(nextRandomArr, c); c = 0; }else if(c < 0){//moving backwards c = randomArr[0];//remember counter for comparison nextRandomArr = MVPUtils.randomiseArray(playlistItems); lastIndexCheck(nextRandomArr, c); c = playlistItems - 1; } }else{//random off if(c > playlistItems - 1){ c = 0; }else if( c < 0){ c = playlistItems - 1; } } }else{//looping off if(c > playlistItems - 1){ lastInOrder = true;//last item c = playlistItems - 1; }else if(c < 0){ lastInOrder = true;//last item c = 0; } if(lastInOrder)return undefined; } var i; if(randomPlay){ if(!playlistSelect){ var arr = nextRandomArr || randomArr; i = arr[c]; }else{ i = c; } }else{ i = c; } return i; } this.advanceHandler = function(a) { playlistSelect = false;//reset if(randomPaused){ handleRandomPaused(a); }else{ self.setCounter(a); } } this.processPlaylistRequest = function(id) { playlistSelect = false;//reset if(randomPlay){ playlistSelect = true; lastPlayedFromPlaylistClick = id;//always remember last played on each click. if(!randomPaused){ lastRandomCounter = counter; randomPaused = true;//needs to stay until random play comes back again! So that the above reference to last random counter doesnt get lost. (if we constantly clicking playlist) } } self.setCounter(id, false); } this.setPlaylistItems = function(val, resetCounter) { if(typeof resetCounter === 'undefined') resetCounter = true; if(resetCounter)counter = -1; playlistItems = val; if(randomPlay) makeRandomList(); } this.reSetCounter = function(num) { if(typeof num === 'undefined'){ counter = -1; }else{//set counter to specific number var n = parseInt(num,10); if(playlistItems){ if(n > playlistItems - 1){ n = playlistItems - 1; }else if(n < 0){ n = 0; } counter = n; }else{ counter = -1; } } } this.setRandom = function(v) { if(typeof v !== 'undefined')randomPlay = v; else randomPlay = !randomPlay; if(playlistItems < 3) randomPlay = false; if(randomPlay) makeRandomList(); randomChange(); $(self).trigger('MVPPlaylistManager.RANDOM_CHANGE', randomPlay); } this.getRandom = function(v) { return randomPlay; } this.setLooping = function(v) { if(typeof v !== 'undefined')loopingOn = v; else loopingOn = !loopingOn; $(self).trigger('MVPPlaylistManager.LOOP_CHANGE', loopingOn); } this.getLooping = function(v) { return loopingOn; } this.getPosition = function(val) { return randomArr.indexOf(val); } //exiting randomPaused and going back to random mode function handleRandomPaused(a) { //just an exit out of randomPaused (because of a playlist click) and back to random again randomPaused = false;//reset before because of the getCounter() if(lastRandomCounter + a > playlistItems - 1){ counter = playlistItems - 1; $(self).trigger('MVPPlaylistManager.COUNTER_READY', self.getCounter()); return; } else if( lastRandomCounter + a < 0){ counter = 0; $(self).trigger('MVPPlaylistManager.COUNTER_READY', self.getCounter()); return; } self.setCounter(lastRandomCounter + a, false); } function randomChange() {//when random is turned on / off if(randomPlay){ activeIndexFirst(); counter = 0;//we have to do it like this, because with (setCounter(0, false)) media starts to play from the beginning if its already playing. (when random requested) //we need to say this on the every beginning of random to redirect the counter from wherever the currently is to 0, so that it becomes first index in randomArr. (after we have moved active index to beginning of randomArr) }else{ //we are not going through setCounter here because its just getting out of random mode, and its not changing counter, it just stays where it is (playing or not) if(randomPaused){ counter = lastPlayedFromPlaylistClick; randomPaused = false;//when random mode stops randomPaused stops also. }else{ counter = randomArr[counter];//when we turn off random we need to set counter to the value of the current counter in randomArr, so if the counter is 1, and thats value 3 in randomArr for example, we want the active counter to stay 3, not 1, and next to go to 4, not 2. } } } function checkCounter() { if(isNaN(counter)){ alert('MVPPlaylistManager message: No active media, counter = ' + counter); return; } //reset lastInOrder = false; if(loopingOn){ if(randomPlay){ if(counter > playlistItems - 1){//moving fowards counter = randomArr[ playlistItems - 1];//remember counter for comparison makeRandomList(); _firstIndexCheck(randomArr, counter); counter = 0; }else if(counter < 0){//moving backwards counter = randomArr[0];//remember counter for comparison makeRandomList(); lastIndexCheck(randomArr, counter); counter = playlistItems - 1; } }else{//random off if(counter > playlistItems - 1){ counter = 0; }else if( counter < 0){ counter = playlistItems - 1; } } $(self).trigger('MVPPlaylistManager.COUNTER_READY', self.getCounter()); }else{//looping off if(counter > playlistItems - 1){ counter = playlistItems - 1; lastInOrder = true;//last item }else if(counter < 0){ lastInOrder = true;//last item counter = 0; } if(!lastInOrder){ $(self).trigger('MVPPlaylistManager.COUNTER_READY', self.getCounter()); }else{ $(self).trigger('MVPPlaylistManager.PLAYLIST_END'); } } } function makeRandomList() { if(nextRandomArr){//if generated from querying for next playlist item randomArr = nextRandomArr.slice(); nextRandomArr = null; }else{ randomArr = MVPUtils.randomiseArray(playlistItems); } console.log(randomArr) } function _firstIndexCheck (arr, c) { //check that first item in newly generated random array isnt equal to last active item. if(arr[0] == c){//if yes, put it at the last place in array. var i = arr.splice(0,1); arr.push(i); } } function lastIndexCheck(arr, c) { if(arr[playlistItems - 1] == c){//if yes, put it at the first place in array. var i = arr.splice(playlistItems - 1,1); arr.unshift(i); } } function activeIndexFirst() {//when going into random (playing or not) put currently active index on the first place of random array. var i,len = randomArr.length, j; for(i = 0; i < len; i++){ if(randomArr[i] == counter){ if(i == 0){//if its already on the first place no need for action. break; } j = randomArr.splice(i,1); randomArr.unshift(parseInt(j,10)); break; } } } }; window.MVPPlaylistManager = MVPPlaylistManager; }(window,jQuery)); (function (window, $){ var MVPAspectRatio = function(){}; MVPAspectRatio.resizeMedia = function(type, aspectRatio, holder, target) { var o, x, y, w = holder.width(), h = holder.height(); if(aspectRatio == 0) {//original dimensions o = getMediaSize(type, target); }else if(aspectRatio == 1) {//fitscreen o = retrieveObjectRatio(true, type, holder, target); }else if(aspectRatio == 2) {//fullscreen o = retrieveObjectRatio(false, type, holder, target); } x = parseInt(((w - o.width) / 2),10); y = parseInt(((h - o.height) / 2),10); target.css({ width: o.width+'px', height: o.height+'px', left:x+'px', top:y+'px' }); } function retrieveObjectRatio(fitScreen, type, holder, target) { var val = {}, paddingX = 0, paddingY = 0, w = holder.width(), h = holder.height(), o = getMediaSize(type, target), targetWidth = o.width, targetHeight = o.height, destinationRatio = (w - paddingX) / (h - paddingY), targetRatio = targetWidth / targetHeight; if (targetRatio < destinationRatio) { if (!fitScreen) {//fullscreen val.height = ((w - paddingX) /targetWidth) * targetHeight; val.width = (w - paddingX); } else {//fitscreen val.width = ((h - paddingY) / targetHeight) *targetWidth; val.height = (h - paddingY); } } else if (targetRatio > destinationRatio) { if (fitScreen) {//fitscreen val.height = ((w - paddingX) /targetWidth) * targetHeight; val.width = (w - paddingX); } else {//fullscreen val.width = ((h - paddingY) / targetHeight) *targetWidth; val.height = (h - paddingY); } } else {//fitscreen and fullscreen val.width = (w - paddingX); val.height = (h - paddingY); } return val; } function getMediaSize(type, target) { var o={}, default_w = 16, default_h = 9;//default values if(type == 'video'){ if(target[0] && target[0].videoWidth && target[0].videoHeight){ o.width = target[0].videoWidth; o.height = target[0].videoHeight; }else{ o.width = default_w; o.height = default_h; } }else if(type == 'iframe'){ if(target.sw && target.sh){ o.width = target.sw; o.height = target.sh; }else{ o.width = default_w; o.height = default_h; } }else if(type == 'image'){ o.width = target.width(); o.height = target.height(); } return o; } window.MVPAspectRatio = MVPAspectRatio; }(window,jQuery)); (function($) { $.fn.mvp = function(settings) { "use strict" //############################################// /* settings */ //############################################// var defaults = { //scripts vimeo_js: "https://player.vimeo.com/api/player.js", vimeoLoader_js: 'js/vimeoLoader.js', youtube_js: "https://www.youtube.com/iframe_api", youtubeLoader_js: 'js/youtubeLoader.js', mCustomScrollbar_js: "https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.concat.min.js", mCustomScrollbar_css: "css/jquery.mCustomScrollbar.min.css", perfectScrollbar_js: 'https://cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/1.5.0/perfect-scrollbar.min.js', perfectScrollbar_css: "css/perfect-scrollbar.css", hls_js: "https://cdn.jsdelivr.net/npm/hls.js@latest", dash_js: "https://cdn.dashjs.org/latest/dash.all.min.js", mediatags_js: "https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.0/jsmediatags.min.js", jquery_touchSwipe: "https://cdnjs.cloudflare.com/ajax/libs/jquery.touchswipe/1.6.19/jquery.touchSwipe.min.js", adsbygoogle_js: "//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", three_js: "js/three.min.js",//r127 orbitControls_js: "https://unpkg.com/three@0.85.0/examples/js/controls/OrbitControls.js", md5_js: "https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.min.js", equalizer_js: "js/equalizer.js", rel_js: "js/rel_pagination.js", share_js: "js/share_manager.js", cache_js: "js/cache.js", playlist_navigation_js: "js/playlist_navigation.js", cast_js: 'js/cast.js', vast_js: 'js/vast.js', imaLoader_js: 'js/ima.js?49', ima_js: '//imasdk.googleapis.com/js/sdkloader/ima3.js?2', sourcePath: "", playlistList: "#mvp-playlist-list", instanceName: "", queryInstance: "", playerType:'normal', createPlayer:true, rememeberCaptionState:true, youtubePlayerType: 'chromeless', blockYoutubeEvents:true, vimeoPlayerType: 'default', vimeoPlayerColor: '#00adef', blockVimeoEvents:true, playerRatio: 1.7777777,//16/9 combinePlayerRatio:true, playlistBottomHeight: 300, playlistSideWidth: 320,//width of the vertical playlist on side volume:0.5, preload: 'auto', s3UrlExpireTime: '+15 seconds', s3ThumbExtension: 'jpg', s3Region: 'us-east-1', autoPlay:false, autoPlayAfterFirst:false, autoPlayInViewport:false, addResizeEvent:true, mediaEndAction:'next', useShare:true, adUpcomingMsgTime:5, thumbScrollValue: 50, youtubePlayerColor: 'red', verticalBottomSepearator: 750,//the limit for when side vertical playlist drops below player subtitleOffText: 'Disabled', useMobileNativePlayer:false, hideQualityMenuOnSingleQuality: true, useLightboxAdvanceButtons: true, minimizeOnScroll:false, minimizeOnScrollOnlyIfPlaying:false, aspectRatio: 2, gridType:'javascript', adUpcomingTime:5, randomPlay: false, playlistScrollType: 'mcustomscrollbar', loopingOn: true, captionStateKey: "mvp-caption-state",//caption enabled / disabled hidePlaylistOnFullscreenEnter: true, useAirPlay: true, focusVideoInTheater:true, hidePlaylistOnTheaterEnter: true, playlistItemContent: 'thumb,title,description', playbackPositionKey: "mvp-playback-position", rightClickContextMenu: 'custom', tooltipClose: "Close", tooltipLightboxPrevious: "Previous", tooltipLightboxNext: "Next", closeSettingsMenuOnSelect:true, playlistOpened:true, hidePlaylistOnMinimize:true, clickOnBackgroundClosesLightbox:true, limitDescriptionText:2, togglePlaybackOnMultipleInstances:true, showStreamVideoBitrateMenu:true, showStreamAudioBitrateMenu:true, useKeyboardNavigationForPlayback:false, keyboardControls: [], seekTime: 10, scrollToPlayer:0, seekToChapterStart:true, autoOpenChapterMenu:true, hideChapterMenuOnChapterSelect:false, useSwipeNavigation: false, forceAdMutedOnIos:true, autoPlaylistStyleVrbSwitch:true, createAdMarkers:true, showPrevNextVideoThumb:true, playAdsOnlyOnce:false, showAnnotationsOnlyOnce:false, displayWatchedPercentage:false, autoRotateSpeed:0.5, autoRotatePanorama:true, enablePerspectiveWhenVrNotAvailable:true, addPlaylistEvents:true, idleTimeout:2000, caption_breakPointArr:[ {width:0, size:18}, {width:480, size:20}, {width:768, size:22}, {width:1024, size:24}, {width:1280, size:36} ], youtubeAppId:'', youtubeThumbSize:'medium', castConnectingMsg: 'Connecting to Chromecast', embedSrc: 'Embed url goes here', textTrackStyle: { fontScale: 1.0, foregroundColor: '#FFFFFFFF', backgroundColor: '#00000000', edgeColor: '#00000066', edgeType: 'DROP_SHADOW', fontStyle: 'NORMAL', fontFamily: 'Serif', fontGenericFamily: 'CURSIVE' }, vimeoThumbSize:'295x166', searchDescriptionInPlaylist:true, minimizeClass: 'mvp-minimize-br', whatsAppWarning:"Please share this content on mobile device!", comingnextTime:10, showControlsBeforeStart:false, useStatistics:false, disableVideoSkip:false, keepCaptionFontSizeAfterManualResize:false, percentToCountAsPlay: 25, requirePosterFromFolder:true, requireThumbnailsFromFolder:true, useAudioEqualizer:false, playbackPositionTime:null,//we use this to set video start time, we cant use start alone in querystring because query playlist does not exist (unless we have other required query string parameters for playlist, then we can use start) mediaId:null, mediaTitle:null, //pagination paginationPreviousBtnTitle:"Previous", paginationPreviousBtnText:"Prev", paginationNextBtnTitle:"Next", paginationNextBtnText:"Next", closeIcon:'' } var settings = $.extend(true, {}, defaults, settings); //############################################// /* url params */ //############################################// //check url params, overwrite settings //check playlist from url params var urlParams = MVPUtils.getUrlParameter(), queryPlaylistArr = [], queryPlaylist = []; var q_pathArr = [], q_subtitleArr = []; if(decodeURIComponent(urlParams['mvp-query-instance']) == settings.instanceName){//on if share url is for this instance Object.keys(urlParams).forEach(function(key) { if(key.indexOf('mvp-')==0){//url params start with 'mvp-' var k = key.substr(4),//remove mvp- camelCased = k; var value = decodeURIComponent(urlParams[key]).replace(/\+/g, ' ');//+ to space if(k.indexOf('path-') == -1 && k.indexOf('subtitle-') == -1){//dont camel case camelCased = k.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); } if(value){ if(settings.hasOwnProperty(camelCased)){//update settings if(value === "true")value = true; else if(value === "false")value = false; settings[camelCased] = value;//only accept if property already exist }else{//check for playlist value = value.split(",").map(function(item){ return item.trim(); }); if(camelCased.indexOf('path-') > -1){ q_pathArr.push({key:camelCased, value: value}); }else if(camelCased.indexOf('subtitle-') > -1){ q_subtitleArr.push({key:camelCased, value: value}); }else{ queryPlaylistArr.push({key:camelCased, value: value}); } } } } }); //check if path or subttiles if(q_pathArr.length){ q_pathArr = MVPUtils.regroupArray(q_pathArr); queryPlaylistArr.push({key: "path", value: q_pathArr}); } if(q_subtitleArr.length){ q_subtitleArr = MVPUtils.regroupArray(q_subtitleArr); queryPlaylistArr.push({key: "subtitles", value: q_subtitleArr}); } q_pathArr = null; q_subtitleArr = null; //playlist from url params if(queryPlaylistArr.length){ var i, j, len = queryPlaylistArr.length, len2 = queryPlaylistArr[0].value.length, item, obj, value; for(j = 0;j'+ '
'+ '
'+ '
'+ ''+ '
'; if(settings.useLightboxAdvanceButtons){ lightboxHtml += '
'+ ''+ '
'+ '
'+ ''+ '
'; } lightboxHtml += '
'+ '
'+ ''; lightboxWrap = $(lightboxHtml); if(settings.playlistPosition == 'wall'){ lightboxWrap.addClass(wrapper.attr('id')).prependTo(wrapper); lightboxContentInner = lightboxWrap.find('.mvp-lightbox-content-inner').append(wrapper.find('.mvp-player-wrap')) wrapper.find('.mvp-playlist-holder').prependTo(wrapper) } else if(settings.playerType == 'lightbox'){ lightboxWrap.addClass(wrapper.attr('id')).appendTo($('body')); lightboxContentInner = lightboxWrap.find('.mvp-lightbox-content-inner').append(wrapper.addClass('mvp-is-lightbox')); } lightbox = lightboxWrap.find('.mvp-lightbox') lightboxContent = lightboxWrap.find('.mvp-lightbox-content') lightboxInner = lightboxWrap.find('.mvp-lightbox-inner') lightboxClose = lightboxWrap.find('.mvp-lightbox-close') lightboxPrev = lightboxWrap.find('.mvp-lightbox-prev') lightboxNext = lightboxWrap.find('.mvp-lightbox-next') ligthboxPadding = (parseInt(lightboxContentInner.css('padding'),10)*2) } var playerWrap = wrapper.find('.mvp-player-wrap'), mediaHolder = wrapper.find('.mvp-media-holder').show(), playlistHolder = wrapper.find('.mvp-playlist-holder'), playlistInner = wrapper.find('.mvp-playlist-inner'), playlistContent = wrapper.find('.mvp-playlist-content'), playlistFilterMsg = wrapper.find('.mvp-playlist-filter-msg'), subtitleHolder = wrapper.find('.mvp-subtitle-holder').css('display','none'), subtitleHolderInner = wrapper.find('.mvp-subtitle-holder-inner').attr('aria-hidden',true), annotationHolder = wrapper.find('.mvp-annotation-holder').css('display','none'), playerHolder = wrapper.find('.mvp-player-holder').show(), imaHolder, videoHolder, youtubeHolder, vimeoHolderDefault, vimeoHolderChromeless, posterHolder, imageHolder, customHolder, playerControls = wrapper.find('.mvp-player-controls'), playerControlsBottom = wrapper.find('.mvp-player-controls-bottom'), playbackToggle = wrapper.find('.mvp-playback-toggle'), mediaTimeCurrent = wrapper.find('.mvp-media-time-current').html('00:00'), mediaTimeSeparator = wrapper.find('.mvp-media-time-separator'), mediaTimeTotal = wrapper.find('.mvp-media-time-total').html('00:00'), previewSeekWrap = wrapper.find('.mvp-preview-seek-wrap'), previewSeekInner = wrapper.find('.mvp-preview-seek-inner'), previewSeekInfo = wrapper.find('.mvp-preview-seek-info'), seekbar = wrapper.find('.mvp-seekbar'), progressBg = wrapper.find('.mvp-progress-bg'), loadLevel = wrapper.find('.mvp-load-level'), progressLevel = wrapper.find('.mvp-progress-level'), volumeWrapper = wrapper.find('.mvp-volume-wrapper'), volumeToggle = wrapper.find('.mvp-volume-toggle'), volumeSeekbar = wrapper.find('.mvp-volume-seekbar'), volumeBg = wrapper.find('.mvp-volume-bg'), volumeLevel = wrapper.find('.mvp-volume-level'), infoHolder = wrapper.find('.mvp-info-holder'), infoToggle = wrapper.find('.mvp-info-toggle').hide(), videoTitle, playerTitle = wrapper.find('.mvp-player-title'), playerDesc = wrapper.find('.mvp-player-desc'), pwdHolder = wrapper.find('.mvp-pwd-holder'), pwdField = wrapper.find('.mvp-pwd-field'), pwdErrorMsg = wrapper.find('.mvp-pwd-error').text(), playlistToggle = wrapper.find('.mvp-playlist-toggle'), playerLoader = wrapper.find('.mvp-player-loader').show(), bigPlay = wrapper.find('.mvp-big-play'), loopToggle = wrapper.find('.mvp-loop-toggle'), shuffleToggle = wrapper.find('.mvp-shuffle-toggle'), downloadToggle = wrapper.find('.mvp-download-toggle').hide(), shareToggle = wrapper.find('.mvp-share-toggle'), shareHolder = wrapper.find('.mvp-share-holder'), embedToggle = wrapper.find('.mvp-embed-toggle'), embedHolder = wrapper.find('.mvp-embed-holder'), ageVerifyHolder = wrapper.find('.mvp-age-verify-holder'), resumeHolder = wrapper.find('.mvp-resume-holder'), resumeHeaderTitle = wrapper.find('.mvp-resume-header-title'), vrInfo, liveNote = wrapper.find('.mvp-live-note'), upnextWrap = wrapper.find('.mvp-upnext-wrap'), upnextThumb = upnextWrap.find('.mvp-upnext-thumb'), upnextTitle = upnextWrap.find('.mvp-upnext-title'), upnextDuration = upnextWrap.find('.mvp-upnext-duration'), upnextWrap2 = wrapper.find('.mvp-upnext-wrap2'), upnextThumb2 = upnextWrap2.find('.mvp-upnext-thumb'), upnextHeader2 = upnextWrap2.find('.mvp-upnext-header'), upnextTitle2 = upnextWrap2.find('.mvp-upnext-title'), upnextDuration2 = upnextWrap2.find('.mvp-upnext-duration'), nextToggle = wrapper.find('.mvp-next-toggle'), prevToggle = wrapper.find('.mvp-previous-toggle'), rewindToggle = wrapper.find('.mvp-rewind-toggle'), skipBackwardToggle = wrapper.find('.mvp-skip-backward-toggle'), skipForwardToggle = wrapper.find('.mvp-skip-forward-toggle'), settingsToggle = wrapper.find('.mvp-settings-toggle'), playbackRateMenu = wrapper.find('.mvp-playback-rate-menu'), qualityMenu = wrapper.find('.mvp-quality-menu'), qualitySettingsMenu = wrapper.find('.mvp-quality-settings-menu'), subtitleMenu = wrapper.find('.mvp-subtitle-menu'), subtitleSettingsMenu = wrapper.find('.mvp-subtitle-settings-menu'), audioLanguageMenu = wrapper.find('.mvp-audio-language-menu'), audioLanguageMenuHolder = wrapper.find('.mvp-audio-language-menu-holder'), audioLanguageToggle = wrapper.find('.mvp-audio-language-toggle').hide(), audioLanguageSettingsMenu = wrapper.find('.mvp-audio-language-settings-menu'), pipToggle = wrapper.find('.mvp-pip-toggle').hide(), captionToggle = wrapper.find('.mvp-cc-toggle').hide(), castToggle, vrToggle = wrapper.find('.mvp-vr-toggle').hide(), theaterToggle = wrapper.find('.mvp-theater-toggle'), unmuteToggle = wrapper.find('.mvp-unmute-toggle'), airplayToggle = wrapper.find('.mvp-airplay-toggle').hide(), //coming next comingnextHolder = wrapper.find('.mvp-comingnext-holder'), comingnextPosterHolder = wrapper.find('.mvp-comingnext-poster-holder'), comingnextDataTitle = wrapper.find('.mvp-comingnext-data-title'), comingnextTimerCircleStroke = wrapper.find('.mvp-comingnext-timer-circle-stroke'), comingnextTimerWrap = wrapper.find('.mvp-comingnext-timer-wrap'), comingnextCancel = wrapper.find('.mvp-comingnext-cancel'), //restrict download redirectLoginHolderDownload = wrapper.find('.mvp-redirect-login-holder-download'), redirectLoginHolderWatch = wrapper.find('.mvp-redirect-login-holder-watch'), redirectLoginHolder, //rel relHolder = wrapper.find(".mvp-rel-holder"), //chapter menu chapterToggle = wrapper.find('.mvp-chapter-toggle').hide(), nextChapterToggle = wrapper.find('.mvp-next-chapter-toggle').hide(), prevChapterToggle = wrapper.find('.mvp-prev-chapter-toggle').hide(), chapterMenuHolder = wrapper.find(".mvp-chapter-menu-holder"), chapterMenu = wrapper.find('.mvp-chapter-menu'), //chapter window chaptersHolder = wrapper.find(".mvp-chapters-holder"), chaptersContainer = chaptersHolder.find(".mvp-chapters-container"), //transcript transcriptToggle = wrapper.find('.mvp-transcript-toggle').hide(), transcriptHolder = settings.transcriptHolder ? $(settings.transcriptHolder) : wrapper.find('.mvp-transcript-holder'), transcriptHeaderTitle = transcriptHolder.find('.mvp-transcript-header-title'), transcriptContainerWrap = transcriptHolder.find('.mvp-transcript-container-wrap'), transcriptContainer = transcriptHolder.find('.mvp-transcript-container'), transcriptLanguageSelectorWrap = transcriptHolder.find('.mvp-transcript-language-selector-wrap'), transcriptLanguageSelector = transcriptHolder.find('.mvp-transcript-language-selector'), //playlist selector playlistSelectorHolder = wrapper.find(".mvp-playlist-selector-holder"), playlistSelectorContainer = wrapper.find(".mvp-playlist-selector-container"), playlistSelectorHeaderTitle = wrapper.find('.mvp-playlist-selector-header-title'), playlistSelectorHeaderIcon = wrapper.find('.mvp-playlist-selector-header-icon'), //ad adSeekbar = wrapper.find('.mvp-ad-seekbar'), adProgressBg = wrapper.find('.mvp-ad-progress-bg'), adLoadLevel = wrapper.find('.mvp-ad-load-level'), adProgressLevel = wrapper.find('.mvp-ad-progress-level'), adInfoTime = wrapper.find('.mvp-ad-info-time'), adSkipBtn = wrapper.find('.mvp-ad-skip-btn'), adSkipMsg = wrapper.find('.mvp-ad-skip-msg'), adSkipMsgText = wrapper.find('.mvp-ad-skip-msg-text'), adSkipMsgContent = adSkipMsgText.html(), adSkipMsgEnd = wrapper.find('.mvp-ad-skip-msg-end'), adSkipThumb = wrapper.find('.mvp-ad-skip-thumb'), adControls = wrapper.find('.mvp-ad-controls'), //ad info start msg adInfoStart = wrapper.find('.mvp-ad-info-start'), adInfoStartTime = wrapper.find('.mvp-ad-info-start-time') //generate player classes var playlistStyleVrbSwitch if(settings.playerClass){ var cl = settings.playerClass; }else{ var skin = settings.skin, navigationType = settings.navigationType || '',//scroll, buttons, hover, none playlistPosition = settings.playlistPosition || '',//mvp-vrb, mvp-vlb, mvp-vb, mvp-ht, mvp-hb, outer, wall, no-playlist navigationStyle = '',//spaced, normal playlistStyle = settings.playlistStyle || '',//dot, drot, gdot, gdbt playerShadow = settings.playerShadow || ''; if(playlistPosition == 'hb'){ if(navigationType == 'buttons'){ if(playlistStyle == 'dot' || playlistStyle == 'drot'){ navigationStyle = settings.navigationStyle; } } } if(playlistPosition == 'no-playlist'){ playlistStyle = ''; } if(playlistPosition == 'vrb' || playlistPosition == 'vb' || playlistPosition == 'hb'){ }else{ navigationType = ''; navigationStyle = ''; } if(playlistPosition == 'vrb' || playlistPosition == 'vb' || playlistPosition == 'hb' || playlistPosition == 'no-playlist'){ }else{ playerShadow = ''; } //check if corrrect class has been set if(playlistPosition == 'outer' || playlistPosition == 'wall'){ if(playlistStyle != 'gdot' && playlistStyle != 'gdbt' && playlistStyle != 'gdrot')playlistStyle = 'gdot'; } else if(playlistPosition == 'vrb' || playlistPosition == 'vb' || playlistPosition == 'hb'){ if(playlistStyle != 'dot' && playlistStyle != 'drot')playlistStyle = 'drot'; } var navigationDirection = 'v';/* vertical, horizontal */ if(playlistPosition == 'hb')navigationDirection = 'h'; var cl = 'mvp-player mvp-skin-'+skin+''; if(skin.indexOf('flat')>-1)cl += ' mvp-skin-flat'//so we dont repeat css for multiple flat skins if(!MVPUtils.isEmpty(playlistPosition))cl += ' mvp-'+playlistPosition; if(!MVPUtils.isEmpty(navigationType)){ if(navigationType == 'scroll-browser')cl += ' mvp-nt-scroll'; else cl += ' mvp-nt-'+navigationType; } if(!MVPUtils.isEmpty(navigationStyle))cl += ' mvp-ns-'+navigationStyle; if(!MVPUtils.isEmpty(playlistStyle)){ cl += ' mvp-ps-'+playlistStyle; if(playlistStyle == 'dot' && settings.autoPlaylistStyleVrbSwitch)playlistStyleVrbSwitch = true; } if(!MVPUtils.isEmpty(playerShadow))cl += ' mvp-'+playerShadow + ' mvp-shadow-effect-hidden'; settings.navigationDirection = navigationDirection; settings.navigationType = navigationType; } if(navigationStyle == 'spaced'){ if(playlistHolder.find('.mvp-nav-backward-horizontal').length == 0)$('
').appendTo(playlistHolder) } if(navigationType == 'scroll-browser'){ if(playlistPosition == 'vrb' || playlistPosition == 'vb'){ playlistInner.addClass('mvp-scroll-content mvp-scrollable-y') }else if(playlistPosition == 'hb'){ playlistInner.addClass('mvp-scroll-content mvp-scrollable-x') } } wrapper.addClass(cl); //mods if(playlistPosition == 'wall'){ settings.playerType = 'lightbox'; settings.playlistOpened = true; playlistToggle.remove(); } else if(playlistPosition == 'outer'){ settings.playerType = 'normal'; settings.minimizeOnScroll = false; settings.hidePlaylistOnFullscreenEnter = false; } else if(playlistPosition == 'no-playlist'){ createPlaylist = false; playlistHolder.remove(); playlistToggle.remove(); } if(settings.playerType == 'lightbox'){ settings.autoPlayInViewport = false; settings.minimizeOnScroll = false; settings.hidePlaylistOnFullscreenEnter = false; theaterToggle.remove(); } if(settings.minimizeOnScroll && settings.useMinimizeCloseBtn){ playerWrap.append('
'); } if(wrapper.find('.mvp-playlist-bar').length){ //if(navigationDirection =='h')playlistHolder.height(playlistHolder.height()+wrapper.find('.mvp-playlist-bar').height())//auto calculate playlist height if(playlistPosition == 'wall' || playlistPosition == 'outer'){ wrapper.find('.mvp-playlist-bar').prependTo(playlistInner);//put search field above playlist } } if(settings.youtubePlayerType == 'default')settings.blockYoutubeEvents = false; else if(useSwipeNavigation)settings.blockYoutubeEvents = true; if(settings.gridType != 'javascript'){ settings.breakPointArr = null; wrapper.addClass('mvp-grid mvp-'+settings.gridType) } if(settings.breakPointArr && settings.breakPointArr.length){ MVPUtils.keysrt(settings.breakPointArr, 'width');//sort from low to high } if(settings.elementsVisibilityArr && settings.elementsVisibilityArr.length)MVPUtils.keysrt(settings.elementsVisibilityArr, 'width');//sort from low to high if(settings.caption_breakPointArr && settings.caption_breakPointArr.length){ MVPUtils.keysrt(settings.caption_breakPointArr, 'width');//sort from low to high } if(settings.wrapperMaxWidth){ if(settings.playerType == 'lightbox')lightboxInner.css('max-width',settings.wrapperMaxWidth); else wrapper.css('max-width',settings.wrapperMaxWidth); } //############################################// /* vars */ //############################################// var isIOS = MVPUtils.isIOS(), isiPhone = MVPUtils.isiPhoneIpod(), isAndroid = MVPUtils.isAndroid(), hasFullscreen = MVPUtils.hasFullscreen(), hasDownloadSupport = MVPUtils.hasDownloadSupport(), volumeCanBeSet = MVPUtils.volumeCanBeSet(), supportsWebGL = MVPUtils.supportsWebGL(), mp4Support = MVPUtils.canPlayMp4(), mp3Support = MVPUtils.canPlayMp3(), wavSupport = MVPUtils.canPlayWav(), isChrome = MVPUtils.isChrome(), isSafari = MVPUtils.isSafari(), hasLocalStorage = MVPUtils.hasLocalStorage(), pictureInPictureEnabled = document.pictureInPictureEnabled, useGa = settings.useGa && settings.gaTrackingId, rememberPlaybackPosition = settings.rememberPlaybackPosition && hasLocalStorage, playbackPositionKey = settings.playbackPositionKey + settings.instanceName, captionStateKey = settings.instanceName + settings.captionStateKey, playlistItemContent = settings.playlistItemContent.replace(/\s+/g, '').split(','), vimeoThumbSize = settings.vimeoThumbSize.substr(0,settings.vimeoThumbSize.indexOf('x')), useAudioEqualizer = !isIOS && (settings.useAudioEqualizer && (window.AudioContext || window.webkitAudioContext)) ? true : false, playlistList = $(settings.playlistList), autoPlay = settings.autoPlay, volume = settings.volume, initialVolume = settings.volume, lastVolume = settings.volume || 0.5,//if we click unmute from mute on the beginning aspectRatio, hidePlaylistOnFullscreenEnterDone,//remember playlist was closed hidePlaylistOnTheaterEnterDone,//remember playlist was closed hidePlaylistOnMinimizeDone,//remember playlist was closed trackStatTimeoutID, componentInited = false, playlistTransitionOn = true, loadMoreProcess, loadMoreType,//remember last load more type for lightbox (where is no media type) //add more on total scroll addMoreLimit, addMoreNumResults, addMoreOffset, encryptMediaPaths, globalPwd, addMoreSortOrder,//order_id, title addMoreSortDirection,//asc, desc playlistTaxonomy, playlistCategory, playlistTag, playlistTaxonomyMatch, loadMoreItem,//playlist item which holds data for load more (required for cache) nextPageToken, loadMoreOnTotalScroll, addMoreOnTotalScroll = settings.addMoreOnTotalScroll, self = this, _body = $('body'), _window = $(window), _doc = $(document), _html = $('html'), lastScrollX = 0, lastScrollY = 0,//restore scroll position after fs exit //pagnation paginationInited, lastActivePaginationBtn, paginationWrap,//pagination buttons go here paginationTotalPages, paginationCurrentPage, paginationArr = [],//save playlist items per page documentFullsceen = false, windowResizeTimeoutID, windowResizeTimeout = 250, startResizeDone, mediaStarted, mediaCounter, dataIntervalID, dataInterval = 500, renderAnimationID, vrAnimationLoop, lastProgressWidth, currMediaData, mainMediaData, activePlaylist, activePlaylistItem, playlistLength, defaultMenuQuality = 'default', minimizeScrollEvent = 'scroll.minimize'+settings.instanceName, autoplayScrollEvent = 'scroll.autoplay'+settings.instanceName, unmuteToggleInited, unmuteHappened, setMediaInformationDone, settingsMenuHeightDiff = 60,//player height - settings menu bottom theaterModeOn, _MVPPlaylistNavigation, //lightbox lightboxOpened, //preview seek previewSeekImg, previewSeekArr = [], previewSeekReady, last_previewSeek_top,//dont change top while seeking singleMediaSourcesArr = ['audio', 'video', 'image', 'youtube_single', 'vimeo_single', 'hls', 'dash'], singleMediaDurationSourcesArr = ['audio', 'video', 'youtube_single', 'vimeo_single', 'hls', 'dash'],//non image media //hls hls, hlsSupport, streamHasAudioTracks, hlsInited, streamVideoBitrateMenuBuilt, streamAudioBitrateMenuBuilt, streamSubtitleMenuBuilt, externalSubtitle,//hls, dash //dash dash, dashSupport = window.MediaSource, dashHasAudioTracks, dashInited, dashInitialized, //audio id3Counter, id3Start, audioInited, audio, audioUp2Js, audioReady, //audio equalizer _MVPAudioEqualizer, canvasAudio, //video poster, isPoster, posterExist, posterInited, videoUp2Js, video, videoInited, videoReady, //youtube _MVPYoutubeLoader, youtubeIframe, youtubePlayer, youtubeInited, youtubeReady, youtubeStarted, youtubePlayed, youtubeBlocker, //vimeo _MVPVimeoLoader, activeVimeoIframe, activeVimeoPlayer, activeVimeoHolder, activeVimeoPlayerType = settings.vimeoPlayerType, vimeoPlayerDefault, vimeoPlayerChromeless, vimeoInitedDefault, vimeoInitedChromeless, vimeoIframeDefault, vimeoIframeChromeless, vimeoReadyDefault, vimeoReadyChromeless, vimeoStarted, vimeoPlayed, vimeoDuration = 0,//because of promise vimeoCurrentTime = 0, vimeoProgress = 0, vimeoBlocker, vimeoDefaultLastID, vimeoChromelessLastID, //360 video supportFor360Video = true, vrInfoVisible, mode360monoscopic_created, mode360stereoscopic_created, vwidth = 640, vheight = 360, vcanvas, vrenderer, videoTexture, vscene, vcanvas2, vrenderer2, videoTexture2, vscene2, vcontrols2, doRender, vrCurrentSession, vrSupported, camera, camera2, orbitControls, orbitControls2, cameraCreated, camera2Created, orbitControlsCreated, //thumb load thumbLoadArr = [], //image image, imageStartTime, imageDuration, durationTimeoutID, //360 image image360DataCreated, image360Ready, icanvas, itextureLoader, imaterial, iscene, irenderer, imesh, //vart _mvpVastLoader, vastFirstQuartile, vastMidpoint, vastThirdQuartile, vastRequest, vastLinearArr = [], adMidTimesReady, isIma, isImaLinear, imaAdMarkerArr = [], _mvpImaLoader, imaLoaded, imaStarted, //viewport autoplay autoPlayInViewportDone, //masonry grid _masonry, //minimize interval playerOffsetTop, minimizeIntervalID, minimizeInterval = 400, isScrollTimeout, qualityChange, qualityArr = [], resumeTime, mediaType, subMediaType, mediaPath, mediaPlaying, playlistClick, mediaForcePause,//toggle info, embed infoOpened, shareOpened, embedOpened, ageVerifyOpened, ageVerifyKey = 'mvp-av-key-'+settings.instanceName, videoUrlOpened, redirectLoginOpened, interfaceHidden = true, disableSeekingPastWatchedPointTime, //stat countryData, subtitleHolderRestore, annotationHolderRestore, idleTimeoutID, lastPlaylist, playlistId, autoInitActiveItem, processPlaylistLength, playlistProcessCounter = -1, playlistDataArr = [], lastPlaylistDataArr = [],//for load more playlistProcessData = [], playlistProcessDataUrl = [], playlistData, toggleResumeOpened, upNextClosed, bsf_match = 'ebsfm:', //global playlist options globalLockTime, globalLockVideoUserRoles, globalStartTime, globalEndTime, globalPlaybackRate, globalVast, getEmbedDetails, //playback rate ,quality, subtitles activePlaybackRateMenuItem, activeQualityMenuItem, activeAudioLanguageMenuItem, activeSubtitleMenuItem, subtitleOn, allSubtitleArr = [],//all subtitles for media subtitleArr = [],//current subtitle for media activeSubtitle, subtitleSizeSet, subtitlesReady, //transcript activeTranscriptLanguageItem, activeTranscriptLanguage, transcriptOpened, transcriptReady, transcriptInited, transcriptRequest, transcriptLangaugeMenuOpened, //context menu contextMenu, contextMenuVideoUrl, contextMenuFullscreen, //slideshow _MVPImageSlideshow, //api endInsert,//insert at playlist end insertPosition, addTrackProcess, addTrackPlayit, playlistNavigationInit, chapterHorizSizeInited, //grid column, gutter, lastColumn, //preview seek previewSeekVideoInited, previewSeekAuto, previewSeekSnapshotDone, videoForPreviewSeek, hlsForPreviewSeek, dashForPreviewSeek, dashForPreviewSeekInitialized, previewSeekCanvas, previewSeekCanvasCtx, previewSeekCanvasWidth, previewSeekCanvasHeight, _MVPCast, isCasting, castReady = 0, castSupported, //chapters chapterArr = [], //chaptersLoaded, chaptersCreated, chaptersReady, chapterActiveMenuItem, chapterActiveWindowItem, chapterActiveHighlight, chapterMenuOpened, currentActiveChapterData,//track chapter changes as time goes seekbarSizeSet, adSeekbarSizeSet, //playlist selector playlistSelectorOpened, lastPlaylistSelectorActiveItem, //ads adSection, globalAdData, adSeekbarSize = 0, adResumeTime,//for ad mid adDataTaken, adOn,//is advert on adPreArr = [], adCounter, adEndArr = [], adMidArr = [], adEndOn,//is ad end on skipEnable,//skip enable time skipEnableDone, skipBtnShown, adMarkersCreated, //annotations annotationArr = [], lastTime = null, annotationDataTaken, annotationSection, globalAnnotationData, hasAdSense, //coming next comingnextInterval, comingnextInitialOffset = '169', comingnextPoster, comingnextOpened, //rel _MVPRelPagination, relOpened, //share _MVPShareManager, //cache _MVPCacheManager, cacheOn, useCache = settings.useCache && "indexedDB" in window && typeof settings.cacheTime != undefined, //user roles currentUserRoles, downloadVideoUserRoles, allowedViewVideoUserRole, allowedDownloadVideoUserRole = true, viewVideoWithoutAdsUserRoles, showAds = true if(settings.showVideoTitle || settings.showChapterTitle){ videoTitle = $('
').insertAfter(playerControls) } if(settings.currentUserRoles)currentUserRoles = settings.currentUserRoles.split(','); if(settings.downloadVideoUserRoles)downloadVideoUserRoles = settings.downloadVideoUserRoles.split(','); if(currentUserRoles && downloadVideoUserRoles){ allowedDownloadVideoUserRole = MVPUtils.arrayContainsAnotherArray(downloadVideoUserRoles, currentUserRoles); } if(settings.viewVideoWithoutAdsUserRoles)viewVideoWithoutAdsUserRoles = settings.viewVideoWithoutAdsUserRoles.split(','); if(settings.viewVideoWithoutAdsForLoggedInUser && settings.isUserLoggedIn)showAds = false; if(currentUserRoles && viewVideoWithoutAdsUserRoles){ showAds = !MVPUtils.arrayContainsAnotherArray(viewVideoWithoutAdsUserRoles, currentUserRoles); } if(settings.playlistContent)playlistContent = $(settings.playlistContent)//custom playlist element //############################################// /* setup */ //############################################// if(volume < 0)volume = 0; else if(volume > 1)volume = 1; settings.volume = volume; //check if scrollbar css exist window.playlistScrollLoading = false;//for multiple instances if(typeof window.mvp_mediaArr === 'undefined')window.mvp_mediaArr = []; mvp_mediaArr.push({inst: self, id: settings.instanceName}); //hidden playlist from dom if(playlistContent.length == 0){ playlistContent = $('
'); playlistPosition = 'no-playlist'; createPlaylist = false; navigationType = ''; } //load more if(settings.playlistPosition == 'outer' || settings.playlistPosition == 'wall'){ if(wrapper.find('.mvp-load-more-btn').length == 0) playlistHolder.append('
LOAD MORE
'); } var loadMoreBtn = wrapper.find('.mvp-load-more-btn').on('click',function(){ if(!componentInited) return false; if(loadMoreProcess) return false; if(loadMoreOnTotalScroll)self.loadMore(); else if(addMoreOnTotalScroll){ addMore(); } loadMoreBtn.css('opacity',0); }); //swipe if(useSwipeNavigation){ if(typeof $.fn.swipe === "undefined"){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.jquery_touchSwipe))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.jquery_touchSwipe); else var src = settings.jquery_touchSwipe; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ initSwipe(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ initSwipe(); } } function initSwipe(){ mediaHolder.swipe({ swipeLeft:function(event, direction, distance, duration, fingerCount, fingerData) { if(!componentInited) return false; if(mediaType == 'audio' || mediaType == 'video' && !currMediaData.is360 || mediaType == 'image' && !currMediaData.is360 || mediaType == 'youtube' && settings.youtubePlayerType == 'chromeless' && !currMediaData.is360 || mediaType == 'vimeo' && activeVimeoPlayerType == 'chromeless' && !currMediaData.is360){ nextMedia(); } }, swipeRight:function(event, direction, distance, duration, fingerCount, fingerData) { if(!componentInited) return false; if(mediaType == 'audio' || mediaType == 'video' && !currMediaData.is360 || mediaType == 'image' && !currMediaData.is360 || mediaType == 'youtube' && settings.youtubePlayerType == 'chromeless' && !currMediaData.is360 || mediaType == 'vimeo' && activeVimeoPlayerType == 'chromeless' && !currMediaData.is360){ previousMedia(); } } }); } //lightbox if(settings.playerType == 'lightbox'){ //close lightboxClose.on('click',function(){ self.closeLightbox(); }); if(settings.clickOnBackgroundClosesLightbox){ lightbox.on('click',function(e){ if(e.target == this){ // only if the target itself has been clicked self.closeLightbox(); } }); } //prev lightboxPrev.on('click',function(e){ e.stopImmediatePropagation(); previousMedia(); }); //next lightboxNext.on('click',function(e){ e.stopImmediatePropagation(); nextMedia(); }); } //download downloadToggle.on('click', function(e){ //e.preventDefault();//prevent a tag scroll $(self).trigger('mediaDownload', {instance:self, instanceName: settings.instanceName, media: currMediaData}); //download if(useGa && typeof ga !== "undefined"){ ga('send', { hitType: "event", eventCategory: "Modern video player: " + settings.instanceName, eventAction: "downloaded", eventLabel: "Video title: " + currMediaData.title, nonInteraction: true }); } if((settings.restrictDownloadForLoggedInUser && !settings.isUserLoggedIn) || !allowedDownloadVideoUserRole){ toggleRedirectLoginScreen('download'); return false; } if(settings.useStatistics){ getStats('mvp_download_count', mediaCounter); } }); //############################################// /* google analytics */ //############################################// if(useGa){ if(!window["ga"]){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); } ga('create', settings.gaTrackingId, 'auto'); ga('send', 'pageview'); } //if(isSafari)windowResizeTimeout = 500;//window size not yet ready? if(!(settings.theaterElement && !MVPUtils.isEmpty(settings.theaterElement) && settings.theaterElementClass && !MVPUtils.isEmpty(settings.theaterElementClass))) delete settings.theaterElement; if(settings.autoPlayInViewport || settings.autoPlayAfterFirst){ autoPlay = false; } if(autoPlay || settings.autoPlayInViewport){ volume = 0; settings.volume = 0; if(settings.autoPlayInViewport && initialVolume != 0){//unmute html5 video _doc.on('mousedown.apmvp, keydown.apmvp', function(){ _doc.off('mousedown.apmvp, keydown.apmvp'); if(!unmuteHappened){ unmuteHappened = true; if(!autoPlayInViewportDone){ if(videoUp2Js){ toggleMute(); /*videoUp2Js.volume = initialVolume; videoUp2Js.muted = false;*/ } } } }); } } if(isMobile){ if(settings.displayPosterOnMobile){ autoPlay = false; settings.autoPlayInViewport = false; } }else{ settings.displayPosterOnMobile = false; } //hide embed functionality if already embeded if(location.href.indexOf('apmvp/includes/embed.php?') > -1 && settings.hideEmbedFunctionWhenEmbeded){ embedToggle.remove() embedHolder.remove() } if(!createPlaylist){ settings.playlistOpened = false; playlistHolder.remove(); } if(isiPhone){//not supported pipToggle.remove(); } if(!supportsWebGL){ supportFor360Video = false; if(isChrome){ console.log('Turn Hardware Acceleration On Within Chrome Browser to enable 360 videos!'); } }else{ //360 info image if(settings.vrInfoImage)vrInfo = $('drag').insertAfter(mediaHolder); } if (location.href.indexOf("https:") != -1 && 'xr' in navigator ) { navigator.xr.isSessionSupported( 'immersive-vr' ).then( function ( supported ) { if(supported){ vrSupported = true; }else{ vrSupported = false; //console.log('vr not supported') } } ); } else { if ( window.isSecureContext === false ) { //console.log('WEBXR NEEDS HTTPS'); } else { //console.log('WEBXR NOT AVAILABLE'); } } async function onVrSessionStarted( session ) { session.addEventListener( 'end', onVrSessionEnded ); await vrenderer2.xr.setSession( session ); vrCurrentSession = session; } function onVrSessionEnded() { vrCurrentSession.removeEventListener( 'end', onVrSessionEnded ); vrCurrentSession = null; } if(playlistPosition == 'hb' && navigationDirection == 'v'){ playlistHolder.css({height: settings.playlistBottomHeight}); } //playback position var eventName = isIOS ? "pagehide" : "beforeunload", addListener = window.attachEvent || window.addEventListener; if(rememberPlaybackPosition){ addListener(eventName, function (event) { if(window.event)window.event.cancelBubble = true; saveMediaState() }); /*if(isIOS){ document.addEventListener("unload", function(e){ saveMediaState() }); }*/ } function saveMediaState(){ if(!componentInited) return false; if(!mediaType) return false; var d = { activePlaylist: activePlaylist,//remember active playlist so if we change active playlist we probably dont want to resume playback? volume: volume, activeItem: mediaCounter, playbackPositionTime: parseInt(self.getCurrentTime(),10) }; localStorage.setItem(playbackPositionKey, JSON.stringify(d)); } //upnext upnextWrap.find('.mvp-upnext-close').on('click', function(){ upnextWrap.removeClass('mvp-upnext-on mvp-upnext-visible'); upNextClosed = true; }); upnextThumb.on('click', function(){ upnextWrap.removeClass('mvp-upnext-on mvp-upnext-visible'); nextMedia(); }); upnextTitle.on('click', function(){ upnextWrap.removeClass('mvp-upnext-on mvp-upnext-visible'); nextMedia(); }); // ad skip adSkipBtn.on('click', function(){ if(!componentInited) return false; if(!adOn || !skipEnableDone) return false; if(adOn){ if(currMediaData.TrackingEvents)vastTracking("skip"); $(self).trigger('adSkip', {instance:self, instanceName: settings.instanceName, media: currMediaData}); } mediaEndHandler(); }); //annotations annotationHolder.on('click', '.mvp-annotation-close', function(){ if(settings.showAnnotationsOnlyOnce){ var annotation = $(this).closest('.mvp-annotation'), id = annotation.attr('data-id'), i, len = annotationArr.length; annotation.remove(); for(i=0; i= 2){ clearInterval(castReadyInterval); _MVPCast = new MVPCast({ parent: self, wrapper: wrapper, settings: settings, btn: castToggle }) } },100); } this.setIsCasting = function(v){ isCasting = v if(isCasting)wrapper.addClass('mvp-player-casting') else wrapper.removeClass('mvp-player-casting') } //############################################// /* vast */ //############################################// function initVast(url){ if(typeof MVPVastLoader === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.vast_js); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ initVast(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); return; } _mvpVastLoader = new MVPVastLoader(settings); $(_mvpVastLoader).on('MVPVastLoader.END_LOAD', function(e, data){ if(!vastRequest)return; //linear var i, len = data.linear.length, obj for(i = 0;i < len; i++){ obj = data.linear[i] if(obj.adPre){ adPreArr.push(obj); } else if(obj.adMid){ adMidArr.push({begin:obj.begin, data:obj}) } else if(obj.adEnd){ adEndArr.push(obj); } } //non linear var i, len = data.nonlinear.length, obj, item for(i = 0;i < len; i++){ obj = data.nonlinear[i] item = $('
'+ ''+ 'image'+ ''+ '
' +settings.closeIcon+ '
'+ '
').appendTo(annotationHolder); annotationArr.push({ id: i, start: obj.start, end: obj.end, item: item }); } if(annotationArr.length)annotationHolder.show(); if(adPreArr.length){ adCounter = 0; if(adPreArr[adCounter].type){ if(adPreArr[adCounter].data)currMediaData = adPreArr[adCounter].data;//json else currMediaData = adPreArr[adCounter];//vast } else currMediaData = getAdData(adPreArr[adCounter]); adOn = true; } else if(adEndArr.length){ adCounter = -1; } checkMedia() }); $(_mvpVastLoader).on('MVPVastLoader.ERROR', function(e, data){ console.log('MVPVastLoader.ERROR: ', data) }); var url = currMediaData.vast if(url.substr(-11) == 'correlator='){ var randNum = Math.floor(Math.random() * (9999999 - 1 + 1)).toString(); url += randNum; } _mvpVastLoader.load(url); } function vastTracking(event){ //console.log('vastTracking : ', event) var uri, i, len = currMediaData.TrackingEvents.length, obj; for(i = 0; i < len; i++){ obj = currMediaData.TrackingEvents[i] if(event == obj.event){ uri = obj.URI; break; } } if(uri)vastPing(uri); } function vastPing(uri){ //console.log('vastPing : ', uri) if(!uri) return; var img = new Image(); img.src = uri; } //############################################// /* ima */ //############################################// function loadIma(){ var imaReady, imaLoaderReady var script = document.createElement('script'); script.type = 'text/javascript'; script.src = settings.ima_js; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ imaReady = true; } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); if(typeof MVPImaLoader === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.imaLoader_js); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ imaLoaderReady = true; } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ imaLoaderReady = true; } var interval = setInterval(function(){ if(imaReady && imaLoaderReady){ clearInterval(interval); imaLoaded = true; initIma() } },100); } function initIma(){ if(!imaHolder)imaHolder = $('
').appendTo(mediaHolder); if(!_mvpImaLoader)_mvpImaLoader = new MVPImaLoader(settings, self, mediaHolder, imaHolder); } //############################################// /* */ //############################################// var hasTouch, downEvent, moveEvent, upEvent; if("ontouchstart" in window){ hasTouch = true; downEvent = "touchstart.ap mousedown.ap"; moveEvent = "touchmove.ap mousemove.ap"; upEvent = "touchend.ap mouseup.ap"; }else{ if(window.PointerEvent){ downEvent = "pointerdown.ap"; moveEvent = "pointermove.ap"; upEvent = "pointerup.ap"; }else{ downEvent = "mousedown.ap"; moveEvent = "mousemove.ap"; upEvent = "mouseup.ap"; } } mediaHolder.on('click', function(e){ if(!componentInited) return false; if(settings.displayPosterOnMobile)return false; if(isIma && (adOn || !isImaLinear))return false; if(mediaType == 'image'){ if(adOn){//open link on ad pause, for video link is opened in pause handler if(currMediaData.link){ if(currMediaData.ClickTracking) vastPing(currMediaData.ClickTracking); if(currMediaData.target && currMediaData.target == '_blank'){ window.open(currMediaData.link); }else{ var link = currMediaData.link; destroyMedia(); window.location = link; return; } } } return false; } if(currMediaData.is360) return false; //show controls on first tap, pause on second if(!interfaceHidden)self.togglePlayback(); else if(!mediaStarted)self.togglePlayback(); else if(adOn)self.togglePlayback(); }); //############################################// /* filter tracks */ //############################################// if(wrapper.find('.mvp-search-field').length)wrapper.addClass('mvp-has-search-bar') var isSearchActive var searchSelector = wrapper.find('.mvp-search-field').on('keyup',function(){ if(playlistSelectorOpened){ //search playlists var len = playlistSelectorContainer.find('.mvp-playlist-selector-item').length if(len == 0)return false; var value = $(this).val().toLowerCase(), i, j = 0, pi, title; for(i = 0; i < len; i++){ pi = playlistSelectorContainer.find('.mvp-playlist-selector-item').eq(i); title = pi.find('.mvp-playlist-selector-item-title').html().toLowerCase(); if(pi.find('.mvp-playlist-selector-item-description'))title += pi.find('.mvp-playlist-selector-item-description').html().toLowerCase(); if(title.indexOf(value) >- 1){ playlistSelectorContainer.find('.mvp-playlist-selector-item').eq(i).fadeIn(200) }else{ playlistSelectorContainer.find('.mvp-playlist-selector-item').eq(i).fadeOut(200) j++; } } if(j == len){ playlistFilterMsg.show(); }else { playlistFilterMsg.hide(); } }else{ if(playlistLength == 0)return false; var value = $(this).val().toLowerCase(), i, j = 0, pi, title, description; for(i = 0; i < playlistLength; i++){ pi = playlistContent.children('.mvp-playlist-item').eq(i); if(pi.find('.mvp-playlist-title').length)title = pi.find('.mvp-playlist-title').html().toLowerCase(); else title = ''; if(settings.searchDescriptionInPlaylist){ if(pi.find('.mvp-playlist-description').length)title += pi.find('.mvp-playlist-description').html().toLowerCase(); } if(title.indexOf(value) >- 1){ playlistContent.children('.mvp-playlist-item').eq(i).removeClass('mvp-filter-hidden').fadeIn(200) }else{ playlistContent.children('.mvp-playlist-item').eq(i).addClass('mvp-filter-hidden').fadeOut(200) j++; } } if(j == playlistLength){ playlistFilterMsg.show(); isSearchActive = false; if(loadMoreBtn)loadMoreBtn.addClass('mvp-force-hide') }else { playlistFilterMsg.hide(); isSearchActive = true; if(settings.navigationType == 'scroll' && _MVPPlaylistNavigation)_MVPPlaylistNavigation.updatePosition() if(loadMoreBtn)loadMoreBtn.removeClass('mvp-force-hide') } } }); //playlist selector if(settings.makePlaylistSelector){ wrapper.addClass('mvp-playlist-selector') createPlaylistSelector() } //############################################// /* fullscreen */ //############################################// var componentSize = 'normal', fullscreenRequestId;//which instance requested fullscreen (if there are multiple instances in page) _doc.on("fullscreenchange.mvp mozfullscreenchange.mvp MSFullscreenChange.mvp webkitfullscreenchange.mvp", function(e){ if(fullscreenRequestId == settings.instanceName){ if(componentSize == "fullscreen"){ fullscreenExitAction(); }else{ fullscreenEnterAction(); } } }); //NOTE: we have mvp-fullscreen-toggle in normal controls and in ad controls, so we attach click handler like this. Currently it doesnt cause problems? (if we dont call fullscreenToggle.click manually!) var fullscreenToggle = wrapper.find('.mvp-fullscreen-toggle').on('click', function(){ toggleFullscreen(); }); function toggleFullscreen(){ //cancel theater mode theaterModeOn = false; wrapper.removeClass('mvp-theater'); if(settings.theaterElement)$(settings.theaterElement).removeClass(settings.theaterElementClass); //remove lightbox center if(lightboxInner)lightboxInner.removeClass('mvp-lightbox-center'); fullscreenRequestId = settings.instanceName; if(documentFullsceen){ var elem = document.documentElement; }else{ var elem = wrapper[0]; } if(componentSize == "normal"){ var d = document, r = d.documentElement, b = d.body; lastScrollX = r.scrollLeft || b.scrollLeft || 0; lastScrollY = r.scrollTop || b.scrollTop || 0; $(self).trigger("fullscreenBeforeEnter", {instance:self, instanceName: settings.instanceName, media:currMediaData}); } if(hasFullscreen){ if (elem.requestFullscreen) { if (document.fullscreenElement) { document.exitFullscreen(); } else { elem.requestFullscreen(); } } else if (elem.webkitRequestFullScreen) { if (document.webkitIsFullScreen) { document.webkitCancelFullScreen(); } else { elem.webkitRequestFullScreen(); } } else if (elem.msRequestFullscreen) { if (document.msIsFullscreen || document.msFullscreenElement) { document.msExitFullscreen(); } else { elem.msRequestFullscreen(); } } else if (elem.mozRequestFullScreen) { if (document.fullscreenElement || document.mozFullScreenElement) { document.mozCancelFullScreen(); } else { elem.mozRequestFullScreen(); } } }else{ if(componentSize == "fullscreen"){ fullscreenExitAction(); }else{ fullscreenEnterAction(); } } setTimeout(function(){ doneResizing(); }, 250); } function fullscreenEnterAction(){ componentSize = "fullscreen"; playerWrap.removeClass(settings.minimizeClass); _html.addClass('mvp-fs-overflow'); wrapper.addClass('mvp-fs'); if(settings.playerType == 'lightbox')lightboxContentInner.addClass('mvp-fs'); fullscreenToggle.find('.mvp-btn-fullscreen').hide(); fullscreenToggle.find('.mvp-btn-normal').show(); theaterToggle.hide(); document.body.style.cursor = 'default'; if(settings.rightClickContextMenu == 'custom'){ contextMenuFullscreen.find('.mvp-context-fullscreen-enter').hide(); contextMenuFullscreen.find('.mvp-context-fullscreen-exit').show(); } if(settings.hidePlaylistOnFullscreenEnter && settings.playlistOpened){ hidePlaylistOnFullscreenEnterDone = true; //playlistHolder.hide(); settings.playlistOpened = false; } if(playlistPosition == 'outer')playlistToggle.hide(); if(currMediaData.TrackingEvents)vastTracking("playerExpand"); $(self).trigger("fullscreenEnter", {instance:self, instanceName: settings.instanceName, media:currMediaData}); } function fullscreenExitAction(){ componentSize = "normal"; _html.removeClass('mvp-fs-overflow'); wrapper.removeClass('mvp-fs'); if(settings.playerType == 'lightbox')lightboxContentInner.removeClass('mvp-fs'); fullscreenToggle.find('.mvp-btn-fullscreen').show(); fullscreenToggle.find('.mvp-btn-normal').hide(); theaterToggle.show(); document.body.style.cursor = 'default'; if(settings.rightClickContextMenu == 'custom'){ contextMenuFullscreen.find('.mvp-context-fullscreen-enter').show(); contextMenuFullscreen.find('.mvp-context-fullscreen-exit').hide(); } if(hidePlaylistOnFullscreenEnterDone && !settings.playlistOpened){ hidePlaylistOnFullscreenEnterDone = false; //playlistHolder.show(); settings.playlistOpened = true; } if(playlistPosition == 'outer')playlistToggle.show(); window.scrollTo(lastScrollX, lastScrollY); if(settings.minimizeOnScroll){ if(settings.minimizeOnScrollOnlyIfPlaying){ if(mediaPlaying)checkPlayerMinimize(); }else{ checkPlayerMinimize(); } } fullscreenRequestId = null; if(currMediaData.TrackingEvents)vastTracking("playerCollapse"); $(self).trigger("fullscreenExit", {instance:self, instanceName: settings.instanceName, media:currMediaData}); } //set visibility on start fullscreenToggle.find('.mvp-btn-normal').hide(); fullscreenToggle.find('.mvp-btn-fullscreen').show(); //############################################// /* context menu */ //############################################// if(settings.rightClickContextMenu == 'disabled'){ wrapper.on("contextmenu", function(){ return false; }); }else if(settings.rightClickContextMenu == 'custom'){ contextMenu = wrapper.find('.mvp-context-menu').on("contextmenu",function(e){//prevent right click on context menu return false; }); contextMenuVideoUrl = contextMenu.find(".mvp-context-copy-video-url").on("click", function(e){ var url = window.location.href + self.getCurrentMediaUrl(); var dummy = document.createElement("input"); dummy.setAttribute("id", "mvp-copy-url"); document.body.appendChild(dummy); document.getElementById("mvp-copy-url").value = url; dummy.select(); try{ document.execCommand("copy"); }catch(er){} document.body.removeChild(dummy); }); contextMenuFullscreen = contextMenu.find(".mvp-context-fullscreen").on("click", function(e){ toggleFullscreen(); }); function hideContextMenu(){ _body.off("click.apcc", hideContextMenu); contextMenu.hide(); } function showContextMenu(e){ if(settings.displayPosterOnMobile)return false; if($(e.target).hasClass('mvp-player-title'))return true; if($(e.target).hasClass('mvp-player-desc'))return true; if($(e.target).hasClass('mvp-volume-level'))return false;//volume if($(e.target).hasClass('mvp-volume-level'))return false;//volume if($(e.target).hasClass('mvp-volume-bg'))return false; if($(e.target).hasClass('mvp-progress-level'))return false;//seekbar if($(e.target).hasClass('mvp-progress-bg'))return false; if($(e.target).hasClass('mvp-load-level'))return false; if(pwdHolder.css('display') == 'block')return false; if(adOn)return false; e.preventDefault(); e.stopPropagation(); var main = playerHolder[0].getBoundingClientRect(), cw = contextMenu.outerWidth(true), ch = contextMenu.outerHeight(true), l = parseInt(e.pageX - _window.scrollLeft() - main.left, 10), t = parseInt(e.pageY - _window.scrollTop() - main.top,10); //keep within component if(l > playerHolder.width() - cw)l -= cw; if(t > playerHolder.height() - ch)t -= ch; contextMenu.css({left: l+'px', top: t+'px'}).show(); _body.one("click.apcc", hideContextMenu); } playerHolder.on("contextmenu", showContextMenu).on("mouseleave", hideContextMenu); _body.on("mouseleave.mvp", hideContextMenu); _doc.on("contextmenu.mvp", hideContextMenu).keyup(function(e){ if(e.keyCode == 27){//esc hideContextMenu(); } }); } //############################################// /* tooltips */ //############################################// var tooltip = wrapper.find('.mvp-tooltip'); if(!isMobile){ wrapper.on("mouseenter", "[data-tooltip]", function(e){ var item = $(this), text = item.attr('data-tooltip'); if(MVPUtils.isEmpty(text))return false; if(playerWrap.hasClass(settings.minimizeClass))var container = playerWrap; else if(lightboxOpened)var container = playerWrap; else container = wrapper; var main = container[0].getBoundingClientRect(), element = item[0].getBoundingClientRect(); tooltip.text(text); if(item.attr('data-tooltip-position') != undefined){ if(item.attr('data-tooltip-position') == 'left'){ var t = parseInt(element.top - main.top - tooltip.outerHeight()/2 + item.outerHeight()/2), l = parseInt(element.left - main.left - tooltip.outerWidth() - 3); } else if(item.attr('data-tooltip-position') == 'bottom'){ var t = parseInt(element.top - main.top + item.outerHeight()), l = parseInt(element.left - main.left - tooltip.outerWidth()/2 + item.outerWidth()/2); } } else{//top var t = parseInt(element.top - main.top - tooltip.outerHeight()), l = parseInt(element.left - main.left - tooltip.outerWidth()/2 + item.outerWidth()/2); } //keep within component if(l < 0) l = 0; else if(l + tooltip.outerWidth() > container.width())l = container.width() - tooltip.outerWidth(); if(t + main.top < 0)t = parseInt(element.top - main.top + tooltip.outerHeight() + 15);//position below tooltip.css({ left: l+'px', top: t+'px' }).show(); }).on("mouseleave", "[data-tooltip]", function(e){ tooltip.hide(); }); } //############################################// /* seekbar */ //############################################// var seekbarDown, seekbarSize; seekbar.on(downEvent,function(e){ if(!componentInited) return; if(settings.disableSeekbar) return false; if(settings.disableVideoSkip) return false; if(settings.seekToChapterStart && chapterArr.length)return false; if(adOn)return false; onDragStartSeek(e); return false; }); // Start dragging function onDragStartSeek(e) { if(!seekbarDown){ var point; if(e.type == 'touchstart'){ var currTouches = e.originalEvent.touches; if(currTouches && currTouches.length > 0) { point = currTouches[0]; }else{ return false; } }else{ point = e; e.preventDefault(); } seekbarDown = true; if(isCasting)if(_MVPCast)_MVPCast.startSeeking() _doc.on(moveEvent, function(e) { onDragMoveSeek(e); }).on(upEvent, function(e) { onDragReleaseSeek(e); }); } return false; } function onDragMoveSeek(e) { var point; if(e.type == 'touchmove'){ var touches; if(e.originalEvent.touches && e.originalEvent.touches.length) { touches = e.originalEvent.touches; }else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { touches = e.originalEvent.changedTouches; }else{ return false; } // If touches more then one, so stop sliding and allow browser do default action if(touches.length > 1) { return false; } point = touches[0]; e.preventDefault(); } else { point = e; e.preventDefault(); } setProgress(point); return false; } function onDragReleaseSeek(e) { if(seekbarDown){ seekbarDown = false; _doc.off(moveEvent).off(upEvent); if(isCasting)if(_MVPCast)_MVPCast.stopSeeking() var point; if(e.type == 'touchend'){ var touches; if(e.originalEvent.touches && e.originalEvent.touches.length) { touches = e.originalEvent.touches; }else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { touches = e.originalEvent.changedTouches; }else{ return false; } // If touches more then one, so stop sliding and allow browser do default action if(touches.length > 1) { return false; } point = touches[0]; e.preventDefault(); } else { point = e; e.preventDefault(); } setProgress(point); } return false; } function setProgress(point) { var seekPercent = point.pageX - progressBg.offset().left; if(seekPercent < 0) seekPercent = 0; else if(seekPercent > seekbarSize) seekPercent = seekbarSize; seekbarSize = progressBg.width(); var v = Math.max(0, Math.min(1, seekPercent / seekbarSize)); if(mediaStarted){ if(isCasting){ _MVPCast.seek(v); return; } var t,d; if(mediaType == 'audio' && !isNaN(audioUp2Js.duration)){ d = audioUp2Js.duration; t = v * d; if(t > d - 2)t = d - 2; if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } try{ audioUp2Js.currentTime = (t).toFixed(1); }catch(er){} }else if(mediaType == 'video' && !isNaN(videoUp2Js.duration)){ d = videoUp2Js.duration; t = v * d; if(t > d - 2)t = d - 2; if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } try{ videoUp2Js.currentTime = (t).toFixed(1); }catch(er){} }else if(mediaType == 'youtube'){ d = youtubePlayer.getDuration(); t = v * d; if(t > d - 2)t = d - 2; if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } youtubePlayer.seekTo(t); }else if(mediaType == 'vimeo'){ if(activeVimeoPlayerType == 'chromeless'){ playerLoader.show();//slow vimeo api! } if(vimeoDuration != 0){ d = vimeoDuration; t = v * d; if(t > d - 2)t = d - 2; if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } activeVimeoPlayer.setCurrentTime(t); }else{ activeVimeoPlayer.getDuration().then(function(duration) { d = duration; t = v * d; if(t > d - 2)t = d - 2; if(settings.disableSeekingPastWatchedPoint){ if(t > disableSeekingPastWatchedPointTime)return false; } activeVimeoPlayer.setCurrentTime(t); }); } } if(!mediaPlaying){ lastTime = null; trackProgress(true);//update } }else{ if(currMediaData.duration){//seek before video start with controls shown and duration available t = v * currMediaData.duration; currMediaData.start = t; progressLevel.width((t / currMediaData.duration) * progressBg.width()); } } } //############################################// /* seekbar tooltip */ //############################################// if(!isMobile){ seekbar.on('mouseover', function mouseOverHandlerSeek(){ if(!mediaStarted && !currMediaData && !currMediaData.duration) return; seekbar.on(moveEvent, mouseMoveHandlerSeekTooltip).on('mouseout', mouseOutHandlerSeek); _doc.on('mouseout.mvp', mouseOutHandlerSeek); }); function mouseOutHandlerSeek() { if(!mediaStarted && !currMediaData && !currMediaData.duration) return; seekbar.off(moveEvent, mouseMoveHandlerSeekTooltip).off('mouseout', mouseOutHandlerSeek); _doc.off('mouseout.mvp', mouseOutHandlerSeek); if(currMediaData.previewSeek){ previewSeekWrap.hide(); if(previewSeekAuto)stopDrawPreviewSeek() } tooltip.hide(); last_previewSeek_top = null } } function mouseMoveHandlerSeekTooltip(e){ var s = e.pageX - progressBg.offset().left; if(!MVPUtils.isNumber(s))return false; seekbarSize = progressBg.width() if(s < 0) s = 0; else if(s > seekbarSize) s = seekbarSize; var newPercent = Math.max(0, Math.min(1, s / seekbarSize)); if(!MVPUtils.isNumber(newPercent))return false; if(playerWrap.hasClass(settings.minimizeClass))var container = playerWrap; else if(lightboxOpened)var container = playerWrap; else container = wrapper; var main = container[0].getBoundingClientRect(), element = seekbar[0].getBoundingClientRect(); if(currMediaData.duration){ var d = currMediaData.duration; }else{//if media started if(mediaType == 'audio'){ var d = audioUp2Js.duration; }else if(mediaType == 'video'){ var d = videoUp2Js.duration; }else if(mediaType == 'youtube'){ var d = youtubePlayer.getDuration(); }else if(mediaType == 'vimeo'){ var d = vimeoDuration; } } if(currMediaData.previewSeek){ var time = d*newPercent; if(MVPUtils.isNumber(d)){ var chapter_title = getChapterTitle(time) if(chapter_title){ var ch = '
'+chapter_title+'
'+MVPUtils.formatTime(time)+'
'; previewSeekInfo.html(ch); }else{ var ch = '
'+MVPUtils.formatTime(time)+'
'; previewSeekInfo.html(ch); } } if(previewSeekArr.length){ var i, len = previewSeekArr.length, item, start, end; for(i = 0; i < len; i++){ item = previewSeekArr[i]; start = item.start, end = item.end; if(time >= start && time <= end){ if(!previewSeekImg){ var data = item.url, fragment = data.substr(data.lastIndexOf('=')+1), f = fragment.split(','), pos = '-'+f[0]+'px' + ' ' + '-'+f[1]+'px'; data = encodeURI(data);//spaces in filename previewSeekImg = {}; previewSeekImg.start = start; previewSeekImg.end = end; previewSeekInner.css({'background-image': 'url(' + data + ')', 'background-position': pos}); } }else{ if(previewSeekImg){ if(time < previewSeekImg.start || time > previewSeekImg.end){ previewSeekImg = null; } } } } } var l = e.pageX - _window.scrollLeft() - main.left - previewSeekWrap.outerWidth()/2, t = element.top - main.top - previewSeekWrap.outerHeight() - 5; if(last_previewSeek_top){ if(t + 2 > last_previewSeek_top || t - 2 < last_previewSeek_top){//if it hasnt changed drastically last_previewSeek_top = t; } }else{ last_previewSeek_top = t; } //keep within component if(settings.playerType != 'lightbox'){ if(l < 0) l = 0; else if(l + previewSeekWrap.outerWidth() > container.width())l = container.width() - previewSeekWrap.outerWidth(); } if(previewSeekAuto){ startDrawPreviewSeek(time) } previewSeekWrap.css({ left: parseInt(l,10)+'px', top: last_previewSeek_top+'px' }).show(); }else{ var l = e.pageX - _window.scrollLeft() - main.left - tooltip.outerWidth()/2, t = element.top - main.top - tooltip.outerHeight(); //keep within component if(settings.playerType != 'lightbox'){ if(l < 0) l = 0; else if(l + tooltip.outerWidth() > container.width())l = container.width() - tooltip.outerWidth(); } tooltip.css({ left: parseInt(l,10)+'px', top: parseInt(t,10)+'px' }).show(); if(MVPUtils.isNumber(d))tooltip.text(MVPUtils.formatTime(d*newPercent)+' / '+MVPUtils.formatTime(d)); } } //############################################// /* volume */ //############################################// var volumeTouch = false, volumeHorizontal = volumeSeekbar.hasClass('mvp-volume-horizontal'), volumeSeekbarSize = volumeHorizontal ? volumeSeekbar.width() : volumeSeekbar.height(), volumeSize = volumeHorizontal ? volumeBg.width() : volumeBg.height(), volumeBarDown; if(!volumeCanBeSet || isMobile){ volumeSeekbar.remove(); volumeToggle.on('click',function(e){ toggleMute(); }); } else{ volumeToggle.on('click',function(e){ if(!isMobile || volumeSeekbar.length == 0 || volumeSeekbar.hasClass('mvp-force-hide')){ toggleMute(); } }); } /*volumeWrapper.on('mouseenter', function() { volumeSeekbar.css('display','block'); }).on('mouseleave', function () { volumeSeekbar.css('display','none'); });*/ volumeSeekbar.on(downEvent,function(e){ onDragStartVolume(e); return false; }); function onDragStartVolume(e) { if(!componentInited) return; if(!volumeBarDown){ var point; if(e.type == 'touchstart'){ var currTouches = e.originalEvent.touches; if(currTouches && currTouches.length > 0) { point = currTouches[0]; }else{ return false; } }else{ point = e; e.preventDefault(); } volumeBarDown = true; _doc.on(moveEvent, function(e) { onDragMoveVolume(e); }).on(upEvent, function(e) { onDragReleaseVolume(e); }); } return false; } function onDragMoveVolume(e) { var point; if(e.type == 'touchmove'){ var touches; if(e.originalEvent.touches && e.originalEvent.touches.length) { touches = e.originalEvent.touches; }else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { touches = e.originalEvent.changedTouches; }else{ return false; } // If touches more then one, so stop sliding and allow browser do default action if(touches.length > 1) { return false; } point = touches[0]; e.preventDefault(); } else { point = e; e.preventDefault(); } volumeTo(point); return false; } function onDragReleaseVolume(e) { if(volumeBarDown){ volumeBarDown = false; _doc.off(moveEvent).off(upEvent); var point; if(e.type == 'touchend'){ var touches; if(e.originalEvent.touches && e.originalEvent.touches.length) { touches = e.originalEvent.touches; }else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) { touches = e.originalEvent.changedTouches; }else{ return false; } // If touches more then one, so stop sliding and allow browser do default action if(touches.length > 1) { return false; } point = touches[0]; e.preventDefault(); } else { point = e; e.preventDefault(); } volumeTo(point); } return false; } function toggleMute(){ if(!componentInited) return false; if(volume>0){ lastVolume = volume;//remember last volume volume = 0; if(currMediaData && currMediaData.TrackingEvents)vastTracking("mute"); }else{ volume = lastVolume;//restore last volume if(currMediaData && currMediaData.TrackingEvents)vastTracking("unmute"); } setVolume(); } function volumeTo(v) { if(volumeHorizontal){ volume = Math.max(0, Math.min(1, (v.pageX - volumeBg.offset().left) / volumeSize)); }else{ volume = Math.max(0, Math.min(1, (v.pageY - volumeBg.offset().top) / volumeSize)); volume = 1 - volume;//reverse for up dir } setVolume(); } function setVolume(v){ if(typeof v !== 'undefined')volume = v; if(typeof volume !== 'undefined'){ if(isIma)if(_mvpImaLoader)_mvpImaLoader.setVolume(volume); if(isCasting){ if(_MVPCast)_MVPCast.setVolume(volume); }else if(mediaType == 'audio'){ if(audioUp2Js){ audioUp2Js.volume = volume; if(volume == 0){ audioUp2Js.muted = true; }else{ audioUp2Js.muted = false; } } }else if(mediaType == 'video'){ if(videoUp2Js){ videoUp2Js.volume = volume; if(volume == 0){ videoUp2Js.muted = true; }else{ videoUp2Js.muted = false; } } }else if(mediaType == 'youtube'){ if(youtubePlayer){ youtubePlayer.setVolume(volume * 100); if(volume == 0){//15.2.2020 ios needs this, or it wont start autoplay muted //dont use if(youtubePlayer.isMuted()) because its not reliable youtubePlayer.mute(); }else{ youtubePlayer.unMute(); } } }else if(mediaType == 'vimeo'){ if(activeVimeoPlayer)activeVimeoPlayer.setVolume(volume); } } volumeToggle.children().hide();//hide all volume btns if(volume == 0){ volumeToggle.find('.mvp-btn-volume-off').show(); }else if(volume > 0 && volume < 0.5){ volumeToggle.find('.mvp-btn-volume-down').show(); }else if(volume >= 0.5 && volume <= 1){ volumeToggle.find('.mvp-btn-volume-up').show(); } if(volume > 0){ if(unmuteToggle){ unmuteToggle.remove(); unmuteToggle = null; } } var prop = volumeHorizontal ? 'width' : 'height'; volumeLevel.css(prop, volume*volumeSize+'px'); $(self).trigger("volumeChange", {instance:self, instanceName: settings.instanceName, volume: volume}); } self.setVolumeExternal = function(v){ volume = v; volumeToggle.children().hide();//hide all volume btns if(volume == 0){ volumeToggle.find('.mvp-btn-volume-off').show(); }else if(volume > 0 && volume < 0.5){ volumeToggle.find('.mvp-btn-volume-down').show(); }else if(volume >= 0.5 && volume <= 1){ volumeToggle.find('.mvp-btn-volume-up').show(); } if(volume > 0){ if(unmuteToggle){ unmuteToggle.remove(); unmuteToggle = null; } } var prop = volumeHorizontal ? 'width' : 'height'; volumeLevel.css(prop, volume*volumeSize+'px'); $(self).trigger("volumeChange", {instance:self, instanceName: settings.instanceName, volume: volume}); } //############################################// /* volume tooltip */ //############################################// if(!isMobile){ volumeSeekbar.on('mouseover', function mouseOverHandlerSeek(){ volumeSeekbar.on(moveEvent, mouseMoveHandlerVolumeTooltip).on('mouseout', mouseOutHandlerVolume); _doc.on('mouseout.mvp', mouseOutHandlerVolume); }); function mouseOutHandlerVolume() { volumeSeekbar.off(moveEvent, mouseMoveHandlerVolumeTooltip).off('mouseout', mouseOutHandlerVolume); _doc.off('mouseout.mvp', mouseOutHandlerVolume); tooltip.hide(); } } function mouseMoveHandlerVolumeTooltip(e){ if(volumeHorizontal)var s = e.pageX - volumeBg.offset().left; else var s = e.pageY - volumeBg.offset().top; if(s<0) s=0; else if(s>volumeSize) s=volumeSize; var newPercent = Math.max(0, Math.min(1, s / volumeSize)); if(!MVPUtils.isNumber(newPercent))return false; if(!volumeHorizontal)newPercent = 1 - newPercent;//reverse for up dir var value=parseInt(newPercent * 100, 10); tooltip.text(value+' %'); if(playerWrap.hasClass(settings.minimizeClass))var container = playerWrap; else if(lightboxOpened)var container = playerWrap; else container = wrapper; var main = container[0].getBoundingClientRect(), element = volumeSeekbar[0].getBoundingClientRect(); if(volumeHorizontal){ var l = parseInt(e.pageX - _window.scrollLeft() - main.left - tooltip.outerWidth()/2), t = parseInt(element.top - main.top - tooltip.outerHeight()); }else{ var l = parseInt(element.left - main.left - tooltip.outerWidth()/2 + volumeSeekbar.outerWidth()/2), t = parseInt(e.pageY - _window.scrollTop() - main.top - tooltip.outerHeight() - 10); } tooltip.css({ left: l+'px', top: t+'px' }).show(); } //############################################// /* share */ //############################################// if(settings.useShare){ if(typeof MVPShareManager === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.share_js); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ _MVPShareManager = new MVPShareManager(settings); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ _MVPShareManager = new MVPShareManager(settings); } } //############################################// /* settings menu */ //############################################// var settingsWrap = wrapper.find('.mvp-settings-wrap'), settingsHolder = wrapper.find('.mvp-settings-holder'), settingsHolderInner = wrapper.find('.mvp-settings-holder-inner'), settingsHome = wrapper.find('.mvp-settings-home'); settingsToggle.on('click', function() { if(settingsHolder.hasClass('mvp-holder-visible')){ settingsHolder.one("transitionend", function(){ settingsHolder.css({display:'none', width:'auto', height:'auto'}); //restore home menu settingsHolder.find('.mvp-settings-menu').css('display','none'); settingsHome.css('display','block'); settingsHolder.css('maxHeight','none').removeClass('mvp-settings-holder-scrollable'); }).removeClass('mvp-holder-visible'); }else{ settingsHolder.css('display','block'); setTimeout(function(){ settingsHolder.addClass('mvp-holder-visible'); },20); if(chapterMenuOpened && !settings.useChapterWindow)toggleChapterMenu(false);//close chapter menu since settings menu lies behind } }); settingsHome.find('.mvp-menu-item').on('click', function(){ var target = $(this).attr('data-target'); var w0 = settingsHolder.width(), h0 = settingsHolder.height();//get last size settingsHome.css('display','none'); settingsHolder.find('.mvp-settings-menu').css('display','none'); settingsHolder.css('maxHeight','none').removeClass('mvp-settings-holder-scrollable'); settingsHolder.css({width:'auto', height:'auto'});//reset size to auto to get child size var sh = settingsHolder.find('.'+target).css('display','block');//show child var w = sh.width(), h = sh.height();//get child size if(h > playerHolder.height()-settingsMenuHeightDiff){//doesnt fit in player settingsHolder.css('maxHeight', playerHolder.height()-settingsMenuHeightDiff).addClass('mvp-settings-holder-scrollable'); } settingsHolder.css({width:w0+'px', height:h0+'px'}); setTimeout(function(){ settingsHolder.css({width:w+'px', height:h+'px'}); },20); }); settingsHolder.find('.mvp-menu-header').on('click', function(){//header click, close submenu showSettingsMenu(); }); function showSettingsMenu(){ settingsHolder.find('.mvp-settings-menu').css('display','none'); var w0 = settingsHolder.width(), h0 = settingsHolder.height();//get last size settingsHolder.css({width:'auto', height:'auto'});//reset size to auto settingsHome.css('display','block');//show child var w = settingsHome.width(), h = settingsHome.height();//get child size settingsHolder.css({width:w0+'px', height:h0+'px'}); setTimeout(function(){ settingsHolder.css({width:w+'px', height:h+'px'}); },20); } //############################################// /* playback rate */ //############################################// playbackRateMenu.find('.mvp-menu-item').on('click', function(){ if(isCasting)return false; if($(this).hasClass('mvp-menu-active')){ if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } return false;//active item } var value = $(this).attr('data-value'); currMediaData.playbackRate = value;//remember for quality change setPlaybackRateActiveMenuItem(value); if(mediaStarted)self.setPlaybackRate(value); if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } }); function setPlaybackRateActiveMenuItem(value){ //needed for youtube where we only set quality in menu if quality has been changed! if(activePlaybackRateMenuItem)activePlaybackRateMenuItem.removeClass('mvp-menu-active'); activePlaybackRateMenuItem = playbackRateMenu.find(".mvp-menu-item[data-value='" + value + "']").addClass('mvp-menu-active'); settingsHolder.find('.mvp-playback-rate-menu-value').text(activePlaybackRateMenuItem.text()); } //############################################// /* playback quality */ //############################################// function buildQualityMenu(available_quality, current_quality){ var i, len = available_quality.length, item, li; for(i=0;i').addClass('mvp-menu-item').attr({'data-value': item.value, 'data-label': item.label}).text(item.label).on('click', clickQualityMenuItem).appendTo(qualityMenu); }else{//same label and value li = $('
  • ').addClass('mvp-menu-item').attr('data-value', item).text(item).on('click', clickQualityMenuItem).appendTo(qualityMenu); } } setQualityActiveMenuItem(current_quality); qualitySettingsMenu.removeClass('mvp-force-hide'); } function clickQualityMenuItem(){ if(isCasting)return false; if($(this).hasClass('mvp-menu-active')){ if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } return false;//active item } var quality = $(this).attr('data-value'); currMediaData.quality = quality; setQualityActiveMenuItem(quality); if(mediaStarted)self.setPlaybackQuality(quality); else getQuality();//update quality if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } } function setQualityActiveMenuItem(value){ //set active only on callback because for some api it may not be accepted on request if(activeQualityMenuItem)activeQualityMenuItem.removeClass('mvp-menu-active'); activeQualityMenuItem = qualityMenu.find(".mvp-menu-item[data-value='" + value + "']").addClass('mvp-menu-active'); settingsHolder.find('.mvp-quality-menu-value').text(activeQualityMenuItem.text()); } //############################################// /* audio language */ //############################################// function toggleAudioLanguage(){ if(isCasting)return false; var curr_audio = $(this).attr('data-value'); if(subMediaType == 'hls')hls.audioTrack = curr_audio; if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } } function setAudioLanguageActiveMenuItem(value){ if(activeAudioLanguageMenuItem)activeAudioLanguageMenuItem.removeClass('mvp-menu-active'); activeAudioLanguageMenuItem = audioLanguageMenu.find(".mvp-menu-item[data-value='" + value + "']").addClass('mvp-menu-active'); settingsHolder.find('.mvp-audio-language-menu-value').text(activeAudioLanguageMenuItem.text()); } //############################################// /* subtitles */ //############################################// function buildSubtitleMenu(){ var i, len = currMediaData.subtitles.length, item, li, default_subtitle, default_transcript, subtitle_state; //transcript var transcript_menu = '
      ' if(settings.rememeberCaptionState && hasLocalStorage && localStorage.getItem(captionStateKey)){ subtitle_state = JSON.parse(localStorage.getItem(captionStateKey)); } for(i = 0; i < len; i++){ item = currMediaData.subtitles[i]; li = $('
    • ').addClass('mvp-menu-item').attr({'data-value': item.value, 'data-label': item.label, 'data-id': i.toString()}).text(item.label).on('click', clickSubtitleMenuItem).appendTo(subtitleMenu); if(subtitle_state){ if(subtitle_state.active && subtitle_state.value == item.label){//check if subtitle exist becuase if we move to next video, that subtitle might not be present default_subtitle = item.label; } } else if(item.default){ default_subtitle = item.label; default_transcript = item.label; } //transcript if(item.label != settings.subtitleOffText)transcript_menu += '
    • '+item.label+'
    • ' } //transcript transcript_menu += '
    ' transcriptLanguageSelector.html(transcript_menu) if(!default_subtitle){ default_subtitle = settings.subtitleOffText; } self.setSubtitle(default_subtitle); subtitleSettingsMenu.removeClass('mvp-force-hide'); captionToggle.show(); transcriptToggle.show(); subtitlesReady = true; } function clickSubtitleMenuItem(){//click subtitle menu item if($(this).hasClass('mvp-menu-active')){ if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } return false;//active item } var value = $(this).attr('data-label'); if(isCasting){ var id = parseInt($(this).attr('data-id'),10); _MVPCast.loadSubtitle(id); if(activeSubtitleMenuItem)activeSubtitleMenuItem.removeClass('mvp-menu-active'); activeSubtitleMenuItem = subtitleMenu.find(".mvp-menu-item[data-label='" + value + "']").addClass('mvp-menu-active'); }else{ self.setSubtitle(value); } if(settings.closeSettingsMenuOnSelect){ settingsToggle.click(); }else{ showSettingsMenu(); } } this.toggleSubtitle = function(){//click caption toggle if(!componentInited) return false; if(!mediaType) return false; if(currMediaData && currMediaData.subtitles){ var i, len = currMediaData.subtitles.length, item, default_subtitle, subtitle_state; if(settings.rememeberCaptionState && hasLocalStorage && localStorage.getItem(captionStateKey)){ subtitle_state = JSON.parse(localStorage.getItem(captionStateKey)); //reverse (if exist set off, if not exist set last active) if(subtitle_state.active)default_subtitle = settings.subtitleOffText; else default_subtitle = subtitle_state.value; if(default_subtitle)self.setSubtitle(default_subtitle); } } } this.setSubtitle = function(value){ if(!componentInited) return false; if(!mediaType) return false; subtitleHolderInner.empty(); subtitleHolder.show(); activeTranscriptLanguage = value; if(value == settings.subtitleOffText || value == ''){//subtitle off if(value == '')value = settings.subtitleOffText; subtitleOn = false; activeSubtitle = null; if(activeSubtitleMenuItem)activeSubtitleMenuItem.removeClass('mvp-menu-active'); activeSubtitleMenuItem = subtitleMenu.find(".mvp-menu-item[data-label='" + value + "']").addClass('mvp-menu-active'); //caption toggle captionToggle.addClass('mvp-btn-disabled'); if(settings.autoLoadTranscript && !transcriptInited)toggleTranscript() }else{ if(allSubtitleArr[value]){//already have subtitle subtitleOn = true; activeSubtitle = null; if(activeSubtitleMenuItem)activeSubtitleMenuItem.removeClass('mvp-menu-active'); activeSubtitleMenuItem = subtitleMenu.find(".mvp-menu-item[data-label='" + value + "']").addClass('mvp-menu-active'); subtitleArr = allSubtitleArr[value];//save for reuse lastTime = null; trackProgress(true);//update }else{//get subtitle var i, len = currMediaData.subtitles.length, item; for(i = 0; i < len; i++){ item = currMediaData.subtitles[i]; if(item.label == value){ subtitleOn = false; activeSubtitle = null; if(activeSubtitleMenuItem)activeSubtitleMenuItem.removeClass('mvp-menu-active'); activeSubtitleMenuItem = subtitleMenu.find(".mvp-menu-item[data-label='" + value + "']").addClass('mvp-menu-active'); if(externalSubtitle)getSubtitleUrl(item); else getSubtitle(item); break; } } } //caption toggle captionToggle.removeClass('mvp-btn-disabled'); } //remember active subtitle for mainMediaData and ads var i = 0, len = currMediaData.subtitles.length; for(i = 0; i < len; i++){ item = currMediaData.subtitles[i]; delete item.default; if(item.value == value){ item.default = true; } } settingsHolder.find('.mvp-subtitle-menu-value').text(value); if(settings.rememeberCaptionState && hasLocalStorage){ if(localStorage.getItem(captionStateKey))var d = JSON.parse(localStorage.getItem(captionStateKey)); else var d = {}; if(value == settings.subtitleOffText){ d.active = false; }else{ d.active = true; //save last active subtitle before disabled d.value = value; } localStorage.setItem(captionStateKey, JSON.stringify(d)); } } function getSubtitleUrl(item){ $.ajax({ url: item.src }).done(function( file ) { var lines = file.split(/[\r\n]/), found; for (var i in lines){ var line = lines[i]; if (/.vtt/.test(line)) { //console.log(line) item.src = item.src.substr(0, item.src.lastIndexOf('/')+1)+line; found = true; break; } } if(found)getSubtitle(item); else console.log('Error loading subtitle!') }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); }); } function getSubtitle(item){//load subtitle file if(window.location.protocol == 'file:'){ console.log('Getting subtitle requires server connection.'); return false; } var src = item.src; if(src.indexOf(bsf_match) != -1)src = MVPUtils.b64DecodeUnicode(src.substr(6)); //check cors if(item.cors && settings.cors){ src = settings.cors + src console.log(src) } $.ajax({ url: src, }).done(function( data ) { var srt = data.replace(/\r\n|\r|\n/g, '\n'); //var srt = data.replace(/\r\n\s*\r\n/g, '\n'); var arr =[] srt = MVPUtils.strip(srt); var sub = srt.split('\n\n'), s, st, z = 0, j, number, start, end, text; for(s in sub) { st = sub[s].split('\n'); if(st == "WEBVTT")continue; if(st.length >= 2) { //number = st[0]; if(st[0] == "WEBVTT")continue; if(st.length > 2){ if(st[0] == '')st.shift(); start = MVPUtils.strip(st[1].split(' --> ')[0]); end = MVPUtils.strip(st[1].split(' --> ')[1]); text = st[2]; if(st.length > 3) { for(j=3; j ')[0]); end = MVPUtils.strip(st[0].split(' --> ')[1]); text = st[1]; } arr[z] = {}; arr[z].start = MVPUtils.toSeconds(start); arr[z].end = MVPUtils.toSeconds(end); arr[z].text = text; z++; } } if(transcriptRequest){ var act_sub = activeSubtitleMenuItem.attr('data-label') createTranscript(act_sub, arr) }else{ subtitleArr = arr; subtitleOn = true; if(mediaStarted){ lastTime = null; trackProgress(true);//update } if(settings.autoLoadTranscript && !transcriptInited)toggleTranscript() } allSubtitleArr[item.label] = arr;//save }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); }); } //############################################// /* chapters */ //############################################// function toggleChapterMenu(v){ if(typeof v !== 'undefined'){ if(chapterMenuOpened && v == true)return false; else if(!chapterMenuOpened && v == false)return false; chapterMenuOpened = !v; } if(settings.useChapterWindow){ if(chapterMenuOpened){ if(componentSize == 'fullscreen' && !settings.playlistOpened){ self.togglePlaylist() } else{ chaptersHolder.hide(); chapterMenuOpened = false; chaptersSearchInput.val('') } }else{ //on h navigation, chapter ehight is going to be bigger than playlist item height because chapters contains header with buttons if(navigationDirection == 'h' && !chapterHorizSizeInited){ chapterHorizSizeInited = true; playlistHolder.height(playlistHolder.height() + 35); doneResizing() } if(componentSize == 'fullscreen' && !settings.playlistOpened){//we have to open the playlist as well because chapter window is part of the playlist self.togglePlaylist() } else{ chaptersHolder.show(); chapterMenuOpened = true; } } }else{ if(chapterMenuOpened){ chapterMenuHolder.one("transitionend", function(){ chapterMenuHolder.css('display','none'); chapterMenuOpened = false; }).removeClass('mvp-holder-visible'); }else{ chapterMenuHolder.css('display','block'); setTimeout(function(){ chapterMenuHolder.addClass('mvp-holder-visible'); chapterMenuOpened = true; },20); } } } function getChapterTitle(time){ var i, len = chapterArr.length, ch, title for(i=0;i= time){ title = ch.text; break; } } return title; } function getChapters(){//load chapters chapterArr = []; var src = currMediaData.chapters //check cors if(currMediaData.chaptersCors && settings.cors){ src = settings.cors + src console.log(src) } $.ajax({ url: src }).done(function( data ) { var srt = data.replace(/\r\n|\r|\n/g, '\n'); srt = MVPUtils.strip(srt); var sub = srt.split('\n\n'), s, st, z = 0, j, start, end, text, img, ib; for(s in sub) { st = sub[s].split('\n'); if(st == "WEBVTT")continue; if(st.length >= 2) { img = null; if(st.length > 2){ if(st[0] == '')st.shift(); start = MVPUtils.strip(st[1].split(' --> ')[0]); end = MVPUtils.strip(st[1].split(' --> ')[1]); text = st[2]; if(text.indexOf('#img=') > -1){ //has image ib = text.split('#img=') text = ib[0] img = ib[1] }else{ if(st.length > 2) { for(j=3; j ')[0]); end = MVPUtils.strip(st[0].split(' --> ')[1]); text = st[1]; if(text.indexOf('#img=') > -1){ //has image ib = text.split('#img=') text = ib[0] img = ib[1] } } } chapterArr[z] = {}; chapterArr[z].id = z; chapterArr[z].start = MVPUtils.toSeconds(start); chapterArr[z].end = MVPUtils.toSeconds(end); chapterArr[z].text = text; if(img)chapterArr[z].img = img; z++; } //chaptersLoaded = true; if(currMediaData.duration && settings.showControlsBeforeStart){ makeChapters(currMediaData.duration);//chapters are alternatively built after video starts and we get duration } chaptersReady = true; }).fail(function(jqXHR, textStatus, errorThrown) { console.log("Error loading chapters: ", jqXHR.responseText, textStatus, errorThrown); }); } //click chapter in seekbar if(settings.seekToChapterStart){//if false, we use seekbar to seek anywhere wrapper.on('click', '.mvp-chapter-indicator', function(){ var item = $(this), id = item.attr('data-id'); setChapterActiveMenuItem(id); var t = Number(item.attr('data-start')); if(mediaStarted){ self.seek(t); if(!mediaPlaying){ lastTime = null; trackProgress(true);//update } }else{ currMediaData.start = t; if(currMediaData.duration){ seekbarSize = progressBg.width(); progressLevel.width((t / currMediaData.duration) * seekbarSize); } } }); } if(!isMobile){ wrapper.on('mouseenter', '.mvp-chapter-indicator', function(){ if(!componentInited)return false; var item = $(this), id = item.attr('data-id'); //seekbar hover indicator item.find('.mvp-chapter-indicator-highlight').addClass('mvp-chapter-indicator-highlight-visible'); //menu hover chapterMenu.find('.mvp-chapter-menu-item[data-id="'+id+'"]').addClass('mvp-chapter-menu-item-active'); }).on('mouseleave', '.mvp-chapter-indicator', function(){ if(!componentInited)return false; var item = $(this), id = item.attr('data-id'); if(currentActiveChapterData && currentActiveChapterData.id == id)return;//if not active chapter //seekbar hover indicator item.find('.mvp-chapter-indicator-highlight').removeClass('mvp-chapter-indicator-highlight-visible'); //menu hover chapterMenu.find('.mvp-chapter-menu-item[data-id="'+id+'"]').removeClass('mvp-chapter-menu-item-active'); }); } //click chapter menu item wrapper.on('click', '.mvp-chapter-menu-item', function(){ var item = $(this), id = item.attr('data-id'); setChapterActiveMenuItem(id); var t = Number(item.attr('data-start')); if(mediaStarted){ self.seek(t); if(!mediaPlaying){ lastTime = null; trackProgress(true);//update } }else{ currMediaData.start = t; if(currMediaData.duration){ seekbarSize = progressBg.width(); progressLevel.width((t / currMediaData.duration) * seekbarSize); } self.togglePlayback()//make chapter menu auto start video when clicked } if(settings.hideChapterMenuOnChapterSelect)toggleChapterMenu(false); }) if(!isMobile){ wrapper.on('mouseenter', '.mvp-chapter-menu-item, .mvp-chapter-item', function(){ var item = $(this), id = item.attr('data-id'); //seekbar hover indicator progressBg.find('.mvp-chapter-indicator[data-id="'+id+'"]').find('.mvp-chapter-indicator-highlight').addClass('mvp-chapter-indicator-highlight-visible'); //menu hover if(item.hasClass('mvp-chapter-menu-item'))item.addClass('mvp-chapter-menu-item-active'); }).on('mouseleave', '.mvp-chapter-menu-item, .mvp-chapter-item', function(){ var item = $(this), id = item.attr('data-id'); if(currentActiveChapterData && currentActiveChapterData.id == id)return;//if not active chapter //seekbar hover indicator progressBg.find('.mvp-chapter-indicator[data-id="'+id+'"]').find('.mvp-chapter-indicator-highlight').removeClass('mvp-chapter-indicator-highlight-visible'); //menu hover if(item.hasClass('mvp-chapter-menu-item'))item.removeClass('mvp-chapter-menu-item-active'); }); } //chapter window //click chapter in window chaptersHolder.on('click', '.mvp-chapter-item', function(){ var item = $(this), id = item.attr('data-id'); setChapterActiveMenuItem(id); var t = Number(item.attr('data-start')); if(mediaStarted){ self.seek(t); if(!mediaPlaying){ lastTime = null; trackProgress(true);//update } }else{ currMediaData.start = t; if(currMediaData.duration){ seekbarSize = progressBg.width(); progressLevel.width((t / currMediaData.duration) * seekbarSize); } } }); //search chapters var chaptersSearchInput = chaptersHolder.find('.mvp-chapters-search-input').on('keyup',function(){ var len = chaptersContainer.find('.mvp-chapter-item').length if(len == 0)return false; var value = $(this).val().toLowerCase(), i, j = 0, pi, title; for(i = 0; i < len; i++){ pi = chaptersContainer.find('.mvp-chapter-item').eq(i); title = pi.find('.mvp-chapter-item-text').html().toLowerCase(); if(title.indexOf(value) >- 1){ chaptersContainer.find('.mvp-chapter-item').eq(i).fadeIn(200) }else{ chaptersContainer.find('.mvp-chapter-item').eq(i).fadeOut(200) j++; } } if(j == len){ playlistFilterMsg.show(); }else { playlistFilterMsg.hide(); } }); function makeChapters(d){//we need duration for this var i, len = chapterArr.length, item, perc, chapter, chapter_menu_item, t, l, chapter_window = ''; for(i = 0; i < len; i++){ item = chapterArr[i]; t = Math.abs(item.end - item.start); perc = (t/d*100); l = (item.start / d) * 100; //chapters in seekbar chapter = $('
    ').css({width: perc+'%', left: l+'%'}) .attr({'data-id': i, 'data-title': item.text, 'data-start': item.start, 'data-end': item.end}) .appendTo(progressBg); var c_start = MVPUtils.formatTime(item.start) if(settings.useChapterWindow){ //chapter window chapter_window += '
    ' if(item.img){//has thumb var alt = item.text.replace(/"/g, "'"); chapter_window += '
    '+alt+'
    ' } chapter_window += '
    ' chapter_window += '
    '+item.text+'
    ' chapter_window += '
    '+c_start+'
    ' chapter_window += '
    ' chapter_window += '
    ' chaptersContainer.html(chapter_window) }else{ //chapter menu chapter_menu_item = $('
  • '+item.text+''+c_start+'
  • ') .attr({'data-id': i, 'title': item.text, 'data-start': item.start}) .appendTo(chapterMenu); } } if(settings.useChapterWindow){ if(navigationDirection == 'h'){ //get playlist item size var pi_test = $('
    ').prependTo(wrapper); var size = pi_test.outerWidth(true); pi_test.remove(); pi_test = null; chaptersContainer.width(len*size); } } chaptersCreated = true; chapterToggle.show(); nextChapterToggle.show(); prevChapterToggle.show(); if(settings.autoOpenChapterMenu)toggleChapterMenu(); } function setChapterActiveMenuItem(id){ //menu hover if(chapterActiveMenuItem)chapterActiveMenuItem.removeClass('mvp-chapter-menu-item-active'); chapterActiveMenuItem = chapterMenu.find(".mvp-chapter-menu-item[data-id='" + id + "']").addClass('mvp-chapter-menu-item-active'); //seekbar hover indicator if(chapterActiveHighlight)chapterActiveHighlight.removeClass('mvp-chapter-indicator-highlight-visible'); chapterActiveHighlight = progressBg.find(".mvp-chapter-indicator[data-id='" + id + "']").find('.mvp-chapter-indicator-highlight').addClass('mvp-chapter-indicator-highlight-visible'); currentActiveChapterData = chapterArr[id]; //chapter window if(settings.useChapterWindow){ //menu hover if(chapterActiveWindowItem)chapterActiveWindowItem.removeClass('mvp-chapter-item-active'); chapterActiveWindowItem = chaptersContainer.find(".mvp-chapter-item[data-id='" + id + "']").addClass('mvp-chapter-item-active'); } if(settings.showChapterTitle){ videoTitle.html(currentActiveChapterData.text).addClass('mvp-visible'); } } //############################################// /* playlist selector */ //############################################// function createPlaylistSelector(){ var item, html = '', i = 0; playlistList.children().each(function(){ i++ item = $(this) html += '
    ' if(item.attr('data-thumb')){ html += '
    ' } html += '
    ' if(item.attr('data-title')){ html += '
    '+item.attr('data-title')+'
    ' } if(item.attr('data-description')){ html += '
    '+item.attr('data-description')+'
    ' } html += '
    ' html += '
    ' }) playlistSelectorContainer.html(html) wrapper.on('click', '.mvp-playlist-selector-header-inner', function(){ togglePlaylistSelector() }) if(navigationDirection == 'h'){ //get playlist item size var pi_test = $('
    ').prependTo(wrapper); var size = pi_test.outerWidth(true); pi_test.remove(); pi_test = null; playlistSelectorContainer.width(i*size); } if(settings.autoOpenPlaylistSelector)togglePlaylistSelector(); } playlistSelectorContainer.on('click', '.mvp-playlist-selector-item', function(){ var item = $(this) if(item.hasClass('mvp-playlist-selector-item-active'))return false; if(lastPlaylistSelectorActiveItem)lastPlaylistSelectorActiveItem.removeClass('mvp-playlist-selector-item-active') lastPlaylistSelectorActiveItem = item.addClass('mvp-playlist-selector-item-active') var id = item.attr('data-id') self.loadPlaylist('.'+id) }); function togglePlaylistSelector(v){ if(typeof v !== 'undefined'){ if(playlistSelectorOpened && v == true)return false; else if(!playlistSelectorOpened && v == false)return false; playlistSelectorOpened = !v; } searchSelector.val('').trigger('keyup') if(playlistSelectorOpened){ playlistSelectorHolder.hide(); playlistSelectorOpened = false; playlistSelectorHeaderIcon.removeClass('mvp-playlist-selector-header-inner-opened') playlistInner.show() }else{ playlistInner.hide() playlistSelectorHeaderIcon.addClass('mvp-playlist-selector-header-inner-opened') playlistSelectorHolder.show(); playlistSelectorOpened = true; } } //############################################// /* ad markers */ //############################################// function makeAdMarkers(d){ var i, len = adMidArr.length, item, l; for(i = 0; i < len; i++){ item = adMidArr[i]; l = Math.round((item.begin / d) * 100); item.marker = $('
    ').css({left: l+'%'}).appendTo(progressBg); } //marker for ad end if(adEndArr.length){ $('
    ').css({right: 0}).appendTo(progressBg); } console.log(imaAdMarkerArr) } this.makeAdMarkersIma = function(arr){ //note: ima only plays ads once! (so we can remove ad point after it has played) var i, len = arr.length, item, begin, l, d = self.getDuration() for(i = 0; i < len; i++){ begin = arr[i]; if(begin > 0){ l = Math.round((begin / d) * 100); item = $('
    ').css({left: l+'%'}).appendTo(progressBg); imaAdMarkerArr.push({marker:item, begin:begin}) } else if(begin == -1){ //we just use for ad message (ad will start in...) otherwise we dont need it begin = d; item = $('
    ').css({right: 0}).appendTo(progressBg); imaAdMarkerArr.push({marker:item, begin:d}) } } } //############################################// /* preview seek */ //############################################// //auto function initPreviewSeekVideo(){ if(!previewSeekCanvas){ previewSeekCanvas = document.createElement('canvas'); previewSeekCanvas.className = "mvp-preview-seek-canvas"; previewSeekCanvasWidth = previewSeekWrap.width() previewSeekCanvasHeight = previewSeekWrap.height() previewSeekCanvas.width = previewSeekCanvasWidth; previewSeekCanvas.height = previewSeekCanvasHeight; previewSeekCanvasCtx = previewSeekCanvas.getContext('2d'); previewSeekInner.append(previewSeekCanvas) videoForPreviewSeek = document.createElement("video"); videoForPreviewSeek.muted = true; videoForPreviewSeek.playsinline = true; videoForPreviewSeek.setAttribute("playsinline", "playsinline"); videoForPreviewSeek.setAttribute("muted", "muted"); videoForPreviewSeek.addEventListener('seeked', function(){ if(!previewSeekSnapshotDone){ previewSeekSnapshotDone = true; //draw preview seek /* //auto calculate size and set preview seek size automatically? var w = videoForPreviewSeek.videoWidth; var h = videoForPreviewSeek.videoHeight; var tw = previewSeekInner.width() var th = Math.round(videoForPreviewSeek.videoHeight * (tw/videoForPreviewSeek.videoWidth));*/ previewSeekCanvasCtx.drawImage(videoForPreviewSeek, 0, 0, previewSeekCanvasWidth, previewSeekCanvasHeight); } }) } if(subMediaType == 'hls'){ if(hlsSupport){ hlsForPreviewSeek = new Hls(); hlsForPreviewSeek.on(Hls.Events.MEDIA_ATTACHED, function () { hlsForPreviewSeek.loadSource(mediaPath); }); } }else if(subMediaType == 'dash'){ if(!dashForPreviewSeek)dashForPreviewSeek = dashjs.MediaPlayer().create(); } } function setPreviewSeekVideoSource(){ if(subMediaType == 'hls'){ if(hlsSupport){ hlsForPreviewSeek.attachMedia(videoForPreviewSeek); }else if(videoForPreviewSeek.canPlayType('application/vnd.apple.mpegurl') == 'true'){ videoForPreviewSeek.src = mediaPath; }else if(currMediaData.mp4){//backup videoForPreviewSeek.src = currMediaData.mp4; videoForPreviewSeek.load(); }else{ try{ videoForPreviewSeek.src = mediaPath; videoForPreviewSeek.load(); }catch(er){ console.log("This browser or device does not support HLS extension. Please use mp4 video for playback!"); } } }else if(subMediaType == 'dash'){ if(dashSupport){ if(!dashForPreviewSeekInitialized){ dashForPreviewSeek.initialize(videoForPreviewSeek, mediaPath, true); dashForPreviewSeekInitialized = true; }else{ dashForPreviewSeek.attachSource(mediaPath); } }else{ if(currMediaData.mp4){//backup videoForPreviewSeek.src = currMediaData.mp4; videoForPreviewSeek.load(); }else{ console.log("This browser or device does not support MPEG-DASH extension. Please use mp4 video for playback!"); } } }else{ videoForPreviewSeek.src = mediaPath; videoForPreviewSeek.load(); } } function startDrawPreviewSeek(t){ previewSeekSnapshotDone = false; var promise = videoForPreviewSeek.play(); if (promise !== undefined) { promise.then(function(){ }).catch(function(error){ }); } try{ videoForPreviewSeek.currentTime = t; }catch(er){} } function stopDrawPreviewSeek(){ if(videoForPreviewSeek)videoForPreviewSeek.pause(); if(previewSeekCanvasCtx)previewSeekCanvasCtx.clearRect(0, 0, previewSeekCanvasWidth, previewSeekCanvasHeight); } //vtt function getPreviewSeek(){ if(window.location.protocol == 'file:'){ console.log('Getting preview seek requires server connection.'); return false; } previewSeekArr = []; $.ajax({ url: currMediaData.previewSeek }).done(function( data ) { //console.log(data) var srt = data.replace(/\r\n|\r|\n/g, '\n'); srt = MVPUtils.strip(srt); var sub = srt.split('\n\n'), s, st, z = 0, j, start, end, url; for(s in sub) { st = sub[s].split('\n'); if(st == "WEBVTT")continue; if(st.length >= 2) { start = MVPUtils.strip(st[0].split(' --> ')[0]); end = MVPUtils.strip(st[0].split(' --> ')[1]); url = st[1]; previewSeekArr[z] = {}; previewSeekArr[z].start = MVPUtils.toSeconds(start); previewSeekArr[z].end = MVPUtils.toSeconds(end); previewSeekArr[z].url = url; } z++; } //console.log(previewSeekArr) previewSeekReady = true; }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); }); } //############################################// /* controls */ //############################################// if(settings.useKeyboardNavigationForPlayback && settings.keyboardControls.length){ if(!Array.isArray(settings.keyboardControls)){ settings.keyboardControls = settings.keyboardControls.split(';') } wrapper.hover(function(){ _doc.on('keydown', function(e){ if(!componentInited) return false; var _keycode = e.keyCode, target = $(e.target); if(target.hasClass('mvp-input-field'))return true; if(settings.modifierKey){ var i, len = settings.keyboardControls.length, obj for(i = 0; i < len; i++){ obj = settings.keyboardControls[i] if(e[settings.modifierKey] && _keycode == obj.keycode){ if(obj.action == 'seekBackward') {//left arrow self.seekBackward(settings.seekTime); } else if(obj.action == 'seekForward') {//right arrow self.seekForward(settings.seekTime); } else if(obj.action == 'togglePlayback') {//space self.togglePlayback(); }else if (obj.action == 'volumeUp'){//up arrow settings.volume += .1; if(settings.volume > 1) settings.volume = 1; self.setVolume(settings.volume) }else if (obj.action == 'volumeDown'){//down arrow settings.volume -= .1; if(settings.volume < 0) settings.volume = 0; self.setVolume(settings.volume) } else if(obj.action == 'toggleMute') {//m toggleMute(); } else if(obj.action == 'nextMedia') {//page up self.nextMedia(); } else if(obj.action == 'previousMedia') {//page down self.previousMedia(); } else if(obj.action == 'rewind') {//r self.seek(0); } else if(obj.action == 'toggleFullscreen') {//f toggleFullscreen(); } else if(obj.action == 'toggleTheater') {//t if(componentSize == 'fullscreen') return false; theaterToggle.click(); } else if(obj.action == 'toggleSubtitle') {//c self.toggleSubtitle(); } else if(obj.action == 'subtitleSizeUp') {//+ if(activeSubtitle){ var fs = parseInt(subtitleHolderInner.css('fontSize'),10) + 1; subtitleHolderInner.css('fontSize', fs+'px'); } }else if(obj.action == 'subtitleSizeDown') {//- if(activeSubtitle){ var fs = parseInt(subtitleHolderInner.css('fontSize'),10) - 1; if(fs < 10) fs = 10; subtitleHolderInner.css('fontSize', fs+'px'); } } break; } } }else{ var i, len = settings.keyboardControls.length, obj for(i = 0; i < len; i++){ obj = settings.keyboardControls[i] if(_keycode == obj.keycode){ if(obj.action == 'seekBackward') {//left arrow self.seekBackward(settings.seekTime); } else if(obj.action == 'seekForward') {//right arrow self.seekForward(settings.seekTime); } else if(obj.action == 'togglePlayback') {//space self.togglePlayback(); }else if (obj.action == 'volumeUp'){//up arrow settings.volume += .1; if(settings.volume > 1) settings.volume = 1; self.setVolume(settings.volume) }else if (obj.action == 'volumeDown'){//down arrow settings.volume -= .1; if(settings.volume < 0) settings.volume = 0; self.setVolume(settings.volume) } else if(obj.action == 'toggleMute') {//m toggleMute(); } else if(obj.action == 'nextMedia') {//page up self.nextMedia(); } else if(obj.action == 'previousMedia') {//page down self.previousMedia(); } else if(obj.action == 'rewind') {//r self.seek(0); } else if(obj.action == 'toggleFullscreen') {//f toggleFullscreen(); } else if(obj.action == 'toggleTheater') {//t if(componentSize == 'fullscreen') return false; theaterToggle.click(); } else if(obj.action == 'toggleSubtitle') {//c self.toggleSubtitle(); } else if(obj.action == 'subtitleSizeUp') {//+ if(activeSubtitle){ var fs = parseInt(subtitleHolderInner.css('fontSize'),10) + 1; subtitleHolderInner.css('fontSize', fs+'px'); } }else if(obj.action == 'subtitleSizeDown') {//- if(activeSubtitle){ var fs = parseInt(subtitleHolderInner.css('fontSize'),10) - 1; if(fs < 10) fs = 10; subtitleHolderInner.css('fontSize', fs+'px'); } } else{ return true; } break; } } } return false; }); },function(){ _doc.off('keydown'); }); } var buttonArr=[ playbackToggle, playlistToggle, bigPlay, volumeWrapper, infoToggle, shareToggle, embedToggle, loopToggle, shuffleToggle, nextToggle, prevToggle, rewindToggle, skipBackwardToggle, skipForwardToggle, pipToggle, theaterToggle, captionToggle, vrToggle, chapterToggle, transcriptToggle, castToggle, nextChapterToggle, prevChapterToggle, airplayToggle, wrapper.find('.mvp-chapter-menu-close'), wrapper.find('.mvp-pwd-confirm'), wrapper.find('.mvp-info-close'), wrapper.find('.mvp-transcript-close'), wrapper.find('.mvp-share-item'), wrapper.find('.mvp-share-close'), wrapper.find('.mvp-redirect-login-cancel'), wrapper.find('.mvp-minimize-close'), wrapper.find('.mvp-resume-continue'), wrapper.find('.mvp-resume-restart'), wrapper.find('.mvp-embed-close'), wrapper.find('.mvp-chapters-close'), ], btn,len = buttonArr.length,i; for(i = 0;i chapterArr.length - 1){ next_chapter_id = 0; } if(settings.useChapterWindow)chaptersContainer.find('.mvp-chapter-item[data-id='+next_chapter_id+']').trigger("click"); else chapterMenu.find('.mvp-chapter-menu-item[data-id='+next_chapter_id+']').trigger("click") }else{//no selected chapter chapterMenu.find('.mvp-chapter-menu-item[data-id=0]').trigger("click") } }else if(currentTarget.hasClass('mvp-prev-chapter-toggle')){ if(currentActiveChapterData){ var next_chapter_id = currentActiveChapterData.id next_chapter_id--; if(next_chapter_id < 0){ next_chapter_id = chapterArr.length - 1; } if(settings.useChapterWindow)chaptersContainer.find('.mvp-chapter-item[data-id='+next_chapter_id+']').trigger("click"); else chapterMenu.find('.mvp-chapter-menu-item[data-id='+next_chapter_id+']').trigger("click") }else{//no selected chapter chapterMenu.find('.mvp-chapter-menu-item[data-id=0]').trigger("click") } }else if(currentTarget.hasClass('mvp-transcript-toggle')){ toggleTranscript(); }else if(currentTarget.hasClass('mvp-transcript-close')){ toggleTranscript(false); }else if(currentTarget.hasClass('mvp-cast-toggle')){ if(isCasting){ _MVPCast.stopCasting(); isCasting = false; } }else if(currentTarget.hasClass('mvp-airplay-toggle')){ videoUp2Js.webkitShowPlaybackTargetPicker(); }else if(currentTarget.hasClass('mvp-chapter-menu-close')){ toggleChapterMenu(false); }else if(currentTarget.hasClass('mvp-minimize-close')){ _window.off(minimizeScrollEvent); checkPlayerMinimize(true); settings.minimizeOnScroll = false; }else if(currentTarget.hasClass('mvp-pwd-confirm')){ var pwd = pwdField.val(); if(MVPUtils.isEmpty(pwd)){ alert(pwdErrorMsg); }else{ if(typeof md5 === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.md5_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.md5_js); else var src = settings.md5_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ if(md5(pwd) != currMediaData.pwd){ alert(pwdErrorMsg); }else{ delete currMediaData.pwd; pwdHolder.one("transitionend", function(){ pwdHolder.css('display','none'); }).removeClass('mvp-holder-visible'); pwdField.val(''); //check lock time if(currMediaData.lockTime == '0' && !allowedViewVideoUserRole){ toggleRedirectLoginScreen('watch'); }else{ setMedia(); } } } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ if(md5(pwd) != currMediaData.pwd){ alert(pwdErrorMsg); }else{ delete currMediaData.pwd; pwdHolder.one("transitionend", function(){ pwdHolder.css('display','none'); }).removeClass('mvp-holder-visible'); pwdField.val(''); //check lock time if(currMediaData.lockTime == '0' && !allowedViewVideoUserRole){ toggleRedirectLoginScreen('watch'); }else{ setMedia(); } } } } }else if(currentTarget.hasClass('mvp-previous-toggle')){ if(settings.disableVideoSkip) return false; previousMedia(); }else if(currentTarget.hasClass('mvp-next-toggle')){ if(settings.disableVideoSkip) return false; nextMedia(); }else if(currentTarget.hasClass('mvp-rewind-toggle')){ self.seek(0); }else if(currentTarget.hasClass('mvp-skip-backward-toggle')){ self.seekBackward(); }else if(currentTarget.hasClass('mvp-skip-forward-toggle')){ self.seekForward(); }else if(currentTarget.hasClass('mvp-loop-toggle')){ _MVPPlaylistManager.setLooping(); }else if(currentTarget.hasClass('mvp-shuffle-toggle')){ _MVPPlaylistManager.setRandom(); }else if(currentTarget.hasClass('mvp-share-toggle')){ toggleShare(); }else if(currentTarget.hasClass('mvp-embed-toggle')){ toggleEmbed(); }else if(currentTarget.hasClass('mvp-pip-toggle')){ if(pictureInPictureEnabled){ if(!document.pictureInPictureElement) { try{ videoUp2Js.requestPictureInPicture(); }catch(er){} }else{ try{ document.exitPictureInPicture(); }catch(er){} } } else if(videoUp2Js.webkitSupportsPresentationMode && typeof videoUp2Js.webkitSetPresentationMode === "function"){ videoUp2Js.webkitSetPresentationMode(videoUp2Js.webkitPresentationMode === "picture-in-picture" ? "inline" : "picture-in-picture"); } }else if(currentTarget.hasClass('mvp-theater-toggle')){ //only in normal mode this button is available, in fs we cant use theater if(theaterModeOn){ if(settings.theaterElement)$(settings.theaterElement).removeClass(settings.theaterElementClass); $(self).trigger("beforeTheaterExit", {instance:self, instanceName: settings.instanceName, media:currMediaData}); if(hidePlaylistOnTheaterEnterDone && !settings.playlistOpened){ hidePlaylistOnTheaterEnterDone = false; //playlistHolder.show(); settings.playlistOpened = true; } wrapper.removeClass('mvp-theater'); doneResizing(); }else{ if(settings.theaterElement)$(settings.theaterElement).addClass(settings.theaterElementClass); $(self).trigger("beforeTheaterEnter", {instance:self, instanceName: settings.instanceName, media:currMediaData}); if(settings.hidePlaylistOnTheaterEnter && settings.playlistOpened){ hidePlaylistOnTheaterEnterDone = true; //playlistHolder.hide(); settings.playlistOpened = false; } wrapper.addClass('mvp-theater'); doneResizing(); setTimeout(function(){doneResizing();},250);//to resize once again if vertical scrollbar appears if(settings.focusVideoInTheater){ var top = playerHolder.offset().top; $('html,body').animate({scrollTop: top}, 500); } } theaterModeOn = !theaterModeOn; }else{ if(currentTarget.hasClass('mvp-share-item')){ if(!mediaType)return false; if(_MVPShareManager)_MVPShareManager.share(currentTarget.attr('data-type').toLowerCase(), currMediaData, self.getCurrentMediaUrl()); } } } function clickPlaylistItem(e){ e.preventDefault(); if(!componentInited)return false; if(settings.disableVideoSkip) return false; var currentTarget = $(e.currentTarget); playlistClick = true; if(currMediaData)beforeMediaAdvanceAction(); var id = currentTarget.attr('data-id'); _MVPPlaylistManager.processPlaylistRequest(id); $(self).trigger('clickPlaylistItem', {instance:self, instanceName: settings.instanceName}); //scroll to video if(playlistPosition == 'outer'){ var top = playerHolder.offset().top; if(_window.scrollTop() > top)$('html,body').animate({scrollTop: top}, 500); } else if(isMobile && playlistHolder.hasClass('mvp-playlist-holder-bottom')){ var top = playerHolder.offset().top; if(_window.scrollTop() > top)$('html,body').animate({scrollTop: top}, 500); } } function overPlaylistItem(e){ e.preventDefault(); if(!componentInited) return false; var currentTarget = $(e.currentTarget), id = currentTarget.attr('data-id'), data = playlistDataArr[id].data; //hover preview if(!isMobile){ if(data.hoverPreviewImg){ var thumb = currentTarget.find('.mvp-thumbimg'); thumb.attr('data-src', thumb.attr('src')).attr('src',data.hoverPreviewImg);//save src } else if(data.hoverPreviewVideo){ var pvid_holder = currentTarget.find('.mvp-playlist-thumb-preview').addClass('mvp-playlist-thumb-preview-visible'); var pvid = pvid_holder.find('.mvp-playlist-thumb-preview-video')[0]; pvid.src = data.hoverPreviewVideo; pvid.load(); } } if(activePlaylistItem && activePlaylistItem.is(currentTarget))return false;//active item currentTarget.addClass('mvp-playlist-item-selected'); } function outPlaylistItem(e){ e.preventDefault(); if(!componentInited) return false; var currentTarget = $(e.currentTarget), id = currentTarget.attr('data-id'), data = playlistDataArr[id].data; //hover preview if(!isMobile){ if(data.hoverPreviewImg){ var thumb = currentTarget.find('.mvp-thumbimg'); thumb.attr('src',thumb.attr('data-src'));//restore src } else if(data.hoverPreviewVideo){ var pvid_holder = currentTarget.find('.mvp-playlist-thumb-preview').removeClass('mvp-playlist-thumb-preview-visible'); var pvid = pvid_holder.find('.mvp-playlist-thumb-preview-video')[0]; pvid.src = ""; } } if(activePlaylistItem && activePlaylistItem.is(currentTarget))return false;//active item currentTarget.removeClass('mvp-playlist-item-selected'); } function enableActivePlaylistItem(){ activePlaylistItem.removeClass('mvp-playlist-item-selected'); $(self).trigger('playlistItemEnabled', {instance:self, instanceName: settings.instanceName}); activePlaylistItem = null; } function disableActivePlaylistItem(){ if(activePlaylistItem){//enable active playlist item enableActivePlaylistItem(); } activePlaylistItem = playlistContent.children('.mvp-playlist-item').eq(mediaCounter); if(activePlaylistItem.length){ activePlaylistItem.addClass('mvp-playlist-item-selected'); if(createPlaylist && playlistLength > 0){//scroll to active item if(!playlistClick){//not on playlist item click if(navigationType == 'buttons' || navigationType == 'scroll'){ if(_MVPPlaylistNavigation){ _MVPPlaylistNavigation.scrollTo(activePlaylistItem) }else{ var interval = setInterval(function(){ if(_MVPPlaylistNavigation){ clearInterval(interval); _MVPPlaylistNavigation.scrollTo(activePlaylistItem) } },100); } } } playlistClick = false; } $(self).trigger('playlistItemDisabled', {instance:self, instanceName: settings.instanceName}); } } //############################################// /* next, previous on hover */ //############################################// if(!isMobile && settings.showPrevNextVideoThumb){ nextToggle.on('mouseenter', function(){ upnextHeader2.html(upnextHeader2.attr('data-next-title')); setUpNextOnBtn(nextToggle, 1); }).on('mouseleave', function(){ upnextWrap2.removeClass('mvp-upnext-wrap2-visible'); }); prevToggle.on('mouseenter', function(){ upnextHeader2.html(upnextHeader2.attr('data-prev-title')); setUpNextOnBtn(prevToggle, -1); }).on('mouseleave', function(){ upnextWrap2.removeClass('mvp-upnext-wrap2-visible'); }); }else{ upnextWrap2.remove(); } function setUpNextOnBtn(btn, dir){ var nc = _MVPPlaylistManager.getNextCounter(dir), next_data; if(typeof nc !== 'undefined'){ next_data = playlistDataArr[nc].data; if(next_data.thumb || next_data.title){ if(next_data.thumb)upnextThumb2.css({'background-image': 'url(' + encodeURI(next_data.thumb) + ')'}).closest('.mvp-upnext-thumb-wrap').css('display','block'); else upnextThumb2.closest('.mvp-upnext-thumb-wrap').css('display','none'); if(next_data.title)upnextTitle2.html(next_data.title); else upnextTitle2.html(''); if(next_data.duration)upnextDuration2.show().html(MVPUtils.formatTime(next_data.duration)); else upnextDuration2.hide().html(''); } }else{ return false; } if(playerWrap.hasClass(settings.minimizeClass))var container = playerWrap; else if(lightboxOpened)var container = playerWrap; else container = wrapper; var main = container[0].getBoundingClientRect(), element = btn[0].getBoundingClientRect(), controls = playerControlsBottom[0].getBoundingClientRect(); if(upnextWrap2.hasClass('mvp-upnext-l-side')){//position on sides (for next/previous button that are located left and right in the player) if(dir == 1)var l = parseInt(element.left - main.left - upnextWrap2.width() - 10);//left of button else var l = parseInt(element.left - main.left + element.width + 10);//right of button }else{ if(upnextWrap2.hasClass('mvp-upnext-l-center')){//center horizontally var l = parseInt(element.left - main.left - upnextWrap2.width()/2 + element.width/2); }else{//left var l = parseInt(element.left - main.left); } } if(upnextWrap2.hasClass('mvp-upnext-t-center')){//center vertically var t = parseInt(element.top - main.top + element.height/2 - upnextWrap2.height()/2); }else{//top var t = parseInt(controls.top - main.top - upnextWrap2.height() - 10); } upnextWrap2.addClass('mvp-upnext-wrap2-visible').css({left: l+'px', top: t+'px'}); } //############################################// /* interface */ //############################################// function startIdleTimer() { if(!mediaType)return; if(adOn)return; if(mediaType == 'youtube' && settings.youtubePlayerType == 'default' || mediaType == 'vimeo' && activeVimeoPlayerType == 'default' || mediaType == 'custom' || mediaType == 'custom_html')return; idleTimeoutID = window.setTimeout(function(){ if(mediaPlaying){ playerControls.one("transitionend", function(){ interfaceHidden = true; }).removeClass('mvp-player-controls-visible'); if(activeSubtitle)subtitleHolderInner.removeClass('mvp-subtitle-visible'); adInfoStart.removeClass('mvp-ad-info-start-controls-align'); if(componentSize == "fullscreen")document.body.style.cursor = 'none'; tooltip.hide(); if(currMediaData.previewSeek){ previewSeekWrap.hide(); if(previewSeekAuto)stopDrawPreviewSeek() } //volumeSeekbar.css('display','none'); if(chapterMenuOpened)chapterMenuHolder.removeClass('mvp-holder-visible'); } }, settings.idleTimeout); } function resetIdleTimer(e) { if(!mediaType)return; if(adOn)return; if(mediaType == 'youtube' && settings.youtubePlayerType == 'default' || mediaType == 'vimeo' && activeVimeoPlayerType == 'default' || mediaType == 'custom' || mediaType == 'custom_html')return; if(idleTimeoutID)clearTimeout(idleTimeoutID); if(mediaStarted){ if(interfaceHidden){ playerControls.one("transitionend", function(){ interfaceHidden = false; }).addClass('mvp-player-controls-visible'); if(activeSubtitle)subtitleHolderInner.addClass('mvp-subtitle-visible'); if(adInfoStart.hasClass('mvp-ad-info-start-visible') && playerControls.length)adInfoStart.addClass('mvp-ad-info-start-controls-align'); if(chapterMenuOpened)chapterMenuHolder.addClass('mvp-holder-visible'); if(componentSize == "fullscreen")document.body.style.cursor = 'default'; } } if(mediaPlaying)startIdleTimer(); } //############################################// /* description */ //############################################// function toggleInfo(v){ if(typeof v !== 'undefined'){ if(infoOpened && v == true)return false; else if(!infoOpened && v == false)return false; infoOpened = !v; } if(infoOpened){ infoHolder.one("transitionend", function(){ infoHolder.css('display','none'); infoOpened = false; checkIfMediaCanResume() }).removeClass('mvp-holder-visible'); }else{ if(settings.pauseVideoOnDialogOpen && mediaPlaying && !isCasting){ self.pauseMedia(); mediaForcePause = true; } infoHolder.css('display','block'); setTimeout(function(){ infoHolder.addClass('mvp-holder-visible'); infoOpened = true; },20); } } //############################################// /* embed */ //############################################// function toggleEmbed(v){ if(typeof v !== 'undefined'){ if(embedOpened && v == true)return false; else if(!embedOpened && v == false)return false; embedOpened = !v; } if(embedOpened){ embedHolder.one("transitionend", function(){ embedHolder.css('display','none'); embedOpened = false; embedHolder.find('.mvp-embed-field-wrap').removeClass('mvp-embed-field-wrap-selected') checkIfMediaCanResume() }).removeClass('mvp-holder-visible'); }else{ if(settings.pauseVideoOnDialogOpen && mediaPlaying && !isCasting){ self.pauseMedia(); mediaForcePause = true; } //set embed data embedHolder.find('.mvp-embed-field-wrap').removeClass('mvp-embed-field-wrap-selected') if(settings.wpEmbedUrl){ //wp var e_url = settings.wpEmbedUrl + 'includes/embed.php?', pid_exist if(settings.playerId != null && settings.playerId != -1){ e_url += 'player_id='+settings.playerId pid_exist = true; }else{ //use default preset } if(settings.useSingleVideoEmbed){ //get track data var s = encodeURIComponent(getEmbedCode()) if(!pid_exist && s.charAt(0) == '&'){ s = s.substr(1) } e_url += s }else{ if(pid_exist)e_url += '&' if(playlistId != null){ e_url += 'playlist_id='+playlistId+'&active_item='+mediaCounter }else{ //copy html var h = playlistList.find('.mvp-playlist-anon').html().replace(/\n/g,''), v = encodeURIComponent(h) e_url += 'plhtml='+v } } if(playlistLength == 1 || settings.useSingleVideoEmbed){//use just player for single video e_url += '&playlist_position=no-playlist' } }else{ //manual embed var e_url = ''; if(settings.embedSrc)e_url = settings.embedSrc } var es = '' //embed wrapper.find('.mvp-video-embed').text(es) //link var url = window.location.href + self.getCurrentMediaUrl(); wrapper.find('.mvp-video-link').text(url) embedHolder.css('display','block'); setTimeout(function(){ embedHolder.addClass('mvp-holder-visible'); embedOpened = true; },20); } } function getEmbedCode(){ //we need to use htis way because for youtube and other types then get processed, html is not the same on start! var skip_keys = ['playlistId','mediaPath','safeTitle'] var s = '' $.each(currMediaData, function(key, value) { if(typeof value === 'string'){ if(skip_keys.indexOf(key) > 0) return key = key.split(/(?=[A-Z])/).join('_').toLowerCase();//camelCase to _ s += '&' + key + '=' + value } }); if((currMediaData.type == 'video' || currMediaData.type == 'audio') && currMediaData.path){ var path = '', quality = '' var i, len = currMediaData.path.length, p for (i = 0; i < len; i++) { p = currMediaData.path[i] $.each(p, function(key, value) { if(key == 'quality')quality += value + ',' else path += value + ',' //console.log(key, i, value) }); } path = path.substr(0, path.length - 1);//remove comma quality = quality.substr(0, quality.length - 1); s += '&path=' + path + '&quality_title=' + quality } //subs if(currMediaData.subtitles){ var i, len = currMediaData.subtitles.length, p var subtitle_src = '', subtitle_label = '', subtitle_active for (i = 0; i < len; i++) { p = currMediaData.subtitles[i] if(p['label'] == settings.subtitleOffText)continue; subtitle_src += p['src'] + ',' subtitle_label += p['label'] + ',' if(p['default'])subtitle_active = p['label'] } subtitle_src = subtitle_src.substr(0, subtitle_src.length - 1);//remove comma subtitle_label = subtitle_label.substr(0, subtitle_label.length - 1); s += '&subtitle_src=' + subtitle_src + '&subtitle_label=' + subtitle_label if(subtitle_active)s += '&subtitle_active='+subtitle_active } return s; } embedHolder.on('click', '.mvp-embed-copy', function(){ embedHolder.find('.mvp-embed-field-wrap').removeClass('mvp-embed-field-wrap-selected') var field = $(this).closest('.mvp-embed-box').find('.mvp-embed-field-wrap').addClass('mvp-embed-field-wrap-selected'), data = $.trim(field.text()) var dummy = document.createElement("input"); dummy.setAttribute("id", "mvp-copy-url"); document.body.appendChild(dummy); document.getElementById("mvp-copy-url").value = data; dummy.select(); try{ document.execCommand("copy"); }catch(er){} document.body.removeChild(dummy); }) function checkIfMediaCanResume(){ if(shareOpened)return false; if(infoOpened)return false; if(embedOpened)return false; if(redirectLoginOpened)return false; if(mediaForcePause){//if it was playing self.playMedia(); mediaForcePause = false; } } //############################################// /* share */ //############################################// function toggleShare(v){ if(typeof v !== 'undefined'){ if(shareOpened && v == true)return false; else if(!shareOpened && v == false)return false; shareOpened = !v; } if(shareOpened){ shareHolder.one("transitionend", function(){ shareHolder.css('display','none'); shareOpened = false; checkIfMediaCanResume() }).removeClass('mvp-holder-visible'); }else{ if(settings.pauseVideoOnDialogOpen && mediaPlaying && !isCasting){ self.pauseMedia(); mediaForcePause = true; } shareHolder.css('display','block'); setTimeout(function(){ shareHolder.addClass('mvp-holder-visible'); shareOpened = true; },20); } } //############################################// /* age verify */ //############################################// wrapper.on('click', '.mvp-age-verify-enter', function(){ if(hasLocalStorage && settings.ageVerifyExpireTime){ var d = parseInt(settings.ageVerifyExpireTime,10) + getCurrentTimeInSeconds(); localStorage.setItem(ageVerifyKey, d); } toggleAgeVerify(false); resumeCheckMedia() }) wrapper.on('click', '.mvp-age-verify-exit', function(){ toggleAgeVerify(false); }) function checkAgeVerify(){ var ls = localStorage.getItem(ageVerifyKey); if(ls){ return getCurrentTimeInSeconds() < ls }else{ return false; } } function getCurrentTimeInSeconds() { return Date.now() * 0.001; } function toggleAgeVerify(v){ if(typeof v !== 'undefined'){ if(ageVerifyOpened && v == true)return false; else if(!ageVerifyOpened && v == false)return false; ageVerifyOpened = !v; } if(ageVerifyOpened){ ageVerifyHolder.one("transitionend", function(){ ageVerifyHolder.css('display','none'); ageVerifyOpened = false; }).removeClass('mvp-holder-visible'); }else{ ageVerifyHolder.css('display','block'); setTimeout(function(){ ageVerifyHolder.addClass('mvp-holder-visible'); ageVerifyOpened = true; },20); } } //############################################// /* transcript */ //############################################// function toggleTranscript(v){ if(typeof v !== 'undefined'){ if(transcriptOpened && v == true)return false; else if(!transcriptOpened && v == false)return false; transcriptOpened = !v; } if(transcriptOpened){ if(componentSize == 'fullscreen' && !settings.playlistOpened){ self.togglePlaylist() } else{ transcriptHolder.hide(); transcriptOpened = false; transcriptLanguageSelectorWrap.css('display','none').removeClass('mvp-holder-visible'); transcriptLangaugeMenuOpened = false; transcriptSearchInput.val('') } }else{ if(componentSize == 'fullscreen' && !settings.playlistOpened){ self.togglePlaylist() } else{ if(!transcriptInited)getTranscript() transcriptHolder.show(); transcriptOpened = true; } } } function getTranscript(){ var i, len = currMediaData.subtitles.length, value for(i = 0; i < len; i++){ item = currMediaData.subtitles[i]; if(item.default && item.label != settings.subtitleOffText){ value = item.label break; } } if(!value){ //get first if no default sub on start value = currMediaData.subtitles[0].label } if(allSubtitleArr[value]){//already have subtitle var arr = allSubtitleArr[value] createTranscript(value, arr); }else{ //no default sub on start transcriptLanguageSelector.find(".mvp-menu-item").eq(0).trigger('click') } } function createTranscript(value, arr){ var i, len = arr.length, s = '' for(i = 0; i < len; i++){ item = arr[i]; s += '
    ' s += '
    '+MVPUtils.formatTime(item.start)+'
    ' s += '
    '+item.text+'
    ' s += '
    ' } transcriptContainer.html(s) if(!activeTranscriptLanguageItem)activeTranscriptLanguageItem = transcriptLanguageSelector.find(".mvp-menu-item[data-label='" + activeTranscriptLanguage + "']").addClass('mvp-menu-active'); transcriptHeaderTitle.html(activeTranscriptLanguage) transcriptInited = true; transcriptRequest = false transcriptReady = true; } //toggle language menu transcriptHolder.find('.mvp-transcript-header-inner').on('click', function(){ toggleTranscriptLangaugeMenu() }) function toggleTranscriptLangaugeMenu(){ if(typeof v !== 'undefined'){ if(transcriptLangaugeMenuOpened && v == true)return false; else if(!transcriptLangaugeMenuOpened && v == false)return false; transcriptLangaugeMenuOpened = !v; } if(transcriptLangaugeMenuOpened){ transcriptLanguageSelectorWrap.one("transitionend", function(){ transcriptLanguageSelectorWrap.css({display:'none'}); transcriptLangaugeMenuOpened = false; }).removeClass('mvp-holder-visible'); }else{ transcriptLanguageSelectorWrap.css('display','block'); setTimeout(function(){ transcriptLanguageSelectorWrap.addClass('mvp-holder-visible'); transcriptLangaugeMenuOpened = true; },20); } } //search transcript var transcriptSearchInput = transcriptHolder.find('.mvp-transcript-search-input').on('keyup',function(){ var len = transcriptContainer.find('.mvp-transcript-item').length if(len == 0)return false; var value = $(this).val().toLowerCase(), i, j = 0, pi, title; for(i = 0; i < len; i++){ pi = transcriptContainer.find('.mvp-transcript-item').eq(i); title = pi.find('.mvp-transcript-item-text').html().toLowerCase(); if(title.indexOf(value) >- 1){ transcriptContainer.find('.mvp-transcript-item').eq(i).fadeIn(200) }else{ transcriptContainer.find('.mvp-transcript-item').eq(i).fadeOut(200) j++; } } if(j == len){ playlistFilterMsg.show(); }else { playlistFilterMsg.hide(); } }); transcriptContainer.on('click', '.mvp-transcript-item', function(){ if(!componentInited) return false; var time = Number($(this).attr('data-start')) self.seek(time) //self.playMedia() if(!mediaPlaying){ lastTime = null; trackProgress(true);//update } }); //change lang transcriptLanguageSelector.on('click', '.mvp-menu-item', function(){ if(!componentInited) return false; if(transcriptRequest) return false; if($(this).hasClass('mvp-menu-active')){ return false;//active item } if(activeTranscriptLanguageItem)activeTranscriptLanguageItem.removeClass('mvp-menu-active'); activeTranscriptLanguageItem = $(this).addClass('mvp-menu-active'); transcriptRequest = true; if(transcriptLangaugeMenuOpened)toggleTranscriptLangaugeMenu(false)//close var value = $(this).attr('data-label') transcriptHeaderTitle.html(value) activeTranscriptLanguage = value; if(allSubtitleArr[value]){//already have subtitle var arr = allSubtitleArr[value]; createTranscript(activeTranscriptLanguage, arr); }else{//get subtitle var i, len = currMediaData.subtitles.length, item; for(i = 0; i < len; i++){ item = currMediaData.subtitles[i]; if(item.label == value){ if(externalSubtitle)getSubtitleUrl(item); else getSubtitle(item); break; } } } }); function synchronizeTrancript(currentTime) { var scrollContainer = transcriptContainer, wrapContainer = transcriptContainerWrap // Highlight the current transcript item. scrollContainer.find('.mvp-transcript-item').each(function() { var start = parseFloat($(this).attr('data-start')), end = parseFloat($(this).attr('data-end')) if (currentTime >= start && currentTime <= end) { // If this item isn't already highlighted, it should be if (!($(this).hasClass('mvp-transcript-item-active'))) { // remove all previous highlights before adding one to current scrollContainer.find('.mvp-transcript-item').removeClass('mvp-transcript-item-active'); $(this).addClass('mvp-transcript-item-active'); scrollContainer.movingHighlight = true; } return false; } }); scrollContainer.currentHighlight = scrollContainer.find('.mvp-transcript-item-active'); if (scrollContainer.currentHighlight.length == 0) { scrollContainer.currentHighlight = null; } if (scrollContainer.currentHighlight) { var newTop = Math.floor(wrapContainer.scrollTop() + scrollContainer.currentHighlight.position().top - (wrapContainer.height() / 2 + scrollContainer.currentHighlight.height() / 2)); if (newTop != Math.floor(wrapContainer.scrollTop())) { // only scroll once after moving a highlight if (scrollContainer.movingHighlight) { //wrapContainer.scrollTop(newTop); scrollContainer.currentHighlight[0].scrollIntoView({behavior: 'smooth'}); scrollContainer.movingHighlight = false; } } } } //############################################// /* login */ //############################################// function toggleRedirectLoginScreen(type){ //note: we use different screen for watch / download login but we cant have both opened at the same time since media is paused during this screen if(redirectLoginOpened){ redirectLoginHolder.one("transitionend", function(){ redirectLoginHolder.css('display','none'); redirectLoginOpened = false; checkIfMediaCanResume() }).removeClass('mvp-holder-visible'); }else{ $(self).trigger("beforeLoginScreen", {instance:self, instanceName: settings.instanceName, media:currMediaData}); if(mediaPlaying){ self.pauseMedia(); mediaForcePause = true; } redirectLoginHolder = (type == 'download') ? redirectLoginHolderDownload : redirectLoginHolderWatch; redirectLoginHolder.css('display','block'); setTimeout(function(){ redirectLoginHolder.addClass('mvp-holder-visible'); redirectLoginOpened = true; },20); } } //############################################// /* resume modal */ //############################################// function toggleResumeScreen(v){ if(typeof v !== 'undefined'){ if(toggleResumeOpened && v == true)return false; else if(!toggleResumeOpened && v == false)return false; toggleResumeOpened = !v; } if(toggleResumeOpened){ resumeHolder.one("transitionend", function(){ resumeHolder.css('display','none'); toggleResumeOpened = false; }).removeClass('mvp-holder-visible'); }else{ resumeHeaderTitle.html(currMediaData.title); resumeHolder.css('display','block'); setTimeout(function(){ resumeHolder.addClass('mvp-holder-visible'); toggleResumeOpened = true; },20); } } //############################################// /* playlist process */ //############################################// function setPlaylist(id){ playlistTransitionOn = true; playerLoader.show(); if(lastPlaylist)destroyPlaylist(); if(playlistList.length)var playlist = playlistList.find(id); else var playlist = $(id); if(playlist.length == 0){ console.log('Failed playlist selection! Playlist - ' + id + ' does not exist. Check activePlaylist option in settings!'); playlistTransitionOn = false; playerLoader.hide(); activePlaylist = null; return false; } if(settings.makePlaylistSelector){ var cl = id.substr(1) var pi = playlistSelectorContainer.find('.mvp-playlist-selector-item[data-id="'+cl+'"]') if(pi.length){ lastPlaylistSelectorActiveItem = pi.addClass('mvp-playlist-selector-item-active') if(pi.find('.mvp-playlist-selector-item-title')){ playlistSelectorHeaderTitle.html(pi.find('.mvp-playlist-selector-item-title').html()) } } } //for load more and stats if(playlist.attr('data-playlist-id') != undefined){ playlistId = playlist.attr('data-playlist-id'); }else{ playlistId = null; } activePlaylist = id; $(self).trigger('playlistStartLoad', {instance:self, instanceName: settings.instanceName}); playlistProcessCounter = -1;//reset playlistProcessData = []; playlistProcessDataUrl = []; //global playlist options if(playlist.find('.mvp-global-playlist-data').length){ playlistData = playlist.find('.mvp-global-playlist-data').css('display','none').clone().prependTo(playlistContent); if(playlistData.find(".mvp-ad-section").length){ globalAdData = playlistData.find(".mvp-ad-section"); } if(playlistData.find(".mvp-annotation-section").length){ globalAnnotationData = playlistData.find(".mvp-annotation-section"); } if(playlistData.attr('data-pwd') != undefined){ globalPwd = playlistData.attr('data-pwd'); } if(playlistData.attr('data-start') != undefined && !MVPUtils.isEmpty(playlistData.attr('data-start'))){ globalStartTime = Number(playlistData.attr('data-start')); } if(playlistData.attr('data-end') != undefined && !MVPUtils.isEmpty(playlistData.attr('data-end'))){ globalEndTime = Number(playlistData.attr('data-end')); } if(playlistData.attr('data-playback-rate') != undefined && !MVPUtils.isEmpty(playlistData.attr('data-playback-rate'))){ globalPlaybackRate = Number(playlistData.attr('data-playback-rate')); } if(playlistData.attr('data-lock-time') != undefined){ globalLockTime = Number(playlistData.attr('data-lock-time')); } if(playlistData.attr('data-lock-video-user-roles') != undefined && !MVPUtils.isEmpty(playlistData.attr('data-lock-video-user-roles'))){ globalLockVideoUserRoles = playlistData.attr('data-lock-video-user-roles').split(','); } if(playlistData.attr('data-vast') != undefined){ globalVast = playlistData.attr('data-vast'); } if(playlistData.attr('data-get-embed-details') != undefined){ getEmbedDetails = true; } } playlist.children('.mvp-playlist-item').each(function() { playlistProcessDataUrl.push(getTrackData($(this))); }); playlistLength = playlistProcessDataUrl.length; if(getEmbedDetails){ fetchEmbedCounter = playlistLength; fetchEmbed() }else{ checkProcessCounter(); } } function createLoader(type){//added this because of cache playlist where if playlist was loaded from cache and loaders were not created and if we used load more on total scroll, we needed to have loaders if(type == 'youtube'){ if(typeof MVPYoutubeLoader === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.youtubeLoader_js); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ createLoader(type); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); return; } _MVPYoutubeLoader = new MVPYoutubeLoader(settings); $(_MVPYoutubeLoader).on('MVPYoutubeLoader.END_LOAD', function(e, data){ var i, len = data.data.length, obj; for(i=0;i'+data.er+'').on('click', function(){ $(this).remove() }).appendTo(mediaHolder) }); if(loadMoreItem && nextPageToken){//happens on load more on total scroll call after load playlist from cache _MVPYoutubeLoader.setDataFromCache(getTrackData($(loadMoreItem))); cacheOn = false; } } else if(type == 'vimeo'){ if(typeof MVPVimeoLoader === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.vimeoLoader_js); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ createLoader(type); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); return; } _MVPVimeoLoader = new MVPVimeoLoader(settings); $(_MVPVimeoLoader).on('MVPVimeoLoader.END_LOAD', function(e, data){ var i, len = data.data.length, obj; for(i=0;i -1){ var obj = playlistProcessDataUrl[fetchEmbedCounter] var type = obj.type; if(type == 'youtube_single'){ var url = 'https://www.youtube.com/watch?v=' + obj.path; obj.type = 'youtube' } else if(type == 'vimeo_single'){ var url = 'https://vimeo.com/' + obj.path; obj.type = 'vimeo' } else{ fetchEmbed() } $.getJSON('https://noembed.com/embed', {format: 'json', url: url}, function (data) { if(data.title)obj.title = data.title if(data.thumbnail_url){ obj.thumb = data.thumbnail_url obj.poster = data.thumbnail_url } if(data.description)obj.description = data.description if(data.duration)obj.duration = data.duration if(data.account_type) obj.userAccount = data.account_type if(data.upload_date){ var d = data.upload_date.split(' ') obj.date = d[0] } playlistProcessData.push(obj); fetchEmbed() }); }else{ buildPlaylist() } } function checkProcessCounter() { playlistProcessCounter++; if(playlistProcessCounter>playlistLength - 1){ buildPlaylist(); }else{ var data = playlistProcessDataUrl[playlistProcessCounter], type = data.type; if(RegExp(/^youtube/).test(type)) { if(data.noApi){ playlistProcessData.push(data); checkProcessCounter(); }else{ loadMoreType = 'youtube'; if(data.loadMore)loadMoreOnTotalScroll = true;//from addtrack if(!_MVPYoutubeLoader){ createLoader('youtube'); var interval = setInterval(function(){ if(_MVPYoutubeLoader){ clearInterval(interval); _MVPYoutubeLoader.setData(data); } },100); } else _MVPYoutubeLoader.setData(data); } }else if(RegExp(/^vimeo/).test(type)) { if(data.noApi){ playlistProcessData.push(data); checkProcessCounter(); }else{ loadMoreType = 'vimeo'; if(data.loadMore)loadMoreOnTotalScroll = true;//from addtrack if(!_MVPVimeoLoader){ createLoader('vimeo'); var interval = setInterval(function(){ if(_MVPVimeoLoader){ clearInterval(interval); _MVPVimeoLoader.setData(data); } },100); } else _MVPVimeoLoader.setData(data); } }else if(type == 'gdrive_folder') { processGdriveFolder(data); }else if(type == 'onedrive_folder') { processOnedriveFolder(data); }else if(RegExp(/^folder/).test(type)) { processFolder(data); }else if(RegExp(/^audio|^video|^image|^hls|^dash|^custom/).test(type)){ playlistProcessData.push(data); checkProcessCounter(); }else if(type == 's3_video'){ playlistProcessData.push(data); checkProcessCounter(); }else if(type == 's3_bucket_video'){ processS3Bucket(data); }else if(type == 'xml'){ processXml(data); }else if(type == 'json'){ processJson(data); } } } //############################################// /* xml */ //############################################// function processXml(data){ $.ajax({ type: 'GET', url: data.path, dataType: "html", }).done(function(result) { $(result).children('.mvp-playlist-item').each(function() { playlistProcessDataUrl.push(getTrackData($(this))); }); playlistLength = playlistProcessDataUrl.length; checkProcessCounter(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); checkProcessCounter(); }); } //############################################// /* json */ //############################################// function processJson(data){ //first load json file, then process its content $.ajax({ type: 'GET', url: data.path, dataType: "json" }).done(function(track) { playlistProcessCounter = -1; playlistProcessData = []; playlistProcessDataUrl = []; lastPlaylist = playlistContent; if(Array.isArray(track))playlistProcessDataUrl = track; else playlistProcessDataUrl.push(track); playlistLength = playlistProcessDataUrl.length; checkProcessCounter(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log('Error processJson: ' + jqXHR, textStatus, errorThrown); checkProcessCounter(); }); } //############################################// /* bucket */ //############################################// function processS3Bucket(data){ if(window.location.protocol == 'file:'){ console.log('Reading folders requires server connection.'); return false; } var url = settings.sourcePath + 'includes/aws/aws.php', ajax_data = {bucket: data.bucket, action: 'list_bucket', region: settings.s3Region, cred: settings.s3}; $.ajax({ type: 'GET', url: url, data: ajax_data, dataType: "json" }).done(function(media) { var i, len = media.length, entry, obj; if(data.sort){ if(data.sort == 'filename-asc')MVPUtils.keysrt(media, 'filename'); else if(data.sort == 'filename-desc')MVPUtils.keysrt(media, 'filename', true); } for(i=0; i < len; i++){ entry = media[i]; if(/mp4/.test(entry)){ obj = $.extend(true, {}, data); obj.type = obj.origtype = 's3_video'; obj.key = entry; obj.title = entry.substr(0, entry.lastIndexOf('.')); obj.poster = 'poster/' + obj.title + '.' + settings.s3ThumbExtension; obj.thumb = 'thumb/' + obj.title + '.' + settings.s3ThumbExtension; playlistProcessData.push(obj); } } checkProcessCounter(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log('Error processS3Bucket: ' + jqXHR.responseText, textStatus, errorThrown); checkProcessCounter(); }); } //############################################// /* folder */ //############################################// function processFolder(data){ if(window.location.protocol == 'file:'){ console.log('Reading files from folders locally is not possible! This requires online server connection.'); checkProcessCounter(); return false; } var type = data.type; if(type == 'folder_video'){ var query = ['mp4']; }else if(type == 'folder_audio'){ if(data.id3)id3Start = id3Counter = playlistProcessData.length-1; var query = ['mp3','wav','flac','aac']; }else if(type == 'folder_image'){ var query = ['jpg', 'jpeg', 'png', 'gif', 'webp']; } var ajax_data = {type: query, dir: data.path, limit: data.limit || 100}; $.ajax({ type: 'GET', url: settings.sourcePath + 'includes/folder_parser.php', data: ajax_data, dataType: "json" }).done(function(media) { console.log(media) if(data.sort){ if(data.sort == 'filename-asc')MVPUtils.keysrt(media, 'filename'); else if(data.sort == 'filename-desc')MVPUtils.keysrt(media, 'filename', true); else if(data.sort == 'date-asc')MVPUtils.keysrt(media, 'filemtime'); else if(data.sort == 'date-desc')MVPUtils.keysrt(media, 'filemtime', true); } var i, len = media.length, entry, obj, full_path; for(i=0; i < len; i++){ entry = media[i]; //console.log(entry) if(type == 'folder_audio'){ if(/mp3|wav|aac|flac/.test(entry.basename)){ obj = $.extend(true, {}, data); obj.type = 'audio'; full_path = entry.fullpath; if(entry.extension == 'mp3')obj.path = [{quality:defaultMenuQuality, 'mp3':full_path}]; else if(entry.extension == 'wav')obj.path = [{quality:defaultMenuQuality, 'wav':full_path}]; if(settings.requirePosterFromFolder)obj.poster = full_path.substr(0, full_path.lastIndexOf('/')+1) + 'poster/' + entry.filename + '.jpg';//assume poster file exist in the poster directory with the same name! if(settings.requireThumbnailsFromFolder)if(!obj.thumb)obj.thumb = full_path.substr(0, full_path.lastIndexOf('/')+1) + 'thumb/' + entry.filename + '.jpg';//thumb comes from thumb directory if(!obj.share)obj.share = full_path; if(!obj.title)obj.title = entry.filename; playlistProcessData.push(obj); id3Counter++; } }else if(type == 'folder_video'){ if(/mp4/.test(entry.basename)){ obj = $.extend(true, {}, data); obj.type = 'video'; full_path = entry.fullpath; obj.path = [{quality:defaultMenuQuality, mp4:full_path}]; if(settings.requirePosterFromFolder)obj.poster = full_path.substr(0, full_path.lastIndexOf('/')+1) + 'poster/' + entry.filename + '.jpg';//assume poster file exist in the poster directory with the same name! if(settings.requireThumbnailsFromFolder)if(!obj.thumb)obj.thumb = full_path.substr(0, full_path.lastIndexOf('/')+1) + 'thumb/' + entry.filename + '.jpg';//thumb comes from thumb directory if(!obj.share)obj.share = full_path; if(!obj.title)obj.title = entry.filename; playlistProcessData.push(obj); } }else if(type == 'folder_image'){ if(/jpg|jpeg|png|gif/.test(entry.basename)){ obj = $.extend(true, {}, data); obj.type = 'image'; full_path = entry.fullpath; obj.path = full_path; if(settings.requireThumbnailsFromFolder)if(!obj.thumb)obj.thumb = full_path.substr(0, full_path.lastIndexOf('/')+1) + 'thumb/' + entry.filename + '.jpg';//assume thumb file exist in the thumb directory with the same name! if(!obj.share)obj.share = full_path; if(!obj.title)obj.title = entry.filename; playlistProcessData.push(obj); } } } if(type == 'folder_audio'){ if(data.id3){ getId3(); }else{ checkProcessCounter(); } }else{ checkProcessCounter(); } }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); checkProcessCounter(); }); } //############################################// /* id3 tags */ //############################################// function getId3(){ /*https://github.com/aadsm/jsmediatags*/ if(typeof jsmediatags === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.mediatags_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.mediatags_js); else var src = settings.mediatags_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ getId3(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ var item = playlistProcessData[id3Counter], url = item.path[0].mp3 || item.path[0].wav; jsmediatags.read(url, { onSuccess: function(tag) { var tags = tag.tags, image = tags.picture; if(tags.artist) item.artist = tags.artist; if(tags.title) item.title = tags.title; if(tags.album) item.album = tags.album; if(image){ var base64String = "", i, len = image.data.length; for(i = 0; i < len; i++)base64String += String.fromCharCode(image.data[i]); item.thumb = "data:" + image.format + ";base64," + window.btoa(base64String); } id3Counter--; if(id3Counter > id3Start){ getId3(); }else{ checkProcessCounter(); } }, onError: function(error) { console.log("ID3 error: ", error.type, error.info); id3Counter--; if(id3Counter > id3Start){ getId3(); }else{ checkProcessCounter(); } } }); } } //############################################// /* google drive folder */ //############################################// function processGdriveFolder(data){ if(window.location.protocol == 'file:'){ console.log('Reading files from folders locally is not possible! This requires server connection.'); return false; } if(MVPUtils.isEmpty(settings.gDriveAppId)){ console.log('gDriveAppId has not been set in settings!'); return false; } var url = "https://www.googleapis.com/drive/v3/files?q='" + data.path + "'+in+parents&pageSize=1000&key=" + settings.gDriveAppId; $.ajax({ url: url, dataType: "jsonp", }).done(function(media) { var i, len = media.files.length, entry, obj, imgArr = [], mediaArr = []; for(i=0; i < len; i++){ entry = media.files[i]; //split video and images (assume there is equal number of video and image files named the same in folder!) if(/video/.test(entry.mimeType)){ mediaArr.push(entry); }else if(/image/.test(entry.mimeType)){ imgArr.push(entry); } } if(data.sort){ if(data.sort == 'filename-asc'){ MVPUtils.keysrt(mediaArr, 'name'); MVPUtils.keysrt(imgArr, 'name'); } else if(data.sort == 'filename-desc'){ MVPUtils.keysrt(mediaArr, 'name', true); MVPUtils.keysrt(imgArr, 'name', true); } } len = mediaArr.length; for(i=0; i < len; i++){ entry = mediaArr[i]; obj= $.extend(true, {}, data); obj.type = 'video'; obj.path = 'https://drive.google.com/uc?export=view&id='+entry.id; if(settings.createDownloadIconsInPlaylist){ if(!obj.download)obj.download = 'https://drive.google.com/uc?export=download&id=' + entry.id; } //if(!obj.share)obj.share = 'https://drive.google.com/open?id=' + entry.id; if(settings.createLinkIconsInPlaylist)if(!obj.link)obj.link = 'https://drive.google.com/open?id=' + entry.id; if(settings.requireThumbnailsFromFolder)if(!obj.thumb && imgArr[i])obj.thumb = 'https://drive.google.com/uc?export=view&id=' + imgArr[i].id; if(settings.requirePosterFromFolder)if(!obj.poster && imgArr[i])obj.poster = 'https://drive.google.com/uc?export=view&id=' + imgArr[i].id; if(!obj.title)obj.title = entry.name.substr(0, entry.name.lastIndexOf('.')); playlistProcessData.push(obj); } checkProcessCounter(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log('Error processGdriveFolder: ' + jqXHR, textStatus, errorThrown); checkProcessCounter(); }); } //############################################// /* onedrive folder */ //############################################// function processOnedriveFolder(data){ if(window.location.protocol == 'file:'){ console.log('Reading files from folders locally is not possible! This requires server connection.'); return false; } var p = data.path if(p.indexOf('?') > -1)p = p.substr(0,p.indexOf('?')) var id = btoa(p); var url = 'https://api.onedrive.com/v1.0/shares/u!'+id+'/root?expand=children' $.ajax({ url: url, dataType: "json", }).done(function(response) { var d = response; var i, len = d.children.length, entry, obj, imgArr = [], mediaArr = []; for(i=0; i < len; i++){ entry = d.children[i]; if(entry.file){ if(data.sort == 'date-asc' || data.sort == 'date-desc'){ var date = new Date(entry.fileSystemInfo.lastModifiedDateTime); entry.fileSystemInfo.lastModifiedDateTime = date.getTime(); } else if(data.sort == 'created-date-asc' || data.sort == 'created-date-desc'){ var date = new Date(entry.fileSystemInfo.createdDateTime); entry.fileSystemInfo.createdDateTime = date.getTime(); } //split video and images (assume there is equal number of video and image files named the same in folder!) if(/video/.test(entry.file.mimeType)){ mediaArr.push(entry); }else if(/image/.test(entry.file.mimeType)){ imgArr.push(entry); } } } if(data.sort){ if(data.sort == 'filename-asc'){ MVPUtils.keysrt(mediaArr, 'name'); MVPUtils.keysrt(imgArr, 'name'); } else if(data.sort == 'filename-desc'){ MVPUtils.keysrt(mediaArr, 'name', true); MVPUtils.keysrt(imgArr, 'name', true); } else if(data.sort == 'date-asc'){ MVPUtils.keysrt2(mediaArr, 'fileSystemInfo', 'lastModifiedDateTime'); MVPUtils.keysrt2(imgArr, 'fileSystemInfo', 'lastModifiedDateTime'); } else if(data.sort == 'date-desc'){ MVPUtils.keysrt2(mediaArr, 'fileSystemInfo', 'lastModifiedDateTime', true); MVPUtils.keysrt2(imgArr, 'fileSystemInfo', 'lastModifiedDateTime', true); } else if(data.sort == 'created-date-asc'){ MVPUtils.keysrt2(mediaArr, 'fileSystemInfo', 'createdDateTime'); MVPUtils.keysrt2(imgArr, 'fileSystemInfo', 'createdDateTime'); } else if(data.sort == 'created-date-desc'){ MVPUtils.keysrt2(mediaArr, 'fileSystemInfo', 'createdDateTime', true); MVPUtils.keysrt2(imgArr, 'fileSystemInfo', 'createdDateTime', true); } } len = mediaArr.length; for(i=0; i < len; i++){ entry = mediaArr[i]; obj= $.extend(true, {}, data); obj.type = 'video'; if(!obj.title)obj.title = entry.name.substr(0, entry.name.lastIndexOf('.')); obj.path = entry['@content.downloadUrl'] if(settings.requireThumbnailsFromFolder)if(!obj.thumb && imgArr[i])obj.thumb = imgArr[i]['@content.downloadUrl']; if(settings.requirePosterFromFolder)if(!obj.poster && imgArr[i])obj.poster = imgArr[i]['@content.downloadUrl']; playlistProcessData.push(obj); } checkProcessCounter(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log('Error processOnedriveFolder: ' + jqXHR, textStatus, errorThrown); checkProcessCounter(); }); } function buildPlaylist() { var counter, i, j = !addTrackProcess ? playlistDataArr.length : insertPosition, len = playlistProcessData.length, type, div, data, thumb, pictures_arr, plen, alt, playlistThumb, playlistInfo, title, counter_add = 0, currentInsert; lastPlaylistDataArr = []; thumbLoadArr = []; //console.log(playlistProcessData) for(i=0; i < len; i++){ counter = i+j; if(addTrackProcess)counter_add++; data = playlistProcessData[i]; type = data.type; if(createPlaylist){ if(!data.origclasses)data.origclasses = 'mvp-playlist-item'; div = $('
    ').attr('data-type', type); delete data.origclasses; //thumb if(playlistItemContent.indexOf('thumb') != -1){ thumb = null; if(data.type == 'youtube'){ /* default 120x90 medium 320x180 high 480x360 standard 640x480 maxres 1280x720 */ if(data.thumbnails){ $.each(data.thumbnails, function(key, value) { if(key == settings.youtubeThumbSize){ thumb = value.url; return false; } }); if(!thumb){ if(data.thumbnails.medium)thumb = data.thumbnails.medium.url; else if(data.thumbnails.high)thumb = data.thumbnails.high.url; else if(data.thumbnails.standard)thumb = data.thumbnails.standard.url; } //get poster so we have it for chapters menu if(settings.showControlsBeforeStart && !data.poster){ if(data.thumbnails.maxres)data.poster = data.thumbnails.maxres.url; else if(data.thumbnails.high)data.poster = data.thumbnails.high.url; else if(data.thumbnails.standard)data.poster = data.thumbnails.standard.url; } } } else if(data.type == 'vimeo'){ /* //not always those heights! 100x75, 200x150, 295x166, 640x360, 960x540, 1280x720, 1920x1080 */ if(data.pictures){ pictures_arr = data.pictures.sizes, plen = pictures_arr.length; var z; for(z = 0; z < plen; z++){ if(pictures_arr[z].width == vimeoThumbSize){ thumb = pictures_arr[z].link; break; } } if(!thumb){ for(z = 0; z < plen; z++){ if(pictures_arr[z].width == 295 || pictures_arr[z].width == 640){ thumb = pictures_arr[z].link; break; } } } if(settings.showControlsBeforeStart && !data.poster){//get poster so we have it for chapters menu for(z = 0; z < plen; z++){ if(pictures_arr[z].width == 1280 || pictures_arr[z].width == 1920){ data.poster = pictures_arr[z].link; break; } } } } } if(!thumb)thumb = data.thumb || data.thumbDefault; if(thumb){ playlistThumb = $('
    ').addClass('mvp-playlist-thumb').appendTo(div); if(data.alt)alt = data.alt; else if(data.title)alt = data.title.replace(/"/g, "'"); else alt = 'image'; var isrc = $(new Image()).addClass('mvp-thumbimg').appendTo(playlistThumb).attr({alt: alt}); if(data.origtype == 's3_video' && settings.getThumbFromBucket){ thumbLoadArr.push({isrc: isrc, thumb: thumb, bucket: data.bucket }) isrc.attr('src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=') }else{ isrc.attr('src', thumb) } //hover preview if(data.hoverPreview){ //try to detect extension if(data.hoverPreview.indexOf('.gif') > -1){ data.hoverPreviewImg = data.hoverPreview; }else{//should be video data.hoverPreviewVideo = data.hoverPreview; $('
    ').appendTo(playlistThumb); } } data.thumb = thumb;//save used thumb so we can have it for up next //duration in thumbnail if(playlistItemContent.indexOf('duration') > -1){ if(data.duration){ $(''+MVPUtils.formatTime(data.duration)+'').appendTo(playlistThumb); } } //watched percentage if(settings.displayWatchedPercentage){ $('
    ').appendTo(playlistThumb); } } } //title if(data.title || data.description || data.publishedAt){ playlistInfo = $('
    ').appendTo(div); var z, zlen = playlistItemContent.length, zitem; for(z = 0;z < zlen; z++){ zitem = playlistItemContent[z]; if(zitem == 'title' && data.title){ title = data.title.replace(/"/g, "'"); div.attr('title', title); $(''+title+'').appendTo(playlistInfo); } else if(zitem == 'date' && data.date){ var published = new Date(data.date), publishedAt = (published.getMonth()+1) + '/' + published.getDate() + '/' + published.getFullYear(); $(''+publishedAt+'').appendTo(playlistInfo); } else if(zitem == 'description' && data.description){ var dsc = data.description.replace(/"/g, "'"); div.attr('data-description', dsc); var clamped_class = '' if(settings.limitDescriptionText)clamped_class = ' mvp-playlist-description-clamp'; $('
    '+dsc+'
    ').appendTo(playlistInfo); } } } //copy data to playlist items if(data.mediaId != undefined){ div.attr('data-media-id', data.mediaId); } else if(data.path){ if(settings.getWatchedPercentage)div.attr('data-media-url', data.path); } if(data.title){ var st = data.title.replace(/['"\|]/g,''); st = st.replace(/[^a-z\d,\s\.]+/gi,''); st = st.replace(/\s+/g,' '); div.attr('data-safe-title', st);//note: we have added this so we can have stats on grouped media with same media id! data.safeTitle = st; } if(data.category){ div.attr('data-category', data.category); } if(data.tag){ div.attr('data-tag', data.tag); } if(data.customContent){//copy any content to generated playlist item div.append(data.customContent); delete data.customContent; } if(!addTrackProcess){ div.appendTo(playlistContent); }else{ if(!currentInsert){ if(endInsert){ div.appendTo(playlistContent); }else{ playlistContent.children('div').eq(insertPosition).before(div); } }else{ currentInsert.after(div); } currentInsert = div; } if(createPlaylist && settings.addPlaylistEvents){ div.on('click', clickPlaylistItem); if(!isMobile)div.on('mouseenter', overPlaylistItem).on('mouseleave', outPlaylistItem); } }else{//no playlist if(settings.useStatistics){ if(data.mediaId != undefined){ if(data.title){ var st = data.title.replace(/['"\|]/g,''); data.safeTitle = st; } } } } if(playlistId != undefined)data.playlistId = playlistId; playlistDataArr.splice(counter, 0, {id: counter, type: type, data: data}); lastPlaylistDataArr.push({id: counter, type: type, data: data}); } lastPlaylist = playlistContent; updatePlaylist(); //console.log('playlistDataArr = ', playlistDataArr); if(!addTrackProcess){ _MVPPlaylistManager.setPlaylistItems(playlistLength); }else{ var current_counter = _MVPPlaylistManager.getCounter(); _MVPPlaylistManager.setPlaylistItems(playlistLength, false); if(insertPosition <= current_counter){ if(!endInsert)_MVPPlaylistManager.reSetCounter(current_counter + counter_add); } if(addTrackPlayit && !isMobile){ autoPlay = true; settings.autoPlay = true; } if(addTrackPlayit){ isPoster = false; _MVPPlaylistManager.setCounter(insertPosition, false); } } endInit(); } function updatePlaylist(){ playlistLength = playlistDataArr.length; if(createPlaylist){ var i = 0; playlistContent.find('.mvp-playlist-item').each(function(){ $(this).attr('data-id', i); playlistDataArr[i].id = i; i++; }); }else{ var i; for(i = 0;i < playlistLength; i++){ playlistDataArr[i].id = i; } } } function endInit(){ playlistTransitionOn = false; if(!componentInited){ componentInited = true; //playlist global data if(playlistData){ addMoreLimit = parseInt(playlistData.attr('data-add-more-limit'),10); addMoreNumResults = parseInt(playlistData.attr('data-add-more-num-results'),10); addMoreOffset = parseInt(playlistData.attr('data-add-more-offset'),10); addMoreSortOrder = playlistData.attr("data-add-more-sort-order"); addMoreSortDirection = playlistData.attr("data-add-more-sort-direction"); encryptMediaPaths = playlistData.attr("data-encrypt-media-paths"); if(playlistData.attr("data-taxonomy") != undefined)playlistTaxonomy = playlistData.attr("data-taxonomy"); if(playlistData.attr("data-category") != undefined)playlistCategory = playlistData.attr("data-category"); if(playlistData.attr("data-tag") != undefined)playlistTag = playlistData.attr("data-tag"); if(playlistData.attr("data-match") != undefined)playlistTaxonomyMatch = playlistData.attr("data-match"); if(playlistData.attr('data-add-more-on-total-scroll') != undefined){ addMoreOnTotalScroll = true; } if(playlistData.attr('data-use-pagination') != undefined){ paginationTotalPages = Math.ceil(addMoreNumResults / addMoreLimit); if (addMoreNumResults > addMoreLimit){ paginationCurrentPage = 0; createPagination(paginationCurrentPage); var i,obj; for(i = 0;i 0){ if(settings.gridType == 'javascript' && settings.breakPointArr){ getColumns(); lastColumn = column; playlistContent.find('.mvp-playlist-item').each(function(){ if(gutter > 0){ var perc = 100/column; $(this).css({marginLeft: 0, marginTop: 0, marginRight: gutter+'px', marginBottom: gutter+'px', width: 'calc('+perc+'% - '+gutter+'px)'}); }else{ $(this).css({marginLeft: 0, marginTop: 0, marginRight: gutter+'px', marginBottom: gutter+'px', width: 100/column+'%'}); } }); } if(navigationDirection == 'h'){ playlistContent.width(playlistLength*settings.pi_size); } //fade thumbs if(thumbLoadArr.length){ getAwsThumb(thumbLoadArr[0]) }else{ fadeThumbs() } if(settings.displayWatchedPercentage && createPlaylist)getWatchedPercentage(); if(navigationType == 'scroll' && settings.playlistScrollType == 'perfect-scrollbar'){ if(_MVPPlaylistNavigation)_MVPPlaylistNavigation.updateScrollPosition() } } if(!autoInitActiveItem){//only on first playlist create, not after addTrackProcess or load more if(!addTrackProcess && playlistLength>0){ //active item on start if(settings.mediaId != undefined){ if(settings.mediaTitle){ var pi = playlistContent.find('.mvp-playlist-item[data-media-id='+settings.mediaId+'][title="'+settings.mediaTitle+'"]');//if we have title if(pi.length == 0){//if fails var pi = playlistContent.find('.mvp-playlist-item[data-media-id='+settings.mediaId+']'); } delete settings.mediaTitle; }else{ var pi = playlistContent.find('.mvp-playlist-item[data-media-id='+settings.mediaId+']'); } var index = playlistContent.children('.mvp-playlist-item').index(pi); if(index == undefined || index == -1){ alert('No media with ID to load! LoadMedia failed.'); return false; } delete settings.mediaId; _MVPPlaylistManager.processPlaylistRequest(index); }else{ var ai = settings.activeItem; if(ai>playlistLength-1)ai = playlistLength-1; if(ai>-1)_MVPPlaylistManager.setCounter(ai, false); } autoInitActiveItem = true; } } addTrackProcess = false; playerLoader.hide(); if(loadMoreProcess){ loadMoreProcess = false; if(navigationType == 'buttons'){ if(_MVPPlaylistNavigation)_MVPPlaylistNavigation.showButtons('forward') } } if(loadMoreBtn){ if(loadMoreOnTotalScroll){ if(nextPageToken){ loadMoreBtn.css('opacity',1); }else{ loadMoreBtn.remove(); loadMoreBtn = null; loadMoreOnTotalScroll = false; } }else if(addMoreOnTotalScroll){ if(addMoreNumResults > 0){ if(addMoreNumResults > addMoreOffset){ loadMoreBtn.css('opacity',1); }else{ loadMoreBtn.remove(); loadMoreBtn = null; addMoreOnTotalScroll = false; } } }else{ loadMoreBtn.remove(); loadMoreBtn = null; } } $(self).trigger('playlistEndLoad', {instance:self, instanceName: settings.instanceName, loadMoreOnTotalScroll:loadMoreOnTotalScroll, addMoreOnTotalScroll:addMoreOnTotalScroll}); if(settings.gridType == 'masonry'){ if(!_masonry){ playlistContent.prepend('
    ') wrapper.addClass('mvp-masonry') if(typeof $.fn.masonry === 'undefined'){ console.log('Link to masonry.pkgd.min.js file missing in head tag!') } if(typeof imagesLoaded !== 'function'){ console.log('Link to imagesloaded.pkgd.min file missing in head tag!'); } _masonry = playlistContent.masonry({ itemSelector: '.mvp-playlist-item' }); playlistContent.imagesLoaded( function() { _masonry.masonry('layout'); }); }else{//load more playlistContent.masonry('reloadItems'); playlistContent.imagesLoaded( function() { _masonry.masonry('layout'); }); } } } function fadeThumbs(){ var fadeArr = []; playlistContent.find('.mvp-thumbimg:not(.mvp-visible)').each(function(){ fadeArr.push($(this)); }); var p=0, len = fadeArr.length, z; for(z=0;z point.width){ column = point.column; gutter = point.gutter; } } playlistInner.css({paddingTop: gutter+'px', paddingLeft: gutter+'px'}); } function initPlaylistNavigation(){ settings.parent = self; settings.wrapper = wrapper; settings.playlistHolder = playlistHolder; settings.playlistInner = playlistInner; settings.playlistContent = playlistContent; _MVPPlaylistNavigation = new MVPPlaylistNavigation(settings) } //############################################// /* viewport autoplay */ //############################################// //continuosly monitor viewport function checkViewport(){ if(MVPUtils.isScrolledIntoView(wrapper[0])){ //console.log('in view', instanceName: settings.instanceName) autoPlayInViewportDone = true; autoPlay = true; settings.autoPlay = true; self.playMedia(); }else{ _window.on(autoplayScrollEvent, function() { if(isScrollTimeout)return; isScrollTimeout = true; if(MVPUtils.isScrolledIntoView(wrapper[0])){ //console.log('in view', instanceName: settings.instanceName) autoPlayInViewportDone = true; autoPlay = true; settings.autoPlay = true; self.playMedia(); }else{ //console.log('out', instanceName: settings.instanceName) self.pauseMedia(); } setTimeout(function() { isScrollTimeout = false; }, 250); }); } } //############################################// /* minimize on scroll */ //############################################// function checkPlayerMinimize(end_minimize) { if(componentSize == "fullscreen")return; if(!end_minimize && MVPUtils.getScrollTop() > playerOffsetTop){ if(!playerWrap.hasClass(settings.minimizeClass)){ playerWrap.addClass(settings.minimizeClass); if(settings.hidePlaylistOnMinimize && settings.playlistOpened){ hidePlaylistOnMinimizeDone = true; //playlistHolder.hide(); settings.playlistOpened = false; } } }else{ if(playerWrap.hasClass(settings.minimizeClass)){ playerWrap.removeClass(settings.minimizeClass); if(settings.hidePlaylistOnMinimize && !settings.playlistOpened){ hidePlaylistOnMinimizeDone = false; //playlistHolder.show(); settings.playlistOpened = true; } } } doneResizing(); } //############################################// /* playlist manager */ //############################################// if(settings.autoAdvanceToNextPlaylist)settings.loopingOn = false; var _MVPPlaylistManager = new MVPPlaylistManager(settings); $(_MVPPlaylistManager).on('MVPPlaylistManager.COUNTER_READY', function(e, counter){ //change media mods // mainMediaData = null; isPoster = false; setMediaInformationDone = false; upNextClosed = false; disableSeekingPastWatchedPointTime = 0; //-- ads --// adDataTaken = false; adResumeTime = null; adCounter = 0; adPreArr = []; adMidArr = []; adEndOn = null; adEndArr = []; adSection = null; progressBg.find('.mvp-ad-indicator').remove(); adMarkersCreated = false; adMidTimesReady = false; vastLinearArr = [] isIma = false; imaAdMarkerArr = [] imaStarted = false; //-- ads --// //chapters progressBg.find('.mvp-chapter-indicator').remove(); chapterArr = []; //chaptersLoaded = false; chaptersCreated = false; chaptersReady = false; chapterActiveMenuItem = null; chapterActiveWindowItem = null; chapterActiveHighlight = null; seekbar.removeClass('mvp-seekbar-chapters'); //-- annotations --// annotationDataTaken = false; annotationSection = null; //-- annotations --// //restore seekabr width after ad lastProgressWidth = null; progressLevel.removeClass('mvp-progress-sizing'); if(mediaType){ cleanMedia(); } mediaCounter = counter; currMediaData = playlistDataArr[mediaCounter].data; disableActivePlaylistItem(); allowedViewVideoUserRole = true; if(settings.isUserLoggedIn){ if(typeof currMediaData.lockTime != undefined){ if(currentUserRoles && currMediaData.lockVideoUserRoles){ allowedViewVideoUserRole = MVPUtils.arrayContainsAnotherArray(currMediaData.lockVideoUserRoles, currentUserRoles); } } }else{ allowedViewVideoUserRole = false; } //-- annotations --// if(!annotationDataTaken){//take from main media (adverts do not have annotations) annotationDataTaken = true; if(currMediaData.annotationSection){ annotationSection = currMediaData.annotationSection; if(annotationSection instanceof $ == false)annotationSection = $(annotationSection);//if we convert to innerhtml } } mainMediaData = currMediaData;//save for going back from ad to main media if(showAds){ if(currMediaData.vast){ if(settings.useImaLoader){ if(!(currMediaData.type != 'video' || currMediaData.type != 'audio')){ delete currMediaData.vast }else{ isIma = true; adDataTaken = true;//if we use ima loader we cant have ads (pre,mid,end) } } } //-- ads --// if(!adDataTaken){ adDataTaken = true; if(currMediaData.adPre || currMediaData.adMid || currMediaData.adEnd){//ads from json if(currMediaData.adMid){ var a, len = currMediaData.adMid.length, am; for(i = 0; i < len; i++){ am = currMediaData.adMid[i]; adMidArr.push({begin:am.begin, data:am, type:am.type}); } } if(currMediaData.adEnd){ var a, len = currMediaData.adEnd.length, am; for(i = 0; i < len; i++){ am = currMediaData.adEnd[i]; adEndArr.push({data:am, type:am.type}); } adCounter = -1; } if(currMediaData.adPre){ var a, len = currMediaData.adPre.length, am; for(i = 0; i < len; i++){ am = currMediaData.adPre[i]; adPreArr.push({data:am, type:am.type}); } adCounter = 0; currMediaData = adPreArr[adCounter].data; adOn = true; } }else if(currMediaData.adSection){ adSection = currMediaData.adSection; if(adSection instanceof $ == false)adSection = $(adSection);//if we convert to innerhtml adSection.find('.mvp-ad').each(function(){//ads from html var item = $(this); if(item.hasClass('mvp-ad-pre')){//pre adPreArr.push(item); } else if(item.hasClass('mvp-ad-mid')){//mid var time = item.attr('data-begin') adMidArr.push({begin:time, data:item}) } else if(item.hasClass('mvp-ad-end')){//end adEndArr.push(item); } }); if(currMediaData.vast){ }else{ if(adPreArr.length){ adCounter = 0; currMediaData = getAdData(adPreArr[adCounter]); console.log(currMediaData) adOn = true; } else if(adEndArr.length){ adCounter = -1; } } } } //-- ads --// } $(self).trigger("mediaRequest", {instance:self, instanceName: settings.instanceName, media:currMediaData}); if(currMediaData.origtype == 's3_video'){ getAwsUrl(currMediaData) }else{ if(currMediaData.vast){ vastRequest = true; currMediaData.origtype = currMediaData.type; if(isIma){ if(!imaLoaded)loadIma() }else{ initVast() return//continue in vast loaded event } } checkMedia(); } }).on('MVPPlaylistManager.RANDOM_CHANGE', function(e, randomPlay){ if(randomPlay)shuffleToggle.addClass('mvp-contr-btn-hover'); else shuffleToggle.removeClass('mvp-contr-btn-hover'); }).on('MVPPlaylistManager.LOOP_CHANGE', function(e, loopingOn){ if(loopingOn)loopToggle.addClass('mvp-contr-btn-hover'); else loopToggle.removeClass('mvp-contr-btn-hover'); }).on('MVPPlaylistManager.PLAYLIST_END', function(e, loopingOn){ if(settings.autoAdvanceToNextPlaylist){ if(settings.makePlaylistSelector){ //auto advance in playlist selector var pi = playlistSelectorContainer.find('.mvp-playlist-selector-item-active') if(pi.length){ var next = pi.next() if(next.length)next.trigger('click') else playlistSelectorContainer.find('.mvp-playlist-selector-item').eq(0).trigger('click')//loop }else{ playlistSelectorContainer.find('.mvp-playlist-selector-item').eq(0).trigger('click') } }else{ if(activePlaylist){//auto advance in default playlist list var active_pl = playlistList.find(activePlaylist); if(active_pl.length){ var next = active_pl.next() if(next.length){ setPlaylist('.'+next.attr('class')) } } } } } }); //############################################// /* aws */ //############################################// function getAwsUrl(data){ if(data.key.indexOf(bsf_match) != -1)data.key = MVPUtils.b64DecodeUnicode(data.key.substr(6)); var url = settings.sourcePath + 'includes/aws/aws.php'; var ajax_data = {object_key: data.key, bucket: data.bucket, action: 'get_url', region: settings.s3Region, expire: settings.s3UrlExpireTime, cred: settings.s3}; $.ajax({ type: 'GET', url: url, data: ajax_data, dataType: "json" }).done(function(result) { mediaType = 'video'; currMediaData.path = result checkMedia(); }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); $(self).trigger('getAws_error:', {instance:self, instanceName:settings.instanceName, media:currMediaData, error:errorThrown}); }); } function resumeAwsUrl(data){ if(data.key.indexOf(bsf_match) != -1)data.key = MVPUtils.b64DecodeUnicode(data.key.substr(6)); var url = settings.sourcePath + 'includes/aws/aws.php'; var ajax_data = {object_key: data.key, bucket: data.bucket, action: 'get_url', region: settings.s3Region, expire: settings.s3UrlExpireTime, cred: settings.s3}; $.ajax({ type: 'GET', url: url, data: ajax_data, dataType: "json" }).done(function(result) { videoUp2Js.src = result; var promise = videoUp2Js.play(); if (promise !== undefined) { promise.then(function(){ }).catch(function(error){ bigPlay.show(); playerLoader.hide(); }); } }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); $(self).trigger('getAws_error:', {instance:self, instanceName:settings.instanceName, media:currMediaData, error:errorThrown}); }); } function getAwsPoster(data){ playerLoader.show() var url = settings.sourcePath + 'includes/aws/aws.php', ajax_data = {object_key: data.poster, bucket: data.bucket, action: 'get_url_thumb', region: settings.s3Region, expire: settings.s3UrlExpireTime, cred: settings.s3}; $.ajax({ type: 'GET', url: url, data: ajax_data, dataType: "json" }).done(function(result) { currMediaData.poster = result; currMediaData.posterFetch = true setPoster() }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); $(self).trigger('getAwsPoster_error', {instance:self, instanceName:settings.instanceName, media:currMediaData, error:errorThrown}); }); } function getAwsThumb(data){ var url = settings.sourcePath + 'includes/aws/aws.php', ajax_data = {object_key: data.thumb, bucket: data.bucket, action: 'get_url_thumb', region: settings.s3Region, expire: settings.s3UrlExpireTime, cred: settings.s3}; $.ajax({ type: 'GET', url: url, data: ajax_data, dataType: "json" }).done(function(result) { thumbLoadArr[0].isrc.attr('src', result) thumbLoadArr.shift() if(thumbLoadArr.length){ getAwsThumb(thumbLoadArr[0]) }else{ fadeThumbs() } }).fail(function(jqXHR, textStatus, errorThrown) { console.log(jqXHR, textStatus, errorThrown); $(self).trigger('getAwsThumb_error', {instance:self, instanceName:settings.instanceName, media:currMediaData, error:errorThrown}); thumbLoadArr.shift() if(thumbLoadArr.length){ getAwsThumb(thumbLoadArr[0]) }else{ fadeThumbs() } }); } //############################################// /* aws */ //############################################// function checkMedia(){ qualityChange = false; //redirect type from no api if(currMediaData.type == 'youtube_single')currMediaData.type = 'youtube'; else if(currMediaData.type == 'vimeo_single')currMediaData.type = 'vimeo'; else mediaType = currMediaData.type; mediaType = currMediaData.type; if(isCasting){//moving from casting video to non supported type (user shouldnt mix non supported casting media anyway) if(!self.isCastSupportedMedia()){ _MVPCast.stopCasting(); isCasting = false; } } var allowed_types = ['audio', 'video', 'folder_video', 'folder_audio']//multiple qualities possible if((allowed_types.indexOf(currMediaData.type) > -1 || allowed_types.indexOf(currMediaData.origtype) > -1) && Array.isArray(currMediaData.path)){ getQuality(); if(settings.hideQualityMenuOnSingleQuality && qualityArr.length == 1){ }else{ if(qualityArr.length)buildQualityMenu(qualityArr, currMediaData.quality); } }else{ mediaPath = currMediaData.path; } if(mediaPath.indexOf(bsf_match) != -1)mediaPath = MVPUtils.b64DecodeUnicode(mediaPath.substr(6)); currMediaData.mediaPath = mediaPath; //redirect if(mediaType == 'hls'){ mediaType = 'video'; subMediaType = 'hls'; } else if(mediaType == 'dash'){ mediaType = 'video'; subMediaType = 'dash'; } else if(mediaType == 's3_video'){ mediaType = 'video'; } //check if poster exist posterExist = false; if(!adOn && !adResumeTime){//dont show poster on main media resume after ad if(mediaType == 'audio'){ if(useAudioEqualizer && !settings.displayPosterOnMobile){ //currMediaData.slideshowImages = null//in toggle playback if autopaly false we cannot start audio }else if(currMediaData.slideshowImages){ posterExist = true; }else if(currMediaData.poster){ posterExist = true; } } else if(mediaType == 'video' || mediaType == 'youtube' || mediaType == 'vimeo'){ if(currMediaData.poster && !settings.autoPlayInViewport){ posterExist = true; } } else if(mediaType == 'custom' || mediaType == 'custom_html'){ if(currMediaData.poster){ posterExist = true; } } }else{ //allow poster in ad with audio if(mediaType == 'audio'){ if(currMediaData.poster){ posterExist = true; } } } //check aspect ratio if(currMediaData.aspectRatio != undefined){ aspectRatio = Number(currMediaData.aspectRatio); }else{ aspectRatio = Number(settings.aspectRatio); } if(currMediaData.ageVerify && !checkAgeVerify()){ toggleAgeVerify() }else{ resumeCheckMedia() } //show lightbox if(settings.playerType == 'lightbox' && !lightboxOpened){ lightboxOpened = true; lightboxWrap.css('display','block'); doneResizing();//resize player after lightbox is shown if(lightboxWrap.css('opacity') != 1){ setTimeout(function(){ clearTimeout(this); lightboxWrap.css('opacity',1); },50); } } if(settings.scrollToPlayer && settings.playerType != 'lightbox'){ delete settings.scrollToPlayer; var top = playerHolder.offset().top; $('html,body').animate({scrollTop: top}, 500); } } function resumeCheckMedia(){ //check password if(currMediaData.pwd){ if(!autoPlay && posterExist){ setPoster(); }else{ pwdHolder.css('display','block'); setTimeout(function(){ pwdHolder.addClass('mvp-holder-visible'); },20); } }else{ //check lock time if(currMediaData.lockTime == '0' && !allowedViewVideoUserRole){ toggleRedirectLoginScreen('watch'); }else{ if(mediaType == 'audio'){ if(posterExist)setPoster(); else setMedia(); }else{ if(!autoPlay && posterExist)setPoster(); else setMedia(); } } } } function getQuality(){ qualityArr = []; var i, len = currMediaData.path.length, item, currentQuality; if(len > 1){ currentQuality = currMediaData.quality; if(isMobile && currMediaData.qualityMobile)currentQuality = currMediaData.qualityMobile; } if(!currentQuality){//if not specified currentQuality = currMediaData.path[0].quality; } currMediaData.quality = currentQuality; //get current quality for playback for(i = 0;i').appendTo(mediaHolder); if(mediaType == 'audio'){ isPoster = true; if(currMediaData.slideshowImages){ posterHolder.empty().show() if(!_MVPImageSlideshow){ _MVPImageSlideshow = new MVPImageSlideshow({holder: posterHolder, settings:settings, media: currMediaData}); } _MVPImageSlideshow.setData(currMediaData) if(!autoPlay){ bigPlay.show(); }else{ setMedia(); } }else{ $(new Image()).addClass('mvp-media').appendTo(posterHolder.empty().show()) .on('load',function() { poster = $(this); //MVPAspectRatio.resizeMedia('image', aspectRatio, playerHolder, poster); poster.addClass('mvp-visible mvp-media-img'); posterInited = true; if(!settings.displayPosterOnMobile){ if(!autoPlay){ bigPlay.show(); if(adOn){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } }else{ setMedia(); } } }).on('error',function(e){console.log(e)}).attr({'src': currMediaData.poster, 'alt': currMediaData.title}); } } else if(mediaType == 'video' || mediaType == 'youtube' || mediaType == 'vimeo'){ playerControls.css('display','none').removeClass('mvp-player-controls-visible'); interfaceHidden = true; isPoster = true; $(new Image()).addClass('mvp-media').appendTo(posterHolder.empty().show()) .on('load',function() { poster = $(this); //MVPAspectRatio.resizeMedia('image', aspectRatio, playerHolder, poster); poster.addClass('mvp-visible mvp-media-img'); playerLoader.hide(); posterInited = true; if(!settings.displayPosterOnMobile){ bigPlay.show(); if(adOn){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } } }).on('error',function(e){console.log(e)}).attr({'src': currMediaData.poster, 'alt': currMediaData.title}); } else if(mediaType == 'custom' || mediaType == 'custom_html'){ playerControls.css('display','none').removeClass('mvp-player-controls-visible'); interfaceHidden = true; isPoster = true; $(new Image()).addClass('mvp-media').appendTo(posterHolder.empty().show()) .on('load',function() { poster = $(this); //MVPAspectRatio.resizeMedia('image', aspectRatio, playerHolder, poster); poster.addClass('mvp-visible mvp-media-img'); playerLoader.hide(); posterInited = true; bigPlay.show(); }).on('error',function(e){console.log(e)}).attr({'src': currMediaData.poster, 'alt': currMediaData.title}); } if(settings.showControlsBeforeStart){ //if(!qualityChange)setMediaInformation(); setMediaInformation(); if(currMediaData.duration){ //display controls before video starts if(!adOn){ //ad markers if(!adMarkersCreated){ if(settings.createAdMarkers && adMidArr.length){ if(!adMidTimesReady)checkAdMidTimes(currMediaData.duration) makeAdMarkers(currMediaData.duration); adMarkersCreated = true; } } //time mediaTimeTotal.html(MVPUtils.formatTime(currMediaData.duration)); //playback rate setPlaybackRateActiveMenuItem(currMediaData.playbackRate || 1); //listen for data ready var interval = setInterval(function(){ if(subtitlesReady && chaptersReady && previewSeekReady){ clearInterval(interval); playerControls.css('display','block'); playerControls.one("transitionend", function(){ interfaceHidden = false; }).addClass('mvp-player-controls-visible'); if(chapterMenuOpened)chapterMenuHolder.addClass('mvp-holder-visible'); } },100); } } } } function setPosterForPause(){ //set poster for pause if(!posterHolder)posterHolder = $('
    ').appendTo(mediaHolder); $(new Image()).addClass('mvp-media').appendTo(posterHolder.empty().show()) .on('load',function() { poster = $(this); poster.addClass('mvp-visible mvp-media-img'); }).on('error',function(e){console.log(e)}).attr({'src': currMediaData.poster, 'alt': currMediaData.title}); } function setMedia(){//continue from set media because of async script loading if(mediaType != 'audio'){ if((poster || currMediaData.slideshowImages) && !mediaStarted){ posterHolder.hide(); bigPlay.hide(); playerLoader.show(); } } //load scripts dynamically on if needed if(currMediaData.is360){ if(typeof THREE === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.three_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.three_js); else var src = settings.three_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ if(typeof THREE.OrbitControls === 'undefined'){ var script2 = document.createElement('script'); script2.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.orbitControls_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.orbitControls_js); else var src = settings.orbitControls_js; script2.src = src; script2.onload = script2.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ setMedia(); } }; script2.onerror = function(){ console.log("Error loading " + this.src); } var tag2 = document.getElementsByTagName('script')[0]; tag2.parentNode.insertBefore(script2, tag2); }else{ setMedia(); } } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); return; }else if(typeof THREE.OrbitControls === 'undefined'){ var script2 = document.createElement('script'); script2.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.orbitControls_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.orbitControls_js); else var src = settings.orbitControls_js; script2.src = src; script2.onload = script2.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ setMedia(); } }; script2.onerror = function(){ console.log("Error loading " + this.src); } var tag2 = document.getElementsByTagName('script')[0]; tag2.parentNode.insertBefore(script2, tag2); return; } } if(subMediaType == 'hls'){ if(!hlsInited){ if(typeof Hls === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.hls_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.hls_js); else var src = settings.hls_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ initHls(); setMedia(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ initHls(); setMedia(); } return; } } if(subMediaType == 'dash'){ if(!dashInited){ if(typeof dashjs === 'undefined'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.dash_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.dash_js); else var src = settings.dash_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ initDash(); setMedia(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); }else{ initDash(); setMedia(); } return; } } else if(mediaType == 'audio'){ if(useAudioEqualizer && !settings.displayPosterOnMobile){ if(typeof MVPAudioEqualizer === 'undefined'){ if(!canvasAudio)canvasAudio = $('').prependTo(mediaHolder); var script = document.createElement('script'); script.type = 'text/javascript'; script.src = MVPUtils.qualifyURL(settings.sourcePath+settings.equalizer_js) + '?=' + Math.random(); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ _MVPAudioEqualizer = new MVPAudioEqualizer({holder:mediaHolder, canvas:canvasAudio[0]}); setMedia(); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); return; } } } if(isPoster){ resumeTime = currMediaData.start || 0;//force play after poster isPoster = false; } //-- ads --// if(adResumeTime && !adOn){//resume main media time resumeTime = adResumeTime; adResumeTime = null; } //-- ads --// //resume playback position if(settings.playbackPositionTime != undefined && !adOn){//remember playback position for main video (adverts are ignored) resumeTime = settings.playbackPositionTime; delete settings.playbackPositionTime; playerLoader.hide() if(toggleResumeOpened){ toggleResumeScreen(false); }else{ toggleResumeScreen(); return; } } if(mediaType == 'audio' || mediaType == 'video' || mediaType == 'youtube' && settings.youtubePlayerType == 'chromeless' && autoPlay && youtubePlayed || mediaType == 'vimeo' && activeVimeoPlayerType == 'chromeless' && autoPlay && vimeoPlayed){ playerLoader.show(); } if(mediaType == 'audio'){ if(!audioInited){ audio = $(document.createElement("audio")).attr('preload',settings.preload); audioUp2Js = audio[0]; audioInited = true; } audioReady = false; audioUp2Js.src = mediaPath; audio.on("ended", function(){ mediaEndHandler(); }) .on("loadedmetadata", function(){ setTimeout(function(){ if(!audioReady)audio.trigger('canplay'); },100); }) .on("canplay", function(){ if(!audioReady){ audioReady = true; setVolume(); if(currMediaData.playbackRate){ audioUp2Js.playbackRate = Number(currMediaData.playbackRate); } setPlaybackRateActiveMenuItem(audioUp2Js.playbackRate); if(resumeTime)audioUp2Js.currentTime = resumeTime; else if(currMediaData.start)audioUp2Js.currentTime = currMediaData.start; if(isIma && !imaStarted){ playerLoader.hide() startloadIma(); }else{ if(autoPlay || resumeTime != null){ var promise = audioUp2Js.play(); if (promise !== undefined) { promise.then(function(){ }).catch(function(error){ bigPlay.show(); playerLoader.hide(); }); } }else{ bigPlay.show(); playerLoader.hide(); } } if(adOn){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } resumeTime = null; if(settings.autoPlayInViewport && !autoPlayInViewportDone)checkViewport(); } else if(settings.resumeTime){//from resume aws audioUp2Js.currentTime = settings.resumeTime; settings.resumeTime = null; } }) .on("play", function(){ playHandler(); }) .on("pause", function(){ pauseHandler(); }) .on("ratechange", function(){ setPlaybackRateActiveMenuItem(audioUp2Js.playbackRate); }) .on("error", function(e){ console.log(e) $(self).trigger("mediaError", {instance:self, instanceName: settings.instanceName, media:currMediaData}); if((currMediaData.origtype == 's3_bucket_audio' || currMediaData.origtype == 's3_audio') && audioUp2Js.error && audioUp2Js.error.message && audioUp2Js.error.message.indexOf('PIPELINE_ERROR_READ') > -1){ if(audioUp2Js.currentTime)settings.resumeTime = audioUp2Js.currentTime resumeAwsUrl(currMediaData) } }); if(autoPlay){ audioUp2Js.load(); } }else if(mediaType == 'video'){ if(currMediaData.posterFrameTime)mediaPath += '#t=' + currMediaData.posterFrameTime; videoReady = false; if(!videoInited){ if(!videoHolder)videoHolder = $('
    ').prependTo(mediaHolder); var np = ' playsinline'; if(settings.useMobileNativePlayer)np = ''; var airplay = '' if(settings.useAirPlay) airplay = 'x-webkit-airplay="allow"'; var disableRemotePlayback = settings.disableRemotePlayback || '' var videoCode = ''; videoHolder.html(videoCode); } videoInited = true; video = videoHolder.find('.mvp-media'); videoUp2Js = video[0]; if(!currMediaData.is360){ videoHolder.show(); }else{ videoHolder.hide(); } if(supportFor360Video && currMediaData.is360){ if(window.location.protocol == 'file:'){ console.log('Playing 360 videos requires online server connection!'); } if(currMediaData.vrMode == 'monoscopic'){ if(!mode360monoscopic_created){//create only once mode360monoscopic_created = true; vrenderer = new THREE.WebGLRenderer({ antialias: true}); vrenderer.setPixelRatio( window.devicePixelRatio ); vrenderer.setSize(vwidth, vheight); vrenderer.domElement.className += 'mvp-canvas-video mvp-canvas-video-m mvp-media'; mediaHolder.prepend($(vrenderer.domElement)); vcanvas = mediaHolder.find('.mvp-canvas-video-m'); //videoUp2Js.crossOrigin = ''; videoTexture = new THREE.Texture(videoUp2Js); /*videoTexture.minFilter = THREE.LinearFilter; videoTexture.magFilter = THREE.LinearFilter; videoTexture.format = THREE.RGBFormat;*/ vscene = new THREE.Scene(); // left var geometry1 = new THREE.SphereGeometry(500, 60, 40); geometry1.scale( - 1, 1, 1 ); var material1 = new THREE.MeshBasicMaterial({map: videoTexture}); var mesh1 = new THREE.Mesh(geometry1, material1); vscene.add(mesh1); if(!cameraCreated){ cameraCreated = true; camera = new THREE.PerspectiveCamera(75, vwidth / vheight, 1, 1100); camera.position.x = camera.position.x + 0.1; if(!vrSupported && isMobile && currMediaData.vrModeOrig == 'stereoscopic' && settings.enablePerspectiveWhenVrNotAvailable){ if(typeof THREE.DeviceOrientationControls !== 'function'){ vcontrols2 = new THREE.DeviceOrientationControls( camera ); }else{ alert('DeviceOrientationControls missing') } } } if(!orbitControlsCreated){ orbitControlsCreated = true; orbitControls = new THREE.OrbitControls(camera, mediaHolder[0]);//https://gist.github.com/mrflix/8351020 orbitControls.enableZoom = false; orbitControls.enableKeys = false; } } } else if(currMediaData.vrMode == 'stereoscopic'){ if(!mode360stereoscopic_created){//create only once mode360stereoscopic_created = true; vrenderer2 = new THREE.WebGLRenderer({ antialias: true}); vrenderer2.setPixelRatio( window.devicePixelRatio ); vrenderer2.setSize(vwidth, vheight); vrenderer2.xr.enabled = true; vrenderer2.xr.setReferenceSpaceType( 'local' ); vrenderer2.domElement.className += 'mvp-canvas-video mvp-canvas-video-s mvp-media'; mediaHolder.prepend($(vrenderer2.domElement)); vcanvas2 = mediaHolder.find('.mvp-canvas-video-s'); videoTexture2 = new THREE.Texture(videoUp2Js); vscene2 = new THREE.Scene(); // left var geometry1 = new THREE.SphereGeometry(500, 60, 40); geometry1.scale( - 1, 1, 1 ); const uvs1 = geometry1.attributes.uv.array; for ( let i = 0; i < uvs1.length; i += 2 ) { uvs1[ i ] *= 0.5; } var material1 = new THREE.MeshBasicMaterial({map: videoTexture2}); var mesh1 = new THREE.Mesh(geometry1, material1); mesh1.rotation.y = - Math.PI / 2; mesh1.layers.set( 1 ); // display in left eye only vscene2.add(mesh1); // right var geometry2 = new THREE.SphereGeometry( 500, 60, 40 ); geometry2.scale( - 1, 1, 1 ); const uvs2 = geometry2.attributes.uv.array; for ( let i = 0; i < uvs2.length; i += 2 ) { uvs2[ i ] *= 0.5; uvs2[ i ] += 0.5; } var material2 = new THREE.MeshBasicMaterial({ map: videoTexture2 }); const mesh2 = new THREE.Mesh(geometry2, material2); mesh2.rotation.y = - Math.PI / 2; mesh2.layers.set( 2 ); // display in right eye only vscene2.add( mesh2 ); if(!camera2Created){ camera2Created = true; camera2 = new THREE.PerspectiveCamera(70, vwidth / vheight, 1, 2000); camera2.layers.enable( 1 ); // render left view when no stereo available if(typeof THREE.DeviceOrientationControls !== 'function'){ vcontrols2 = new THREE.DeviceOrientationControls( camera2 ); }else{ alert('DeviceOrientationControls missing') } } } } } video.on("ended", function(){ mediaEndHandler(); }) .on("loadedmetadata", function(){ /*if(supportFor360Video && currMediaData.is360){ }else{ //MVPAspectRatio.resizeMedia('video', aspectRatio, playerHolder, video); }*/ setTimeout(function(){ if(!videoReady)video.trigger('canplay'); },100); }) .on("canplay", function(){ if(!videoReady){ videoReady = true; if(settings.selectorInit && !unmuteHappened){ volume = initialVolume; unmuteHappened = true; } setVolume(); /*if(supportFor360Video && currMediaData.is360){ }else{ MVPAspectRatio.resizeMedia('video', aspectRatio, playerHolder, video); }*/ if(currMediaData.playbackRate){ videoUp2Js.playbackRate = Number(currMediaData.playbackRate); } setPlaybackRateActiveMenuItem(videoUp2Js.playbackRate); if(resumeTime)videoUp2Js.currentTime = resumeTime; else if(currMediaData.start)videoUp2Js.currentTime = currMediaData.start; if(!isCasting){ if(isIma){ playerLoader.hide() if(autoPlay){ startloadIma(); }else{ if(!currMediaData.poster){ video.addClass('mvp-visible'); bigPlay.show(); }else{ //coming from poster startloadIma() } } }else{ if(autoPlay || resumeTime != null){ var promise = videoUp2Js.play(); if (promise !== undefined) { promise.then(function(){ }).catch(function(error){ bigPlay.show(); playerLoader.hide(); }); } }else{ bigPlay.show(); playerLoader.hide(); } } }else{ if(poster){ posterHolder.show(); setTimeout(function(){ poster.addClass('mvp-visible'); },20); }else if(posterExist){ setPosterForPause() } mediaStarted = true;//needed for seekbar } if(adOn){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } resumeTime = null; if(settings.autoPlayInViewport && !autoPlayInViewportDone)checkViewport(); if(pictureInPictureEnabled || videoUp2Js.webkitSupportsPresentationMode && typeof videoUp2Js.webkitSetPresentationMode === "function")pipToggle.show(); if(previewSeekAuto){ setPreviewSeekVideoSource() } //airplay var hasAirplay if (window.WebKitPlaybackTargetAvailabilityEvent) { videoUp2Js.addEventListener('webkitplaybacktargetavailabilitychanged', function(event) { switch (event.availability) { case "available": airplayToggle.show(); hasAirplay = true; break; case "not-available": airplayToggle.hide(); break; } } ) /*if(hasAirplay){ videoUp2Js.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', function(event) { }) }*/ } } else if(settings.resumeTime){//from resume aws videoUp2Js.currentTime = settings.resumeTime; settings.resumeTime = null; } }) .on("canplaythrough", function(){ if(!isIma)video.addClass('mvp-visible'); //MVPAspectRatio.resizeMedia('video', aspectRatio, playerHolder, video); }) .on("waiting", function(){ if(subMediaType == 'hls' || subMediaType == 'dash'){ //loader sometimes not hiding, possibly other events show it again after seek? }else{ //if(settings.mediaEndAction != 'loop')if(mediaPlaying)playerLoader.show();//do not show preloader on video end, especially if we are in loop mode } }) .on("playing", function(){ playerLoader.hide(); }) .on("play", function(){ playHandler(); }) .on("pause", function(){ if(!(videoUp2Js.currentTime >= videoUp2Js.duration)){ //console.log('calling pause') pauseHandler(); } }) .on("seeking", function(){ //doRender = false; if(mediaPlaying)playerLoader.show(); }) .on("seeked", function(){ playerLoader.hide(); if(supportFor360Video && currMediaData.is360){ doRender = true; } }) .on("ratechange", function(){ setPlaybackRateActiveMenuItem(videoUp2Js.playbackRate); }) .on("error", function(e){ if((currMediaData.origtype == 's3_video')){ if(videoUp2Js.currentTime)settings.resumeTime = videoUp2Js.currentTime if(!mediaStarted)videoReady = false;//for fade in resumeAwsUrl(currMediaData) } switch (e.target.error.code) { case e.target.error.MEDIA_ERR_ABORTED: console.log('You aborted the video playback.'); break; case e.target.error.MEDIA_ERR_NETWORK: console.log('A network error caused the video download to fail part-way.'); break; case e.target.error.MEDIA_ERR_DECODE: console.log('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.'); break; case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED: console.log('The video could not be loaded, either because the server or network failed or because the format is not supported.'); break; default: console.log('An unknown error occurred.'); break; } }); if(subMediaType == 'hls'){ if(hlsSupport){ hls.attachMedia(videoUp2Js); }else if(videoUp2Js.canPlayType('application/vnd.apple.mpegurl') == 'true'){//ios backup videoUp2Js.src = mediaPath; }else if(currMediaData.mp4){//backup videoUp2Js.src = currMediaData.mp4; videoUp2Js.load(); }else{ try{ videoUp2Js.src = mediaPath; videoUp2Js.load(); }catch(er){ alert("This browser or device does not support HLS extension. Please use mp4 video for playback!"); } } }else if(subMediaType == 'dash'){ if(dashSupport){ if(!dashInitialized){ dash.initialize(videoUp2Js, mediaPath, autoPlay); dashInitialized = true; }else{ dash.attachSource(mediaPath); } }else{ if(currMediaData.mp4){//backup videoUp2Js.src = currMediaData.mp4; videoUp2Js.load(); }else{ alert("This browser or device does not support MPEG-DASH extension. Please use mp4 video for playback!"); } } }else{ videoUp2Js.src = mediaPath; videoUp2Js.load(); } } else if(mediaType == 'image'){ if(!imageHolder)imageHolder = $('
    ').prependTo(mediaHolder).hide(); if(currMediaData.is360){ if(window.location.protocol == 'file:'){ console.log('Playing 360 video and images requires online server connection!'); } if(!image360DataCreated){//create only once iscene = new THREE.Scene(); var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 ); // invert the geometry on the x-axis so that all of the faces point inward geometry.scale( - 1, 1, 1 ); itextureLoader = new THREE.TextureLoader(); imaterial = new THREE.MeshBasicMaterial( { map: itextureLoader } ); imesh = new THREE.Mesh( geometry, imaterial ); iscene.add( imesh ); irenderer = new THREE.WebGLRenderer(); irenderer.setPixelRatio( window.devicePixelRatio ); irenderer.setSize( vwidth, vheight ); irenderer.domElement.className += 'mvp-canvas-image mvp-media'; mediaHolder.prepend($(irenderer.domElement)); icanvas = mediaHolder.find('.mvp-canvas-image'); if(!cameraCreated){ cameraCreated = true; camera = new THREE.PerspectiveCamera(90, vwidth / vheight, 0.1, 10000); camera.position.x = camera.position.x + 0.1; } if(!orbitControlsCreated){ orbitControlsCreated = true; orbitControls = new THREE.OrbitControls(camera, mediaHolder[0]);//https://gist.github.com/mrflix/8351020 orbitControls.enableZoom = false; orbitControls.enableKeys = false; } image360DataCreated = true; } itextureLoader.load( // resource URL mediaPath, // Function when resource is loaded function ( texture ) { // do something with the texture icanvas.show(); icanvas.addClass('mvp-visible'); imaterial.map = texture; var w = mediaHolder.width(), h = mediaHolder.height(); irenderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); orbitControls.addEventListener('change', controlsChange); irenderer.render(iscene, camera); mediaStarted = true; mediaPlaying = true;//because of hide interface if(settings.autoRotatePanorama){ orbitControls.autoRotate = true; orbitControls.autoRotateSpeed = settings.autoRotateSpeed; doRender = true; if(renderAnimationID) cancelAnimationFrame(renderAnimationID); renderAnimationID = requestAnimationFrame(renderVideo360); } if(vrInfo){ setTimeout(function(){ vrInfo.show(300); vrInfoVisible = true; },1000) } image360Ready = true; if(currMediaData.duration){ imageStartTime = new Date().getTime(); imageDuration = currMediaData.duration*1000; if(durationTimeoutID)clearTimeout(durationTimeoutID); durationTimeoutID = setTimeout(function() { clearTimeout(this); if(!infoOpened && !shareOpened)mediaEndHandler(); },imageDuration); } }, // Function called when download progresses function ( xhr ) { //console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, // Function called when download errors function ( xhr ) { //console.log( 'An error happened' ); } ); } else{//image playerLoader.show(); $(new Image()).addClass('mvp-media mvp-media-img').prependTo(imageHolder.show()) .on('load',function() { playerLoader.hide(); image = $(this); //MVPAspectRatio.resizeMedia('image', aspectRatio, playerHolder, image); image.addClass('mvp-visible'); mediaStarted = true; mediaPlaying = true;//because of hide interface if(currMediaData.duration){ imageStartTime = new Date().getTime();// so we can display ad seekbar when ad is image imageDuration = currMediaData.duration*1000; if(durationTimeoutID)clearTimeout(durationTimeoutID); durationTimeoutID = setTimeout(function() { clearTimeout(this); if(!infoOpened && !shareOpened)mediaEndHandler(); },imageDuration); } }).on('error',function(e){console.log(e)}).attr({'src': mediaPath, 'alt': mediaPath}); } if(adOn){ //-- ads --// if(currMediaData.duration){ adSeekbar.show(); setTimeout(function(){ adSeekbar.addClass('mvp-visible-fast'); },20); adSeekbarSize = adProgressBg.width(); adControls.find('.mvp-volume-toggle').hide(); adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); if(dataIntervalID){ clearInterval(dataIntervalID); dataIntervalID = null; } dataIntervalID = setInterval(trackProgress, dataInterval); } //-- ads --// }else{ playerControls.css('display','block'); if(idleTimeoutID)clearTimeout(idleTimeoutID); resetIdleTimer(); } } else if(mediaType == 'youtube'){ if(!youtubeInited){ var yt_frameId = 'ytplayer' + Math.floor(Math.random()*0xFFFFFF) youtubeHolder = $('
    ').css('display','block').prependTo(mediaHolder); var yt_sett = { height: '100%', width: '100%', playerVars: { //autoplay: 1, controls: settings.youtubePlayerType == 'chromeless' ? 0 : 1, modestbranding: 1, playsinline: settings.useMobileNativePlayer ? 0 : 1, rel: 0, wmode: 'transparent', iv_load_policy: 3, cc_load_policy: 0, showinfo: 0, disablekb: 1, color: settings.youtubePlayerColor, }, videoId: mediaPath, events: { onReady: onYtPlayerReady, onPlaybackQualityChange: onYtPlayerPlaybackQualityChange, onPlaybackRateChange: onYtPlayerPlaybackRateChange, onStateChange: onYtPlayerStateChange, onError: onYtPlayerError } } // if(settings.youtubeNoCookie)yt_sett.host = '//www.youtube-nocookie.com'; var domain = window.location.href.split("/"), origin = domain[0] + "//" + domain[2]; if(/^http/.test(origin))yt_sett.playerVars.origin = origin; if(resumeTime)yt_sett.playerVars.start = resumeTime; else if(currMediaData.start)yt_sett.playerVars.start = parseInt(currMediaData.start,10); if(currMediaData.end)yt_sett.playerVars.end = parseInt(currMediaData.end,10); if(!window.YT){ var tag = document.createElement('script'); tag.src = settings.youtube_js; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); } var interval = setInterval(function(){ if(window.YT && window.YT.Player){ if(interval) clearInterval(interval); youtubePlayer = new YT.Player(yt_frameId, yt_sett); } }, 100); youtubeInited = true; }else{ if(youtubeReady){ var st = 0; if(resumeTime)st = resumeTime; else if(currMediaData.start)st = currMediaData.start; if(autoPlay){ youtubePlayer.loadVideoById({'videoId':mediaPath, 'startSeconds':st, 'endSeconds': currMediaData.end}); }else{ youtubePlayer.cueVideoById({'videoId':mediaPath, 'startSeconds':st, 'endSeconds': currMediaData.end}); } } } youtubeHolder.show(); } else if(mediaType == 'vimeo'){ //check if video can be chromeless (we need second vimeo instance for this, with and without bg) if(settings.vimeoPlayerType == 'chromeless'){ if(currMediaData.userAccount){ if(currMediaData.userAccount == 'basic'){ activeVimeoPlayerType = 'default'; }else{ activeVimeoPlayerType = 'chromeless'; } }else{ activeVimeoPlayerType = 'chromeless'; } }else{ activeVimeoPlayerType = 'default'; } if(activeVimeoPlayerType == 'default'){ if(!vimeoInitedDefault){ if(!vimeoHolderDefault)vimeoHolderDefault = $('
    ').prependTo(mediaHolder); vimeoIframeDefault = getVimeoParams('0'); vimeoHolderDefault.show().append(vimeoIframeDefault); activeVimeoHolder = vimeoHolderDefault; activeVimeoIframe = vimeoIframeDefault; if(!window.Vimeo){ var tag = document.createElement('script'); tag.src = settings.vimeo_js; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); } var interval = setInterval(function(){ if(window.Vimeo){ if(interval) clearInterval(interval); vimeoPlayerDefault = new Vimeo.Player(vimeoIframeDefault[0]); activeVimeoPlayer = vimeoPlayerDefault; activeVimeoPlayer.on('loaded', onVimLoaded);//do not dispose, needed for every video activeVimeoPlayer.on('play', onVimPlay); activeVimeoPlayer.on('pause', onVimPause); activeVimeoPlayer.on('ended', onVimEnded); activeVimeoPlayer.on('error', onVimError); if(rememberPlaybackPosition){ //we cant wait for promise in unload to get current time activeVimeoPlayer.on('timeupdate', onVimPlayProgress); } vimeoReadyDefault = true; } }, 100); vimeoInitedDefault = true; }else{ activeVimeoHolder = vimeoHolderDefault; activeVimeoIframe = vimeoIframeDefault; activeVimeoPlayer = vimeoPlayerDefault; if(vimeoReadyDefault){ activeVimeoHolder.show(); activeVimeoPlayer.loadVideo(mediaPath); //if(mediaPath == vimeoDefaultLastID){//fix, loaded does not fire if same video? setTimeout(function(){ clearTimeout(this); onVimLoaded(); },500); //} } } //vimeoDefaultLastID = mediaPath; }else{ if(!vimeoInitedChromeless){ if(!vimeoHolderChromeless)vimeoHolderChromeless = $('
    ').prependTo(mediaHolder); vimeoIframeChromeless = getVimeoParams('1'); vimeoHolderChromeless.show().append(vimeoIframeChromeless); activeVimeoHolder = vimeoHolderChromeless; activeVimeoIframe = vimeoIframeChromeless; if(!window.Vimeo){ var tag = document.createElement('script'); tag.src = settings.vimeo_js; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); } var interval = setInterval(function(){ if(window.Vimeo){ if(interval) clearInterval(interval); vimeoPlayerChromeless = new Vimeo.Player(vimeoIframeChromeless[0]); activeVimeoPlayer = vimeoPlayerChromeless; activeVimeoPlayer.on('loaded', onVimLoaded);//do not dispose, needed for every video activeVimeoPlayer.on('play', onVimPlay); activeVimeoPlayer.on('pause', onVimPause); activeVimeoPlayer.on('ended', onVimEnded); activeVimeoPlayer.on('error', onVimError); activeVimeoPlayer.on('seeking', onVimSeeking); activeVimeoPlayer.on('seeked', onVimSeeked); if(activeVimeoPlayerType == 'chromeless'){ activeVimeoPlayer.on('playbackratechange', onVimPlaybackRateChange); activeVimeoPlayer.on('timeupdate', onVimPlayProgress); } vimeoReadyChromeless = true; } }, 100); vimeoInitedChromeless = true; }else{ activeVimeoHolder = vimeoHolderChromeless; activeVimeoIframe = vimeoIframeChromeless; activeVimeoPlayer = vimeoPlayerChromeless; if(vimeoReadyChromeless){ activeVimeoHolder.show(); activeVimeoPlayer.loadVideo(mediaPath); //if(mediaPath == vimeoChromelessLastID){ setTimeout(function(){ clearTimeout(this); onVimLoaded(); },500); //} } } //vimeoChromelessLastID = mediaPath; } } else if(mediaType == 'custom'){//external file playerLoader.show(); if(!customHolder)customHolder = $('
    ').prependTo(mediaHolder); customHolder.show().load(mediaPath, function(response, status, xhr) { if(status == "error"){ console.log(xhr.status + " " + xhr.statusText); }else if(status == "success"){ customHolder.addClass('mvp-visible'); playerLoader.hide(); mediaStarted = true; } }); playerControls.css('display','none').removeClass('mvp-player-controls-visible'); interfaceHidden = true; }else if(mediaType == 'custom_html'){//direct html playerLoader.show(); if(!customHolder)customHolder = $('
    ').prependTo(mediaHolder); var ch = playlistList.find($('#'+mediaPath)).html()//find element that holds custom html customHolder.html(ch).show().addClass('mvp-visible'); playerLoader.hide(); mediaStarted = true; playerControls.css('display','none').removeClass('mvp-player-controls-visible'); interfaceHidden = true; } if(!qualityChange && !setMediaInformationDone)setMediaInformation();//this is called after poster loads if poster exist } function setMediaInformation(){ if(adOn){ $(self).trigger("adRequest", {instance:self, instanceName: settings.instanceName, media: currMediaData}); }else{ setMediaInformationDone = true; //TODO: since only main media uses this data (not adverts), create this data in counter ready and only dispose there, not in clean media (maybe ads will have the same features once like subs, annotations?) //-- annotations --// if(annotationSection){ var ai = 0; annotationSection.find(".mvp-annotation").each(function(){ var item = $(this).clone().attr('data-id', ai).appendTo(annotationHolder); if(item.hasClass('mvp-adsense-detail')){ var ads = ''; $(ads).prependTo(item); hasAdSense = true; }else if(item.hasClass('mvp-adsense-code')){ hasAdSense = true; } annotationArr.push({ id:ai, start:!isNaN(parseInt(item.attr('data-show'),10)) ? parseInt(item.attr('data-show'),10) : 0, end:!isNaN(parseInt(item.attr('data-hide'),10)) ? parseInt(item.attr('data-hide'),10) : 1000000, item: item }); ai++; }); annotationHolder.show(); if(hasAdSense){ if(typeof adsbygoogle === 'undefined'){ if(window.location.protocol != 'file:'){ var script = document.createElement('script'); script.type = 'text/javascript'; if(!MVPUtils.relativePath(settings.adsbygoogle_js))var src = MVPUtils.qualifyURL(settings.sourcePath+settings.adsbygoogle_js); else var src = settings.adsbygoogle_js; script.src = src; script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'complete'){ annotationHolder.find(".adsbygoogle").each(function(){ (adsbygoogle = window.adsbygoogle || []).push({}); }); } }; script.onerror = function(){ console.log("Error loading " + this.src); } var tag = document.getElementsByTagName('script')[0]; tag.parentNode.insertBefore(script, tag); } }else{ annotationHolder.find(".adsbygoogle").each(function(){ (adsbygoogle = window.adsbygoogle || []).push({}); }); } } } if(mediaType == 'audio' || mediaType == 'video' || mediaType == 'youtube' && settings.youtubePlayerType == 'chromeless' || mediaType == 'vimeo' && activeVimeoPlayerType == 'chromeless'){ //subtitles if(currMediaData.subtitles){ subtitlesReady = false; buildSubtitleMenu(); }else{ subtitlesReady = true; } //chapters if(currMediaData.chapters){ chaptersReady = false; getChapters(); seekbar.addClass('mvp-seekbar-chapters');//for hover seekbar }else{ chaptersReady = true; } //preview seek if(!isMobile && currMediaData.previewSeek){ if(currMediaData.previewSeek == 'auto' && mediaType == 'video'){ previewSeekReady = true; previewSeekAuto = true; //if(!previewSeekVideoInited){ initPreviewSeekVideo() //previewSeekVideoInited = true; /// } }else{ previewSeekReady = false; getPreviewSeek(); } }else{ previewSeekReady = true; previewSeekAuto = false; } } //up next auto screen if(settings.mediaEndAction != 'loop' && settings.upNextTime && !upNextClosed){ var nc = _MVPPlaylistManager.getNextCounter(1); if(typeof nc !== 'undefined'){ var next_data = playlistDataArr[nc].data; if(next_data.thumb || next_data.title){ if(next_data.thumb)upnextThumb.css({'background-image': 'url(' + encodeURI(next_data.thumb) + ')', 'display': 'block'}); else upnextThumb.css('display','none'); if(next_data.title)upnextTitle.html(next_data.title); if(next_data.duration)upnextDuration.show().html(MVPUtils.formatTime(next_data.duration)); else upnextDuration.hide().html('') upnextWrap.addClass('mvp-upnext-on'); } } } //title if(currMediaData.title){ playerTitle.html(currMediaData.title); infoToggle.show(); //video title if(settings.showVideoTitle){ videoTitle.html(currMediaData.title).addClass('mvp-visible'); } } //description if(currMediaData.description){ playerDesc.html(currMediaData.description); infoToggle.show(); } //download if(hasDownloadSupport && currMediaData.download){ if((settings.restrictDownloadForLoggedInUser && !settings.isUserLoggedIn) || !allowedDownloadVideoUserRole){ downloadToggle.show(); }else{ downloadToggle.show().find('a').attr({href: currMediaData.download, download: ''}); } } //show elements if(mediaType == 'audio' || mediaType == 'video' || mediaType == 'youtube' && settings.youtubePlayerType == 'chromeless' || mediaType == 'vimeo' && activeVimeoPlayerType == 'chromeless'){ if(currMediaData.liveStream){ mediaTimeCurrent.hide(); mediaTimeSeparator.hide(); mediaTimeTotal.hide(); seekbar.hide(); liveNote.show(); }else{ mediaTimeCurrent.show(); mediaTimeSeparator.show(); mediaTimeTotal.show(); seekbar.show(); } playbackToggle.show(); volumeWrapper.show(); settingsWrap.show(); skipBackwardToggle.show(); skipForwardToggle.show(); rewindToggle.show(); if(mediaType == 'audio' || mediaType == 'hls' || mediaType == 'video'){ if(castSupported){ if(_MVPCast){ _MVPCast.checkCastState() }else{ var interval = setInterval(function(){ if(_MVPCast){ clearInterval(interval); _MVPCast.checkCastState() } },500); } } } }else{ //image playbackToggle.hide(); volumeWrapper.hide(); mediaTimeCurrent.hide(); mediaTimeSeparator.hide(); mediaTimeTotal.hide(); seekbar.hide(); settingsWrap.hide(); skipBackwardToggle.hide(); skipForwardToggle.hide(); rewindToggle.hide(); } } } //############################################// /* youtube */ //############################################// window.onYouTubeIframeAPIReady = function() {} function onYtPlayerReady(event) { youtubeReady = true; if(!youtubeIframe){ youtubeIframe = youtubeHolder.find('.mvp-emiframe'); if(settings.youtubePlayerType == 'chromeless' && settings.forceYoutubeChromeless)youtubeIframe.addClass('mvp-yt-clean'); } youtubeIframe.addClass('mvp-visible'); if(settings.selectorInit && !unmuteHappened){ volume = initialVolume; unmuteHappened = true; } setVolume(); if(autoPlay){ youtubePlayer.playVideo(); }else{ if(resumeTime != null || currMediaData.poster){//if coming from poster youtubePlayer.playVideo(); } youtubeIframe.addClass('mvp-visible'); } if(adOn){ if(settings.youtubePlayerType == 'chromeless'){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } } if(settings.autoPlayInViewport && !autoPlayInViewportDone)checkViewport(); } function onYtPlayerPlaybackQualityChange(event) { setQualityActiveMenuItem(event.data); } function onYtPlayerPlaybackRateChange(event) { setPlaybackRateActiveMenuItem(event.data); } function onYtPlayerStateChange(event) { if(!youtubeHolder.is(":visible"))return; if(event.data == -1){//unstarted if(adOn){ if(settings.youtubePlayerType == 'chromeless'){ adControls.show(); setTimeout(function(){ adControls.addClass('mvp-visible-fast'); },20); } } } else if(event.data == 0){//ended mediaEndHandler(); } else if(event.data == 1){//playing if(!youtubeStarted){ resumeTime = null; if(currMediaData.playbackRate && currMediaData.playbackRate != 1){ youtubePlayer.setPlaybackRate(Number(currMediaData.playbackRate)); }else{ if(settings.youtubePlayerType == 'chromeless')setPlaybackRateActiveMenuItem(1); } if(settings.blockYoutubeEvents){ if(!youtubeBlocker){//transparent div over yt iframe (+ hide right click, - cannot close yt ads) youtubeBlocker = $('
    ').css('display','block').appendTo(youtubeHolder); } } youtubeStarted = true; } if(youtubeBlocker && !currMediaData.is360)youtubeBlocker.css('display','block');//hide for 360 videos playHandler(); youtubePlayed = true; } else if(event.data == 2){//paused //if(youtubeBlocker)youtubeBlocker.css('display','none'); pauseHandler(); } else if(event.data == 3){//buffering youtubeIframe.addClass('mvp-visible'); } else if(event.data == 5){//cued if(!autoPlay){ youtubeIframe.addClass('mvp-visible'); } } } function onYtPlayerError(e) { switch(e.data){ case 2: console.log("Error code = "+e.data+": The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.") break; case 100: console.log("Error code = "+e.data+": Video not found, removed, or marked as private") break; case 101: console.log("Error code = "+e.data+": Embedding disabled for this video") break; case 150: console.log("Error code = "+e.data+": Video not found, removed, or marked as private [same as error 100]") break; } } //############################################// /* vimeo */ //############################################// function getVimeoParams(bg){ var color = MVPUtils.rgbToHex(settings.vimeoPlayerColor); if(color.charAt(0) == '#')color = color.substr(1); var np = '1'; if(settings.useMobileNativePlayer)np = '0'; var iap = autoPlay ? '1' : '0'; var loop = settings.mediaEndAction == 'loop' ? '1' : '0'; //https://developer.vimeo.com/apis/oembed //https://github.com/vimeo/player.js //https://help.vimeo.com/hc/en-us/articles/360001494447-Using-Player-Parameters var vim_frameId = 'player'+Math.floor(Math.random()*0xFFFFFF), color = '?color=' + color, byline = '&byline=1', portrait = '&portrait=1', title = '&title=1', autopause = '&autopause=1', loop = '&loop='+loop, playsinline = '&playsinline='+np, dnt = '&dnt=1', muted = '&muted=0', ap = '&autoplay='+iap, speed = '&speed=1',//pro background = '&background='+bg//plus+ /* background bugs: 1. 360 video cannot be panned, https://github.com/vimeo/player.js/issues/287 2. click not detected as above, we have to use blocker 3. set playback rate does no work, https://github.com/vimeo/player.js/issues/195 4. with autoplay true, force muted autoplay false, it makes play, then 2x pause events which show our controls volume: https://github.com/vimeo/player.js/issues/236 */ if(autoPlay){ //muted = '&muted=1'; if(settings.autoPlayInViewport){ ap = '&autoplay=0'; }else{ ap = '&autoplay=1'; ap = true; } //setVolume(); } if(mediaPath.indexOf('/')>-1)mediaPath = mediaPath.substr(0,mediaPath.indexOf('/'));//unlisted var iframeSrc = 'https://player.vimeo.com/video/' + mediaPath + color + byline + portrait + title + autopause + playsinline + loop + dnt + background + speed + muted + ap; if(settings.vimeoNoCookie)iframeSrc += '&dnt=1'; if(currMediaData.quality)iframeSrc += '&quality='+currMediaData.quality;//https://help.vimeo.com/hc/en-us/articles/224983008-Setting-default-quality-for-embedded-videos var iframe = $('