Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save astamicu/eb351ce10451f1a51b71a1287d36880f to your computer and use it in GitHub Desktop.
Save astamicu/eb351ce10451f1a51b71a1287d36880f to your computer and use it in GitHub Desktop.
Script to remove all videos from Youtube Watch Later playlist

UPDATED 22.11.2022

It's been two years since the last update, so here's the updated working script as per the comments below.

Thanks to BryanHaley for this.

setInterval(function () {
    video = document.getElementsByTagName('ytd-playlist-video-renderer')[0];

    video.querySelector('#primary button[aria-label="Action menu"]').click();

    var things = document.evaluate(
        '//span[contains(text(),"Remove from")]',
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

    for (var i = 0; i < things.snapshotLength; i++) 
    {
        things.snapshotItem(i).click();
    }
}, 500);

Non-english users will need to change "Action menu" and "Remove from" to what YouTube uses for their localization.

@JaiganeshKumaran
Copy link

JaiganeshKumaran commented Nov 26, 2024

No longer works for me. It deletes the first one, and then the menu gets stuck at the top-left corner.

@anhtuan219
Copy link

anhtuan219 commented Dec 5, 2024

Thanks @vinivosh
Here's Vietnamese version, including removing the hidden videos and clearing the interval after the playlist is empty

  1. Go to Youtube Watch Later playlist
  2. Ctrl + Shift + I to open chrome devtools -> Choose the Console tab
  3. Type 'allow pasting' in the console
  4. Paste this into the console
var deleteInterval = setInterval(function () {
    video = document.getElementsByTagName('ytd-playlist-video-renderer')[0];

    if(!video) {
         clearInterval(deleteInterval);
         return;
    }

    video.querySelector('#primary button[aria-label="Menu tác vụ"]').click();

    var things = document.evaluate(
        '//span[contains(text(),"Xóa khỏi")]',
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

    for (var i = 0; i < things.snapshotLength; i++) 
    {
        things.snapshotItem(i).click();
    }
}, 1000);
  1. Paste this into the console to remove the hidden videos
// Show hidden videos
var btnListWL = document.querySelector('.metadata-buttons-wrapper.style-scope.ytd-playlist-header-renderer');
btnListWL.lastElementChild.lastElementChild.lastElementChild.click();
setTimeout(() => {
     var showHiddenVideoLink = document.querySelector('a[href="/playlist?list=WL"]').click();
}, 500);

// Remove the hidden videos
setTimeout(() => {
var deleteHiddenVideosInterval = setInterval(function () {
    video = document.getElementsByTagName('ytd-playlist-video-renderer')[0];

    if(!video) {
         clearInterval(deleteHiddenVideosInterval);
         return;
    }

    video.querySelector('button').click();

    var things = document.evaluate(
        '//span[contains(text(),"Xóa khỏi")]',
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

    for (var i = 0; i < things.snapshotLength; i++) 
    {
        things.snapshotItem(i).click();
    }
}, 1000);
}, 1000);

@BryanHaley
Copy link

I found myself wanting to keep a certain amount of videos (i.e. the last 1,000 added), so I sorted by oldest and set the script to stop removing videos once it got to that number. Based on secbug's most recent version.

const KEEP_NUM_VIDEOS = 1000;

const getRandomMillis = (min, max) => {
  return Math.random() * (max - min) + min
}

setInterval(function () {
    let metadataDiv = document.getElementsByClassName('metadata-stats');
    let byline = metadataDiv[0].getElementsByClassName('byline-item');
    let formattedStr = byline[0].getElementsByClassName('yt-formatted-string');
    let numVideosStr = formattedStr[0].innerHTML;

    numVideos = Number(numVideosStr.replace(',',''));

    if (numVideos > KEEP_NUM_VIDEOS) {
        video = document.getElementsByTagName('ytd-playlist-video-renderer')[0];

        video.querySelector('#primary button').click();

        var things = document.evaluate(
            '//span[contains(text(),"Remove from")]',
            document,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null
        );

        for (var i = 0; i < things.snapshotLength; i++) 
        {
            things.snapshotItem(i).click();
        }
    }
}, getRandomMillis(700, 1100));

@John-nata
Copy link

G'day everyone!

I’m stokedto announce a major update to my userscript "YT-Playlist-Cleaner", packed with some fantastic new features and improvements:

🌟 New Features: Welcome message, dark mode, smart retry, and usage stats.
🚀 Enhanced: Error handling, performance, and UI responsiveness.
🛠️ Added Functionality: Batch processing, config persistence, and a cleaner codebase.
🐛 Bug Fixes: Scrolling, deletion, and notification issues resolved.

This update makes the script more powerful and reliable than ever.
The script is fully open-source: feel free to fork it, tweak it, and make it your own!
Collaboration is what makes Github and coding so amazing, am I right?

image

Looking forward to hearing your thoughts!

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment