Is a Macro That Handles YouTube Ads Possible?

I'd like use a macro that automatically closes or otherwise deals with Youtube ads.

There are two types, pre-roll and banner. The pre-roll is an ad that begins playing in front of a video for at least four seconds. When the four seconds are up, Youtube posts a "skip ad" button, which I'd like the macro to auto detect and click. When clicked, the remainder of the ad is abandoned and the video starts.There are some ads which go a variable number of seconds, typically 30, before the video starts and the 'skip ad' button is never posted; once the ad runs, the video starts at its end. The macro can ignore that kind.

The banner ad is posted atop of a video once it's playing. The banner ad contains a small square icon with an X in it in the ad's upper right corner, which, when clicked, makes the ad vanish. I'd like the macro to auto detect the X whenever it's posted by Youtube (it isn't always) and auto click it.

I understand how to prepare and use a "Move and Click from the Centre of the Found Image" action for each of these types, but the problem I'm having is figuring out how to trigger the macro to search for the ad types only when a Safari window's URL search box contains the "https://www.youtube.com.com" portion of a URL. That's because I don't particularly want the macro running the entire time I'm working in Safari on non-Youtube windows, which is most of the time. Ideally the macro would start searching for the X or the Skip Ad buttons whenever it detects a Youtube window is Safari's front window, and automatically stops watching the page when I move to a window with some non-Youtube URL. If it's not possible to create that trigger, and I'm not sure how it would go back to watching the page at the end. Aany suggestions for accomplish the concept would be welcome.

The two type of ads don't seem to appear at the same time. Normally, it's the Skip Ad button that appears firs, and it sticks around until it's clicked (manually, at the moment), followed by the banner X ad, which only appears a few seconds after the video begins. It stays up, usually, for most of the video unless the X is manually clicked.

I'm guessing it might be helpful for KM to have a trigger action that activates when a URL contains some variable text, but I didn't see anything in the list of triggers where that might be accomplished at the moment, unless there's a work-around with another type of trigger action.

Not the subject of your question but why don't you use an ad blocker?

Ad blockers have problematic side effects, as well as, for me, ethical ones.

I was a publisher for decades before I retired a few years ago. I know the genuine value of advertising to support businesses large and small which offer good content, but I’ve also seen the corruption of the business models that once worked fine by using an underlying respect for the audience and content in the last few years.

Largely, the voracious greed of those now in the ad business has swamped those models, so I understand the constant arms race between ad blockers and advertisers.

In any event, I’m trying to use KM to be judious about removing personal ad annoyances on YouTube, rather than be wholesale about it.

I was going to post a new topic showing how to do this, but when I saw your 9 month old question I decided to post my solution here instead. I don't think it solves the problem exactly the way you intended (i.e., it doesn't check URLs) it but I think it gets exactly the results that you want. The reason I use two searches for the "Skip AD" image is that the Skip Ad button is translucent and I got much better results with two searches. I did not post the actual code because the bitmap images may not work on your screen since my monitor probably has a different resolution than any of yours, therefore my code wouldn't work on your computer. My only regret is that sometimes when a commercial pops up I'm actually enjoying the commercial (ads are getting more compelling lately) and the ad disappears too quickly now. :slight_smile:

Hopefully you understand why I'm forcing you to retype the code. Because you need to generate your own bitmaps for the searches.

I find that my code detects Skip Ad correctly about 99% of the time, but it has a lower success rate at detecting the banner X ads because there are actually many types of X's and this code doesn't seem to detect them all.

P.S. I had trouble writing this message because my macro was running and tried clicking on the parts of this message containing the SKIP AD image which was messing me up. :smile:

Hey, thanks, Sleepy!!
And, yes, I understand why your "forcing" (LOL) me to retype the code...
I'll try it out shortly and keep you apprised.
Cool!

