您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add an RSS feed link to the video owner section on YouTube video pages
// ==UserScript== // @name YouTube add Channel RSS Link // @namespace https://greasyfork.org/en/users/4612-gdorn // @version 1.0.1 // @description Add an RSS feed link to the video owner section on YouTube video pages // @author GDorn // @license MIT // @match https://www.youtube.com/watch* // @grant none // ==/UserScript== (function () { 'use strict'; let currentVideoId = null; // Tracks the video ID for which the RSS link was added let isRunning = false; // Semaphore to prevent concurrent execution /** * Extracts the channel ID from available data sources. */ const getChannelId = () => { let channelId = null; // First, try to get it from ytInitialPlayerResponse if (window.ytInitialPlayerResponse && window.ytInitialPlayerResponse.videoDetails) { channelId = window.ytInitialPlayerResponse.videoDetails.channelId; } // If not found, try to get it from ytInitialData if (!channelId && window.ytInitialData) { const data = window.ytInitialData; if (data && data.contents && data.contents.twoColumnWatchNextResults) { const owner = data.contents.twoColumnWatchNextResults.results.contents[0].videoOwnerRenderer; if (owner && owner.ownerEndpoint) { channelId = owner.ownerEndpoint.browseEndpoint.browseId.replace('UC', ''); } } } // If no channelId found yet, fall back to script tag parsing if (!channelId) { const scriptTags = Array.from(document.querySelectorAll('script')); for (const script of scriptTags) { if (script.innerHTML.includes('channelId":"UC')) { const match = script.innerHTML.match(/"channelId":"(UC[0-9A-Za-z-_]+)"/); if (match) { channelId = match[1].replace('UC', ''); break; } } } } return channelId; }; /** * Adds an RSS link to the video owner's section, with retry logic for when the owner box isn't found. */ const addRssLink = () => { const ownerBox = document.querySelector('#owner'); if (ownerBox) { const existingLink = ownerBox.querySelector('.rss-link'); if (existingLink) existingLink.remove(); // Extract channel ID dynamically const channelId = getChannelId(); if (!channelId) { console.log("Failed to find channel ID."); setTimeout(addRssLink, 500); // Retry if channelId is not found return; } const rssLink = `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`; const rssElement = document.createElement('a'); rssElement.href = rssLink; rssElement.textContent = 'RSS Feed'; rssElement.target = '_blank'; rssElement.className = 'rss-link'; rssElement.style.display = 'block'; rssElement.style.marginTop = '10px'; ownerBox.appendChild(rssElement); isRunning = false; console.log("Added RSS link"); } else { // Retry after 500ms if owner box is not found console.log("Owner box not found, retrying..."); setTimeout(addRssLink, 500); } }; /** * Replaces the existing RSS link with a reload link. */ const replaceWithReloadLink = () => { const ownerBox = document.querySelector('#owner'); if (ownerBox) { const existingLink = ownerBox.querySelector('.rss-link'); if (existingLink) existingLink.remove(); const reloadElement = document.createElement('a'); reloadElement.href = location.href; reloadElement.textContent = 'Reload to update RSS link'; reloadElement.target = '_self'; reloadElement.className = 'rss-link'; reloadElement.style.display = 'block'; reloadElement.style.marginTop = '10px'; ownerBox.appendChild(reloadElement); isRunning = false; console.log("Added reload link because video ID changed."); } else { // Retry after 500ms if owner box is not found console.log("Owner box not found, retrying..."); setTimeout(replaceWithReloadLink, 500); } }; /** * Processes the current video page and handles RSS/reload link updates. * If the owner box is not yet present, it retries every 500ms. */ const processVideo = () => { const videoId = new URLSearchParams(window.location.search).get('v'); if (!videoId) return; // No valid video ID // If the video ID has changed, replace the RSS link with the reload link. if (videoId !== currentVideoId) { if (currentVideoId !== null) { console.log("Video ID changed. Replacing RSS link with reload link."); replaceWithReloadLink(); // Replace the RSS link with a reload link currentVideoId = videoId; return; } currentVideoId = videoId; isRunning = true; addRssLink(); // Start the retry logic to wait for the #owner box and add the RSS link } }; // Observe DOM changes to detect navigation to a new video const observer = new MutationObserver(() => { if (!isRunning) { processVideo(); // Process the video when necessary } }); observer.observe(document.body, { childList: true, subtree: true }); console.log("YouTube Channel RSS Link script initialized."); processVideo(); // Initial run })();