Quickly skip video ads in Youtube. 快速跳过油管中的视频广告。
当前为
// ==UserScript==
// @name Youtube AD Skipper 油管广告拦截跳过
// @name:zh-CN Youtube AD Skipper 油管广告拦截跳过
// @namespace http://tampermonkey.net/
// @version 0.9
// @description Quickly skip video ads in Youtube. 快速跳过油管中的视频广告。
// @description:zh-CN Quickly skip video ads in Youtube. 快速跳过油管中的视频广告。
// @icon https://www.gstatic.com/youtube/img/branding/favicon/favicon_144x144.png
// @author gabe
// @license MIT
// @match https://*.youtube.com/*
// @grant none
// ==/UserScript==
(function () {
"use strict";
function log() {
return console.info("[Youtube AD Skipper]", ...arguments);
}
function sleep(delay = 500) {
return new Promise(function (resolve) {
const timer = setTimeout(function () {
clearTimeout(timer);
resolve();
}, delay);
});
}
function newTouch(el) {
const rect = el.getBoundingClientRect();
const x = (rect.left + rect.right) / 2;
const y = (rect.top + rect.bottom) / 2;
return new Touch({
identifier: Date.now(),
target: el,
clientX: x,
clientY: y,
screenX: x,
screenY: y,
pageX: x + document.body.scrollLeft,
pageY: y + document.body.scrollTop,
radiusX: 10.0,
radiusY: 10.0,
rotationAngle: 0.0,
force: 1,
});
}
function newTouchEvent(touch, name) {
return new TouchEvent(name, {
cancelable: true,
bubbles: true,
touches: [touch],
targetTouches: [touch],
changedTouches: [touch],
});
}
function dispatchTouch(el) {
const touch = newTouch(el);
el.dispatchEvent(newTouchEvent(touch, "touchstart"));
// el.dispatchEvent(newTouchEvent(touch, "touchmove"));
el.dispatchEvent(newTouchEvent(touch, "touchend"));
}
async function skipAd(moviePlayer, adOverlay) {
let i = 0;
while (++i < 6) {
if (i > 1) {
adOverlay = moviePlayer.getElementsByClassName(
"ytp-ad-player-overlay"
)[0];
if (!adOverlay) {
log("skip done!!!");
return;
}
}
const skipButton =
adOverlay.getElementsByClassName("ytp-ad-skip-button")[0] ||
adOverlay.getElementsByClassName("ytp-ad-skip-button-modern")[0];
const isMobile = location.hostname === "m.youtube.com";
if (skipButton) {
if (isMobile) {
dispatchTouch(skipButton);
log("skip touch ->", i);
} else {
skipButton.click();
log("skip click ->", i);
}
} else {
const video = moviePlayer.getElementsByTagName("video")[0];
video.currentTime = video.duration;
log("skip play ->", i);
}
await sleep();
}
log("skip failed...");
}
let isBusying = false;
const pageObserver = new MutationObserver(async function () {
if (isBusying) {
return;
}
const moviePlayer = document.getElementById("movie_player");
if (!moviePlayer) {
return;
}
const adOverlay = moviePlayer.getElementsByClassName(
"ytp-ad-player-overlay"
)[0];
if (!adOverlay) {
return;
}
isBusying = true;
try {
const adInfo = adOverlay.getElementsByClassName(
"ytp-ad-player-overlay-instream-info"
)[0];
log("found ad:", adInfo && adInfo.innerText);
await skipAd(moviePlayer, adOverlay);
} catch (err) {
log("got error:", err.message);
} finally {
isBusying = false;
}
});
if (window.self !== window.top) {
return;
}
pageObserver.observe(document.body, {
childList: true,
subtree: true,
});
log("--- start ---");
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址