自動同意年齡提示,到達時間後自動跳過廣告,並註冊一些快捷鍵(詳見最下方的更新日誌)
目前為
// ==UserScript==
// @name Auto play ads on ani.gamer.com.tw
// @name:zh-CN 动画疯自动播放广告
// @name:zh-TW 動畫瘋自動播放廣告
// @namespace ling921
// @version 0.2
// @description Agree to age prompt, auto skip ads when time is up, and register some keyboard shortcuts (see the release notes below for details)
// @description:zh-CN 自动同意年龄提示,到达时间后自动跳过广告,并注册一些快捷键(详见最下方的更新日志)
// @description:zh-TW 自動同意年齡提示,到達時間後自動跳過廣告,並註冊一些快捷鍵(詳見最下方的更新日誌)
// @author ling921
// @match https://ani.gamer.com.tw/animeVideo.php*
// @match https://*.safeframe.googlesyndication.com/*
// @match https://imasdk.googleapis.com/*
// @icon http://gamer.com.tw/favicon.ico
// @grant none
// @run-at document-idle
// @tag video
// @tag anime
// @tag utilities
// @license MIT
// ==/UserScript==
/**
* Global variable to store video player
* @type {HTMLVideoElement}
*/
var videoPlayer;
(function () {
"use strict";
// Handle top level window
if (window === window.top) {
// Register keyboard shortcuts
document.addEventListener("keydown", (event) => {
// Ignore input fields event propagation
if (
event.target.tagName === "INPUT" ||
event.target.tagName === "TEXTAREA" ||
event.target.isContentEditable
) {
return;
}
if (!event.ctrlKey && !event.metaKey && !event.shiftKey) {
// [ goes to previous video
if (event.key === "[") {
const prevButton = document.querySelector(".vjs-pre-button");
if (prevButton) {
console.log("Go to previous video");
prevButton.click();
} else {
console.log("No previous video button found");
}
}
// ] goes to next video
else if (event.key === "]") {
const nextButton = document.querySelector(".vjs-next-button");
if (nextButton) {
console.log("Go to next video");
nextButton.click();
} else {
console.log("No next video button found");
}
}
// P pause or play
else if (event.key === "p") {
const playButton = document.querySelector(".vjs-play-control");
if (playButton) {
console.log("Pause or play");
playButton.click();
}
}
// T enter or exit theater mode
else if (event.key === "t") {
const theaterButton = document.querySelector(".vjs-indent-button");
if (theaterButton) {
console.log("Enter or exit theater mode");
theaterButton.click();
}
}
// F enter or exit fullscreen
else if (event.key === "f") {
const fullscreenButton = document.querySelector(
".vjs-fullscreen-control"
);
if (fullscreenButton) {
console.log("Enter or exit fullscreen");
fullscreenButton.click();
}
}
}
});
videoPlayer = document.querySelector("#ani_video_html5_api");
if (videoPlayer) {
console.log("Add event listener to videoPlayer");
videoPlayer.addEventListener("loadstart", () => {
videoPlayer.muted = false;
});
}
// Define observer to execute functions when DOM changes
const observer = new MutationObserver(() => {
agreeAgePrompt();
handleVideoPlayerAds();
});
// Start observing the body for changes
observer.observe(document.body, { childList: true, subtree: true });
}
// Handle iframe window
else {
if (window.location.href.includes("safeframe.googlesyndication.com")) {
const observer = new MutationObserver(() => {
handleIframeAds(document);
});
observer.observe(document.body, { childList: true, subtree: true });
} else if (window.location.href.includes("imasdk.googleapis.com")) {
const observer = new MutationObserver(() => {
handleIframeAds2(document);
});
observer.observe(document.body, { childList: true, subtree: true });
}
}
})();
/**
* Agree to age prompt
*/
function agreeAgePrompt() {
const agePrompt = document.querySelector("button.choose-btn-agree#adult");
if (agePrompt) {
console.log("Agree to age prompt");
agePrompt.click();
}
}
/**
* Handle ads in video player
*/
function handleVideoPlayerAds() {
const skipButton = document.querySelector("#adSkipButton");
if (skipButton) {
if (skipButton.classList.contains("enable")) {
console.log("Ads time is up, skip ads (#adSkipButton)");
skipButton.click();
} else {
videoPlayer.muted = true;
}
}
const skipButton2 = document.querySelector(".nativeAD-skip-button.enable");
if (skipButton2 && !skipButton2.classList.contains("vjs-hidden")) {
console.log("Ads time is up, skip ads (.nativeAD-skip-button)");
skipButton2.click();
}
}
/**
* Handle ads in iframe
* @param {Document} doc - The iframe document
*/
function handleIframeAds(doc) {
const adsCountDown = doc.querySelector("#count-down-text");
if (adsCountDown) {
const dismissDialog = () => {
const dismissButton = doc.querySelector("#card #dismiss-button-element");
if (dismissButton) {
if (dismissButton.style.display !== "none") {
console.log("Dismiss dialog Ad");
dismissButton.click();
} else {
console.log("Dismiss button is hidden, waiting for it to appear...");
}
} else {
console.log("Dismiss button is not found");
}
};
if (adsCountDown.offsetParent === null) {
dismissDialog();
} else if (adsCountDown.textContent === "1 秒後即可獲得獎勵") {
setTimeout(dismissDialog, 1000);
}
}
}
/**
* Handle ads in iframe
* @param {Document} doc - The iframe document
*/
function handleIframeAds2(doc) {
const skipButton = doc.querySelector('[aria-label="Skip Ad"]');
if (skipButton) {
if (skipButton.textContent === "Skip Ad") {
console.log('Click Skip Ad ([aria-label="Skip Ad"])');
skipButton.click();
} else {
videoPlayer.muted = true;
}
}
}
// Release notes
// 2024-12-15 version 0.2
// - 添加標籤 video, anime, utilities
// 2024-12-14 version 0.1
// - 自動同意年齡確認
// - 廣告倒數結束結束自動跳過廣告
// - 播放廣告時靜音,播放影片時取消靜音
// - 註冊快捷鍵 [ 和 ] 分別跳到上一個和下一個視頻
// - 註冊快速鍵 P 暫停或播放
// - 註冊快速鍵 T 進入或退出劇院模式
// - 註冊快捷鍵 F 進入或退出全螢幕