您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
English Only - Youtube recommends garbage videos with 0-1750 views, so we put them in the garbage disposal.
当前为
// ==UserScript== // @name YouTube GVDS1750 (GarbageVideoDisposalSystem, >1750 view) // @namespace http://tampermonkey.net/ // @version 1.575 // @description English Only - Youtube recommends garbage videos with 0-1750 views, so we put them in the garbage disposal. // @author sir rob // @include https://www.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @grant none // @license GNU GPLv3 // ==/UserScript== // --------------------------------------------------------------------------- // Known issues: // UI when open sits over homepage genre selection - has issues with 1.6k view vids? wtf - misc. aesthetics - Only 20 something videos are filtered on /watch (dynamic load issue) - emoji on reopenbutton moves around? idk - The hate on pineapple on pizza // Future plans/ideas: // call replacement renderer to replace empty blocks - resizable/dragable UI - clickable links in UI - add support for more languages - mine crypto in unsuspecting users browsers teehee // Changelog so I can start remembering what issues I've fixed and what I've fucked up again: // v1.40 Fixed char limit inop when scrolling - Channelgrab working - open/close/open crashes fixed with new "memory" system (lol) // v1.41 Wow, it mostly works? Code cleaned up, some shit reorganized, other code removed = 20 lines less and twice the functionality from v1.39!!! Even with changelog! // v1.42 new memory, somehow simpler than the last? - Tested in Opera/Chrome/Firefox - add video player monitor // v1.43 replace player sniffer, replace with full screen listener grabs from browser not youtube // v1.44 new badvideo logic, able to set a threshold for the filter in preparation for filtering on /watch - // v1.45 another new badvideo logic, previous was unstable/unable to differentiate 1.4k from 1.4m, or anything under 1000 - Removed redundant logic that was getting in the way. // v1.46-50..rolled back to v1.43, I don't want to talk about it (several blocks of new logic were as reliable as my 04' Land Rover) // v1.51 start work on 1750 view filter for /watch - add red 1 pixel border around open button, centered emoji (its off, heck) - implemented random bits of logging for debug (why didn't I do this earlier..) // v1.52 fine tuning on filter - added "no view" to /watch filter // v1.53 let reopenBtn render when refreshing or going direct to /watch video page.. Added redundant logic that will get in the way (I don't know which one is the one thats working, and they're all working atm so..) // v1.54 aesthetics time, changes to sizes of stuff, reopenbtn is just a toggle now, always visible can open/close UI // v1.55 UI panel loads deleted videos on page load when UI is closed // v1.56 short half ass attempt at making the deleted videos linked to their original url // v1.57 remove the above - clean up UI panel and make it a solid size // these settings should probably stay the same past v1.30ish let g_VideosFiltering = true; let g_ShortsFiltering = true; let g_RemoveContainAdsSign = true; let g_RemovedVideosMap = new Map(); let g_PanelVisible = false; // default to closed UI, visible reopenBtn // Always show reopenbutton, now opens and closes UI + stays visible at all times function ShowReopenButton() { let reopenBtn = document.getElementById("reopen-panel-btn"); if (!reopenBtn) { reopenBtn = document.createElement("div"); reopenBtn.innerText = "✦"; // change to whatever emoji you want reopenBtn.id = "reopen-panel-btn"; reopenBtn.style.position = "absolute"; reopenBtn.style.top = "19px"; reopenBtn.style.left = "50px"; reopenBtn.style.width = "16px"; reopenBtn.style.height = "16px"; reopenBtn.style.display = "flex"; reopenBtn.style.alignItems = "center"; reopenBtn.style.justifyContent = "center"; reopenBtn.style.borderRadius = "50%"; reopenBtn.style.backgroundColor = "white"; reopenBtn.style.border = "1px solid red"; reopenBtn.style.cursor = "pointer"; reopenBtn.style.zIndex = "9999"; reopenBtn.style.pointerEvents = "auto"; reopenBtn.style.fontSize = "16px"; document.body.appendChild(reopenBtn); } reopenBtn.onclick = () => { const panel = document.getElementById("removed-videos-panel"); if (panel && panel.style.display !== "none") { panel.style.display = "none"; g_PanelVisible = false; } else { CreateRemovedVideosPanel(); g_PanelVisible = true; } }; } // replacement sniffer for fullscreen, much simpler too! function HandleFullscreenChange() { const isFullscreen = !!document.fullscreenElement; const panel = document.getElementById("removed-videos-panel"); const reopenBtn = document.getElementById("reopen-panel-btn"); if (isFullscreen) { if (panel) panel.style.display = "none"; if (reopenBtn) reopenBtn.style.display = "none"; } else { if (g_PanelVisible && panel) panel.style.display = "block"; if (reopenBtn) reopenBtn.style.display = "block"; } } document.addEventListener("fullscreenchange", HandleFullscreenChange); function FilterWatchSidebar() { const lockups = document.querySelectorAll("yt-lockup-view-model.lockup"); lockups.forEach((el, index) => { const viewsSpan = Array.from(el.querySelectorAll("span")) .find(span => span.textContent.trim().toLowerCase().includes("views")); if (!viewsSpan) { console.log(`Lockup #${index + 1}: No views span found`); return; } const viewsText = viewsSpan.textContent.trim().toLowerCase(); if (viewsText.includes("no views") || viewsText === "") { console.log(`Removing sidebar video with "no views" or empty text:`, viewsText); el.remove(); return; } const match = viewsText.match(/([\d.,]+)\s*([KMkm]?)/); if (!match) { console.log(`Lockup #${index + 1}: Failed to match view count in "${viewsText}"`); return; } let value = parseFloat(match[1].replace(',', '.')); const suffix = match[2].toLowerCase(); if (isNaN(value)) { console.log(`Lockup #${index + 1}: Parsed NaN from "${viewsText}"`); return; } if (suffix === 'k') value *= 1000; else if (suffix === 'm') value *= 1000000; if (value < 1750) { console.log(`Removing sidebar video (views: ${Math.round(value)}):`, viewsText); el.remove(); } else { console.log(`Keeping sidebar video (views: ${Math.round(value)}):`, viewsText); } }); } function CreateRemovedVideosPanel() { let panel = document.getElementById("removed-videos-panel"); if (!panel) { panel = document.createElement("div"); panel.id = "removed-videos-panel"; panel.style.position = "absolute"; panel.style.top = "10px"; panel.style.left = "260px"; panel.style.background = "rgba(0, 0, 0, 0.65)"; panel.style.color = "rgba(255, 255, 255, 0.75)"; panel.style.padding = "8px 10px"; panel.style.borderRadius = "8px"; panel.style.zIndex = "9999"; panel.style.fontSize = "11px"; panel.style.maxWidth = "130px"; panel.style.maxHeight = "80px"; panel.style.overflowY = "hidden"; panel.style.height = "80px"; panel.style.pointerEvents = "none"; panel.style.userSelect = "none"; panel.style.display = "none"; panel.innerHTML = ` <div style="font-weight:bold; margin-bottom:6px;">Removed Videos</div> <ul id='removed-videos-list' style='padding-left: 14px; margin: 0; height: 50px; overflow-y: auto; pointer-events: auto;'></ul> `; const closeBtn = document.createElement("button"); closeBtn.innerText = "✕"; closeBtn.style.position = "absolute"; closeBtn.style.top = "2px"; closeBtn.style.right = "4px"; closeBtn.style.background = "transparent"; closeBtn.style.color = "#fff"; closeBtn.style.border = "none"; closeBtn.style.cursor = "pointer"; closeBtn.style.fontSize = "12px"; closeBtn.style.pointerEvents = "auto"; closeBtn.onclick = () => { g_PanelVisible = false; panel.style.display = "none"; ShowReopenButton(); }; panel.appendChild(closeBtn); const clearBtn = document.createElement("button"); clearBtn.innerText = "Clear"; clearBtn.style.position = "absolute"; clearBtn.style.bottom = "4px"; clearBtn.style.left = "8px"; clearBtn.style.background = "#444"; clearBtn.style.color = "#fff"; clearBtn.style.border = "none"; clearBtn.style.cursor = "pointer"; clearBtn.style.fontSize = "10px"; clearBtn.style.pointerEvents = "auto"; clearBtn.onclick = () => { g_RemovedVideosMap.clear(); document.getElementById("removed-videos-list").innerHTML = ""; }; panel.appendChild(clearBtn); document.body.appendChild(panel); } panel.style.display = g_PanelVisible ? "block" : "none"; } // Reverted AddToRemovedVideosPanel to original version without links function AddToRemovedVideosPanel(title, channelHandle) { if (!title) return; const map = g_RemovedVideosMap; const list = document.getElementById("removed-videos-list"); if (!list) return; const key = title + "|" + channelHandle; if (map.has(key)) { map.set(key, map.get(key) + 1); const item = document.getElementById("removed-" + key); if (item) item.innerText = `${title.slice(0, 20)}... (x${map.get(key)}) - ${channelHandle}`; } else { map.set(key, 1); const li = document.createElement("li"); li.id = "removed-" + key; li.innerText = `${title.slice(0, 20)}... (x1) - ${channelHandle}`; li.style.pointerEvents = "none"; list.appendChild(li); } } function IsBadVideo(videoViews) { if (!videoViews) return false; let text = videoViews.innerText; if (text.length == 0) return false; let numbersExists = false; for (let i = 0; i < text.length; i++) { if (IsNumber(text[i])) { numbersExists = true; break; } } let twoWordsExists = false; for (let i = 0; i < text.length - 2; i++) { if (IsNumber(text[i]) && IsSeparator(text[i + 1]) && IsNumber(text[i + 2])) { let sample = text.substring(i, i + 5); let parsed = parseFloat(sample.replace(',', '.')); if (parsed && parsed >= 1.75) { twoWordsExists = true; break; } } if (!IsNumber(text[i]) && IsSpace(text[i + 1]) && !IsNumber(text[i + 2])) { twoWordsExists = true; break; } } return !numbersExists || !twoWordsExists; } function UpdateVideoFiltering() { if (g_PanelVisible) { CreateRemovedVideosPanel(); } else { ShowReopenButton(); } if (!g_VideosFiltering || !IsHomepage()) return; let videosList = document.getElementsByClassName("style-scope ytd-rich-item-renderer"); for (let i = 0; i < videosList.length; i++) { if (videosList[i].id != "content") continue; const videoElement = videosList[i]; const parent = videoElement.parentElement; let titleEl = videoElement.querySelector("#video-title"); let handleEl = videoElement.querySelector("a.yt-simple-endpoint.style-scope.yt-formatted-string[href^='/@']"); let viewsEl = videoElement.querySelector(".inline-metadata-item.style-scope.ytd-video-meta-block"); let title = titleEl ? titleEl.innerText.trim() : "Unknown Title"; let channelHandle = handleEl ? handleEl.getAttribute("href").replace("/", "") : "Unknown"; const isLowView = IsBadVideo(viewsEl); const hasProgress = videoElement.querySelector("#progress") != null; if (isLowView || hasProgress) { AddToRemovedVideosPanel(title, channelHandle); parent.remove(); } } } function IsHomepage() { return location.pathname === "/"; } function IsNumber(i) { return (i >= '0' && i <= '9'); } function IsSpace(i) { return i == ' '; } function IsSeparator(i) { return i == '.' || i == ','; } function RemoveContainAdsSign() { if (g_RemoveContainAdsSign) { const styleElement = document.createElement('style'); document.head.appendChild(styleElement); const sheet = styleElement.sheet; sheet.insertRule(".ytInlinePlayerControlsTopLeftControls { display: none }", 0); } } document.addEventListener("yt-navigate-finish", () => { g_RemovedVideosMap.clear(); g_PanelVisible = false; CreateRemovedVideosPanel(); setTimeout(UpdateVideoFiltering, 350); RemoveContainAdsSign(); if (location.pathname.startsWith("/watch")) { setTimeout(FilterWatchSidebar, 500); } }); window.addEventListener("load", () => { if (location.pathname.startsWith("/watch")) { ShowReopenButton(); setTimeout(() => { try { FilterWatchSidebar(); } catch (e) { console.error("FilterWatchSidebar failed:", e); } }, 1000); } }); ["message", "load", "scrollend", "click"].forEach(evt => window.addEventListener(evt, () => setTimeout(UpdateVideoFiltering, 200)) ); // video where I make this script, subscribe to support me (: https://www.youtube.com/watch?v=xvFZjo5PgG0 // this used to be under 120 lines, es ist, als ware ich ein BMW ingenieur. Die halfte davon ist definitiv nicht nutzlos und ist absolut notwendig, um wie vorgesehen zu funktionieren
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址