NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Spiegel Online Video Ad remover // @description Entfernt die Videowerbung vor einem Clip auf Spiegel-Online // @include http* // @grant none // @version 2.08 // @namespace https://greasyfork.org/users/16149 // ==/UserScript== var scriptCode = new Array(); scriptCode.push('function spStartVideo6(wrapperElemId, videoId, videoFilename, poster, prerollGateway, postrollGateway, allowAds, credit, displaycat, videocat, server, trackingsize, autoplay, onAdStart, onAdEnd, onVideoEnd, onFinalEnd, embedWidth, embedHeight) { spStartVideo({ wrapperElemId: wrapperElemId, videoId: videoId, videoFilename: videoFilename, poster: poster, prerollGateway: "", postrollGateway: "", allowAds: false, credit: credit, displaycat: displaycat, videocat: videocat, server: server, trackingsize: trackingsize, autoplay: autoplay, callbacks: { /* spStartVideo6 sets callback functions by name inside string - convert them to real JS functions*/ onAdStart: window[onAdStart], onAdEnd: window[onAdEnd], onVideoEnd: window[onVideoEnd], onFinalEnd: window[onFinalEnd] }, embedWidth: embedWidth, embedHeight: embedHeight });} function spStartVideo(config) { /*alert("startVideoGM");*//* set config param defaults */ var defaults = { prerollGateway: \'\', postrollGateway: \'\', overlayGateway: \'\', overlayStartAt: 7, allowAds: false, autoplay: true, callbacks: {}, embedWidth: 640, embedHeight: 360 }; config = $.extend({}, defaults, config); /* special hash param switches to affect ads & statistics */ var hashParams = (typeof spGetHashParams === \'function\' ? spGetHashParams() : []); /* extra ref parameter for statistics */ var refParam = hashParams.ref !== null ? hashParams.ref : \'\'; /* deactivating ads, also possible through ADI */ if (true) { config.prerollGateway = ""; config.postrollGateway = ""; config.overlayGateway = ""; config.allowAds = false; config.callbacks = {}; } /* get ABD (ad-block detection) status - if function is not defined we\'re likely in an Iframe, so let\'s use the SPON interface in that case */ var abd = false; /*(!window.spGetAbdStatus && spInterface) ? spInterface(\'getAbdStatus\') : spGetAbdStatus();*/ var wrapperElem = $(\'#\' + config.wrapperElemId); var html5PlayerWrapperId = wrapperElem.find(\'.videoplayer-placeholder\').attr(\'id\'); if (!html5PlayerWrapperId) { /* assign an ID to player wrapper element, because JW player needs an ID for setup */ var playerIdCount = 1; /* make sure the ID doesn\'t exist yet */ while ($(\'#spVideoplayer-\' + playerIdCount).length) playerIdCount++; html5PlayerWrapperId = \'spVideoplayer-\' + playerIdCount; wrapperElem.find(\'.videoplayer-placeholder\').attr(\'id\', html5PlayerWrapperId); } if ((spUA.isIDevice() || spUA.isAndroid()) && parseInt(config.videoId) < 58671) { /* this video is limited to desktop */ wrapperElem.find(\'.video-player-error\') .html(unescape(\'Dieses Video steht f%FCr iOS- %26 Android-Ger%E4te nicht zur Verf%FCgung.\')) /* work around encoding-problems with umlauts... */ .show(); } else if (!document.createElement(\'video\').canPlayType && !isValidPluginVersion()) { /* no HTML5 video possible & Flash version not sufficient for fallback play */ var fpversion = swfobject.getFlashPlayerVersion(); wrapperElem.find(\'.video-player-error\') .html(unescape(\'Dieses Video ben%F6tigt mindestens Version \') + sp_webcfg_global.flash.pluginversion.major + \'.\' + sp_webcfg_global.flash.pluginversion.minor + \' des Flash-Plugins. Gefundene Version: \' + fpversion.major + \'.\' + fpversion.minor + \'.\' + fpversion.release + \' \' + spnetENV_NOFLASHPLAYER_LINK) .show(); } else { /* make sure a filname is provided (note: JW Player can only play videofiles directly, no video ID HTML redirect possible) */ if (config.videoFilename === null || config.videoFilename === \'\') return; /* set generic player options */ jwplayer.key = spnetENV_JWPLAYER_KEY; var jwplayerOptions = { flashplayer: \'/static/flash/flashvideo/jwplayer7.flash.swf\', primary: \'flash\', image: config.poster, width: config.embedWidth, height: config.embedHeight, autostart: config.autoplay, ga: {}, /* enable Google Analytics, uses the GA JS already on the page */ skin: { name: \'spon\' } }; /* read cookie for HQ/SQ */ var qualityCookieName = \'sponVideoplayerQuality\'; var playerQuality = \'hq\'; if ($.cookie(qualityCookieName)) playerQuality = $.cookie(qualityCookieName); else $.cookie(qualityCookieName, playerQuality, { expires: 365, path: \'/\' }); /* set video sources */ if (typeof config.videoFilename == \'object\') { jwplayerOptions.sources = []; /* check all quality levels that we\'re expecting */ $.each([\'sq\', \'hq\'], function(i, quality) { if (config.videoFilename[quality] !== \'\') { var sourceInfo = {file: config.server + config.videoFilename[quality]}; /* set this quality as default if quality read from cookie matches */ if (playerQuality == quality) sourceInfo[\'default\'] = true; jwplayerOptions.sources.push(sourceInfo); } }); } else { /* legacy: videoFilename is a single string */ jwplayerOptions.file = config.server + config.videoFilename; } /* instantiate player */ var jwplayerInstance = jwplayer(html5PlayerWrapperId).setup(jwplayerOptions); jwplayerInstance.on(\'ready\', function() { var playerElem = $(\'#\' + this.id); /* store player instance from JW Player setup for future reference (i.e. removing player) */ playerElem.data(\'playerInstance\', jwplayerInstance); /* detect if we\'re on a touch device */ var touchabilityClass = \'jw-\'+(\'ontouchstart\' in document.createElement(\'div\') ? \'\' : \'un\')+\'touchable\'; playerElem.addClass(touchabilityClass); /* detect if we\'re inside an iframe */ var isInIframe = window.parent != window.self; /* get video data */ var videoData = playerElem.parents(\'.video-elements\').data(); /* move duration display over to left group */ playerElem.find(\'.jw-text-duration\').detach().appendTo(playerElem.find(\'.jw-controlbar-left-group\')); /* hover handler for icons, cause JW Player has a bug when keeping controls open (won\'t happen on hover for dock icons) */ playerElem.on(\'mouseenter\', \'.jw-icon\', function() { playerElem.addClass(\'jw-flag-icon-hover\'); }); playerElem.on(\'mouseleave\', \'.jw-icon\', function() { playerElem.removeClass(\'jw-flag-icon-hover\'); }); /* add left dock with info button & addtional text */ playerElem.find(\'.jw-dock\').append(\'<div class="jw-dock-left jw-reset"></div>\'); playerElem.find(\'.jw-dock-left\').append(\'<div class="jw-icon jw-icon-info jw-button-color"></div>\'); var infoWindow = \'<div class="jw-infowindow">\'+ \'<a class="jw-spon-logo" href="/"\'+(isInIframe ? \' target="_blank"\' : \'\')+\'><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA8CAIAAABZ6yszAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABAdJREFUeNrsmL9PU1EUxymKAw7UwcVE2sWFaOgfYEKdxaSDiyxtR3WgmzK13WDr5ki7wKADiTpbEpx0aKOyuLSaOOhga6IhYcBPe/R4Oe+9UgqJNLnfvDTv3nt+3O/5ce+D2NOJ+MQ4Y3JizOEJeAKegCfgCXgCnoAn4Al4Av8P5834SuZ2PHVDhx8rT/Y73bnSYyPGJEu8uEvt6kYitxT08av1qVXdmIrPXCvc18lO492XrZfGgovd0moytzSdnJXht/oOT4gcf9Do8yb34OAwcMP8QRjYk1mqpxdDJb/Wd5DElJnHXZRxwBKKOvxQWnW3qs+hEpL4tWubu+U1fnmfmb/eY7/9er/7oxfL9mfeu833PeHsvV6cymt/wl/bJNLukHeE1biYYlLnxZ1REb+aUjzKBsLDH9oDhJb08asz2+lF4idLvDcKK26iVesnBJwh70GvTJp5o+L6FZuD6ifYA26Nbt+6c8IOI4Q4pmGGnB/BbwiBhVfP3eGz2CV9p6sup29eiM8caVeNkH2SpvOoRy1FzR+bwABMJ67yyPvb/MMzd4xGhepf6mubUqNkX7oiCpRBaNUySUo5OueKj4ZUccGuxEh4Ey/UX9w9+B51MANaSvpp8O4VmMIgZoePKFtEhSeqMk1Yx/4mPnSRuRfHkBfK8BdZ1Hyo06BfsxR+kTULK3JhKU6xU40pHDWd+2RkxMz/Ri8mZ/XzQzuVr6Opv0cn161cLmcEsXH/5+7Y41zUQjqdTiaTvbu90zFL8Xh8b2/vVNyPYMqoTAaXK5VKo9HIZDJw2NraarVavKtAKpWq1+uIGbaocD4UCgUZQpsh6q4Yq71P9E4HAZlBIJfLmT1Uq1XEMBjvA5ne13urhV90WR3EDzUjgQP0S6WS7lWtGzF86BB5xELtqynAnhALcjBR0w3gVGIUngGEkDDm4FOr1YrFolRU74Oi3Z6fnzd5aPVxZAEEC7Lb7a6vr7vbFWtBSVGnQCIJsHWTdIHoKDGs5/N5OBhbowGzzWaTMFGcJ/2YSyQSobzJu1S/mxZ+iZxLbDRIS9T7kF6KOlQoEKqA8LlFOHksT6a0yuVyNps9oquGsywlBIeoPGgTm0K1fw9ooUflwfQM8nAQ6yfhgAXJAzUcykFcBA/AQwRoViKBhAm2hCe0PaR+aHFjdwQQIK2l4QvBnkKSR3c3vDNPtWjuggcozJeXlwd41bNvQIaVAzKcEAOaflAYSJ8ciLjElpzubtPIZaQ3kdsSGjkYygHPJLr86jEgd4jQkI5k1bBCzL3syL9olfowGYiF0kBHClEqz429FigWg5UmZZbsw1QwQFeyhyLqOgzeIRJHsW+CJbr+I9DDw8PDw8PDw8PDY/zxW4ABADOl37fKzRkIAAAAAElFTkSuQmCC"/></a>\'+ \'<div class="jw-info-title">\'+videoData.videoTitle+\'</div>\'+ \'<div class="jw-info-text">\'; if (videoData.videoTeaser && videoData.videoTeaser !== \'\') infoWindow += \'<p>\'+videoData.videoTeaser+\'</p>\'; if (videoData.videoArticleUrl && videoData.videoArticleUrl !== \'\') infoWindow += \'<a href="\'+videoData.videoArticleUrl+\'">Zum Artikel</a>\'; infoWindow += \'<span class="jw-info-date">\'+videoData.videoDate+\'</span>\'+ \'</div>\'+ \'</div>\'; playerElem.find(\'.jw-dock-left\').append(infoWindow); /* click handler for info window */ playerElem.on(\'click touchstart\', \'.jw-icon-info\', function() { $(this).add(playerElem.find(\'.jw-infowindow\')).toggleClass(\'jw-open\'); playerElem.toggleClass(\'jw-flag-infowindow-open\'); }); /* add separate area for right dock */ playerElem.find(\'.jw-dock\').append(\'<div class="jw-dock-right jw-reset"></div>\'); /* add share buttons */ playerElem.find(\'.jw-dock-right\').append(\'<div class="jw-icon jw-icon-share jw-button-color"></div>\'); playerElem.find(\'.jw-dock-right\').append(\'<div class="jw-shares"></div>\'); playerElem.find(\'.jw-shares\').append(\'<div class="jw-icon jw-icon-share-facebook jw-button-color"></div>\'); playerElem.find(\'.jw-shares\').append(\'<div class="jw-icon jw-icon-share-twitter jw-button-color"></div>\'); playerElem.find(\'.jw-shares\').append(\'<div class="jw-icon jw-icon-share-googleplus jw-button-color"></div>\'); playerElem.find(\'.jw-shares\').append(\'<div class="jw-icon jw-icon-share-mail jw-button-color"></div>\'); playerElem.find(\'.jw-shares\').append(\'<div class="jw-icon jw-icon-share-link jw-button-color"></div>\'); /* copy share buttons to endscreen */ playerElem.parent().find(\'.video-end-screen .sharebuttons-placeholder\').replaceWith( $(\'<div class="jw-skin-spon \' + touchabilityClass + \'"><div class="jw-dock"></div></div>\') ); playerElem.parent().find(\'.video-end-screen .jw-dock\').append(playerElem.find(\'.jw-dock-right\').clone()); playerElem.parent().find(\'.video-end-screen .jw-icon-share, .video-end-screen .jw-shares\').addClass(\'jw-open\'); /* click handlers for share buttons */ playerElem.on(\'click touchstart\', \'.jw-icon-share\', function() { $(this).add(playerElem.find(\'.jw-shares\')).toggleClass(\'jw-open\'); }); /* handler for actual shares has to be one element up, so that share buttons in endscreen are detected as well */ playerElem.parent().on(\'click touchstart\', \'.jw-shares .jw-icon\', function() { /* social media shares just open their respective share URLs inside new popup */ if ($(this).hasClass(\'jw-icon-share-facebook\')) window.open(\'https://www.facebook.com/sharer/sharer.php?u=\'+videoData.videoSocialUrl+\'&display=popup&ref=plugin&src=share_button\', \'spon-share\', \'top=150,left=200,toolbar=0,status=0,width=670,height=335\'); if ($(this).hasClass(\'jw-icon-share-twitter\')) window.open(\'https://twitter.com/intent/tweet?original_referer=\'+videoData.videoSocialUrl+\'&ref_src=twsrc%5Etfw&text=\'+videoData.videoTitle+\'&tw_p=tweetbutton&url=\'+videoData.videoShortUrl+\'&via=SPIEGELONLINE\', \'spon-share\', \'top=150,left=200,toolbar=0,status=0,width=550,height=420\'); if ($(this).hasClass(\'jw-icon-share-googleplus\')) window.open(\'https://plus.google.com/share?url=\'+videoData.videoSocialUrl+\'&hl=\'+videoData.videoLanguage, \'spon-share\', \'top=150,left=200,toolbar=0,status=0,width=550,height=420\'); /* mail & embed/URL shares may have to use parent methods if inside iframe (inline player or framework player inside iframe) */ if ($(this).hasClass(\'jw-icon-share-mail\')) if ($(\'#video-inline-player\').length || ($(this).parents(\'.videoplayer-framework\').length && isInIframe)) parent.spOpenSendForm(\'de\', \'video\', null, {videoId: config.videoId}); else spOpenSendForm(\'de\', \'video\'); if ($(this).hasClass(\'jw-icon-share-link\')) { if ($(\'#video-inline-player\').length || ($(this).parents(\'.videoplayer-framework\').length && isInIframe)) parent.spOpenEmbedForm(config.videoId, videoData.videoEmbeddable); else spOpenEmbedForm(config.videoId, videoData.videoEmbeddable); } }); /* flags to make sure that tracking is happening only once */ playerElem.data({ startTracked: false, endTracked: false }); }); /* define function for Netmind tracking (depends on whether we\'re in an Iframe or on a normal page) */ var doNmTracking = function(trackingParams) { /* modify default tracking params by the ones passed to this function */ trackingParams = $.extend({ \'sp.atyp\': 33, \'sp.videocredit\': config.credit, \'sp.df\': config.trackingsize, \'sp.videodisplaycatid\': config.displaycat, \'sp.videocatid\': config.videocat, \'sp.aid\': config.videoId, \'sp.channel\': 781 }, trackingParams); if (!window.spNmAjax && spInterface) spInterface(\'reCountPage\', {newParamsOnly: true, params: trackingParams}); else spNmAjax(trackingParams); }; var doTrackEnd = function() { doNmTracking({ \'sp.site\': 1001, \'sp.event\': \'end\' }); if (typeof config.callbacks.onVideoEnd === \'function\') config.callbacks.onVideoEnd(); }; /* callback for start of video */ jwplayerInstance.on(\'play\', function() { var playerElem = $(\'#\' + this.id); /* move HD button over to dock, each time a new video plays - because JW Player puts it back into the controlbar on each new video */ playerElem.find(\'.jw-icon-hd\').detach().prependTo(playerElem.find(\'.jw-dock-right\')); /* only track once! onPlay fires every time the player state switches to PLAYING (= also when unpausing the video) */ /* onPlay does NOT fire on preroll - howevery this is desired, cause we want to track the actual content video */ if (!playerElem.data(\'startTracked\')) { playerElem.data(\'startTracked\', true); doNmTracking({ \'ref\': refParam, \'sp.site\': 1, \'sp.abd\': abd }); /* also track usage of SQ quality */ if (playerQuality == \'sq\') { doNmTracking({ \'sp.site\': 1001, \'sp.videoquality\': \'sq\' }); } } }); /* callback for end of video (fires AFTER end of postroll, if there is one!) */ jwplayerInstance.on(\'complete\', function() { var playerElem = $(\'#\' + this.id); /* if video end hasn\'t been tracked before (= if there is no postroll), track it now */ if (!playerElem.data(\'endTracked\')) doTrackEnd(); if (typeof config.callbacks.onFinalEnd === \'function\') config.callbacks.onFinalEnd(); }); jwplayerInstance.on(\'adImpression\', function(e) { var playerElem = $(\'#\' + this.id); /* always hide the dock & shares */ playerElem.find(\'.jw-icon-share, .jw-shares\').removeClass(\'jw-open-forced\'); playerElem.find(\'.jw-dock, .jw-controlbar\').removeAttr(\'style\'); /* if we\'re at postroll start: track main content video end, because onComplete fires after postroll */ if (e.adposition == \'post\') { /* if endscreen is present, hide share buttons cause they don\'t really make sense after a postroll */ wrapperElem.find(\'.video-end-screen\').addClass(\'jw-after-postroll\'); /* make sure we don\'t track the video-end again on completion of postroll (which is when the JW Player "onComplete" fires) */ playerElem.data(\'endTracked\', true); doTrackEnd(); } if (typeof config.callbacks.onAdStart === \'function\') config.callbacks.onAdStart(); }); jwplayerInstance.on(\'adComplete\', function() { if (typeof config.callbacks.onAdEnd === \'function\') config.callbacks.onAdEnd(); }); jwplayerInstance.on(\'time\', function(player) { var playerElem = $(\'#\' + this.id); /* force display of controls, dock & shares when in last part of video */ if (player.position > player.duration - 3) { playerElem.find(\'.jw-icon-share, .jw-shares\').addClass(\'jw-open-forced\'); playerElem.find(\'.jw-dock, .jw-controlbar\').show(); } else { playerElem.find(\'.jw-icon-share, .jw-shares\').removeClass(\'jw-open-forced\'); playerElem.find(\'.jw-dock, .jw-controlbar\').removeAttr(\'style\'); } }); jwplayerInstance.on(\'levelsChanged\', function(e) { /* track a change in quality when HQ/SQ is clicked */ var playerQuality = e.currentQuality == 1 ? \'hq\' : \'sq\'; $.cookie(qualityCookieName, playerQuality, { expires: 365, path: \'/\' }); /* when switching to SQ we have to track explicitly, because the JW "onPlay" 1st tracking point was already fired */ if (playerQuality == \'sq\') { doNmTracking({ \'sp.site\': 1001, \'sp.videoquality\': \'sq\' }); } }); /* callback for errors, to display user-friendly info */ jwplayerInstance.on(\'error setupError\', function(e) { $(\'#\' + this.id).hide(); var hasGeoBlocking = $(\'.video-player\').hasClass(\'video-player-geoblocking\'); var errorText = hasGeoBlocking ? unescape(\'Dieses Video ist leider an Ihrem Standort nicht verf%FCgbar.\') : unescape(\'Leider steht f%FCr dieses Video keine auf Ihrem Ger%E4t abspielbare Datei zur Verf%FCgung.\'); wrapperElem.find(\'.video-player-error\') .html(errorText) .show(); }); /* click handler for video end screen "replay" button (handler on parent, watching for end screen selector, */ /* cause in case of video component player, where end screen is loaded asynchronously) */ wrapperElem.on(\'click touchstart\', \'.video-end-screen .watch-video-again\', function(e) { e.preventDefault(); spToggleEndScreen(config.wrapperElemId); spRestartVideo(config.wrapperElemId); }); }}'); // now, we put the script in a new script element in the DOM var script = document.createElement('script'); // create the script element script.innerHTML = scriptCode.join('\n'); // add the script code to it scriptCode.length = 0; // recover the memory we used to build the script // this is sort of hard to read, because it's doing 2 things: // 1. finds the first <head> tag on the page // 2. adds the new script just before the </head> tag document.getElementsByTagName('head') [0].appendChild(script);