您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Forwards YouTube links to the youtube.com/embed/* page, so there's just the video in your window and nothing else.
// ==UserScript== // @name YouTube /embed/ forwarder // @description Forwards YouTube links to the youtube.com/embed/* page, so there's just the video in your window and nothing else. // @namespace https://greasyfork.org/en/users/1148791-vuccala // @author Vuccala // @icon https://archive.org/download/yt_icon/yt.png // @match *://*.youtube.com/* // @match *://*.youtu.be/* // @run-at document-start // @version 0.7 // @grant none // @license MIT // ==/UserScript== (function () { const EMBED_BASE = 'https://www.youtube.com/embed/'; // Regex catches watch, embed, v/, shorts/, and ?list= const ID_REGEX = /(?:[?&]v=|\/(?:embed\/|v\/|shorts\/))([^&?/]+)|(?:[?&]list=)([^&?/]+)/g; function parseYouTubeUrl(url) { const parsed = new URL(url); const params = parsed.searchParams; let videoId = null; let playlistId = null; // Handle youtu.be short links if (parsed.hostname === 'youtu.be' && parsed.pathname.length > 1) { videoId = parsed.pathname.slice(1); } let match; while ((match = ID_REGEX.exec(url)) !== null) { if (match[1]) videoId = match[1]; if (match[2]) playlistId = match[2]; } // Extract playlist index const index = params.has('index') ? parseInt(params.get('index'), 10) : null; // Extract start time (from t= or start=) let start = null; if (params.has('t')) { start = parseTime(params.get('t')); } else if (params.has('start')) { start = parseInt(params.get('start'), 10) || null; } if (!videoId) return null; return playlistId ? { type: 'playlist', videoId, playlistId, index, start } : { type: 'video', videoId, index, start }; } function parseTime(t) { // t can be like "90", "1m30s", "2h3m5s" const timeRegex = /(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s?)?/; const match = timeRegex.exec(t); if (!match) return null; const hours = parseInt(match[1] || 0, 10); const minutes = parseInt(match[2] || 0, 10); const seconds = parseInt(match[3] || 0, 10); return hours * 3600 + minutes * 60 + seconds; } function createSpoofPage(embedUrl) { const html = ` <html> <head> <meta http-equiv="refresh" content="0; url='${embedUrl}'" /> <meta name="referrer" content="origin" /> </head> <body> <p>Redirecting to YouTube embed...</p> </body> </html> `; const blob = new Blob([html], { type: 'text/html' }); return URL.createObjectURL(blob); } const currentUrl = window.location.href; const ids = parseYouTubeUrl(currentUrl); if (!ids) return; let embedUrl; if (ids.type === 'playlist') { if (ids.index > 200) { // Fallback: YouTube embed player won’t load >200, so just load the video embedUrl = `${EMBED_BASE}${ids.videoId}?autoplay=1&list=${ids.playlistId}`; } else { // Preserve playlist and index when possible embedUrl = `${EMBED_BASE}${ids.videoId}?list=${ids.playlistId}&autoplay=1`; if (ids.index) embedUrl += `&index=${ids.index}`; } } else { // Normal video embedUrl = `${EMBED_BASE}${ids.videoId}?autoplay=1`; } // Add timestamp if available if (ids.start) { embedUrl += `&start=${ids.start}`; } if (embedUrl && embedUrl !== currentUrl) { const spoofPage = createSpoofPage(embedUrl); window.location.href = spoofPage; } })();