Skip to content

Instantly share code, notes, and snippets.

@nojaja
Last active December 13, 2024 17:25
Show Gist options
  • Select an option

  • Save nojaja/cdeec6bdc0e77decb6a7e6350cb90c44 to your computer and use it in GitHub Desktop.

Select an option

Save nojaja/cdeec6bdc0e77decb6a7e6350cb90c44 to your computer and use it in GitHub Desktop.
youtube広告削除ツール
//広告枠へのタグ追加を監視
document.querySelector("div.video-ads").addEventListener('DOMNodeInserted', function(event) {
//バナー広告の閉じるボタン取得
let element = document.querySelector("div.ytp-ad-overlay-close-container > button");
if(element){
//閉じるボタンが取得できたのでクリック
element.click();
console.log('ad closed');
return;
}
//動画広告のスキップボタン取得
element = document.querySelector(".ytp-ad-skip-button");
if(element){
//スキップボタンが取得できたのでクリック
element.click();
console.log('ad skiped');
return;
}
//動画広告のスキップボタン取得
element = document.querySelector(".ytp-ad-skip-button-modern");
if(element){
//スキップボタンが取得できたのでクリック
element.click();
console.log('ad skiped');
return;
}
element = document.querySelector("span.ytp-ad-preview-container");
if(element){
console.log('動画はまもなく再生されます',element);
const videoElement= document.querySelector("video.video-stream");
if(videoElement) {
console.log('videoElement.playbackRate',videoElement.playbackRate )
videoElement.playbackRate=16
console.log('videoElement.playbackRate',videoElement.playbackRate )
}
return;
}
}, false);
//今⁠な⁠ら⁠、YouTube Premium⁠ ⁠が 3⁠ ⁠ヶ⁠月⁠無⁠料のダイアログ非表示
document.querySelector("ytd-app").addEventListener('DOMNodeInserted', function(event) {
// console.log('ytd-app DOMNodeInserted');
let element = document.querySelector(".ytd-popup-container:not([hidden])")
if(element){
//スキップボタンが取得できたのでクリック
element.hidden=true
console.log('promo hidden');
}
}, false);
console.log('installed youtube ad blocker');
@kassyi

kassyi commented Dec 13, 2024

Copy link
Copy Markdown

https://stackoverflow.com/questions/77836203/finding-some-way-to-click-the-skip-ad-button-that-youtube-has-blocked
スキップボタンはUI Events.isTrustedを見ているようで、スクリプトによる操作を排除しているようです。なので、isTrusted=trueなイベントを作りたい。と併用することで、自動クリックできます。ただとても重く、現実的な用途ではもうひと工夫必要そうです。

//https://qiita.com/i11u/items/0a6d38966c75314bacba
Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function () {
  let args = [...arguments];
  let temp = args[1];
    args[1] = function () {
    let args2 = [...arguments];
      args2[0] = Object.assign({}, args2[0]);
      args2[0].isTrusted = true;
      return temp(...args2);
    };
  return this._addEventListener(...args);
};

//https://gist.github.com/nojaja/cdeec6bdc0e77decb6a7e6350cb90c44
const videoAdsObserver = new IntersectionObserver((entries) => {
	entries.forEach((entry) => {
		if (entry.isIntersecting) {
			const videoAdsElement = entry.target;
			console.log('div.video-ads が表示されました');

			// 任意のボタンセレクタを引数に取る関数を定義
			const observeButton = buttonSelector =>{
				// videoAdsElement 内の変更を監視する MutationObserver を作成
				const buttonObserver = new MutationObserver((mutations) => {
					mutations.forEach((mutation) => {
						if (mutation.type === 'childList') {
							const buttonElement =
								videoAdsElement.querySelector(buttonSelector);
							if (buttonElement) {
								console.log(
									buttonSelector + ' が追加されました'
								);
								
								buttonElement.click();
								console.log('ボタンをクリックしました');
								buttonObserver.disconnect(); // 監視を停止
							}
						}
					});
				});

				// videoAdsElement 内の変更を監視
				buttonObserver.observe(videoAdsElement, {
					childList: true,
					subtree: true,
				});
			}

			// 閉じるボタンを監視
			observeButton('div.ytp-ad-overlay-close-container > button');

			// スキップボタンを監視
			observeButton('.ytp-ad-skip-button');

			// 別のスキップボタンを監視
			observeButton('.ytp-ad-skip-button-modern');

			// 動画広告のプレビュー処理
			let previewContainer = document.querySelector(
				'span.ytp-ad-preview-container'
			);
			if (previewContainer) {
				console.log('動画はまもなく再生されます', previewContainer);
				const videoElement =
					document.querySelector('video.video-stream');
				if (videoElement) {
					console.log(
						'videoElement.playbackRate',
						videoElement.playbackRate
					);
					videoElement.playbackRate = 16;
					console.log(
						'videoElement.playbackRate',
						videoElement.playbackRate
					);
				}
			}

			videoAdsObserver.unobserve(videoAdsElement); // 監視を停止
		}
	});
});

// div.video-ads を監視
videoAdsObserver.observe(document.querySelector('div.video-ads'));

const ytdAppObserver = new IntersectionObserver((entries) => {
	entries.forEach((entry) => {
		if (entry.isIntersecting) {
			console.log('ytd-app が表示されました');

			// YouTube Premium ダイアログの処理
			let promoDialog = document.querySelector(
				'.ytd-popup-container:not([hidden])'
			);
			if (promoDialog) {
				promoDialog.hidden = true;
				console.log('promo hidden');
			}
		}
	});
});

// ytd-app を監視
ytdAppObserver.observe(document.querySelector('ytd-app'));

console.log('installed youtube ad blocker');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment