// ==UserScript==
// @name YouTube - Block AI-generated content (demo)
// @namespace
http://tampermonkey.net/
// @version 1.0
// @description Hide YouTube videos that look AI-generated based on keywords
// @author YourName
// @match
https://www.youtube.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Adjustable keyword list
const AI_KEYWORDS = [
'ai', 'artificial intelligence', 'gpt', 'chatgpt', 'midjourney', 'stable diffusion', 'dalle',
'synced ai', 'ai-generated', 'ai-generated video', 'ai video', 'ai clip'
];
// Preference key
const PREF_KEY = 'yt_block_ai_enabled';
// Default: enabled
if (localStorage.getItem(PREF_KEY) === null) {
localStorage.setItem(PREF_KEY, 'true');
}
function isEnabled() {
return localStorage.getItem(PREF_KEY) === 'true';
}
function setEnabled(v) {
localStorage.setItem(PREF_KEY, v ? 'true' : 'false');
}
// Normalize text
function textNorm(s) {
return (s || '').toLowerCase();
}
// Check if a video card should be hidden based on title/description
function cardMatches(card) {
try {
// YouTube uses shadow DOM in some parts; here we try common structures
let titleEl = card.querySelector('#video-title');
let metaEl = card.querySelector('#description-text');
const title = textNorm(titleEl ? titleEl.textContent : '');
const description = textNorm(metaEl ? metaEl.textContent : '');
for (const kw of AI_KEYWORDS) {
const k = kw.toLowerCase();
if (title.includes(k) || description.includes(k)) return true;
}
} catch (e) {
// ignore
}
return false;
}
// Hide a card if it matches
function hideCard(card) {
if (card && card.style && card.style.display !== 'none') {
card.style.display = 'none';
card.setAttribute('data-ai-blocked', 'true');
}
}
// Unhide a card (if it was previously hidden)
function unhideCard(card) {
if (card && card.style && card.getAttribute('data-ai-blocked') === 'true') {
card.style.display = '';
card.removeAttribute('data-ai-blocked');
}
}
// Process a list of video cards on the page
function processCards(container) {
const cards = [];
// YouTube uses some different card containers; try common selectors
// Home feed / search results use "ytd-grid-video-renderer" and similar
container.querySelectorAll('ytd-grid-video-renderer, ytd-video-renderer, ytd-grid-playlists-renderer')
.forEach(el => cards.push(el));
// If we got no results, try generic video card wrappers
if (cards.length === 0) {
container.querySelectorAll('a#video-title').forEach(a => {
const card = a.closest('ytd-grid-video-renderer, ytd-video-renderer, ytd-grid-playlists-renderer');
if (card) cards.push(card);
});
}
cards.forEach(card => {
try {
if (!card.getAttribute('data-ai-checked')) {
const shouldHide = cardMatches(card);
if (shouldHide) hideCard(card);
else unhideCard(card);
card.setAttribute('data-ai-checked', 'true');
} else {
// already checked; just ensure visibility matches current rule
if (cardMatches(card)) hideCard(card);
else unhideCard(card);
}
} catch (e) {
// ignore per-card errors
}
});
}
// Observe for dynamic content
const observer = new MutationObserver((mutations) => {
if (!isEnabled()) return;
mutations.forEach(() => {
// Try processing within the main content area
const main = document.querySelector('ytd-app') || document.body;
processCards(main);
});
});
function init() {
if (!isEnabled()) return;
// Initial run
processCards(document);
// Observe
observer.observe(document.body, { childList: true, subtree: true });
// Also add a small UI toggle for convenience (in-page)
addToggleUI();
}
// Simple in-page toggle button
function addToggleUI() {
if (document.getElementById('yt-ai-block-toggle')) return;
const btn = document.createElement('button');
btn.id = 'yt-ai-block-toggle';
btn.textContent = 'AI content block: ON';
Object.assign(btn.style, {
position: 'fixed',
bottom: '12px',
right: '12px',
padding: '8px 12px',
zIndex: 9999,
background: '#ff5a5f',
color: '#fff',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
boxShadow: '0 2px 6px rgba(0,0,0,.3)'
});
btn.addEventListener('click', () => {
const on = !isEnabled();
setEnabled(on);
btn.textContent = on ? 'AI content block: ON' : 'AI content block: OFF';
if (on) {
// show already-hidden cards
document.querySelectorAll('[data-ai-blocked="true"]').forEach(el => {
el.style.display = '';
});
// re-run processing to hide new items
processCards(document);
} else {
// remove any hides
document.querySelectorAll('[data-ai-blocked="true"]').forEach(el => {
el.style.display = '';
el.removeAttribute('data-ai-blocked');
});
}
});
document.body.appendChild(btn);
}
// Start after DOM is ready
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();