Guest User

Untitled

a guest
Jun 6th, 2024
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. // ==UserScript==
  2. // @name youtube crappy videos remover from the recommendations
  3. // @namespace http://tampermonkey.net/
  4. // @version 3.1
  5. // @description thanks to youtube for recommending crappy videos with ~10 views
  6. // @author NiceL
  7. // @match *://*.youtube.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. // ---------------------------------------------------------------------------
  13.  
  14. let g_VideosFiltering = true;
  15. let g_ShortsFiltering = true;
  16.  
  17. function IsSubscriptions()
  18. {
  19. return location.pathname.startsWith("/feed/subscriptions");
  20. }
  21.  
  22. function IsChannel()
  23. {
  24. return location.pathname.startsWith("/@");
  25. }
  26.  
  27. function IsShorts()
  28. {
  29. return location.pathname.startsWith("/shorts");
  30. }
  31.  
  32. function IsNumber(i)
  33. {
  34. return (i >= '0' && i <= '9');
  35. }
  36.  
  37. function IsBadVideo(videoViews)
  38. {
  39. if (!videoViews) {
  40. return false;
  41. }
  42.  
  43. let text = videoViews.innerText;
  44.  
  45. let numbersExists = false
  46. for (let i = 0; i < text.length; i++)
  47. {
  48. // searches for a single number to verify that there's more than zero views
  49. if (IsNumber(text[i])) {
  50. numbersExists = true;
  51. break;
  52. }
  53. }
  54.  
  55. let twoWordsExists = false
  56. for (let i = 0; i < text.length - 2; i++)
  57. {
  58. // not number + space + not number = this is >1000 views (this should work for all languages)
  59. if (!IsNumber(text[i]) && text[i + 1] == ' ' && !IsNumber(text[i + 2])) {
  60. twoWordsExists = true;
  61. break;
  62. }
  63. }
  64.  
  65. let badVideo = !numbersExists || !twoWordsExists;
  66. if (badVideo) {
  67. console.log("~BadVideo: '" + text + "'"); // debug
  68. }
  69.  
  70. return badVideo;
  71. }
  72.  
  73. function IsBadShortVideo(videoViews)
  74. {
  75. //console.log("IsBadShortVideo()"); // debug
  76.  
  77. if (!videoViews) {
  78. return false;
  79. }
  80.  
  81. let text = videoViews.innerText;
  82.  
  83. for (let i = 0; i < text.length; i++)
  84. {
  85. // nbsp symbol is found
  86. if (text[i] == '\xa0') {
  87. return false;
  88. }
  89. }
  90.  
  91. console.log("~BadShortVideo: '" + text + "'"); // debug
  92. return true;
  93. }
  94.  
  95. // ---------------------------------------------------------------------------
  96.  
  97. function UpdateVideoFiltering()
  98. {
  99. let videosList;
  100.  
  101. if (IsChannel() || IsSubscriptions()) {
  102. return;
  103. }
  104.  
  105. if (IsShorts())
  106. {
  107. if (g_ShortsFiltering)
  108. {
  109. // skip bad shorts
  110. videosList = document.getElementsByClassName("reel-video-in-sequence style-scope ytd-shorts");
  111. for (let i = 0; i < videosList.length; i++)
  112. {
  113. if (!videosList[i].isActive) {
  114. continue;
  115. }
  116.  
  117. let videoViews = videosList[i].getElementsByClassName("yt-spec-button-shape-with-label__label")[0];
  118.  
  119. if (IsBadShortVideo(videoViews)) {
  120. document.getElementsByClassName("navigation-button style-scope ytd-shorts")[1].getElementsByClassName("yt-spec-touch-feedback-shape__fill")[0].click(); // click to next video button (is it even stable lol?)
  121. }
  122. }
  123. }
  124. }
  125. else
  126. {
  127. if (g_VideosFiltering)
  128. {
  129. // delete videos from the right side
  130. videosList = document.getElementsByClassName("style-scope ytd-compact-video-renderer");
  131. for (let i = 0; i < videosList.length; i++)
  132. {
  133. let videoViews = videosList[i].getElementsByClassName("inline-metadata-item style-scope ytd-video-meta-block")[0];
  134.  
  135. if (IsBadVideo(videoViews)) {
  136. videosList[i].parentElement.remove();
  137. }
  138. }
  139.  
  140. // delete videos from the main page
  141. videosList = document.getElementsByClassName("style-scope ytd-rich-item-renderer");
  142. for (let i = 0; i < videosList.length; i++)
  143. {
  144. if (videosList[i].id != "content") {
  145. continue;
  146. }
  147.  
  148. let videoViews = videosList[i].getElementsByClassName("inline-metadata-item style-scope ytd-video-meta-block")[0];
  149.  
  150. if (IsBadVideo(videoViews)) {
  151. videosList[i].parentElement.remove();
  152. }
  153. }
  154. }
  155. }
  156. }
  157.  
  158. // ---------------------------------------------------------------------------
  159.  
  160. document.addEventListener("yt-navigate-finish", (event) => {
  161. setTimeout(UpdateVideoFiltering, 350);
  162. });
  163.  
  164. window.addEventListener("message", (event) => {
  165. if (!IsShorts()) {
  166. setTimeout(UpdateVideoFiltering, 200);
  167. }
  168. });
  169.  
  170. window.addEventListener("load", (event) => {
  171. if (!IsShorts()) {
  172. setTimeout(UpdateVideoFiltering, 200);
  173. }
  174. });
  175.  
  176. window.addEventListener("scrollend", (event) => {
  177. if (!IsShorts()) {
  178. setTimeout(UpdateVideoFiltering, 0);
  179. }
  180. });
  181.  
  182. window.addEventListener("click", (event) => {
  183. if (!IsShorts()) {
  184. setTimeout(UpdateVideoFiltering, 200);
  185. }
  186. });
Add Comment
Please, Sign In to add comment