Block Youtube Users

Hide videos of blacklisted users/channels and comments

目前为 2021-08-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Block Youtube Users
  3. // @namespace https://github.com/Schegge
  4. // @description Hide videos of blacklisted users/channels and comments
  5. // @icon https://raw.githubusercontent.com/Schegge/Userscripts/master/images/BYUicon.png
  6. // @version 2.4.9
  7. // @author Schegge
  8. // @match https://www.youtube.com/*
  9. // @exclude *://*.youtube.com/embed/*
  10. // @exclude *://*.youtube.com/live_chat*
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM.getValue
  14. // @grant GM.setValue
  15. // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js
  16. // ==/UserScript==
  17.  
  18. // gm4 polyfill https://github.com/greasemonkey/gm4-polyfill
  19. if (typeof GM == 'undefined') {
  20. this.GM = {};
  21. Object.entries({
  22. 'GM_getValue': 'getValue',
  23. 'GM_setValue': 'setValue'
  24. }).forEach(([oldKey, newKey]) => {
  25. let old = this[oldKey];
  26. if (old && (typeof GM[newKey] == 'undefined')) {
  27. GM[newKey] = function(...args) {
  28. return new Promise((resolve, reject) => { try { resolve(old.apply(this, args)); } catch (e) { reject(e); } });
  29. };
  30. }
  31. });
  32. }
  33.  
  34. (async function($) {
  35.  
  36. /* VALUES */
  37.  
  38. const Values = {
  39. storageVer: '1',
  40. storageSep: ',',
  41. storageTimer: 1000,
  42. storageComment: '',
  43. storageVideo: '',
  44. storageAdd: '',
  45. storageBlacklist: [],
  46. storageWhitelist: [],
  47. menuOpen: false,
  48. menuPause: false
  49. };
  50.  
  51. // get saved values
  52. Values.storageVer = await GM.getValue('byuver', '1');
  53. Values.storageSep = await GM.getValue('sep', ',');
  54. Values.storageTimer = await GM.getValue('timer', 1000);
  55. Values.storageComment = await GM.getValue('hidecomments', '');
  56. Values.storageVideo = await GM.getValue('enablepause', '');
  57. Values.storageAdd = await GM.getValue('enableadd', '');
  58. Values.storageBlacklist = getArray(await GM.getValue('savedblocks', ''));
  59. Values.storageWhitelist = getArray(await GM.getValue('savedwhites', ''));
  60.  
  61. // get array from string
  62. function getArray(string) {
  63. if (!string) return [];
  64. return string.split(Values.storageSep).map(v => v.trim()).filter(v => v.length);
  65. }
  66.  
  67. const Where = {
  68. // home, related and page playlist: #metadata #text.ytd-channel-name
  69. // search video: #channel-info #text.ytd-channel-name
  70. // search channel: #channel-title.ytd-channel-renderer span.ytd-channel-renderer, #info #text.ytd-channel-name
  71. // video playlist: #byline.ytd-playlist-panel-video-renderer
  72. // user video: #meta #upload-info #channel-name #text.ytd-channel-name
  73. // comment: #author-text span.ytd-comment-renderer, #name #text.ytd-channel-name
  74. user: `#metadata #text.ytd-channel-name, #channel-info #text.ytd-channel-name, #channel-title.ytd-channel-renderer span.ytd-channel-renderer, #info #text.ytd-channel-name, #byline.ytd-playlist-panel-video-renderer, #meta #upload-info #channel-name #text.ytd-channel-name${Values.storageComment ? ', #author-text span.ytd-comment-renderer, #name #text.ytd-channel-name' : ''}`,
  75. renderer: `ytd-rich-item-renderer, ytd-video-renderer, ytd-channel-renderer, ytd-playlist-renderer, ytd-movie-renderer, ytd-compact-video-renderer, ytd-compact-radio-renderer, ytd-compact-autoplay-renderer, ytd-compact-playlist-renderer, ytd-playlist-video-renderer, ytd-grid-video-renderer, ytd-grid-playlist-renderer, ytd-playlist-panel-video-renderer, ytd-secondary-search-container-renderer${Values.storageComment ? ', ytd-comment-renderer.ytd-comment-replies-renderer, ytd-comment-thread-renderer' : ''}`,
  76. userVideo: '#meta #upload-info #channel-name #text.ytd-channel-name'
  77. };
  78.  
  79. /* INTERVAL FOR BLACKLISTING */
  80.  
  81. search();
  82. setInterval(search, Values.storageTimer);
  83.  
  84. /* CSS */
  85.  
  86. $('head').append(`<style>
  87. #byu-is-black { display: none!important; }
  88. .byu-add { font-size: .8em; margin-right: .5em; cursor: pointer; color: var(--yt-brand-youtube-red, red); font-family: consolas, monospace; float: left; }
  89. #byu-icon { display: inline-block; position: relative; text-align: center; width: 40px; height: 24px; margin: 0 8px; font-weight: 500; }
  90. #byu-icon span { color: var(--yt-spec-icon-active-other); cursor: pointer; font-size: 20px; vertical-align: middle; }
  91. #byu-options { width: 30%; max-width: 250px; display: flex; flex-flow: row wrap; align-items: baseline; position: fixed; right: 10px; padding: 0 15px 15px; text-align: center; color: var(--yt-spec-text-primary); background-color: var(--yt-spec-brand-background-primary); border: 1px solid var(--yt-spec-10-percent-layer); border-top: 0; z-index: 99999; }
  92. #byu-options div { width: 50%; flex-grow: 1; box-sizing: border-box; padding: 5px; font-size: 1em; }
  93. #byu-save { font-size: 1.5em!important; font-weight: bold; cursor: pointer; color: var(--yt-brand-youtube-red, red); }
  94. #byu-pause { cursor: pointer; }
  95. #byu-options .byu-textarea { width: 100%; }
  96. #byu-options .byu-textarea span { font-size: 1.2em; width: 100%; text-align: center; font-weight: bold; }
  97. #byu-options .byu-textarea textarea { font-size: 1em; line-height: 1em; resize: vertical; width: 100%; padding: 4px; color: var(--yt-spec-text-primary); background-color: var(--yt-spec-brand-background-primary); box-sizing: border-box; border: 3px solid var(--ytd-searchbox-legacy-border-color); }
  98. #byu-options .byu-textarea textarea#byu-blacklist { min-height: 6em; }
  99. #byu-options .byu-textarea textarea#byu-whiteklist { min-height: 4em; }
  100. #byu-options .byu-opt { text-align: right; padding-right: 2em; }
  101. #byu-options .byu-opt input { color: var(--yt-spec-text-primary); background-color: var(--yt-spec-brand-background-primary); border: 3px solid var(--ytd-searchbox-legacy-border-color); padding: 0 2px; height: 1.4em; line-height: 1em; vertical-align: middle; box-sizing: border-box; margin: 0; }
  102. #byu-sep { width: 1em; }
  103. #byu-timer { width: 4.2em; }
  104. #byu-video-page-black { position: fixed; z-index: 99999; bottom: 2em; left: 2em; width: 20%; min-width: 10em; font-size: 1.5em; padding: 1em; background: var(--yt-brand-youtube-red, red); color: #fff; border-radius: .5em; }
  105. #byu-notice { position: fixed; z-index: 99999; bottom: 2em; right: 2em; width: 30%; min-width: 10em; font-size: 1.2em; padding: 1.5em; color: var(--yt-brand-youtube-red, red); background: #fff; border-radius: .5em; border: 1px solid var(--yt-brand-youtube-red, red); }
  106. #byu-notice-close { cursor: pointer; background: var(--yt-brand-youtube-red, red); color: #fff; border-radius: .5em; padding: 0 .5em; }
  107. </style>`);
  108.  
  109. /* VIDEO FIRST PAGE */
  110.  
  111. if (Values.storageVideo && /\/watch/.test(window.location.href)) {
  112. let waitUserVideo = setInterval(() => {
  113. if ($(Where.userVideo).length) {
  114. clearInterval(waitUserVideo);
  115.  
  116. let username = $(Where.userVideo).text().trim();
  117. if (ifMatch(username.toLowerCase())) {
  118. let video = $('#player video.video-stream.html5-main-video');
  119. video.get(0).pause();
  120. video.get(0).currentTime = 0;
  121. let pausing = setInterval(() => {
  122. if (!video.get(0).paused) {
  123. video.get(0).pause();
  124. video.get(0).currentTime = 0;
  125. }
  126. }, 500);
  127. $('body').append($(`<div id="byu-video-page-black">${username} is blacklisted</div>`));
  128. $('body').on('click', '.html5-main-video, .html5-video-player, .ytp-play-button, #secondary', () => clearInterval(pausing));
  129. setTimeout(() => {
  130. $('#byu-video-page-black').remove();
  131. clearInterval(pausing);
  132. }, 10000);
  133. }
  134. }
  135. }, 1000);
  136. }
  137.  
  138. /* BLACKLIST MENU */
  139.  
  140. $('body').append(`<div id="byu-options" style="display: none;">
  141. <div><span id="byu-save">save</span></div>
  142. <div><span id="byu-pause">pause</span></div>
  143. <div class="byu-textarea"><span>blacklist</span><textarea spellcheck="false" id="byu-blacklist">${Values.storageBlacklist.join(`${Values.storageSep} `)}</textarea></div>
  144. <div class="byu-textarea"><span>whitelist</span><textarea spellcheck="false" id="byu-whitelist">${Values.storageWhitelist.join(`${Values.storageSep} `)}</textarea></div>
  145. <div class="byu-opt" title="between usernames">separator <input id="byu-sep" type="text" maxlength="1" value="${Values.storageSep}"></div>
  146. <div class="byu-opt" title="hide comments">comments <input id="byu-hidecomments" type="checkbox" value="comments" ${Values.storageComment ? 'checked' : ''}></div>
  147. <div class="byu-opt" title="interval between new checks">timer <input id="byu-timer" type="number" min="500" max="5000" step="500" title="in milliseconds" value="${Values.storageTimer}"></div>
  148. <div class="byu-opt" title="if user blacklisted">pause video <input id="byu-enablepause" type="checkbox" value="pausevideo" ${Values.storageVideo ? 'checked' : ''}></div>
  149. <div class="byu-opt" title="always show [x]">right click add <input id="byu-enableadd" type="checkbox" value="clickadd" ${Values.storageAdd ? 'checked' : ''}></div>
  150. </div>`);
  151.  
  152. // for the B wait till the masthead buttons are added
  153. let waitButton = setInterval(() => {
  154. if ($('#buttons').length) {
  155. clearInterval(waitButton);
  156. $('#buttons').before('<div id="byu-icon"><span>B</span></div>');
  157. $('head').append(`<style>#byu-options { top:${$('#container.ytd-masthead').height()}px; }</style>`);
  158. }
  159. }, 1000);
  160.  
  161. /* NEW VERSION NOTIFICATION */
  162.  
  163. if (Values.storageVer !== '2.4.9') {
  164. Values.storageVer = '2.4.9';
  165. GM.setValue('byuver', Values.storageVer);
  166. /*
  167. $('body').append(`<div id="byu-notice">BLOCK YOUTUBE USERS [${Values.storageVer}]<br><br> -- <br><br><span id="byu-notice-close">close</span></div>`);
  168. $('#byu-notice-close').on('click', () => $('#byu-notice').remove());
  169. */
  170. }
  171.  
  172. /* BLACKLISTING FUNCTIONS */
  173.  
  174. // check if it needs to be blacklisted
  175. function ifMatch(u) {
  176. return (
  177. !Values.storageWhitelist.some(w => u === w.toLowerCase()) &&
  178. Values.storageBlacklist.some(b => {
  179. b = b.toLowerCase();
  180. if (b.startsWith('*')) {
  181. b = b.replace('*', '');
  182. return b && u.includes(b);
  183. } else {
  184. return u === b;
  185. }
  186. })
  187. );
  188. }
  189.  
  190. // do the thing
  191. function findMatch(user, newAdd) {
  192. // add [x] when menu is open or always add selected
  193. if ((Values.menuOpen || Values.storageAdd) && !user.siblings('.byu-add').length) {
  194. $('<span class="byu-add">[x]</span>').insertBefore(user);
  195. }
  196. // if blacklist is paused do nothing
  197. if (Values.menuPause) return;
  198. // retrieve current username
  199. let username = user.text().trim().toLowerCase();
  200. if (!username) return;
  201. // if content or blacklist are changed
  202. if (user.data('username') !== username || newAdd) {
  203. user.data('username', username);
  204. // hide if match
  205. if (ifMatch(username)) {
  206. user.closest(Where.renderer).attr('id', 'byu-is-black');
  207. user.data('black', 'yes');
  208. // show if it was hidden with another username or deleted username from blacklist
  209. } else if (user.data('black')) {
  210. user.closest(Where.renderer).removeAttr('id');
  211. user.data('black', '');
  212. }
  213. }
  214. }
  215.  
  216. // global search
  217. function search(newAdd = false) {
  218. $(Where.user).each(function() { findMatch($(this), newAdd); });
  219. }
  220.  
  221. /* EVENT LISTENERS */
  222.  
  223. // open/close options
  224. $('body').on('click', '#byu-icon', function() {
  225. $('#byu-options').slideToggle();
  226. $(this).css('font-weight', $(this).css('font-weight') === '700' ? '' : '700');
  227. Values.menuOpen = !Values.menuOpen;
  228. if (!Values.storageAdd) {
  229. if (Values.menuOpen) search();
  230. else $('.byu-add').remove();
  231. }
  232. });
  233.  
  234. // save changes
  235. $('#byu-save').on('click', function() {
  236. if (/[*"]|^$/.test($('#byu-sep').val())) {
  237. $(this).text('ERROR! separator');
  238. } else {
  239. Values.storageSep = $('#byu-sep').val();
  240. Values.storageTimer = Math.max(parseInt($('#byu-timer').val(), 10), 500) || 1000;
  241. Values.storageComment = $('#byu-hidecomments').is(':checked') ? 'yes' : '';
  242. Values.storageVideo = $('#byu-enablepause').is(':checked') ? 'yes' : '';
  243. Values.storageAdd = $('#byu-enableadd').is(':checked') ? 'yes' : '';
  244. Values.storageBlacklist = getArray($('#byu-blacklist').val().trim());
  245. Values.storageWhitelist = getArray($('#byu-whitelist').val().trim());
  246. GM.setValue('sep', Values.storageSep);
  247. GM.setValue('timer', Values.storageTimer);
  248. GM.setValue('hidecomments', Values.storageComment);
  249. GM.setValue('enablepause', Values.storageVideo);
  250. GM.setValue('enableadd', Values.storageAdd);
  251. GM.setValue('savedblocks', Values.storageBlacklist.join(`${Values.storageSep} `));
  252. GM.setValue('savedwhites', Values.storageWhitelist.join(`${Values.storageSep} `));
  253. $(this).text('saved');
  254. search(true);
  255. }
  256. setTimeout(() => $(this).text('save'), 2000);
  257. });
  258.  
  259. // pause
  260. $('#byu-pause').on('click', function() {
  261. Values.menuPause = !Values.menuPause;
  262. if (Values.menuPause) {
  263. $('[id="byu-is-black"]').removeAttr('id');
  264. $(this).text('paused');
  265. } else {
  266. search(true);
  267. $(this).text('pause');
  268. }
  269. });
  270.  
  271. // add usernames to blacklist
  272. $('body').on('click contextmenu', '.byu-add', function(e) {
  273. e.preventDefault();
  274. e.stopPropagation();
  275. let username = $(this).next().data('username');
  276. if (!Values.storageBlacklist.includes(username)) {
  277. Values.storageBlacklist.push(username);
  278. let blacks = Values.storageBlacklist.join(`${Values.storageSep} `);
  279. $('#byu-blacklist').val(blacks);
  280. GM.setValue('savedblocks', blacks);
  281. search(true);
  282. }
  283. });
  284.  
  285. })(jQuery);

QingJ © 2025

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