您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Youtube 小屏播放。当你向下滚动时,小屏播放器将会出现。
// ==UserScript== // @name YouTube Mini Player // @name:zh-CN Youtube 小屏播放 // @namespace http://tampermonkey.net/ // @version 2.4.1 // @license MIT // @description Youtube Mini Player. When you scroll down the mini player will appear. // @description:zh-CN Youtube 小屏播放。当你向下滚动时,小屏播放器将会出现。 // @author https://github.com/AkiyaKiko // @homepage https://github.com/AkiyaKiko/YouTubeMiniPlayer // @match https://www.youtube.com/* // @icon https://www.youtube.com/favicon.ico // @run-at document-end // @grant GM_addStyle // @grant GM_log // ==/UserScript== (function() { 'use strict'; GM_log('🛠️ 脚本 "YouTube Mini Player (No Placeholder)" 开始执行'); const miniPlayerClass = 'youtube-mini-player-active'; let playerElement = null; let outerContainer = null; let innerContainer = null; let videoElement = null; let ivVideoContent = null; let bottomChrome = null; let originalOuterContainerStyle = null; let originalInnerContainerStyle = null; let originalVideoStyle = null; let originalIvContentStyle = null; let intersectionObserver = null; let observer = null; let isMiniPlayerActive = false; let lastUrl = location.href; let initializedUrl = null; let isDragging = false; let dragOffsetX = 0; let dragOffsetY = 0; let storedPlayerHeight = 0; function isFullscreen() { return !!document.fullscreenElement; } function minimizeOuterContainer() { if (!outerContainer || isMiniPlayerActive || isFullscreen()) { GM_log('🔽 不满足小窗条件,跳过。'); return; } originalOuterContainerStyle = outerContainer.getAttribute('style'); originalInnerContainerStyle = innerContainer?.getAttribute('style'); originalVideoStyle = videoElement?.getAttribute('style'); originalIvContentStyle = ivVideoContent?.getAttribute('style'); storedPlayerHeight = playerElement.offsetHeight; GM_log(`📏 设置 #player 高度: ${storedPlayerHeight}px`); playerElement.style.height = `${storedPlayerHeight}px`; const floatingWidth = window.innerWidth / 5; const aspectRatio = outerContainer.offsetWidth / outerContainer.offsetHeight; const floatingHeight = floatingWidth / aspectRatio; const rightOffset = window.innerWidth * 0.03; const bottomOffset = window.innerHeight * 0.02; outerContainer.style.position = 'fixed'; outerContainer.style.bottom = `${bottomOffset}px`; outerContainer.style.right = `${rightOffset}px`; outerContainer.style.left = 'auto'; outerContainer.style.top = 'auto'; outerContainer.style.width = `${floatingWidth}px`; outerContainer.style.height = `${floatingHeight}px`; outerContainer.style.zIndex = '3000'; outerContainer.style.boxShadow = '2px 2px 5px rgba(0, 0, 0, 0.3)'; outerContainer.style.minWidth = '0px'; outerContainer.classList.add(miniPlayerClass); isMiniPlayerActive = true; if (innerContainer) { innerContainer.style.width = `${floatingWidth}px`; innerContainer.style.height = `${floatingHeight}px`; innerContainer.style.paddingTop = '0px'; } if (bottomChrome) bottomChrome.style.display = 'none'; if (videoElement) { videoElement.style.width = `${floatingWidth}px`; videoElement.style.height = `${floatingHeight}px`; } if (ivVideoContent) { ivVideoContent.style.width = `${floatingWidth}px`; ivVideoContent.style.height = `${floatingHeight}px`; } enableDragging(); } function restoreOuterContainer() { if (!outerContainer || !isMiniPlayerActive || isFullscreen()) { GM_log('🔼 不满足恢复条件,跳过。'); return; } outerContainer.setAttribute('style', originalOuterContainerStyle || ''); outerContainer.classList.remove(miniPlayerClass); isMiniPlayerActive = false; if (playerElement) { playerElement.style.height = ''; GM_log('🔁 恢复 #player 高度样式为空'); } if (innerContainer) innerContainer.removeAttribute('style'); if (bottomChrome) bottomChrome.style.display = ''; if (videoElement) videoElement.setAttribute('style', originalVideoStyle || ''); if (ivVideoContent) ivVideoContent.setAttribute('style', originalIvContentStyle || ''); disableDragging(); } function enableDragging() { if (!outerContainer) return; outerContainer.addEventListener('mousedown', onMouseDown); } function disableDragging() { if (!outerContainer) return; outerContainer.removeEventListener('mousedown', onMouseDown); } function onMouseDown(e) { if (!isMiniPlayerActive) return; isDragging = true; dragOffsetX = e.clientX - outerContainer.getBoundingClientRect().left; dragOffsetY = e.clientY - outerContainer.getBoundingClientRect().top; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); e.preventDefault(); } function onMouseMove(e) { if (!isDragging) return; outerContainer.style.left = `${e.clientX - dragOffsetX}px`; outerContainer.style.top = `${e.clientY - dragOffsetY}px`; outerContainer.style.right = 'auto'; outerContainer.style.bottom = 'auto'; } function onMouseUp() { isDragging = false; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } function observePlayerVisibility() { if (!playerElement) return; if (intersectionObserver) intersectionObserver.disconnect(); intersectionObserver = new IntersectionObserver(entries => { entries.forEach(entry => { const playerRect = entry.boundingClientRect; if (playerRect.bottom < 0) { if (!isFullscreen()) minimizeOuterContainer(); } else { restoreOuterContainer(); } }); }, { threshold: 0 }); intersectionObserver.observe(playerElement); } function waitForElements() { if (!observer) { observer = new MutationObserver((mutations, obs) => { if (document.getElementById('player') && document.getElementById('player-container-outer') && document.getElementById('player-container-inner') && document.querySelector('video.video-stream.html5-main-video') && document.getElementById('contents')) { obs.disconnect(); observer = null; initialize(); } }); observer.observe(document.body, { childList: true, subtree: true }); } } function handleResize() { if (outerContainer && outerContainer.classList.contains(miniPlayerClass)) { const floatingWidth = window.innerWidth / 5; const aspectRatio = outerContainer.offsetWidth / outerContainer.offsetHeight; const floatingHeight = floatingWidth / aspectRatio; const rightOffset = window.innerWidth * 0.03; const bottomOffset = window.innerHeight * 0.02; outerContainer.style.width = `${floatingWidth}px`; outerContainer.style.height = `${floatingHeight}px`; outerContainer.style.right = `${rightOffset}px`; outerContainer.style.bottom = `${bottomOffset}px`; outerContainer.style.left = 'auto'; outerContainer.style.top = 'auto'; if (innerContainer) { innerContainer.style.width = `${floatingWidth}px`; innerContainer.style.height = `${floatingHeight}px`; } if (videoElement) { videoElement.style.width = `${floatingWidth}px`; videoElement.style.height = `${floatingHeight}px`; } if (ivVideoContent) { ivVideoContent.style.width = `${floatingWidth}px`; ivVideoContent.style.height = `${floatingHeight}px`; } } } function cleanup() { if (intersectionObserver) { intersectionObserver.disconnect(); intersectionObserver = null; } if (observer) { observer.disconnect(); observer = null; } restoreOuterContainer(); window.removeEventListener('resize', handleResize); playerElement = null; outerContainer = null; innerContainer = null; videoElement = null; ivVideoContent = null; bottomChrome = null; initializedUrl = null; isMiniPlayerActive = false; isDragging = false; storedPlayerHeight = 0; } function initialize() { playerElement = document.getElementById('player'); outerContainer = document.getElementById('player-container-outer'); innerContainer = document.getElementById('player-container-inner'); videoElement = document.querySelector('video.video-stream.html5-main-video'); ivVideoContent = document.querySelector('.ytp-iv-video-content'); bottomChrome = document.querySelector('.ytp-chrome-bottom'); if (playerElement && outerContainer && innerContainer && videoElement) { observePlayerVisibility(); window.addEventListener('resize', handleResize); if (observer) { observer.disconnect(); observer = null; } isMiniPlayerActive = false; const rect = playerElement.getBoundingClientRect(); if (rect.bottom < 0) minimizeOuterContainer(); else restoreOuterContainer(); initializedUrl = location.href; } else { waitForElements(); } } function checkUrlAndInitialize() { if (location.pathname.startsWith('/watch')) { if (location.href !== initializedUrl) { cleanup(); setTimeout(() => initialize(), 500); } } else { cleanup(); } } function startUrlWatcher() { setInterval(() => { if (location.href !== lastUrl) { lastUrl = location.href; checkUrlAndInitialize(); } }, 300); } function start() { checkUrlAndInitialize(); startUrlWatcher(); } if (document.readyState === 'complete' || document.readyState === 'interactive') { start(); } else { document.addEventListener('DOMContentLoaded', start); } GM_addStyle(` .${miniPlayerClass} { transition: width 0.3s ease, height 0.3s ease, right 0.3s ease, bottom 0.3s ease, top 0.3s ease, left 0.3s ease; cursor: move; } `); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址