Skip to content

Instantly share code, notes, and snippets.

@deansimcox
Created August 7, 2023 02:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deansimcox/20c247fc5b7feb82f6c91967fb331e23 to your computer and use it in GitHub Desktop.
Save deansimcox/20c247fc5b7feb82f6c91967fb331e23 to your computer and use it in GitHub Desktop.
Some JS that will go through your Watch Later playlist on Youtube, and remove items sequentially
/**
* Works on your watch later playlist `/playlist?list=WL`
* Update NUMBER_OF_LATEST_VIDEOS_TO_KEEP if you want to keep more/less than the 20 most recent videos
*/
const NUMBER_OF_LATEST_VIDEOS_TO_KEEP = 20;
async function doThing(vidArray) {
for (const vid of vidArray) {
vid.click();
await Promise.allSettled([
poll(() => {
const removeBtn = document.querySelector(
"ytd-popup-container ytd-menu-service-item-renderer:nth-child(3)"
);
if (!removeBtn) {
return null;
}
console.log("removeBtn", removeBtn);
removeBtn.click();
}),
wait(1200),
]);
}
}
function wait(milliseconds) {
return new Promise((resolve) => {
setTimeout(resolve, milliseconds);
});
}
function poll(fn, timeout, interval) {
var endTime = Number(new Date()) + (timeout || 1200);
interval = interval || 600;
return new Promise(function (resolve, reject) {
(function p() {
// If the condition is met, we're done!
if (fn()) {
resolve();
}
// If the condition isn't met but the timeout hasn't elapsed, go again
else if (Number(new Date()) < endTime) {
setTimeout(p, interval);
}
// Didn't match and too much time, reject!
else {
reject("timed out for " + fn + ": " + arguments);
}
})();
});
}
const vidBtns = Array.from(
document.querySelectorAll(
`#contents ytd-playlist-video-renderer:nth-child(n+${NUMBER_OF_LATEST_VIDEOS_TO_KEEP}) yt-icon-button button`
)
);
doThing(vidBtns);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment