Ferocity2228

Untitled

Oct 9th, 2025
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         youtube crappy videos remover from the recommendations
  3. // @namespace    http://tampermonkey.net/
  4. // @version      3.3
  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 IsSpace(i)
  38. {
  39.     return i == ' ';
  40. }
  41.  
  42. function IsSeparator(i)
  43. {
  44.     return i == '.' || i == ',';
  45. }
  46.  
  47. function IsBadVideo(videoViews)
  48. {
  49.     if (!videoViews) {
  50.         return false;
  51.     }
  52.  
  53.     let text = videoViews.innerText;
  54.     if (text.length == 0) {
  55.         return false;
  56.     }
  57.  
  58.     let numbersExists = false
  59.     for (let i = 0; i < text.length; i++)
  60.     {
  61.         // searches for a single number to verify that there's more than zero views
  62.         if (IsNumber(text[i])) {
  63.             numbersExists = true;
  64.             break;
  65.         }
  66.     }
  67.  
  68.     let twoWordsExists = false
  69.     for (let i = 0; i < text.length - 2; i++)
  70.     {
  71.         // not number + space + not number = this is >1000 views (this should work for all languages)
  72.         if (!IsNumber(text[i]) && IsSpace(text[i + 1]) && !IsNumber(text[i + 2])) {
  73.             twoWordsExists = true;
  74.             break;
  75.         }
  76.  
  77.         // number + separator + number = this is >1000 views (this should work for all languages)
  78.         if (IsNumber(text[i]) && IsSeparator(text[i + 1]) && IsNumber(text[i + 2])) {
  79.             twoWordsExists = true;
  80.             break;
  81.         }
  82.     }
  83.  
  84.     let badVideo = !numbersExists || !twoWordsExists;
  85.     if (badVideo) {
  86.         console.log("~BadVideo: '" + text + "'"); // debug
  87.     }
  88.  
  89.     return badVideo;
  90. }
  91.  
  92. function IsBadShortVideo(videoViews)
  93. {
  94.     //console.log("IsBadShortVideo()"); // debug
  95.  
  96.     if (!videoViews) {
  97.         return false;
  98.     }
  99.  
  100.     let text = videoViews.innerText;
  101.     if (text.length == 0) {
  102.         return false;
  103.     }
  104.  
  105.     for (let i = 0; i < text.length; i++)
  106.     {
  107.         // nbsp symbol is found
  108.         if (text[i] == '\xa0') {
  109.             return false;
  110.         }
  111.     }
  112.  
  113.     console.log("~BadShortVideo: '" + text + "'"); // debug
  114.     return true;
  115. }
  116.  
  117. // ---------------------------------------------------------------------------
  118.  
  119. function UpdateVideoFiltering()
  120. {
  121.     let videosList;
  122.  
  123.     if (IsChannel() || IsSubscriptions()) {
  124.         return;
  125.     }
  126.  
  127.     if (IsShorts())
  128.     {
  129.         if (g_ShortsFiltering)
  130.         {
  131.             // skip bad shorts
  132.             videosList = document.getElementsByClassName("reel-video-in-sequence style-scope ytd-shorts");
  133.             for (let i = 0; i < videosList.length; i++)
  134.             {
  135.                 if (!videosList[i].isActive) {
  136.                     continue;
  137.                 }
  138.  
  139.                 let videoViews = videosList[i].getElementsByClassName("yt-spec-button-shape-with-label__label")[0];
  140.  
  141.                 if (IsBadShortVideo(videoViews)) {
  142.                     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?)
  143.                 }
  144.             }
  145.         }
  146.     }
  147.     else
  148.     {
  149.         if (g_VideosFiltering)
  150.         {
  151.             // delete videos from the right side
  152.             videosList = document.getElementsByClassName("style-scope ytd-compact-video-renderer");
  153.             for (let i = 0; i < videosList.length; i++)
  154.             {
  155.                 let videoViews = videosList[i].getElementsByClassName("inline-metadata-item style-scope ytd-video-meta-block")[0];
  156.  
  157.                 if (IsBadVideo(videoViews)) {
  158.                     videosList[i].parentElement.remove();
  159.                 }
  160.             }
  161.  
  162.             // delete videos from the main page
  163.             videosList = document.getElementsByClassName("style-scope ytd-rich-item-renderer");
  164.             for (let i = 0; i < videosList.length; i++)
  165.             {
  166.                 if (videosList[i].id != "content") {
  167.                     continue;
  168.                 }
  169.  
  170.                 let videoViews = videosList[i].getElementsByClassName("yt-core-attributed-string yt-content-metadata-view-model__metadata-text yt-core-attributed-string--white-space-pre-wrap yt-core-attributed-string--link-inherit-color")[1];
  171.  
  172.                 if (IsBadVideo(videoViews)) {
  173.                     videosList[i].parentElement.remove();
  174.                 }
  175.             }
  176.         }
  177.     }
  178. }
  179.  
  180. // ---------------------------------------------------------------------------
  181.  
  182. document.addEventListener("yt-navigate-finish", (event) => {
  183.     setTimeout(UpdateVideoFiltering, 350);
  184. });
  185.  
  186. window.addEventListener("message", (event) => {
  187.     if (!IsShorts()) {
  188.         setTimeout(UpdateVideoFiltering, 200);
  189.     }
  190. });
  191.  
  192. window.addEventListener("load", (event) => {
  193.     if (!IsShorts()) {
  194.         setTimeout(UpdateVideoFiltering, 200);
  195.     }
  196. });
  197.  
  198. window.addEventListener("scrollend", (event) => {
  199.     if (!IsShorts()) {
  200.         setTimeout(UpdateVideoFiltering, 0);
  201.     }
  202. });
  203.  
  204. window.addEventListener("click", (event) => {
  205.     if (!IsShorts()) {
  206.         setTimeout(UpdateVideoFiltering, 200);
  207.     }
  208. });
Advertisement
Add Comment
Please, Sign In to add comment