nascent / YouTube Playlist Watched and Streamed Videos Remover

// ==UserScript==
// @name         YouTube Playlist Watched and Streamed Videos Remover
// @namespace    http://youtube.com/
// @version      1.0
// @description  Automatically removes watched and streamed videos from YouTube playlist pages
// @author       nascent
// @license      GPL-3.0-or-later
// @match        https://www.youtube.com/playlist?list=*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Configuration
    const CHECK_INTERVAL = 2000; // How often to check for new videos (in milliseconds)

    // Helper function to check if a video is watched
    function isVideoWatched(videoElement) {
        const watchedOverlay = videoElement.querySelector('ytd-thumbnail-overlay-playback-status-renderer');
        return watchedOverlay !== null;
    }

    // Helper function to check if a video was streamed
    function isVideoStreamed(videoElement) {
        const videoInfo = videoElement.querySelector('#video-info');
        return videoInfo?.textContent.includes('Streamed');
    }

    // Function to process all videos in the playlist
    function processPlaylistVideos() {
        // Get all video elements in the playlist
        const videoElements = document.querySelectorAll('ytd-playlist-video-renderer');

        let removedCount = {
            watched: 0,
            streamed: 0
        };

        // Iterate through each video element
        videoElements.forEach(videoElement => {
            if (isVideoWatched(videoElement)) {
                videoElement.remove();
                removedCount.watched++;
            } else if (isVideoStreamed(videoElement)) {
                videoElement.remove();
                removedCount.streamed++;
            }
        });

        // Log the number of videos removed (if any)
        if (removedCount.watched > 0 || removedCount.streamed > 0) {
            console.log(`Removed ${removedCount.watched} watched videos and ${removedCount.streamed} streamed videos from playlist`);
        }
    }

    // Function to add a control button to the page
    function addControlButton() {
        const playlistHeader = document.querySelector('ytd-playlist-header-renderer');
        if (!playlistHeader || document.getElementById('remove-videos-btn')) return;

        const button = document.createElement('button');
        button.id = 'remove-videos-btn';
        button.innerHTML = 'Remove Watched & Streamed Videos';
        button.style.cssText = `
            background-color: #cc0000;
            color: white;
            border: none;
            border-radius: 2px;
            padding: 10px 20px;
            margin: 10px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
        `;

        button.addEventListener('click', processPlaylistVideos);
        playlistHeader.appendChild(button);
    }

    // Initial setup
    function initialize() {
        // Wait for the page to load
        const observer = new MutationObserver((mutations, obs) => {
            if (document.querySelector('ytd-playlist-header-renderer')) {
                addControlButton();
                processPlaylistVideos();

                // Keep checking periodically for new videos (as YouTube loads them dynamically)
                setInterval(processPlaylistVideos, CHECK_INTERVAL);

                obs.disconnect();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // Start the script
    initialize();
})();