Thanks. It works very well for me (although the banner ad portion needs some work). But I confess that I disable the macro when I'm not watching Youtube videos. I hadn't thought of your idea to check the URL first to see if it's Youtube. There's probably a way to do it, but if I can't figure it out, I'd just use a dirty trick to achieve that goal (which is to look for a bitmap to see if the user is on Youtube.com). Nevertheless the trick involves continual checking, so as long as we have to continually check for something, it might as well be for the SKIP AD graphic. I don't see any benefit to continually checking for the YouTube URL. This macro would be cleaner and clearer if Keyboard Maestro supported variables or arrays of bitmaps, but it doesn't.

I like this solution and if I may, I would like to offer one suggestion. If the skip button is visible but not in a condition to click, click the mute button. Then, when the skip button is visible and can be clicked, unmute the video.

I was going to suggest my solution, to use a downloader for those videos I want to watch without all the annoying adds. For a time I was doing that when I had to switch back to my MacBook pro as it had a less powerful sound card than my now dead iMac had. Playing a video in VLC is always a better sound volume than what is on the YouTube video.

Of course, this is an incomplete solution as many vids you want to check out but not download. This posted solution is one I will try.

Your ideas are welcome. However when the word SKIP appears it is always clickable. There is a small box that appears with a countdown from 5 to 1 that a human could use to infer it's a commercial, but it wouldn't be easy with KM. You're probably thinking about how it used to work, but it changed months ago.

As for downloading videos, that would probably work but it really slows down your ability to watch videos, as you suggest in para #3, so I wouldn't do it that way. And by the way, you don't need a downloader if you use Firefox. As far as I've been able to determine, Firefox is the only browser among the big three that has this ability. This is important to me as I don't trust most addons. I used to be able to do it in Safari but I think that ability was removed (and it wasn't easy at all.)

If I remember correctly, you only have to put in the letters "SS"before "youtube". Yep, just tested this with Safari. Works great. I stopped using this method after I picked up a license for Mac VideoRipper Pro a while back. It hasn’t let me down and makes downloads easier.

I'll skip on the addons which require the SS because you don't need them if you use Firefox. Oh, and Firefox's download ability is free, no license required.

I am not aware of any add ons to do this. SS is just a method that works in any browser without any add ons - as far as I know. Safari is free also. Not knocking Firefox, I also use Firefox. Just saying ...

Today I noticed that Youtube changed it's Ad graphic from "Skip Ad" to "Skip Ads". This may cause the macro above to fail. They made other minor changes too. Eg, today is the first time I've ever seen two 30 second ads at the beginning of a Youtube video, which explains the difference in wording. So this macro is already a little out of date. It's easy to fix, but it will always be a cat and mouse game. I could add more smarts to this macro but only when I'm feeling in the mood. I posted the macro above mainly as an educational example, not as a perfect solution.

This happens to be a very informative post. Got to learn a lot from this. Keep posting such things. Thanks.

Oh, thanks. I love the Find Image action and I can do lots of amazing things with it. It has its quirks and it takes some skill to use it well. I like to think of the Find Image action as an "eyeball on the screen" which works amazingly fast. However it does drag down the CPU a little if you use it many times per second on a 5K screen. I'm looking forward to KM v9 because I think there will be some improved support for image handling and that could impact how I use Find Image.

Hi Sleepy,

I agree with you, the Find Image action can be really powerful.

However, for certain reasons I would like to encourage you to not over-use the Find Image action.

[Let’s see if can convince you]

The first reason is, the Find Image action is extremely expensive (in terms of CPU and probably (not sure) also memory).

The second thing is, it’s unreliable. Your follow-up script might be fine, but when the crucial image changes for whatever reason (the dev changes the image, or any quirk with Dark Mode, whatnot) the whole macro will fail.
‌

My usual approach is this (in order of appearance):

Trying to get to the thing via AppleScript (or JXA)

A fair amount of apps offer a usable AppleScript library (dictionary), and hence the issue can be solved already here. If not…

GUI Scripting or using KM GUI actions

This includes things like clicking buttons via AppleScript following the Accessibility API, or simply via KM (selecting a menu item, etc.)

If nothing works…

using the Find Image action as a really last resort.

Following this “plan” I literally never had to resort to “Find Image” with any macro I made.
(Except one: Cheating a game (WoW), where Find Image can be very useful; but this might be “illegal” :wink: )

