您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Auto-hide "Members only" videos from untrusted channels on YouTube with a toggle to re-show/hide them
// ==UserScript== // @name Hide Members Only Filter and whitelist for youtube // @namespace http://tampermonkey.net/ // @version 2.1 // @description Auto-hide "Members only" videos from untrusted channels on YouTube with a toggle to re-show/hide them // @author Aonnymous // @match https://www.youtube.com/* // @grant GM_registerMenuCommand // @license MIT // ==/UserScript== (function () { 'use strict'; // === Config === const WHITELIST = [ 'channel name 1', 'Some Channel', 'Trusted Creator' ]; const SCAN_INTERVAL_FAST = 2000; // Every 2s for first minute const FAST_SCAN_DURATION = 60000; // Fast mode for 1 minute const MAX_RUNS_PER_MINUTE = 4; // Slow mode limit const DEBUG_BORDER_STYLE = '2px solid red'; // Red border on hidden const AUTO_ENABLE_DELAY_MS = 4500; // Auto-start 4.5s in // === State === let scanInterval = null; let filteringEnabled = false; let scanStartTime = null; let lastRunTimestamp = 0; let runsThisMinute = 0; // === Utilities === const CLEANED_WHITELIST = WHITELIST.map(name => name.trim().toLowerCase()); function log(...args) { console.log('[YT-MembersFilter]', ...args); } function isWhitelisted(name) { const lc = name.trim().toLowerCase(); return CLEANED_WHITELIST.some(w => lc.indexOf(w) !== -1); } function getTopLevelVideoElements() { const sidebarVideos = Array.from(document.querySelectorAll('ytd-compact-video-renderer')) .filter(el => el.closest('ytd-compact-video-renderer') === el); const richItems = Array.from(document.querySelectorAll('div#content.style-scope.ytd-rich-item-renderer')); return [...sidebarVideos, ...richItems]; } function scanAndHide() { const now = Date.now(); const inFastMode = now - scanStartTime < FAST_SCAN_DURATION; if (!inFastMode) { if (now - lastRunTimestamp > 60000) { runsThisMinute = 0; lastRunTimestamp = now; } if (runsThisMinute >= MAX_RUNS_PER_MINUTE) { log('Throttled: max scans this minute reached.'); return; } runsThisMinute++; } const videos = getTopLevelVideoElements(); if (!videos.length) { log('No video elements found.'); return; } let hiddenCount = 0; videos.forEach(vid => { if (vid.dataset._ytMembersFiltered === 'true') return; // Already processed const text = vid.textContent || ''; if (!text.includes('Members only')) return; const channelElem = vid.querySelector('.ytd-channel-name'); const channelName = channelElem?.textContent?.trim() || ''; if (!isWhitelisted(channelName)) { vid.style.display = 'none'; vid.style.border = DEBUG_BORDER_STYLE; vid.dataset._ytMembersFiltered = 'true'; hiddenCount++; log(`Hid video from: "${channelName}"`); } else { log(`Whitelisted video from: "${channelName}"`); } }); if (hiddenCount) { log(`Hidden videos this scan: ${hiddenCount}`); } } function startScanning() { if (scanInterval) clearInterval(scanInterval); scanStartTime = Date.now(); runsThisMinute = 0; lastRunTimestamp = 0; scanInterval = setInterval(scanAndHide, SCAN_INTERVAL_FAST); log('Started scanning every 2s for 1 minute...'); setTimeout(() => { if (scanInterval) clearInterval(scanInterval); log('Fast scan finished. Throttled scanning active.'); scanInterval = setInterval(scanAndHide, 15000); }, FAST_SCAN_DURATION); } function stopScanningAndShowAll() { if (scanInterval) clearInterval(scanInterval); scanInterval = null; const hidden = document.querySelectorAll('[data-_yt-members-filtered="true"]'); hidden.forEach(el => { el.style.display = ''; el.style.border = ''; delete el.dataset._ytMembersFiltered; }); log('Stopped scanning and revealed previously hidden videos.'); } function toggleFiltering() { filteringEnabled = !filteringEnabled; if (filteringEnabled) { log('Filtering ENABLED.'); startScanning(); } else { log('Filtering DISABLED.'); stopScanningAndShowAll(); } } // === Menu Button === GM_registerMenuCommand('Toggle Member Filter On/Off', toggleFiltering); // === Auto Start After Delay === setTimeout(() => { if (!filteringEnabled) { filteringEnabled = true; log('Auto-starting filtering after delay...'); startScanning(); } }, AUTO_ENABLE_DELAY_MS); log('YouTube Member Filter script loaded. Will auto-start in ~4.5s. Toggle anytime via Tampermonkey menu.'); })();