├── 128.png ├── README.md ├── background.js ├── content.js └── manifest.json /128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andykawabata/youtube_ad_skipper/e4a64c6294bbdf02f7cdb577d394e7811e6f1a83/128.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ad Skipper 2 | ## What it Does 3 | Automatically skips all *skippable* youtube ads the instant they appear. Works for ads at the beinging and in the middle of videos as well as the pop-up banner ads. Does not work for ads that have no skip option. 4 | ## How it Works 5 | This is a chrome extension that runs a content script everytime you load a page thats on YouTube. It uses a background script to listen for movement within the YouTube domain (clicking on another video). When it detects you've started a new video, a function is run that repeatedly tries to define the html element that has the "skip add" click listener. Once it's defined it is clicked with the javascript .click() function. 6 | 7 | Mid-video ads and banner adds are detected by a mutation observer that is added to the page whenever a new video is started. This listenes for added or removed child elements in "video-ads" DIV. 8 | 9 | ## How to Install 10 | 11 | 1) Click the green "Clone or Download" button 12 | 2) Click "download ZIP" 13 | 3) Unzip the folder and put it anywhere you like 14 | 4) Open a new tab in your Chrome browser and type in "chrome://extensions" in the search bar. Press enter. 15 | 5) In the upper right corner, turn "Developer Mode" on. 16 | 6) Click "load unpacked" 17 | 7) Find the folder you just downloaded/unzipped "youtube_ad_skipper-master" and click "Select Folder" 18 | 8) Turn "Developer Mode" off 19 | 20 | \*** if you are getting an error that says " 21 | Manifest file is missing or unreadable" it's likey because the "youtube_ad_skipper-master" folder has another folder within it (with the same name).If thats the case, make sure you select the folder within the folder. -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | function handleUpdated(tabId, changeInfo, tabInfo) { 2 | 3 | console.log("in handle updated"); 4 | var newUrl = changeInfo.url; 5 | var currentTab = tabId; 6 | console.log(newUrl); 7 | console.log(newUrl && newUrl.includes("https://www.youtube.com/")); 8 | //setTimeout(function() { 9 | if (newUrl && newUrl.includes("https://www.youtube.com/")) { 10 | chrome.tabs.sendMessage(currentTab, "you are on youtube"); 11 | } 12 | //}, 2000); 13 | } 14 | chrome.tabs.onUpdated.addListener(handleUpdated); 15 | 16 | -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | console.log("running content script"); 2 | var initialSkipInProgress= true; 3 | 4 | //SKIP ON ARIVAL TO YOUTUBE OR REFRESH 5 | 6 | window.addEventListener ("load", myMain, false); 7 | function myMain () { 8 | 9 | console.log("into main"); 10 | initialSkip(); 11 | setTimeout(function(){ 12 | addObserver(); //after 1 second, add mutaion observer 13 | },1000); 14 | } 15 | 16 | //SKIP ON URL CHANGE 17 | 18 | chrome.runtime.onMessage.addListener(gotMessage); 19 | function gotMessage(message, sender, sendResponse){ 20 | 21 | console.log("url has changed"); 22 | initialSkip(); 23 | 24 | setTimeout(function(){ 25 | addObserver(); //after 3 second, add mutaion observer 26 | },3000); 27 | } 28 | 29 | //SKIP FUNCTIONS 30 | 31 | function initialSkip(){ 32 | count = 0; 33 | let skipper = setInterval(function(){ 34 | console.log("initialSkip") 35 | let buttonList = document.getElementsByClassName("ytp-ad-skip-button-container"); 36 | let skipButton = buttonList.item(0); 37 | if( skipButton || count >= 20){ 38 | clearInterval(skipper); 39 | initialSkipInProgress = false; 40 | skipButton.click(); 41 | } 42 | count++; 43 | },200); 44 | } 45 | //same as initialSkip except it also looks for the pop-up banner adds and closes them 46 | function asyncSkip(){ 47 | if(!initialSkipInProgress){ 48 | count = 0; 49 | let skipper = setInterval(function(){ 50 | console.log("asyncSkip") 51 | let buttonList = document.getElementsByClassName("ytp-ad-skip-button-container"); 52 | let skipButton = buttonList.item(0); 53 | let closeButton = document.getElementsByClassName("ytp-ad-overlay-close-button")[0]; 54 | if( skipButton || closeButton || count >= 20){ 55 | clearInterval(skipper); 56 | if(skipButton) 57 | skipButton.click(); 58 | else if(closeButton) 59 | closeButton.click(); 60 | } 61 | count++; 62 | },200); 63 | } 64 | } 65 | 66 | 67 | //SET UP MUTATION OBSERVER 68 | 69 | function callback(mutationList, observer){ 70 | console.log("async tiggered"); 71 | asyncSkip(); 72 | } 73 | 74 | function addObserver(){ 75 | 76 | const targetNode = document.getElementsByClassName("video-ads").item(0); 77 | const config = {childList: true} 78 | console.log(targetNode); 79 | var myObserver = new MutationObserver(callback); 80 | myObserver.observe(targetNode, config); 81 | } 82 | 83 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "Youtube Ad Skipper", 4 | "description": "Automatically skips all skippable youtube ads the instant they appear", 5 | "version": "1", 6 | "permissions": [], 7 | "host_permissions": ["https://www.youtube.com/*"], 8 | "content_scripts": [ 9 | { 10 | "matches": ["https://www.youtube.com/*"], 11 | "js": ["content.js"], 12 | "run_at": "document_end" 13 | } 14 | ], 15 | "icons": { 16 | "128": "128.png" 17 | }, 18 | "background": { 19 | "service_worker": "background.js" 20 | } 21 | } 22 | --------------------------------------------------------------------------------