DEV Community

Cover image for Chrome Extension That Skips YouTube Ads (+Steps How To Create It)

Chrome Extension That Skips YouTube Ads (+Steps How To Create It)

Pavel Bucka on January 02, 2020

Recently I have created chrome extension called My Notes and as it received nice reviews, I have decided to create another one – Skip Ad. I am als...
Collapse
 
penge profile image
Pavel Bucka • Edited

For those who would like to try the solution using Observer out of curiosity, although it seems not to be more performant nor work on pages where #movie_player is not present, here's the code:

const target = document.getElementById('movie_player');
const config = { childList: true, subtree: true };

const callback = function(mutationsList, observer) {
  for(const mutation of mutationsList) {
    if (mutation.addedNodes.length === 0) {
      return;
    }

    if (mutation.target.className !== "video-ads ytp-ad-module") {
      return;
    }

    // Look for Skip Button here :)
  }
};


const observer = new MutationObserver(callback);
observer.observe(target, config);

The solution needs some finishing where the comment is now. Take it as an exercise :)

Collapse
 
offcorner profile image
OffCorner Developer

performance would be better using a document observer instead of calling the function every 300 milliseconds

Collapse
 
penge profile image
Pavel Bucka

Hi!

  1. You need to attach the Observer to the node. The "good" node would be #movie_player but it is not always present on the page, like in home page for example. You would then have to move the observer up the chain to the node that exists on each page. As content script is inserted on the first page load that might not have #movie_player.

  2. If you let's say ignore point 1. (which you can't lol) and test it from #movie_player, then you still find yourself getting HUNDREDS of mutations (no attribute mutations included). You loop the mutations and filter them to only those that have addedNodes. Then, you finally get to the container that encloses the ad, which is having className equal to "video-ads ytp-ad-module".

  3. The ad container that contains the enclosed ad, from point 2., is not the final destination. You still have to look for button inside that node as you don't get mutation for that button. So you end up using getElementsByClassName anyway.

  4. The execution time for the script using setInterval 300ms, is around 0.00024ms every 300ms. That's literally nothing. 500k executions take about 120-130ms and that's tested on really cheap ARM CPU. This execution time, from the top of the tree, is same (no real difference), when compared to starting from #movie_player.

And so for these reasons, I doubt performance using the Observer would be any better.

PS: I'd like to see btw how this could be precisely measured. If you have the time to test it and support your statement with better result, that would be really cool.

Collapse
 
offcorner profile image
OffCorner Developer

Thanks for the response, I just checked how many times the Mutationobserver actually triggers while watching a video, and it's so much more than every 300ms! So yes, your method seems more efficient.
One thing I did, in order to hide the ads shown to the right oft the video, is a tiny bit of css code:

#player-ads {display:none !important}

The ads are still loaded, so the publisher should be paid (unlike with adblock, which blocks the request).

Thread Thread
 
penge profile image
Pavel Bucka • Edited

That's a good idea! Thanks!

I will add it to the next version.

Video overlay banners can also be handled the same way, as I found out they have a different container than Video ads. Hiding it via CSS would make it longer "visible" and publisher would get paid better as closing the banner is handled by youtube's base.js so it's probably tracked.

Video ads would continue to be handled the same way, with a click.

The final code would be like this:

JS

setInterval(() => {
  for (const button of document.getElementsByClassName("ytp-ad-skip-button")) {
    button.click(); // "Skip Ad" or "Skip Ads" buttons
  }
}, 300);

CSS

.ytp-ad-overlay-container, #player-ads {
  display: none !important;
}

Much better!

Collapse
 
juliannicholls profile image
Julian Nicholls

Thank you for this. I have created an extension for myself now.

Collapse
 
acnbandaru profile image
BANDARU ASHOK

Can we make if conditions to skip the ads like if the ads 15 secs longer suppose to skip at 7 sec or if the ad is 30 sec duration to skip at 15 sec or if the ad is longer than 1 minute or more it should skip at 30 sec...? please help me :)

Collapse
 
orelkan profile image
Orel Kanditan

Thanks very cool, didn't know it was this easy to make a simple extension

Collapse
 
penge profile image
Pavel Bucka

Cool!

Collapse
 
anrodriguez profile image
An Rodriguez

I thought this would be something closer to AdBlock Plus!

Collapse
 
penge profile image
Pavel Bucka

How about AdSkip Plus? 😀

Collapse
 
sarthak501 profile image
Sarthak Rana

BUT THIS CODE WILL NOT SKIP UNSKIPPABLE ADS OF YOUTUBE ,IN WHICH THERE IS NO SKIP BUTTON.
LIKE THE IMAGE GIVEN BELOW

Collapse
 
sarthak501 profile image
Sarthak Rana

THIS IMAGE