yt blocker

none

  1. // ==UserScript==
  2. // @name yt blocker
  3. // @version 24
  4. // @description none
  5. // @run-at document-start
  6. // @author rssaromeo
  7. // @license GPLv3
  8. // @match *://youtube.com/*
  9. // @match *://*.youtube.com/*
  10. // @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=
  11. // @grant unsafeWindow
  12. // @require https://update.gf.qytechs.cn/scripts/491829/1356221/tampermonkey%20storage%20proxy.js
  13. // @grant GM_getValue
  14. // @grant GM_setValue
  15. // @grant unsafeWindow
  16. // @namespace https://gf.qytechs.cn/users/1184528
  17. // ==/UserScript==
  18.  
  19. // % of video watched to hide, 0 to not hide any
  20. const hideWatchedVidProg = 1
  21.  
  22. const rclickBlocksUrl = true
  23. const rclickBlocksTitle = true
  24.  
  25. ;(async () => {
  26. const a = loadlib("allfuncs")
  27. const sp = new storageproxy("globaloptions")
  28. var ls = sp.get()
  29. // var lastvol // stores the last volume to restore to when muting from sub button border
  30. var vidlock = true
  31. const LOC = {}
  32. updateLoc()
  33.  
  34. // var LOADED = false
  35. function setVidSpeed() {
  36. unsafeWindow.novidspeedcontroller = true
  37. for (var vid of a.qsa("video")) {
  38. vid.playbackRate = vidlock
  39. ? 0
  40. : Number(!globalname ? 0 : localStorage.playrate ?? 0)
  41. }
  42. }
  43. ls.blockedCreators ??= []
  44. ls.blockedTitles ??= []
  45. ls.blockedTitlesReg ??= []
  46. ls.blockedCreatorsReg ??= []
  47. ls.blockedUrls ??= []
  48. if (LOC.watch) {
  49. var fastint = setInterval(setVidSpeed, 0)
  50. setVidSpeed()
  51. update()
  52. await a.waitforelem(
  53. "#channel-name>#container>#text-container>yt-formatted-string>a"
  54. )
  55. clearInterval(fastint)
  56. }
  57. setInterval(update, 1000)
  58. // LOADED = true
  59. var globalname
  60. function newBlockBtn(title, creator) {
  61. var elem = a.newelem("button", {
  62. innerHTML: ls.blockedCreators.includes(this.title)
  63. ? "unblock"
  64. : "block",
  65. creator,
  66. title,
  67. id: "blockbtn",
  68. onclick(e) {
  69. e.stopImmediatePropagation()
  70. e.stopPropagation()
  71. e.preventDefault()
  72. log(this.creator)
  73. if (ls.blockedCreators.includes(this.creator)) {
  74. ls.blockedCreators.splice(
  75. ls.blockedCreators.indexOf(this.creator),
  76. 1
  77. )
  78. } else {
  79. ls.blockedCreators.push(this.creator)
  80. }
  81. update()
  82. log(ls.blockedCreators, this.creator)
  83. },
  84. oncontextmenu(e) {
  85. e.stopImmediatePropagation()
  86. e.stopPropagation()
  87. e.preventDefault()
  88. if (rclickBlocksUrl) {
  89. log(this.url)
  90. if (ls.blockedUrls.includes(this.url)) {
  91. ls.blockedUrls.splice(ls.blockedUrls.indexOf(this.url), 1)
  92. } else {
  93. ls.blockedUrls.push(this.url)
  94. }
  95. update()
  96. log(ls.blockedUrls, this.url)
  97. }
  98. if (rclickBlocksTitle) {
  99. log(this.title)
  100. if (ls.blockedTitles.includes(this.title)) {
  101. ls.blockedTitles.splice(
  102. ls.blockedTitles.indexOf(this.title),
  103. 1
  104. )
  105. } else {
  106. ls.blockedTitles.push(this.title)
  107. }
  108. update()
  109. log(ls.blockedTitles, this.title)
  110. }
  111. },
  112. })
  113. ;((elem, creator) => {
  114. var val = creator
  115. Object.defineProperty(elem, "creator", {
  116. get() {
  117. return val
  118. },
  119. set(newval) {
  120. val = newval.replace(/ • \d+\w? views$/, "")
  121. },
  122. enumerable: true,
  123. configurable: true,
  124. })
  125. })(elem, creator)
  126. return elem
  127. }
  128. update()
  129. function update() {
  130. try {
  131. updateLoc()
  132. unsafeWindow.ls = ls = sp.get()
  133.  
  134. if (LOC.search) {
  135. addVid(
  136. "div#dismissible.style-scope.ytd-video-renderer:has(a#video-title)",
  137. "a#video-title",
  138. "#video-title",
  139. "#text > a",
  140. "#channel-info"
  141. )
  142. } else if (LOC.root) {
  143. globalname = null
  144. addVid(
  145. "ytd-rich-item-renderer:has(#video-title-link):has(a.yt-simple-endpoint.style-scope.yt-formatted-string):has(a.yt-simple-endpoint.style-scope.yt-formatted-string)",
  146. "#video-title-link",
  147. "#video-title:not(.cbCustomTitle)",
  148. "a.yt-simple-endpoint.style-scope.yt-formatted-string",
  149. "#details>#meta>ytd-video-meta-block:has(#additional-metadata-line):has(#metadata)"
  150. )
  151. } else if (LOC.feed) {
  152. addVid(
  153. "#dismissible:has(#video-title-link)",
  154. "#video-title-link",
  155. "#video-title-link>yt-formatted-string:not(.cbCustomTitle)",
  156. "#container>#text-container>yt-formatted-string#text>a",
  157. "#byline-container"
  158. )
  159. } else if (LOC.userhome || LOC.uservids) {
  160. const CREATOR = getCreatorNameFromUrl(location.href)
  161. const btn = a.qs(
  162. "#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"
  163. )
  164. if (
  165. a.qs(
  166. "#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"
  167. ) &&
  168. !btn
  169. ) {
  170. a.qs(
  171. "#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"
  172. ).appendChild(newBlockBtn(null, CREATOR))
  173. } else if (btn) {
  174. btn.innerHTML = isBlocked(btn.creator, btn.title, btn.url)
  175. ? "unblock - " +
  176. JSON.stringify(
  177. isBlocked(btn.creator, btn.title, btn.url)
  178. )
  179. : "block"
  180. }
  181. if (LOC.userhome) {
  182. addVid(
  183. "#dismissible:has(#video-title-link)",
  184. "#video-title-link",
  185. "#video-title-link",
  186. {
  187. raw: CREATOR,
  188. },
  189. "#byline-container"
  190. )
  191. addVid(
  192. "#dismissible:has(#video-title-link)",
  193. "#video-title-link",
  194. "#video-title-link",
  195. "#container>#text-container>yt-formatted-string#text",
  196. "#byline-container"
  197. )
  198. }
  199. if (LOC.uservids) {
  200. addVid(
  201. "ytd-rich-item-renderer:has(#dismissible #video-title-link)",
  202. "#video-title-link",
  203. "#video-title-link > #video-title:not(.cbCustomTitle)",
  204. {
  205. raw: CREATOR,
  206. },
  207. "#meta > h3"
  208. )
  209. }
  210. } else if (LOC.watch) {
  211. if (!a.qs("#playrate") && a.qs(".ytp-right-controls")) {
  212. a.qs(".ytp-right-controls").appendChild(
  213. a.newelem(
  214. "div",
  215. {
  216. display: "inline flex",
  217. flexDirection: "row",
  218. id: "playrate",
  219. class:
  220. "ytp-button ytp-settings-button ytp-hd-quality-badge",
  221. minWidth: "200xp",
  222. Width: "200xp",
  223. },
  224. [
  225. a.newelem("button", {
  226. innerHTML: "1",
  227. onclick() {
  228. localStorage.playrate = 1
  229. update()
  230. },
  231. }),
  232. a.newelem("button", {
  233. innerHTML: "2",
  234. onclick() {
  235. localStorage.playrate = 2
  236. update()
  237. },
  238. }),
  239. ]
  240. )
  241. )
  242. }
  243. globalname = a.qs(
  244. "#upload-info>ytd-channel-name#channel-name>#container>#text-container>yt-formatted-string#text > a"
  245. )?.textContent
  246. if (
  247. a.qs("ytd-video-owner-renderer") &&
  248. a.qs("#title > h1 > span.cbCustomTitle")
  249. ) {
  250. addVid(
  251. "ytd-watch-metadata",
  252. {
  253. raw: location.href.split("?v=").at(-1).split("&")[0],
  254. },
  255. "#title > h1 > yt-formatted-string",
  256. "#container>#text-container>yt-formatted-string#text>a",
  257. "ytd-video-owner-renderer"
  258. )
  259. a.qs("ytd-watch-metadata").style.display = ""
  260. const btn = a.qs("ytd-video-owner-renderer>#blockbtn")
  261. vidlock = isBlocked(btn.creator, btn.title, btn.url)
  262. btn.innerHTML = isBlocked(btn.creator, btn.title, btn.url)
  263. ? "unblock - " +
  264. JSON.stringify(
  265. isBlocked(btn.creator, btn.title, btn.url)
  266. )
  267. : "block"
  268. }
  269.  
  270. // these don't have creator id anywhere only creator name so all will be hidden
  271.  
  272. // addVid(
  273. // "ytd-compact-video-renderer:has(#dismissible #video-title-link)",
  274. // "#video-title-link",
  275. // "#container>#text-container>yt-formatted-string#text",
  276. // "#metadata"
  277. // )
  278. // these also don't have creator data
  279. // addVid(
  280. // "#movie_player > div.html5-endscreen.ytp-player-content.videowall-endscreen.ytp-show-tiles > div > a:has(span.ytp-videowall-still-info)",
  281. // "span.ytp-videowall-still-info > span > span>div>.cbCustomTitle",
  282. // "span.ytp-videowall-still-info > span > span>.ytp-videowall-still-info-author",
  283. // "span.ytp-videowall-still-info > span > span>div"
  284. // )
  285. // new youtube display classes?
  286. a.qsa(
  287. "yt-lockup-view-model:has(yt-lockup-metadata-view-model)"
  288. ).forEach((e) => (e.style.visibility = "hidden"))
  289. a.qsa(".ytp-videowall-still").forEach(
  290. (e) => (e.style.visibility = "hidden")
  291. )
  292. // addVid(
  293. // "yt-lockup-view-model:has(yt-lockup-metadata-view-model)",
  294. // "div.yt-lockup-metadata-view-model-wiz__text-container > h3 > a",
  295. // "yt-content-metadata-view-model > div:nth-child(1) > span",
  296. // ".yt-lockup-view-model-wiz__metadata:has(yt-lockup-metadata-view-model)"
  297. // )
  298. setVidSpeed()
  299. }
  300. } catch (e) {
  301. trace("update", e)
  302. }
  303. }
  304.  
  305. function addVid(
  306. mainDivID,
  307. url,
  308. titleID,
  309. creatorID,
  310. blockButtonParentID
  311. ) {
  312. try {
  313. // log(mainDivID, a.qsa(mainDivID))
  314. // remove invalid block buttons on root
  315. // if (isroot())
  316. // a.qsa("#blockbtn")
  317. // .filter(function (btn) {
  318. // return btn.closest(blockButtonParentID)
  319. // })
  320. // .forEach((e) => e.remove())
  321. for (var viddiv of a.qsa(mainDivID)) {
  322. if (viddiv.textContent.includes("Free with ads")){
  323. viddiv.style.display='none'
  324. continue
  325. }
  326. var btn = a.qs(blockButtonParentID + ">#blockbtn", viddiv)
  327. if (!btn)
  328. btn = a
  329. .qs(blockButtonParentID, viddiv)
  330. .appendChild(newBlockBtn("", ""))
  331. btn.url =
  332. url.raw ??
  333. a.qs(url, viddiv).href.split("?v=").at(-1).split("&")[0]
  334. btn.title = titleID.raw?.toLowerCase?.() ?? a.qs(titleID, viddiv).textContent.toLowerCase()
  335. btn.creator =
  336. creatorID.raw ??
  337. getCreatorNameFromUrl(a.qs(creatorID, viddiv).href)
  338. btn.innerHTML = ls.blockedCreators.includes(btn.creator)
  339. ? "unblock"
  340. : "block"
  341. var prog =
  342. a.qs(
  343. ".ytd-thumbnail-overlay-resume-playback-renderer.style-scope",
  344. viddiv
  345. ) ||
  346. a.qs(
  347. ".ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment",
  348. viddiv
  349. )
  350.  
  351. viddiv.style.display =
  352. isBlocked(btn.creator, btn.title, btn.url) ||
  353. (hideWatchedVidProg &&
  354. prog &&
  355. prog.style.width.replace("%", "") > hideWatchedVidProg)
  356. ? "none"
  357. : ""
  358. }
  359. } catch (e) {
  360. trace("addVid", e, titleID, creatorID, viddiv)
  361. }
  362. }
  363. unsafeWindow.isBlocked = isBlocked
  364. unsafeWindow.addVid = addVid
  365. function isBlocked(creator, title, url) {
  366. try {
  367. if (creator == undefined)
  368. return {
  369. type: "invalid creator",
  370. val: { creator, title, url },
  371. }
  372.  
  373. if (ls.blockedUrls.includes(url))
  374. return { type: "blockedUrls", val: url }
  375. if (ls.blockedTitles.includes(title))
  376. return { type: "blockedTitles", val: title }
  377. if (ls.blockedCreators.includes(creator))
  378. return { type: "blockedCreators", val: creator }
  379. for (let reg of ls.blockedCreatorsReg) {
  380. if (new RegExp(reg, "i").test(creator))
  381. return { type: "blockedCreatorsReg", val: reg }
  382. }
  383. for (let reg of ls.blockedTitlesReg) {
  384. if (new RegExp(reg, "i").test(title))
  385. return { type: "blockedTitlesReg", val: reg }
  386. }
  387. return false
  388. } catch (e) {
  389. trace("isBlocked", e)
  390. }
  391. }
  392. function updateLoc() {
  393. Object.assign(LOC, {
  394. root: /^https?:\/\/(?:www\.)?youtube\.com\/?(?:\?|#|$)/.test(
  395. location.href
  396. ),
  397. watch:
  398. /^https?:\/\/(?:www\.)?youtube\.com\/watch\/?(?:\?|#|$)/.test(
  399. location.href
  400. ),
  401. search:
  402. /^https?:\/\/(?:www\.)?youtube\.com\/results\?search_query=.*(?:#|$)/.test(
  403. location.href
  404. ),
  405. feed: /^https?:\/\/(?:www\.)?youtube\.com\/feed\/subscriptions/.test(
  406. location.href
  407. ),
  408. userhome:
  409. /^https?:\/\/(?:www\.)?youtube\.com\/@[^\/]+\/?$/.test(
  410. location.href
  411. ),
  412. uservids:
  413. /^https?:\/\/(?:www\.)?youtube\.com\/@[^\/]+\/videos\/?$/.test(
  414. location.href
  415. ),
  416. })
  417. }
  418.  
  419. function getCreatorNameFromUrl(url) {
  420. return url.match(/(?:\/@|\/(?:channel|user|c)\/)([^\/]*)/i)?.[1]
  421. }
  422. })()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址