Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music
// ==UserScript== // @name 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:zh-CN 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:zh-TW 屏蔽所有Youtube廣告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:ar 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:bg 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:cs 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:da 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:de 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:el 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:eo 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:es 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:fi 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:fr 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:fr-CA 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:he 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:hu 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:id 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:it 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:ja YoutubeMusicを含むすべてのYoutube広告をブロックする // @name:ko 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:kr Youtube Music을 포함한 모든 YouTube 광고 차단 // @name:nb 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:nl 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:pl 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:pt-BR 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:ro 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:ru 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:sk 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:sr 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:sv 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:th 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:tr 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:uk 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:ug 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @name:vi 屏蔽所有Youtube广告 Youtube AD blocker (Block all ad). Including blocking Youtube Music. // @description Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:zh-CN 屏蔽所有视频广告、插入广告、页面广告 // @description:zh-TW 屏蔽所有視頻廣告、插入廣告、頁面廣告 // @description:ar Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:bg Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:cs Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:da Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:de Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:el Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:eo Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:es Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:fi Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:fr Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:fr-CA Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:he Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:hu Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:id Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:it Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:ja すべてのビデオ広告をブロックし、広告を挿入し、ページ広告を挿入します。YoutubeMusicを含みます。 // @description:ko Youtube Music을 포함한 모든 비디오 광고, 삽입 광고, 페이지 광고 차단. // @description:kr Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:nb Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:nl Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:pl Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:pt-BR Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:ro Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:ru Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:sk Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:sr Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:sv Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:th Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:tr Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:uk Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:ug Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music // @description:vi Block all video ads, insert ads, page ads. Including Youtube Music. 屏蔽所有视频广告、插入广告、页面广告。包括Youtube Music. // @namespace https://github.com/ChenZihan-sudo/Youtube-AD-blocker/ // @version 6.0.1 [Beta] // @author ChenZihan // @match *.youtube.com/* // @icon // @grant none // ==/UserScript== (function () { let rmAry = new Array(); let { href } = location; setInterval(() => { let bufHref = location.href; //detect the change of href and execute let detectBasicAd; //detect the activity of insert ad in video if (document.getElementsByClassName("ytp-ad-preview-text").length) { detectBasicAd = (document.getElementsByClassName("ytp-ad-preview-text")[0].innerHTML.constructor == String); } //* skipShitVideoAD() can only reset by change of href //! check if the frame exist if (bufHref != href && document.getElementById("iframe")) { console.log("isCallSkipShitVideoAD = false"); isCallSkipShitVideoAD = false; } //* check change of href if (bufHref != href) { console.log("[YT AD block] Detect the change of href.", href); href = bufHref; executeManager('f'); } //* check the insert AD if (detectBasicAd) { console.log("[YT AD block] Found the insert AD."); executeManager('f'); } }, 500); if (location.hostname.search("youtube") != -1) { addBData('id', 'player-ads', 'f'); //add data addBData('id', 'masthead-ad', 'f'); addBData('path', '#YtKevlarVisibilityIdentifier', 'f'); addBData('class', 'ytp-ad-overlay-container', 'a'); addBData('csClick', [ ['ytp-ad-feedback-dialog-reason-input', 'randomPara(0, 2)'], ['ytp-ad-feedback-dialog-confirm-button', '0'], 1 ], 'f'); addBData('csClick', [ ['ytp-ad-skip-button', '0'], 0 ], 'a'); addBData('tag', 'ytd-display-ad-renderer', 'a'); addBData("exe", "skipShitVideoAD();", 'f'); addBData("exe", "addBlockText();", 'f'); addBData("remTactic1", ["badge-style-type-ad", 7, "ytd-section-list-renderer"], 'f'); addBData("remTactic1", ["badge-style-type-ad", 5, "ytd-item-section-renderer"], 'f'); addBData("remTactic1", ["badge-style-type-ad", 5, "ytd-watch-next-secondary-r###lts-renderer"], 'f'); executeManager(); //execute at first time } /** * @param {String} exePara (undefined) or ('f' => execute the data for 20 times, every time interval 500ms ) * */ function executeManager(exePara) { let len = rmAry.length; for (let i = 0; i < len; i++) { if (rmAry[i][2] == 'a' && exePara == undefined) { setInterval(() => { // console.log("[YT AD block] Execute remove insert AD loop"); execute(); //always execute the data }, 800); } else if (rmAry[i][2] == 'f' || exePara == 'f') { //execute only in first time // console.log("[YT AD block] Execute remove AD"); window.onload = function () { intervalExecute(); } //if player already load if (exePara == 'f') { intervalExecute(); } intervalExecute(); function intervalExecute() { let times = 0; let timer = setInterval(() => { times++; if (times > 20) { clearInterval(timer); }; execute(); //excute 20 times in every 500ms }, 500); } } function execute() { let isUniExeTag = rmAry[i][0] == "universal"; //Check is universal tag or not if (!isUniExeTag) { let exeTag = rmAry[i][0]; //Execute Type let exeData = rmAry[i][1]; //Data container of execute type executeBase(exeTag, exeData); } else { //[Beta] Execute Type: universal // let exeLength = rmAry[i][1].length; // for (let layeri = 0; layeri < exeLength; layeri++) { // let layerExeData = rmAry[i][1][layeri]; // let exeTag = layerExeData[0]; // let exeData = layerExeData[1]; // executeBase(layerExeData, exeTag, exeData); // } }; } function executeBase(exeTag, exeData) { let cckClassDataPosi, cckType, cckCs; switch (exeTag) { case 'id': idRm(exeData); break; case 'path': pathRm(exeData); break; case 'class': classRm(exeData); break; case 'csClick': { len = rmAry[i][1].length - 1; //find last one num cckClassDataPosi = rmAry[i][1][len]; cckType = rmAry[i][1][len].constructor; if (cckType == Number) { cckCs = rmAry[i][1][cckClassDataPosi][0]; } else if (cckType == String) { cckCs = rmAry[i][1][2]; } csClick(cckCs, rmAry[i][1]); break; } case 'tag': tagRm(exeData); break; case 'exe': { dataExe(exeData); } break; case 'remTactic1': { let className = exeData[0]; let parentNum = exeData[1]; let expParentClassName = exeData[2]; remTactic1(className, parentNum, expParentClassName); } break; } } } } function addUniData(d2, d3) { addBData('universal', d2, d3); } function addExeData(d2, d3) { addBData('exe', d2, d3); } /** * @param d1 - Execute Type: 'id' => Use document.getElementById() to remove * @param d1 - Execute Type: 'path' => Use document.querySelector() to remove * @param d1 - Execute Type: 'class' => Use document.getElementsByClassName() to remove * @param d1 - Execute Type: 'csClick' => css click event * @param d1 - Execute Type: 'tag' => Use document.getElementsByTagName() to remove * @param d1 - Execute Type: 'exe' => Use eval to execute the code * @param d1 - Execute Type: 'remTactic1' => See remTactic1(); * @param d2 - Data container of d1 execute type * @param d3 - 'a' => Always execute the data, interval 800ms * @param d3 - 'f' => First execute the data for 20 times, every time interval 500ms */ function addBData(d1, d2, d3) { let len = apdAry(rmAry); rmAry[len][0] = d1; rmAry[len][1] = d2; rmAry[len][2] = d3; rmAry[len][3] = rmAry.length - 1; } /** * By finding a className to find higher level of its parent element by class name and remove it * @param {String} className The child node class name (signature class name recommend) * @param {Number} parentNum How many node layers it parent elements have to get className(child node) * @param {String} expParentClassName The parent node class name(signature class name recommend) */ function remTactic1(className, parentNum, expParentClassName) { var sl_length = document.getElementsByClassName(className).length; if (sl_length != 0) { if (parentNum == 0) { var len = document.getElementsByClassName(className).length; for (let i = 0; i < len; i++) { document.getElementsByClassName(className)[0].remove(); } } else { for (var s_i = 0; s_i < sl_length; s_i++) { var parent = ".parentElement"; var finalParent = ""; for (var p_i = 0; p_i < parentNum; p_i++) { finalParent = finalParent + parent; } //Find the parent name var parentNode = "document.getElementsByClassName('" + className + "')[0]" + finalParent; var parentNodeClassListLength = eval(parentNode + ".classList.length"); var isParentClassName = false; for (let ii = 0; ii < parentNodeClassListLength; ii++) { var parentClassName = eval(parentNode + ".classList[" + ii + "]"); if (parentClassName == expParentClassName) { isParentClassName = true; break; } } if (isParentClassName) { eval("document.getElementsByClassName('" + className + "')[0]" + finalParent + ".remove();"); remTactic1(className, parentNum, expParentClassName); break; } } } } } function csClick(cckCs, exAry) { if (document.getElementsByClassName(cckCs).length != 0) { let len = exAry.length; for (let i = 0; i < len; i++) { if (exAry[i].constructor != Array) { break; } //cck data type document.getElementsByClassName(exAry[i][0])[eval(exAry[i][1])].click(); //choose feedback option } } } function classRm(_class) { let times = 0; while (document.getElementsByClassName(_class).length != 0) { times++; if (times > 100) { break; } document.getElementsByClassName(_class)[0].remove(); } } function idRm(id) { if (document.getElementById(id) != null) { document.getElementById(id).remove(); } } function pathRm(path) { if (document.querySelector(path) != null) { document.querySelector(path).remove(); } } function tagRm(tag) { let times = 0; while (document.getElementsByTagName(tag).length != 0) { times++; if (times > 100) { break; } document.getElementsByTagName(tag)[0].parentNode.parentNode.remove(); } } function dataExe(exeData) { if (exeData) { let isArray = exeData.constructor == Array; if (!isArray) { eval(exeData); } else { //[Beta Test] Execute Type: universal if (exeData[0]) { let finalData = exeData[0] + exeData[1]; eval(finalData); } } } } function randomPara(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function apdAry(ary) { ary.splice(ary.length, 0, []); return ary.length - 1; } function addBlockText() { //本屏蔽器自带嘲讽功能[doge] if (document.getElementById("ad-text:a") != (null || undefined)) { document.getElementById("ad-text:a").innerHTML = "Trying Blocking AD..."; } if (document.getElementById("ad-text:b") != (null || undefined)) { document.getElementById("ad-text:b").innerHTML = "[Youtube AD block]"; } let blockText = document.getElementsByClassName("ytp-ad-button-text"); if (blockText.length != 0) { for (let i = 0; i < blockText.length; i++) { blockText[i].innerHTML = "Blocking..." } } } var isCallSkipShitVideoAD = false; function skipShitVideoAD() { if (document.getElementsByClassName("ytp-ad-button-icon").length != 0 && !isCallSkipShitVideoAD && !document.getElementsByClassName('ytp-ad-skip-button').length != 0) { console.log("进入执行"); isCallSkipShitVideoAD = true; //set identifier as true to avoid call this function again console.log("===>", new DocumentTimeline().currentTime); //Open the shit ad card document.getElementsByClassName("ytp-ad-button-icon")[0].click(); // Wait the card load let shitIframeTimes = 0; let iframeDomPosi = 0; //find the iframe document posi let shitIframeTimer = setInterval(function () { shitIframeTimes++; setDisplay("none"); if (document.getElementById("iframe") != (null || undefined) || shitIframeTimes > 50) { console.log("[YT] Detected the ad penel"); //find the iframe document posi for (let i = 0; i < window.frames.length; i++) { let frameId = "iframe"; try { if (window.frames[i].frameElement.id == frameId) { iframeDomPosi = i; break; } } catch (e) { /*console.log(e);*/ } } clearInterval(shitIframeTimer); } }, 40); //Wait for document loaded var waitCardTimes = 0; let frameDom; let waitCardTimer = setInterval(() => { waitCardTimes++; let bodyNodesLength = 0; //iframe body length of child node try { bodyNodesLength = window.frames[iframeDomPosi].document.body.childNodes.length; } catch { } if (waitCardTimes > 100 || bodyNodesLength != 0) { clearInterval(waitCardTimer); //get the iframe document frameDom = window.frames[iframeDomPosi].document; try { let shitStopDisplayBtn = frameDom.childNodes[1].childNodes[1].childNodes[2].childNodes[0].childNodes[0].childNodes[1].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[1].childNodes[1].childNodes[0].childNodes[0]; shitStopDisplayBtn.click(); let deleteClickTimes = 0; let deleteClickTimer = setInterval(() => { deleteClickTimes++; let isCatchErr = false; try { let clickStopAdBtn = frameDom.childNodes[1].childNodes[1].childNodes[9].childNodes[0].childNodes[1].childNodes[1].childNodes[0].childNodes[0].childNodes[1].childNodes[1].childNodes[0]; clickStopAdBtn.click(); console.log("获取到移除按钮,移除===>", clickStopAdBtn); } catch (e) { isCatchErr = true; console.log("错误捕获"); } if (deleteClickTimes > 100 || isCatchErr == false) { clearInterval(deleteClickTimer); console.log("===>", new DocumentTimeline().currentTime); } }, 100); } catch (e) { console.log("2", e); } } }, 100); //close the card let checkCloseTimes = 0; let checkCloseTimer = setInterval(() => { checkCloseTimes++; var alreadyRemoveDisplay = "none"; try { alreadyRemoveDisplay = getComputedStyle(frameDom.childNodes[1].childNodes[1].childNodes[2].childNodes[0].childNodes[0].childNodes[1].childNodes[0]).display; } catch { } if (alreadyRemoveDisplay != "none" || checkCloseTimes > 200) { console.log("close card"); clearInterval(checkCloseTimer); //* close the card let closeShitPanelBtn = frameDom.childNodes[1].childNodes[1].childNodes[2].childNodes[0].childNodes[0].childNodes[0].childNodes[2].childNodes[0].childNodes[0]; closeShitPanelBtn.click(); //* reset the backdrop, setTimeout didn't effect the use. setTimeout(() => { document.getElementsByTagName("tp-yt-iron-overlay-backdrop")[0].style.display = ""; console.log("reback display"); }, 1000); } }, 100); function setDisplay(str) { //* Set the shit backdrop display "none" or "" try { document.getElementsByTagName("tp-yt-iron-overlay-backdrop")[0].style.display = str; } catch { } //* Set the shit ad card display "none" or "" try { document.getElementById("iframe").parentNode.parentNode.style.display = str; } catch { } } } } })();