-
-
Save miketromba/334282421c4784d7d9a191ca25095c09 to your computer and use it in GitHub Desktop.
const ENABLED = false // Keep this false while testing to verify that it's working correctly | |
const DELETE_INTERVAL = 1000 // Amount of time in MS to wait between deletion (more likely to fail with a small number) | |
// This filter should return a boolean (true == delete video, false == keep video) | |
const MIN_DURATION_MS = 1000 * 60 * 1.5 // 1:30 mins | |
const SHOULD_DELETE = videoElement => { | |
try { | |
// Get the duration string | |
const durationString = videoElement.querySelector('[aria-label="Video duration"]').textContent.trim() | |
if(durationString.split(':').length > 2){ return false } // The video is > 1hr long | |
const [mins, secs] = durationString.split(':').map(stringNum => parseInt(stringNum, 10)) | |
const durationMS = (mins * 60 * 1000) + (secs * 1000) | |
// Return true if video is less than MIN_DURATION_MS in length | |
return durationMS < MIN_DURATION_MS | |
} catch(e){ | |
return false | |
} | |
} | |
// This will start up the script | |
let DELETE_OFFSET = 0 // Offset to keep track of skipped (non-deleted) videos | |
deleteNext(SHOULD_DELETE) // Pass in the shouldDelete filter function | |
// Delete the next bad item and wait [DELETE_INTERVAL]ms before proceeding | |
// This is recursive and never-ending | |
async function deleteNext(shouldDelete){ | |
// Extract next item from page | |
const nextItem = await getNextItem(DELETE_OFFSET) | |
// If video does not pass filter, skip it, increment the offset | |
if(!shouldDelete(nextItem)){ | |
DELETE_OFFSET += 1 | |
return deleteNext(shouldDelete) | |
} | |
// Find name and author of video & log it to console | |
try { | |
const [videoName, channelName] = [...nextItem.getElementsByTagName('a')].map(anchor => anchor.textContent.trim()) | |
console.log(`DELETE: ${videoName} by ${channelName}...`) | |
} catch(e){} | |
// Find the next menu button for the item & click it | |
const nextButton = nextItem.getElementsByTagName('button')[0] | |
nextButton.click() | |
// Wait [DELETE_INTERVAL] ms | |
setTimeout(() => { | |
// Get the next delete button on the page & click it | |
const nextMenu = nextItem.querySelector('[aria-label="Activity options menu"]') | |
const nextDeleteButton = nextMenu.querySelector('[aria-label="Delete activity item"]') | |
// If enabled, click delete button, else just increment offset | |
if(ENABLED) nextDeleteButton.click() | |
else DELETE_OFFSET += 1 | |
// Recurse | |
deleteNext(shouldDelete) | |
}, DELETE_INTERVAL) | |
} | |
async function getNextItem(offset){ | |
while(true){ | |
const nextItem = document.querySelectorAll('div[role="listitem"]')[offset] | |
if(nextItem) return nextItem | |
await sleep(200) | |
} | |
} | |
async function sleep(ms){ | |
return new Promise(resolve => { | |
setTimeout(resolve, ms) | |
}) | |
} |
it is deleting only one video at a time
how to loop this
@Uddhav07 It has been a while since I wrote this so I don’t remember exactly how it works, but I think if you don’t want to clear your entire history, the google history UI makes you remove items one-by-one. (Not sure) I also notice that at the top of the script is a DELETE_INTERVAL variable which you can try reducing to speed up the process, but it might cause errors if you make it too fast.
@miguelmota Create a templeMonkey script so it can be add and update easy. tutorial
It's surprising that there's so much interest in this gist in the past few days, 3 years after it was created.
I too had the experience that it was deleting only one video at a time.
So I modified it a little and this seems to work for me. I had to introduce a longer delay between cycles, but.. it works. It will delete only short videos that are in the 100 most recent videos watched - because the 100 most recent is what is displayed on the screen. So eventually the script will run out of things to delete. You can scroll the page down in the browser to "load more" and it will keep deleting.
https://gist.github.com/DinoChiesa/f3f2aa34d7d581782a0b8572fad99278
Has your YouTube feed gotten out of control with bad recommendations?
This script will enable you to programmatically delete videos from your YouTube watch history based on some filter you define.
Note: You must set ENABLED to true for the script to actually delete the videos. If not, they will just be logged to the console.
Tip: Run the script in disabled mode first to review which videos will be deleted and tune your filter before actually letting it delete stuff.
My feed was getting clogged with tons of <1 minute long videos which were mostly just quick, funny TikTok-style videos. Naturally, the more the videos got recommended, the more I clicked on them... which led to more similar recommendations, and so on. My feed used to be filled with tons of great educational programming videos, and this script has helped me to restore it.