NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name YouTube Adfriend // @description Gain control/personalize your advertisement experience on YouTube. // @namespace Ryunigia // @author Ryunigia // @homepage http://glennmoreels.eu/ // @icon https://image.flaticon.com/icons/png/128/174/174883.png // @include http://www.youtube.com/* // @include https://www.youtube.com/* // @exclude https://www.youtube.com/embed/* // @exclude http://www.youtube.com/embed/* // @exclude https://www.youtube.com/user/* // @exclude http://www.youtube.com/user/* // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js // @require https://gist.github.com/raw/2625891/waitForKeyElements.js // @version 0.781 // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @license MIT // ==/UserScript== var AdVolumeMultiplier = GM_getValue("SoundMultiplier", 0.07); var CountDownSeconds = GM_getValue("MovieCountDown", 4); var CurrentCountDownSeconds = CountDownSeconds; var BannerCountDownSeconds = GM_getValue("BannerCountDown", 12); var CurrentBannerCountDownSeconds = BannerCountDownSeconds; var BannerOpaque = GM_getValue("BannerOpacity", 0.4); var AddSubscriberNoBlock = GM_getValue("AddSubscriberNoBlock", false); var oldVolume = 0.5; var UIContainer; var skipContainer; var closeContainer; var video; var button; var InputBox; var SkipBannerInputBox; var SoundInputBox; var OpacityInputBox; var AddSubscriberNoBlockInputBox; // only when add var videoClassName = ".html5-main-video"; // skip var videoAddSkippContainerClassName_Try1 = ".videoAdUiSkipContainer"; var videoAddSkippContainerClassName_Try2 = ".ytp-ad-skip-button-container"; var videoAddSkippContainerClassName = videoAddSkippContainerClassName_Try1; var videoAddSkippClassName_Try1 = ".videoAdUiSkipButton"; var videoAddSkippClassName_Try2 = ".ytp-ad-skip-button"; var videoAddSkippClassName = videoAddSkippClassName_Try1; // UI var videoAddUIClassName_Try1 = ".videoAdUi"; var videoAddUIClassName_Try2 = ".ytp-ad-player-overlay"; var videoAddUIClassName = videoAddUIClassName_Try1; // Banner var bannerContainerName_Try1 = ".ima-container"; var bannerContainerName_Try2 = ".ytp-ad-overlay-container"; var bannerContainerName = bannerContainerName_Try1; var closeButtonName_Try1 = ".ytp-ad-overlay-close-container"; var closeButtonName_Try2 = ".svg-close-button"; var closeButtonName = closeButtonName; // volume var volumeLowered = false; var volumeSliderName = ".ytp-volume-panel"; // on video load waitForKeyElements (videoClassName, OnVideoLoad); function OnVideoLoad(jNode) { // video video = document.querySelector(videoClassName); ConsoleMessage("Video found with volume of:" + video.volume); //oldVolume = video.volume; } function ConsoleMessage(text) { console.log("Adfriend: "+ text); } waitForKeyElements (videoAddUIClassName_Try1, AdDetected); waitForKeyElements (videoAddUIClassName_Try2, AdDetected); function AdDetected (jNode) { //Check if the ad is stil there UIContainer = document.querySelector(videoAddUIClassName); if (!UIContainer) UIContainer = document.querySelector(videoAddUIClassName = videoAddUIClassName_Try2); // skip skipContainer = document.querySelector(videoAddSkippContainerClassName); if (!skipContainer) skipContainer = document.querySelector(videoAddSkippContainerClassName = videoAddSkippContainerClassName_Try2); if (!volumeLowered) { ConsoleMessage("original volume was:" + video.volume); var volumeButton = document.querySelector(volumeSliderName); oldVolume = volumeButton.getAttribute('aria-valuenow') * 0.01; volumeLowered = true; } // button button = document.querySelector(videoAddSkippClassName); if (!button) button = document.querySelector(videoAddSkippClassName = videoAddSkippClassName_Try2); // Continue if(UIContainer) { console.log("Adfriend: Add detected"); setTimeout( QuickSoundCheck, 100 ); setTimeout( CheckIfSkipable, 1000); } } //Check if the skip button is visible function CheckIfSkipable(jNode) { skipContainer = document.querySelector(videoAddSkippContainerClassName); if(skipContainer != null && skipContainer.style.display != "none") { console.log("Adfriend: movie ad countdown started"); CurrentCountDownSeconds = CountDownSeconds; CountDownToSkip(); } else if (UIContainer) { console.log("Adfriend: could not find skipcontainer:" + videoAddSkippContainerClassName + " - retrying"); // try find skipContainer = document.querySelector(videoAddSkippContainerClassName = videoAddSkippContainerClassName_Try1); if (!skipContainer) skipContainer = document.querySelector(videoAddSkippContainerClassName = videoAddSkippContainerClassName_Try2); setTimeout( CheckIfSkipable, 1000); } else { console.log("adfriend: there was no adv?"); } } // Count until skip function CountDownToSkip(jNode) { --CurrentCountDownSeconds; console.log("Adfriend: counting down: "+CurrentCountDownSeconds); if(button) button.textContent = "Skip in "+CurrentCountDownSeconds; else { console.log("Adfriend:Could not find button"); button = document.querySelector(videoAddSkippClassName = videoAddSkippClassName_Try1); if (!button) button = document.querySelector(videoAddSkippClassName = videoAddSkippClassName_Try2); if(button) CountDownToSkip(); else { console.log("Adfriend:no button, ad is possibly skipped"); return; } } if(CurrentCountDownSeconds < 1) SkipAd(); else setTimeout( CountDownToSkip, 1000); } // REDUCE SOUND function QuickSoundCheck(jNode) { //check if ad UIContainer = document.querySelector(videoAddUIClassName); if(UIContainer) { //console.log("Add detected: current Volume:"+ video.volume + " vs old:" + oldVolume); if(video.volume > oldVolume * AdVolumeMultiplier) { console.log("Adfriend: volume was readjusted: "+video.volume); video.volume = oldVolume * AdVolumeMultiplier; console.log("Adfriend: Lowered to:"+video.volume); } setTimeout(QuickSoundCheck,500); return; } //add is gone console.log("Adfriend: Add is gone, moving volume back to: "+oldVolume); video.volume = oldVolume; volumeLowered = false; // check if sound is actually correct in a bit setTimeout(AdditionalSoundCheck, 500); } // is the sound still lowered? function AdditionalSoundCheck(jNode) { //check if ad UIContainer = document.querySelector(videoAddUIClassName); if(!UIContainer) { if(video.volume < oldVolume) { console.log("Adfriend: volume lowered somehow: "+video.volume); video.volume = oldVolume; console.log("Adfriend: readjusted to:"+video.volume); //setTimeout(QuickSoundCheck,500); } else console.log("Adfriend: sound seems good"); } else console.log("Adfriend: Add persists"); } // SKIP THE ADD, WHEN THEBUTTON IS AVAILABLE function SkipAd(jNode) { //retry button = document.querySelector(videoAddSkippClassName); UIContainer = document.querySelector(videoAddUIClassName); if(button) { console.log("Adfriend: Skipping ad"); button.click(); } else if(UIContainer) { console.log("Adfriend: Can't skip this potentially overpayed advertisement, sorry folks"); return; } button = document.querySelector(videoAddSkippClassName); if(button) { console.log("Adfriend: Did a new adv appear? or did it fail?"); setTimeout(CheckIfSkipable, 1000); } else { console.log("Adfriend: Ad was successfully skipped~"); } } // CHECK IF SUBSCRIBED and create ui function checkSubscribed (jNode) { // check it if ( ! /noblock/.test (window.location.href) ) { console.log("Adfriend: Checking subscription"); var elem = document.querySelector("#watch7-headline"); if(elem) { if(AddSubscriberNoBlock) { var child = elem.children[0].children[1]; if (child) { if (child.getAttribute("data-is-subscribed") == 'True') { location.replace (location.href + "&noblock"); } } } } else { var subscribebox = document.querySelector("#subscribe-button"); var child = subscribebox.children[0].children[0]; if(child) { //if() var subscribed = child.getAttribute("subscribed"); if(subscribed !== null) location.replace (location.href + "&noblock"); else { console.log("Adfriend: not subscribed?"); //console.log(child); //console.log(subscribed); } } else { console.log("Adfriend: Could not find subscribe box"); } } } } //waitForKeyElements ("#watch7-subscription-container", checkSubscribed); //waitForKeyElements ("#watch7-headline", checkSubscribed); function AddUI (jNode) { var adfriend = document.querySelector("#Adfriend"); if(adfriend) { ConsoleMessage("was already added"); } else { //Our interface container var newspan = document.createElement("SPAN"); newspan.className = "date style-scope ytd-video-secondary-info-renderer"; newspan.style.display = "inline-block"; newspan.id = "Adfriend"; newspan.style.marginLeft = "5px"; newspan.style.marginTop = "5px"; // old system or new system? var header = document.querySelector("#placeholder-player"); if(!header) header = document.querySelector("#info"); if(header) ConsoleMessage("Found suitable ui container!"); else ConsoleMessage("Can't find place to add ui container.."); header.appendChild(newspan); //Information var textnode = document.createTextNode("Adfriend::Movie:skip:"); newspan.appendChild(textnode); //Input InputBox = document.createElement("input"); InputBox.type = "number"; InputBox.style.width = "25px"; InputBox.defaultValue = CountDownSeconds; InputBox.oninput = saveValue; newspan.appendChild(InputBox); textnode = document.createTextNode("sound%:"); newspan.appendChild(textnode); //Input SoundInputBox = document.createElement("input"); SoundInputBox.type = "number"; SoundInputBox.style.width = "35px"; SoundInputBox.defaultValue = AdVolumeMultiplier * 100; SoundInputBox.oninput = saveValue; newspan.appendChild(SoundInputBox); textnode = document.createTextNode("Banner:skip:"); newspan.appendChild(textnode); SkipBannerInputBox = document.createElement("input"); SkipBannerInputBox.type = "number"; SkipBannerInputBox.style.width = "35px"; SkipBannerInputBox.defaultValue = BannerCountDownSeconds; SkipBannerInputBox.oninput = saveValue; newspan.appendChild(SkipBannerInputBox); textnode = document.createTextNode("Opacity%:"); newspan.appendChild(textnode); OpacityInputBox = document.createElement("input"); OpacityInputBox.type = "number"; OpacityInputBox.style.width = "35px"; OpacityInputBox.defaultValue = BannerOpaque * 100; OpacityInputBox.oninput = saveValue; newspan.appendChild(OpacityInputBox); //AddSubscriberNoBlock textnode = document.createTextNode("sub&noblock:"); //newspan.appendChild(textnode); AddSubscriberNoBlockInputBox = document.createElement("input"); AddSubscriberNoBlockInputBox.type = "checkbox"; //AddSubscriberNoBlockInputBox.style.width = "35px"; AddSubscriberNoBlockInputBox.checked = AddSubscriberNoBlock; AddSubscriberNoBlockInputBox.onclick = saveValueNoblock; //newspan.appendChild(AddSubscriberNoBlockInputBox); } } waitForKeyElements ("#player-container", AddUI); waitForKeyElements ("#placeholder-player", AddUI); function saveValue() { CountDownSeconds = InputBox.value; GM_setValue("MovieCountDown", CountDownSeconds); BannerCountDownSeconds = SkipBannerInputBox.value; GM_setValue("BannerCountDown", BannerCountDownSeconds); AdVolumeMultiplier = SoundInputBox.value / 100; GM_setValue("SoundMultiplier", AdVolumeMultiplier); BannerOpaque = OpacityInputBox.value / 100; GM_setValue("BannerOpacity", BannerOpaque); } function saveValueNoblock() { AddSubscriberNoBlock = AddSubscriberNoBlockInputBox.checked; GM_setValue("AddSubscriberNoBlock", AddSubscriberNoBlock); } //make banner ads transparent waitForKeyElements (bannerContainerName_Try1, bannerFound); waitForKeyElements (bannerContainerName_Try2, bannerFound); function bannerFound(jnode) { var bannerContainer = document.querySelector(bannerContainerName = bannerContainerName_Try1); if (!bannerContainer) bannerContainer = document.querySelector(bannerContainerName = bannerContainerName_Try2) bannerContainer.style.opacity = BannerOpaque; //bannerContainer.style.transition = ""; CurrentBannerCountDownSeconds = BannerCountDownSeconds; console.log("Adfriend: Banner ad detected: applying opacity"); //<div class="close-padding"><a class="close-button" title="Close" role="button" tabindex="0"></a></div> var closeParent = document.querySelector(closeButtonName = closeButtonName_Try1); if (!closeParent) closeParent = document.querySelector(closeButtonName = closeButtonName_Try2); // found close button? if(!closeParent) console.log("Adfriend: failed to find closebutton:" + closeButtonName); closeContainer = document.createElement("SPAN"); closeParent.appendChild(closeContainer); // created succes? if (!closeContainer) console.log("Adfriend: failed to create close container"); //var countDownText = document.createTextNode(""+BannerCountDownSeconds); closeContainer.appendChild(document.createTextNode(BannerCountDownSeconds)); setTimeout(CloseBannerCountDown,1000); } var stopHiding = false; function CloseBannerCountDown() { stopHiding = true; var bannerContainer = document.querySelector(bannerContainerName); if (!bannerContainer) { ConsoleMessage("Could not find a banner?"); return; } bannerContainer.style.opacity = BannerOpaque; --CurrentBannerCountDownSeconds; closeContainer.textContent = CurrentBannerCountDownSeconds; if(CurrentBannerCountDownSeconds < 1) CloseBannerAd(); else setTimeout( CloseBannerCountDown, 1000); } function CloseBannerAd() { // var closeButton = document.querySelector(".ad-container ad-container-single-media-element-annotations ad-overlay"); // if(closeButton) // closeButton.style.height = "0px"; // closeButton.click(); var bannerContainer = document.querySelector(bannerContainerName); if (bannerContainer) bannerContainer.style.opacity = 0.0; var closeButton = document.querySelector(closeButtonName); if(closeButton) { console.log("Adfriend: Banner ad still active, keeping it hidden"); setTimeout(CloseBannerAd,1000); } //else //{ // stopHiding = false; // console.log("Adfriend: succesfully closed banner ad"); // CurrentBannerCountDownSeconds = BannerCountDownSeconds; // //bannerContainer.style.transition = ""; // setTimeout(KeepAdHidden, 3000); //} } function KeepAdHidden() { var bannerContainer = document.querySelector(bannerContainerName); if(bannerContainer.style.opacity != 0.0) bannerContainer.style.opacity = 0.0; if(!stopHiding) setTimeout(KeepAdHidden, 3000); }