-
-
Save miyagawa/bbf0e1be3cc0dca138aae320d38949c3 to your computer and use it in GitHub Desktop.
automatically remove YT video from Watch Later
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let videoMonitor = null; | |
| let currentVideoId = null; | |
| let autoRemovalTriggered = false; | |
| function getCurrentVideoId() { | |
| const location = new URL(window.location.href); | |
| let videoId = location.searchParams.get("v"); | |
| if (location.pathname.startsWith("/shorts/")) { | |
| videoId = location.pathname.split("/")[2]; | |
| } | |
| return videoId; | |
| } | |
| function removeFromWatchLater(videoId) { | |
| const getRemoveVideoParams = (videoId) => ({ | |
| clickTrackingParams: "", | |
| commandMetadata: { webCommandMetadata: { sendPost: true, apiUrl: "/youtubei/v1/browse/edit_playlist" } }, | |
| playlistEditEndpoint: { playlistId: "WL", actions: [{ action: "ACTION_REMOVE_VIDEO_BY_VIDEO_ID", removedVideoId: videoId }] } | |
| }); | |
| const appElement = document.querySelector("ytd-app"); | |
| if (!appElement) return; | |
| const event = new window.CustomEvent('yt-action', { | |
| detail: { | |
| actionName: 'yt-service-request', | |
| returnValue: [], | |
| args: [{ data: {} }, getRemoveVideoParams(videoId)], | |
| optionalAction: false, | |
| } | |
| }); | |
| appElement.dispatchEvent(event); | |
| console.log('Auto-removed video from Watch Later:', videoId); | |
| } | |
| function monitorVideoProgress() { | |
| const video = document.querySelector('video'); | |
| if (!video) return; | |
| const checkProgress = () => { | |
| if (video.duration && video.currentTime) { | |
| const remainingTime = video.duration - video.currentTime; | |
| // 95% reached, or remaining 60s | |
| const triggerThreshold = Math.max(video.duration * 0.05, 60); | |
| if (remainingTime <= triggerThreshold && remainingTime > 0 && !autoRemovalTriggered) { | |
| const videoId = getCurrentVideoId(); | |
| if (videoId) { | |
| autoRemovalTriggered = true; | |
| removeFromWatchLater(videoId); | |
| } | |
| } | |
| } | |
| }; | |
| video.addEventListener('timeupdate', checkProgress); | |
| return () => { | |
| video.removeEventListener('timeupdate', checkProgress); | |
| }; | |
| } | |
| function startMonitoring() { | |
| const videoId = getCurrentVideoId(); | |
| if (videoId !== currentVideoId) { | |
| currentVideoId = videoId; | |
| autoRemovalTriggered = false; | |
| if (videoMonitor) { | |
| videoMonitor(); | |
| } | |
| const waitForVideo = () => { | |
| const video = document.querySelector('video'); | |
| if (video) { | |
| videoMonitor = monitorVideoProgress(); | |
| } else { | |
| setTimeout(waitForVideo, 1000); | |
| } | |
| }; | |
| waitForVideo(); | |
| } | |
| } | |
| function handleNavigation() { | |
| startMonitoring(); | |
| } | |
| const observer = new MutationObserver((mutations) => { | |
| mutations.forEach((mutation) => { | |
| if (mutation.type === 'childList') { | |
| const addedNodes = Array.from(mutation.addedNodes); | |
| if (addedNodes.some(node => | |
| node.nodeType === Node.ELEMENT_NODE && | |
| (node.matches('ytd-watch-flexy') || node.querySelector('ytd-watch-flexy')) | |
| )) { | |
| setTimeout(handleNavigation, 1000); | |
| } | |
| } | |
| }); | |
| }); | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| window.addEventListener('yt-navigate-finish', handleNavigation); | |
| window.addEventListener('popstate', handleNavigation); | |
| setTimeout(startMonitoring, 2000); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "manifest_version": 3, | |
| "name": "YouTube Auto Watch Later", | |
| "version": "1.0", | |
| "description": "Automatically manage YouTube Watch Later playlist", | |
| "permissions": [ | |
| "scripting", | |
| "tabs", | |
| "activeTab" | |
| ], | |
| "host_permissions": [ | |
| "https://www.youtube.com/*" | |
| ], | |
| "content_scripts": [ | |
| { | |
| "matches": ["https://www.youtube.com/*"], | |
| "js": ["content.js"], | |
| "run_at": "document_idle" | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment