您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
YouTubeでおすすめに表示される再生回数の少ない動画・投稿日の古い動画・ライブ視聴者数が少ない動画を非表示にします。再生回数・視聴者数のしきい値はコード内で変更可能。古い動画の非表示は1年前の動画から設定可能。チャンネル内の動画は無視するオプション付き。
当前为
// ==UserScript== // @name YouTube用低視聴回数・古い動画・ライブ動画の非表示 // @namespace http://tampermonkey.net/ // @description YouTubeでおすすめに表示される再生回数の少ない動画・投稿日の古い動画・ライブ視聴者数が少ない動画を非表示にします。再生回数・視聴者数のしきい値はコード内で変更可能。古い動画の非表示は1年前の動画から設定可能。チャンネル内の動画は無視するオプション付き。 // @author sun // @match *://*.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @grant GM_registerMenuCommand // @version 2.1 // ==/UserScript== const VIEW_THRESHOLD = 1000; // 再生回数のしきい値 const AGE_THRESHOLD_YEARS = 0; // 年以上前の動画を非表示(0=無効) const LIVE_FILTER_ENABLED = 0; // ライブ視聴者数で非表示判定(0=無効,1=有効) const LIVE_VIEWER_THRESHOLD = 100; // ライブ視聴者数のしきい値 const DISABLE_ON_SUBSCRIPTIONS = true; // チャンネル内の動画は無視するか const OPTION_STORAGE_KEY = 'YT_LowViewFilter_Settings'; const VIDEO_SELECTORS = "ytd-rich-item-renderer, ytd-compact-video-renderer, .yt-lockup-view-model-wiz"; const VIEW_COUNT_SELECTOR = [ ".inline-metadata-item.style-scope.ytd-video-meta-block", "span.yt-core-attributed-string.yt-content-metadata-view-model-wiz__metadata-text" ]; const LIVE_VIEWER_SELECTORS = [ ".yt-content-metadata-view-model-wiz__metadata-text", "span.yt-core-attributed-string" ]; let menuRegistered = false; function parseViewCount(text) { if (!text) return 0; const multipliers = { "K": 1e3, "M": 1e6, "万": 1e4, "億": 1e8 }; let numText = text.replace(/[^0-9\.KM万億]/g, ""); let unit = Object.keys(multipliers).find(u => numText.includes(u)) || ""; numText = numText.replace(unit, ""); return numText ? parseFloat(numText) * (multipliers[unit] || 1) : 0; } function parseLiveViewerCount(text) { if (!text) return 0; const m = text.replace(/,/g, "").match(/([0-9]+)/); if (m) { return parseInt(m[1], 10); } return 0; } function isLiveVideo(videoElement) { if (!videoElement || LIVE_FILTER_ENABLED === 0) return false; for (const selector of LIVE_VIEWER_SELECTORS) { const elems = videoElement.querySelectorAll(selector); for (const elem of elems) { if (elem && /[0-9,]+ 人が視聴中/.test(elem.innerText)) { const count = parseLiveViewerCount(elem.innerText); if (count > 0 && count < LIVE_VIEWER_THRESHOLD) { return true; } return false; } } } return false; } function isBadVideo(videoElement) { if (!videoElement) return false; if (isLiveVideo(videoElement)) return true; for (const selector of VIEW_COUNT_SELECTOR) { const elems = videoElement.querySelectorAll(selector); for (const elem of elems) { if (elem && elem.innerText.includes('回視聴')) { const viewCount = parseViewCount(elem.innerText); if (viewCount > 0 && viewCount < VIEW_THRESHOLD) { return true; } } } } return false; } function isOldVideo(videoElement) { if (AGE_THRESHOLD_YEARS === 0) return false; const dateTexts = []; const dateSelectors = [ ".inline-metadata-item.style-scope.ytd-video-meta-block", "span.yt-core-attributed-string.yt-content-metadata-view-model-wiz__metadata-text" ]; dateSelectors.forEach(sel => { videoElement.querySelectorAll(sel).forEach(elm => { const text = elm.innerText; if (text && /前$/.test(text)) { dateTexts.push(text); } }); }); for (const dateText of dateTexts) { if (/([0-9]+)\s*年前/.test(dateText)) { const years = parseInt(RegExp.$1, 10); if (years >= AGE_THRESHOLD_YEARS) return true; } if (/([0-9]+)\s*ヶ月前/.test(dateText)) { const months = parseInt(RegExp.$1, 10); if (months >= AGE_THRESHOLD_YEARS * 12) return true; } } return false; } function isSubscriptionsPage() { return location.pathname.includes('/@') && location.pathname.includes('/videos'); } function isLivePage() { return location.pathname.includes('/streams'); } function getSettings() { return JSON.parse(localStorage.getItem(OPTION_STORAGE_KEY)) || { disableOnSubs: DISABLE_ON_SUBSCRIPTIONS }; } function hideBadVideo(videoElement) { if (!videoElement || isLivePage()) return; const { disableOnSubs } = getSettings(); if (disableOnSubs && isSubscriptionsPage()) return; if (isBadVideo(videoElement) || isOldVideo(videoElement)) { videoElement.style.display = "none"; } } const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { hideBadVideo(entry.target); observer.unobserve(entry.target); } }); }, { rootMargin: "300px" }); function update() { if (isLivePage()) return; document.querySelectorAll(VIDEO_SELECTORS).forEach(video => { hideBadVideo(video); observer.observe(video); }); } function initTampermonkeyMenu() { if (menuRegistered) return; menuRegistered = true; const { disableOnSubs } = getSettings(); GM_registerMenuCommand( `チャンネル内の動画は無視する: ${disableOnSubs ? "ON" : "OFF"}`, () => { localStorage.setItem(OPTION_STORAGE_KEY, JSON.stringify({ disableOnSubs: !disableOnSubs })); window.location.reload(); } ); GM_registerMenuCommand( `ライブ視聴者数で非表示判定: ${LIVE_FILTER_ENABLED ? "ON" : "OFF"}`, () => { const newValue = LIVE_FILTER_ENABLED ? 0 : 1; localStorage.setItem('YT_LiveFilter_Enabled', newValue); alert('ライブ視聴者数フィルター設定を変更しました。ページを再読み込みします。'); window.location.reload(); } ); } (function(){ const liveFilterStorage = localStorage.getItem('YT_LiveFilter_Enabled'); if (liveFilterStorage !== null) { window.LIVE_FILTER_ENABLED = parseInt(liveFilterStorage, 10); } else { window.LIVE_FILTER_ENABLED = LIVE_FILTER_ENABLED; } })(); window.addEventListener("load", () => { initTampermonkeyMenu(); update(); ["yt-navigate-finish", "yt-page-data-updated", "yt-action"].forEach(event => { window.addEventListener(event, () => setTimeout(update, 500)); }); const mutationObserver = new MutationObserver(mutations => { if (isLivePage()) return; mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType !== 1) return; if (node.matches?.(VIDEO_SELECTORS)) { hideBadVideo(node); observer.observe(node); } else if (node.querySelectorAll) { node.querySelectorAll(VIDEO_SELECTORS).forEach(video => { hideBadVideo(video); observer.observe(video); }); } }); }); }); mutationObserver.observe(document.body, { childList: true, subtree: true }); });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址