您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
none
// ==UserScript== // @name yt blocker // @version 14 // @description none // @run-at document-start // @author rssaromeo // @license GPLv3 // @match *://youtube.com/* // @match *://*.youtube.com/* // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHJQTFRFAAAAEIijAo2yAI60BYyuF4WaFIifAY6zBI2wB4usGIaZEYigIoiZCIyrE4igG4iYD4mjEomhFoedCoqpDIqnDomlBYyvE4efEYmiDYqlA42xBoytD4mkCYqqGYSUFYidC4qoC4upAo6yCoupDYqmCYur4zowOQAAACZ0Uk5TAO////9vr////1+/D/+/L+/Pf/////+f3///////H4////////+5G91rAAACgUlEQVR4nM2Y22KjIBCGidg1264liZqDadK03X3/V2wNKHMC7MpF/xthHD5mgERAqZhWhfYqH6K+Qf2qNNf625hCoFj9/gblMUi5q5jLkXLCKudgyiRm0FMK82cWJp1fLbV5VmvJbCIc0GCYaFqqlDJgADdBjncqAXYobm1xh72aFMflbysteFfdy2Yi1XGOm5HGBzQ1dq7TzEoxjeNTjQZb7VA3e1c7+ImgasAgQ9+xusNVNZIo5xmOMgihIS2PbCQIiHEUdTvhxCcS/kPomfFI2zHy2PkWmA6aNatIJpKFJyekyy02xh5Y3DI9T4aOT6VhIUrsNTFp1pf79Z4SIIVDegl6IJO6cHiL/GimIZDhgTu/BlYWCQzHMl0zBWT/T3KAhtxOuUB9FtBrpsz0RV4xsjHmW+UCaffcSy/5viMGer0/6HdFNMZBq/vjJL38H9Dqx4Fuy0Em12DbZy+9pGtiDijbglwAehyj11n0tRD3WUBm+lwulE/8h4BuA+iWAQQnteg2Xm63WQLTpnMnpjdge0Mgu/GRPsV4xdjQ94Lfi624fabhDkfUqIKNrM64Q837v8yL0prasepCgrtvw1sJpoqanGEX7b5mQboNW8eawXaWXTMfMGxub472hzWzHSn6Sg2G9+6TAyRruE71s+zAzjWaknoyJCQzwxrghH2k5FDT4eqWunuNxyN9QCGcxVod5oADbYnIUkDTGZEf1xDJnSFteQ3KdsT8zYDMQXcHxsevcLH1TrsABzkNPyA/L7b0jg704viMMlpQI96WsHknCt/3YH0kOEo9zcGkwrFK39ck72rmoehmKqo2RKlilzSy/nJKEV45CT38myJp456fezktHjN5aeMAAAAASUVORK5CYII= // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/491829/1356221/tampermonkey%20storage%20proxy.js // @grant GM_getValue // @grant GM_setValue // @grant unsafeWindow // @namespace https://greasyfork.org/users/1184528 // ==/UserScript== // % of video watched to hide, 0 to not hide any const hideWatchedVidProg = 60 ;(async () => { const a = loadlib("allfuncs") const sp = new storageproxy("globaloptions") var ls = sp.get() // var lastvol // stores the last volume to restore to when muting from sub button border var vidlock = true const LOC = {} updateLoc() // var LOADED = false function setVidSpeed() { unsafeWindow.novidspeedcontroller=true for (var vid of a.qsa("video")) { vid.playbackRate = vidlock ? 0 : Number(!globalname ? 0 : localStorage.playrate ?? 0) } } ls.blockedCreators ??= [] ls.blockedTitles ??= [] ls.blockedTitlesReg ??= [] ls.blockedCreatorsReg ??= [] if (LOC.watch) { var fastint = setInterval(setVidSpeed, 0) setVidSpeed() update() await a.waitforelem( "#channel-name>#container>#text-container>yt-formatted-string>a" ) clearInterval(fastint) } setInterval(update, 1000) // LOADED = true var globalname function newBlockBtn(title, creator) { var elem = a.newelem("button", { innerHTML: ls.blockedCreators.includes(this.title) ? "unblock" : "block", creator, title, id: "blockbtn", onclick(e) { e.stopImmediatePropagation() e.stopPropagation() e.preventDefault() log(this.creator) if (ls.blockedCreators.includes(this.creator)) { ls.blockedCreators.splice( ls.blockedCreators.indexOf(this.creator), 1 ) } else { ls.blockedCreators.push(this.creator) } update() log(ls.blockedCreators, this.creator) }, oncontextmenu(e) { e.stopImmediatePropagation() e.stopPropagation() e.preventDefault() log(this.title) if (ls.blockedTitles.includes(this.title)) { ls.blockedTitles.splice( ls.blockedTitles.indexOf(this.title), 1 ) } else { ls.blockedTitles.push(this.title) } update() log(ls.blockedTitles, this.title) }, }) ;((elem, creator) => { var val = creator Object.defineProperty(elem, "creator", { get() { return val }, set(newval) { val = newval.replace(/ • \d+\w? views$/, "") }, enumerable: true, configurable: true, }) })(elem, creator) return elem } update() function update() { try { updateLoc() unsafeWindow.ls = ls = sp.get() if (LOC.search) { addVid( "div#dismissible.style-scope.ytd-video-renderer", "#video-title", "#text > a", "#channel-info" ) } else if (LOC.root) { globalname = null addVid( "ytd-rich-item-renderer.style-scope.ytd-rich-grid-renderer:has(#video-title-link>yt-formatted-string#video-title):has(#details>#meta>ytd-video-meta-block>#metadata>#byline-container>ytd-channel-name#channel-name>#container>#text-container>yt-formatted-string#text>a)", "#video-title-link>yt-formatted-string#video-title", "#details>#meta>ytd-video-meta-block>#metadata>#byline-container>ytd-channel-name#channel-name>#container>#text-container>yt-formatted-string#text>a", "#details>#meta>ytd-video-meta-block:has(#additional-metadata-line):has(#metadata)" ) } else if (LOC.feed) { addVid( "#dismissible:has(#video-title)", "#video-title", "#container>#text-container>yt-formatted-string#text", "#byline-container" ) } else if (LOC.userhome || LOC.uservids) { const CREATOR = a.qs( "#page-header > yt-page-header-renderer > yt-page-header-view-model > div > div.page-header-view-model-wiz__page-header-headline > div > yt-dynamic-text-view-model > h1 > span" )?.textContent const btn = a.qs( "#page-header > yt-page-header-renderer > yt-page-header-view-model > div > div.page-header-view-model-wiz__page-header-headline > div > yt-dynamic-text-view-model > h1 > #blockbtn" ) if ( a.qs( "#page-header > yt-page-header-renderer > yt-page-header-view-model > div > div.page-header-view-model-wiz__page-header-headline > div > yt-dynamic-text-view-model > h1" ) && !btn ) { a.qs( "#page-header > yt-page-header-renderer > yt-page-header-view-model > div > div.page-header-view-model-wiz__page-header-headline > div > yt-dynamic-text-view-model > h1" ).appendChild(newBlockBtn(null, CREATOR)) } else if (btn) { btn.innerHTML = isBlocked(btn.creator, btn.title) ? "unblock - " + JSON.stringify(isBlocked(btn.creator, btn.title)) : "block" } if (LOC.userhome) { addVid( "#dismissible:has(#video-title)", "#video-title", { raw: CREATOR, }, "#byline-container" ) addVid( "#dismissible:has(#video-title)", "#video-title", "#container>#text-container>yt-formatted-string#text", "#byline-container" ) } if (LOC.uservids) { addVid( "ytd-rich-item-renderer:has(#dismissible #video-title)", "#video-title", { raw: CREATOR, }, "#meta > h3" ) } } else if (LOC.watch) { if (!a.qs("#playrate") && a.qs(".ytp-right-controls")) { a.qs(".ytp-right-controls").appendChild( a.newelem( "div", { display: "inline flex", flexDirection: "row", id: "playrate", class: "ytp-button ytp-settings-button ytp-hd-quality-badge", minWidth: "200xp", Width: "200xp", }, [ a.newelem("button", { innerHTML: "1", onclick() { localStorage.playrate = 1 update() }, }), a.newelem("button", { innerHTML: "2", onclick() { localStorage.playrate = 2 update() }, }), ] ) ) } globalname = a.qs( "#upload-info>ytd-channel-name#channel-name>#container>#text-container>yt-formatted-string#text > a" )?.textContent if ( a.qs("#upload-info") && a.qs("#title > h1 > span.cbCustomTitle") ) { if (a.qs("#upload-info>#blockbtn")) { a.qs("#upload-info>#blockbtn").creator = globalname a.qs("#upload-info>#blockbtn").title=a.qs("#title > h1 > span.cbCustomTitle").textContent||a.qs("#title > h1 > yt-formatted-string").textContent } else { a.qs("#upload-info").appendChild( newBlockBtn( a.qs("#title > h1 > span.cbCustomTitle").textContent||a.qs("#title > h1 > yt-formatted-string").textContent, globalname ) ) } const btn = a.qs("#upload-info>#blockbtn") vidlock = isBlocked(btn.creator, btn.title) btn.innerHTML = isBlocked(btn.creator, btn.title) ? "unblock - " + JSON.stringify(isBlocked(btn.creator, btn.title)) : "block" } addVid( "ytd-compact-video-renderer:has(#dismissible #video-title)", "#video-title", "#container>#text-container>yt-formatted-string#text", "#metadata" ) addVid( "#movie_player > div.html5-endscreen.ytp-player-content.videowall-endscreen.ytp-show-tiles > div > a:has(span.ytp-videowall-still-info)", "span.ytp-videowall-still-info > span > span>div>.cbCustomTitle", "span.ytp-videowall-still-info > span > span>.ytp-videowall-still-info-author", "span.ytp-videowall-still-info > span > span>div" ) setVidSpeed() } } catch (e) { trace("update", e) } } function addVid( mainDivID, titleID, creatorID, blockButtonParentID ) { try { // remove invalid block buttons on root // if (isroot()) // a.qsa("#blockbtn") // .filter(function (btn) { // return btn.closest(blockButtonParentID) // }) // .forEach((e) => e.remove()) for (var viddiv of a.qsa(mainDivID)) { var btn if ( (btn = a.qs(blockButtonParentID + ">#blockbtn", viddiv)) ) { btn.title = titleID.raw ?? a.qs(titleID, viddiv).textContent btn.creator = creatorID.raw ?? a.qs(creatorID, viddiv).textContent btn.innerHTML = ls.blockedCreators.includes(btn.creator) ? "unblock" : "block" } else { btn = a .qs(blockButtonParentID, viddiv) .appendChild( newBlockBtn( titleID.raw ?? a.qs(titleID, viddiv).textContent, creatorID.raw ?? a.qs(creatorID, viddiv).textContent ) ) } var prog = a.qs( ".ytd-thumbnail-overlay-resume-playback-renderer.style-scope", viddiv ) viddiv.style.display = isBlocked(btn.creator, btn.title) || (hideWatchedVidProg && prog && prog.style.width.replace("%", "") > hideWatchedVidProg) ? "none" : "" } } catch (e) { trace("addVid", e) } } unsafeWindow.isBlocked = isBlocked function isBlocked(creator, title) { try { if (ls.blockedTitles.includes(title)) return { type: "blockedTitles", val: title } if (ls.blockedCreators.includes(creator)) return { type: "blockedCreators", val: creator } for (let reg of ls.blockedCreatorsReg) { if (new RegExp(reg, "i").test(creator)) return { type: "blockedCreatorsReg", val: reg } } for (let reg of ls.blockedTitlesReg) { if (new RegExp(reg, "i").test(title)) return { type: "blockedTitlesReg", val: reg } } return false } catch (e) { trace("isBlocked", e) } } function updateLoc() { Object.assign(LOC, { root: /^https?:\/\/(?:www\.)?youtube\.com\/?(?:\?|#|$)/.test( location.href ), watch: /^https?:\/\/(?:www\.)?youtube\.com\/watch\/?(?:\?|#|$)/.test( location.href ), search: /^https?:\/\/(?:www\.)?youtube\.com\/results\?search_query=.*(?:#|$)/.test( location.href ), feed: /^https?:\/\/(?:www\.)?youtube\.com\/feed\/subscriptions/.test( location.href ), userhome: /^https?:\/\/(?:www\.)?youtube\.com\/@[^\/]+\/?$/.test( location.href ), uservids: /^https?:\/\/(?:www\.)?youtube\.com\/@[^\/]+\/videos\/?$/.test( location.href ), }) } })()