Just some thoughts

– Tom

1 Like

Yes it can be a CPU hog. So it should be used with prudence. For example waiting for an "OK" button to appear on the screen is prudent use, as long as the CPU isn't busy doing other things. On the other hand, one time I was attempting (but never succeeded) to write a program in KM that used Find Image to watch a web page where I was supposed to be playing chess with someone on the internet and I was going to use KM to pipe the current chess position into a chess advice program so that the KM program, instead of me, was playing chess against another human. That way I could always beat my nephew in chess. :smile:

1 Like

Hhaha nice trick.Thanks for the tip.Its useful.Now next time i will also beat my friend in chess:) Also you may check thisfree amazon prime guide to get prime account.

Very late reply but just in case anybody else stumbles across this like I did I thought I'd contribute. I'm not sure if this KBM feature was available when this was being discussed, but at the time of writing, you don't need to use "Find Image" action.

KBM can detect buttons in the current window, and that includes the browser. A name attribute on a HTML button isn't needed as the text content of the button can be used instead. You can then use something like an "If Then Else" block to check if the button exists and if it does, execute the "Press a Button" action and in the input, tell it to press the button named "Skip Ads".

CleanShot 2022-02-28 at 2.53.37

This is only part of the problem and not the whole thing, but hopefully this can help somebody in the future. I'm not sure if the close icon on the banner ads has a name attribute or if the X icon within it can be used just like above.

I assume you are correct, and I am in awe of your discovery.

Every year I go back and try to block Youtube ads using KM (just for the fun and challenge of it.) The Skip Ads words aren't the hardest thing to resolve. The hardest thing are the pop-up windows near the bottom of the playback window. I'm going to see if there are "buttons" that correspond to the X and I buttons in those ads at the bottom of the window. Probably not, but I'll try. (I just tried, it doesn't seem to work there.)

Um, would you happen to know if there's an AppleScript method to get the frame of the playback window? I spend a lot of time trying to find the frame in my code.

Something is strange about your button name idea: sometimes the button says "Skip Ad" instead of "Skip Ads" so perhaps I'll have to watch out for both button names.

At the end of Youtube videos, if you have Autoplay turned on, a button called PLAY NOW and a button called CANCEL will appear. However these buttons are not detectable with the KM button condition and action, sadly.

The Skip Ads button works even if the Youtube video is playing in the MiniPlayer. Interesting.

Just played around a bit more and solved the banner ad. Just run this javascript in the browser:

document.querySelector('.ytp-ad-overlay-slot').remove()

CleanShot 2022-02-28 at 5.10.36

As for the "Ad" vs "Ads" situation, I just removed the button check and duplicated the "Press Button" action before making it so that there's no notification or abort on failure by right-clicking each action. That being said, I trigger the macro manually with a hotkey so there's no worry about any processing overhead.

In the If statement, there's the option for "Button with name containing", where "Skip Ad" could detect both eventualities. Maybe you could do that, and then use 2 more "If Then Else" actions within, to check again for each individual one before executing a click. Unfortunately there's no "Press Button with name containing" option.

As for the ad at the end of a video, I just tried it and got a regular "Skip Ad" button. I'll take another look if I get the button you described and post back here.

For automated Ad canceling, using some sort of loop, it might be easier to just run a JavaScript If statement that checks if a div relating to the ad exists (something generic like a common outer container) and then removes it similar to how I removed the banner add above. Something simple like this would do the trick:

document.querySelector('.ad-related-css-class') && document.querySelector('.ad-related-css-class').remove()

Edit: For a video ad, that remove option probably wouldn't work, but could be handy. Maybe you could check for presence and return "true" to KBM before performing another action. You could possibly utilise triggering full screen with the "F" hotkey and then performing a click based on absolute position. Would be a little annoying but at least it would ensure the correct location of the button. Maybe just resize the window instead of full screen for better performance, so many options.

Edit 2: The "Click Front Browser Link" action might come in handy if that non-button element is an anchor tag. I assume it would work the same as "Press Button" where you can just pass the inner text of the button.

1 Like