NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @license MIT // @copyright Copyright (c) 2019, Romain Lebesle <oss@thoughtsunificator.me> (https://thoughtsunificator.me) // @namespace https://thoughtsunificator.me // @name Block ads on Youtube // @author Romain Lebesle <oss@thoughtsunificator.me> (https://thoughtsunificator.me) // @supportURL https://thoughtsunificator.me/ // @version 1.2 // @description Block ads on Youtube // @run-at document-start // @include https://*.youtube.com/* // @grant GM_addStyle // ==/UserScript== GM_addStyle(` #player-ads, .adDisplay, .ad-container, .ytd-display-ad-renderer, .video-ads, #masthead-ad { display: none !important; } `); let video const observer = new MutationObserver(mutations => { for(const mutation of mutations) { for(const addedNode of mutation.addedNodes) { if(addedNode.className && (addedNode.classList.contains("ytp-ad-skip-button-slot") || addedNode.classList.contains("ytp-ad-overlay-close-button"))) { console.log("ytp-ad") addedNode.click() } else if(addedNode.className && addedNode.classList.contains("ad-showing")) { console.log("ad-showing") if(!isNaN(video.duration)) { video.play() video.currentTime = video.duration } } else if(addedNode.tagName === "VIDEO" && addedNode.classList.contains("html5-main-video")) { console.log("video") video = addedNode video.addEventListener("durationupdate", () => { console.log("durationupdate") video.play() video.currentTime = video.duration }) video.addEventListener("timeupdate", () => { const adSkipButton = document.querySelector(".ytp-ad-skip-button-slot button,.ytp-ad-overlay-close-button") if(adSkipButton) { adSkipButton.click() } if(document.querySelector(".ad-showing")) { if(!isNaN(video.duration)) { video.play() video.currentTime = video.duration } } }) } } } }) observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true })