❓ Skip Ad, ✅ PiP widget for Youtube in Safari (Javascript from AppleEvents and Applescript)

I'm trying to Show/Hide a Skip Ad widget based on the presence of a youtube ad in safari.

Most of the script is ok, but I'm having trouble with that javascript part:

(*
Ways to find if div of specific class exists:

METHOD 1 (requires AJAX, so can't use)
if ($(".mydivclass")[0]){

// Do something if class exists

} else {

// Do something if class does not exist

}


METHOD 2
if (document.querySelector('.mydivclass') !== null) {

// .. it exists

}

*)


--Show/Hide Skip Ad widget based on the presence of a youtube ad in safari

--set str to "" as string

if application "Safari" is running then

tell application "Safari"

if URL of current tab of front window contains "www.youtube.com/watch" then

set state to do JavaScript ["document.querySelector('.videoAdUi')"] as text

(*

if state = "*div found* (placeholder)" then

return "Skip Ad"

else if state = "*div not found* (placeholder)" then

return ""

end if

*)

return state

--return "URL TRUE, ready to return"

else

--return "noURL"

return state

end if

end tell

else

return "No Safari"

end if

--return str

@iAmWaldo, i think this would be useful to you and i think you’re probably the one I should ask for help

Hey,

Here is the script to know if a skip ad is showing:

set str to ""

if application "Safari" is running then

tell application "Safari"

repeat with t in tabs of windows

if URL of t contains "YouTube" then

tell t

set state to do JavaScript "document.getElementsByClassName('videoAdUiSkipButton videoAdUiAction videoAdUiFixedPaddingSkipButton')[0].getAttributeNames()"

if state = {"class"} then

set str to "Skip Ad"

end if

end tell

end if

end repeat

end tell

return str

else

return str

end if

And here is the script to click on skip ad:

tell application "Safari"

repeat with t in tabs of windows

if URL of t contains "YouTube" then

tell t

do JavaScript "document.getElementsByClassName('videoAdUiSkipButton videoAdUiAction videoAdUiFixedPaddingSkipButton')[0].click()"

end tell

end if

end repeat

end tell

With this you should be able ot skip the ad even if you are on another app and without switching to the tab

1 Like

Wow nice!

I’ll check it out soon.
One thing i’d like to ask though, does it skip ad even if the skip add countdown isnt up? I’ve been trying to do that and it’ll especially be useful for unskippable ads. Currently I set it to report the ad quickly and it closes the ad even if it’s unskippable, but you’d need to have google’s tracking on for that to popup and i’m sure theres another better way.

Also, are you going to use this in your preset? :wink:

p.s. trying to work on a Picture in Picture button too

No this script is only reporting when the button "Skip Ad" is visible, I haven't tested it for when the countdown is not up because I couldn't find any videos with skipable ads (kind of ironic if you think about it..), and I went through a thousand videos, so I kinda gave up haha (not sure if the button shows up before the time is up either but I do believe it would).

I'm interested though, how are you able to skip the ad before it even shows or even has a skip button?

Yeah, I'm gonna put it there but just for the sake of it, but I doubt a lot of people will use it as I believe a lot of people have ad blockers (like me :wink: ) and don't really need it.

For the picture-in-picture, I haven't given it much thoughts yet but I believe its doable, however, it might be even easier if people installed the safari extension that ads it to the player bar directly. But I'll look into it

Hi @iAmWaldo,

Yeh i think the ads only come after a set time limit so you’d have to watch for a certain time to expend it, then ads will appear (probably so you don’t see an ad every. time. you skip a video...)

Currently that script just reports the ad XD
once reported the ad closes so it technically skips. even works on unskippable ads. I do it a lot especially on mobile as tapping the buttons to report is faster than the 5 second wait... But it doesn’t work in some conditions so yeh, don’t know if i’ll release it officially using that

Coming to that point, what adblock do you use? mine doesn’t seem to be filtering out yt ads, and mojave rendered my trusty AdBlock Plus kind of bad (though i know they’re working on it). I’d like to know what you use

Also what is that PiP extension?
You can already activate PiP on youtube via either the default macOS Safari TouchBar, or by double-right clicking the video (if you didn’t know) but that PiP extension sounds great

Yesh, I now just realized that people won't be looking for a skip add button but for the ad to be skipped automatically when it is detected. Could probably also cook up a script that closes banner ads on videos as well, riding all annoying ads automatically.

Oh i see what you mean, yeah that's quite smart, I do it on my phone as well and I think a script that automatically does that on every video would be great. What are the conditions when it doesn't work ?

I use 1Blocker. Its the only one in my experience that don't make youtube glitch on safari (by the way the other adblocks glitch because the ads are no longer static, they are dynamic and reload and everything, which makes the ad bllocker block like a thousand ads on one page, and making youtube unusable. Its google way of fighting ad blockers)

For the PiP extension, its called PiPifier button. Its a free extension for safari and works great !

1 Like

This script skips all ads as long as it is possible to do the "Don't show this ad anymore" on it (i've noticed that some ads don't have that button on them)

**set** state **to** ""

**tell** *application* "Safari"

**repeat** **with** t **in** *tabs* **of** *windows*

**if** URL **of** t **contains** "youtube.com/watch" **then**

**tell** t

**set** state **to** **do JavaScript** "document.getElementsByClassName('videoAdUiAttributionIcon')[0].getAttributeNames()"

**if** state = {"class", "id"} **then**

**do JavaScript** "document.getElementsByClassName('videoAdUiAttributionIcon')[0].click()"

**do JavaScript** "document.getElementsByClassName('videoAdUiWhyThisAdMute videoAdUiHideIfEmpty')[0].click()"

**do JavaScript** "document.getElementsByClassName('videoAdUiMuteCancel videoAdUiPopupButton')[0].click()"

**end** **if**

**end** **tell**

**end** **if**

**end** **repeat**

**end** **tell**

yeh, and also if you turn off googles ad tracking you can't skip this way

Here's my take on the report to skip ad:

Show Code
to clickClassName2(theClassName, elementnum)
	if application "Safari" is running then
		try
			tell application "Safari"
				repeat with t in tabs of windows
					if URL of t contains "youtube.com/watch" then
						tell t
							--videoAdUi
							do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
						end tell
					end if
				end repeat
			end tell
		end try
	else
		return ""
	end if
end clickClassName2

clickClassName2("videoAdUiAttributionIcon", 0)
delay 0.1
clickClassName2("videoAdUiWhyThisAdMute videoAdUiHideIfEmpty", 0)
delay 0.1
clickClassName2("videoAdUiMuteOption0", 0)
delay 0.1
clickClassName2("videoAdUiMuteConfirm videoAdUiPopupDefaultButton", 0)

1Blocker is paid :disappointed:... ahh well

Ah I see, well I guess people will have to active google's ad tracking to be able to skip ads then (very ironic haha)

I used youtube and the widget a lot yesterday, and sometimes (most of the time) it doesn't show up.. Need to look into this issue further.

Also, I guess if you have an ad blocker, the ad won't show up, thus the button won't show up so it kinda works for everyone if we get it working stably.

What I want to do next / trying to do next:

  • Display the countdown in the widget
  • Find a new way to skip the ad. (delete the div? somehow bypass the countdown and send skip request? etc.)
  • If we can't do that then use the report-to-skip if available. if it can't do that, the widget knows and it'll wait for the skip button and click that instead of trying to report again.
  • PiP widget

Hey,

Tried to work out the ad thing for youtube and I couldn't find any div or something like that for the video ads they run as it seems to be embeded on the main container div for the video player, and removing it removes the actual video you want to watch lol
If you know what to remove, let me know and I'll try to make it happen :wink:

However, I was able to write a script to detect when the little banner ads, as well as the ads on the side of the video player, are showing and removing them automatically when they do (just put it in a widget that will run in the background every 2-3 secs or so, should be fine)
here is the code:

set state to null
tell application "Safari"
	repeat with t in tabs of windows
		if URL of t contains "youtube.com/watch" then
			tell t
				set state to do JavaScript "document.getElementsByClassName('video-ads')[0].getAttributeNames()"
				if state = {"class", "data-layer"} then
					do JavaScript "document.getElementsByClassName('video-ads')[0].remove()"
					do JavaScript "document.getElementsByClassName('style-scope ytd-iframe-companion-renderer')[2].remove()"
				end if
			end tell
		end if
	end repeat
end tell

Hope it helps :slight_smile:

I've found this:

Not sure how to merge it in though... My code isn't that strong. It seems to do a little line of javascript though, so if it's still working today then that'll be great.

It doesn't seem to work anymore :confused:

For the PiP widget, I modified some of the code here to make it work with the pipifier extension's button on youtube:

**tell** *application* "Safari"

**repeat** **with** t **in** *tabs* **of** *windows*

**if** URL **of** t **contains** "youtube.com/watch" **then**

**tell** t

**do JavaScript** "document.getElementsByClassName('ytp-button PiPifierButton')[0].click()"

**end** **tell**

**end** **if**

**end** **repeat**

**end** **tell**
1 Like

I use a mouse click then context menu action for this on youtube, and it works pretty well.

One benefit of this is no installing extra items, and because it works pretty quickly and stably its the way to go for me.

(if you didn’t notice, double right click on the youtube video and you’ll see the PiP option, which is what I target.)

After reading this topic I made some adjustments to make it work for me (on multiple sites)
Maybe someone else can use this.

I'm new to writing Applescript so it might need some improvement.

Apple Script Widget (for Safari):

tell application "Safari"
	try
		set video to (do JavaScript "
        var video = document.querySelectorAll('video').length;
        video;" in document 1)
		
		if video = 1 then
			return "Picture-in-Picture"
		else
			return ""
		end if
	end try
end tell

Apple Script blocking

tell application "Safari"
	activate
	try
		tell document 1
			do JavaScript "document.querySelector('video').webkitSetPresentationMode(document.querySelector('video').webkitPresentationMode === 'picture-in-picture' ? 'inline' : 'picture-in-picture')"
		end tell
	end try
	
end tell
1 Like