您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
osu! play-along mode with default trail settings (2 images, 150ms fade) and fade slider that goes down to 5ms 💨🖱️✨🎯 Super snappy!
// ==UserScript== // @name YouTube osu! Play-Along Mode (v1.7.7 Default Trail + 5ms Fade Option) // @namespace https://osu.ppy.sh/ // @version 1.7.8 // @description osu! play-along mode with default trail settings (2 images, 150ms fade) and fade slider that goes down to 5ms 💨🖱️✨🎯 Super snappy! // @author ThunderBirdo+ChatGPT // @license MIT // @match https://www.youtube.com/* // @grant none // ==/UserScript== (function () { 'use strict'; let popupShown = false; let popupDisabled = false; let playModeActive = false; let customCursorStyle = null; let customStyle = null; let trailURL = ''; let trailMax = 2; let fadeTime = 150; let trailImages = []; let trailContainer = null; function createPopup() { if (document.getElementById('osu-playalong-popup') || popupDisabled) return; const popup = document.createElement('div'); popup.id = 'osu-playalong-popup'; Object.assign(popup.style, { position: 'fixed', top: '10px', left: '10px', background: '#111', color: 'white', padding: '10px', borderRadius: '8px', zIndex: '9999', fontSize: '16px', display: 'flex', alignItems: 'center', gap: '10px', }); const label = document.createElement('span'); label.textContent = 'Play Along?'; const yesBtn = document.createElement('button'); yesBtn.textContent = 'Yes'; const noBtn = document.createElement('button'); noBtn.textContent = 'No'; yesBtn.addEventListener('click', () => { const video = document.querySelector('video'); if (video) video.pause(); popup.remove(); requestAnimationFrame(() => { setTimeout(showConfigForm, 100); }); }); noBtn.addEventListener('click', () => { popupDisabled = true; popup.remove(); }); popup.appendChild(label); popup.appendChild(yesBtn); popup.appendChild(noBtn); document.body.appendChild(popup); } function showConfigForm() { if (document.getElementById('osu-playalong-config')) return; const form = document.createElement('div'); form.id = 'osu-playalong-config'; Object.assign(form.style, { position: 'fixed', top: '10px', left: '10px', background: '#222', color: 'white', padding: '10px', borderRadius: '8px', zIndex: '9999', fontSize: '14px', display: 'flex', flexDirection: 'column', gap: '6px', width: '320px', }); const cursorInput = document.createElement('input'); cursorInput.type = 'text'; cursorInput.placeholder = 'Cursor Image URL'; cursorInput.style.width = '100%'; const defaultCursorBtn = document.createElement('button'); defaultCursorBtn.textContent = 'Use Default Cursor'; defaultCursorBtn.addEventListener('click', () => { cursorInput.value = 'https://osuskinner.com/elements/interface/cursor/152/1557.png'; }); const trailInput = document.createElement('input'); trailInput.type = 'text'; trailInput.placeholder = 'Cursor Trail Image URL'; trailInput.style.width = '100%'; const defaultTrailBtn = document.createElement('button'); defaultTrailBtn.textContent = 'Use Default Trail'; defaultTrailBtn.addEventListener('click', () => { trailInput.value = 'https://osuskinner.com/elements/interface/cursortrail/1562/8236.png'; }); const trailLengthInput = document.createElement('input'); trailLengthInput.type = 'range'; trailLengthInput.min = '0'; trailLengthInput.max = '50'; trailLengthInput.value = trailMax; const trailLabel = document.createElement('label'); trailLabel.textContent = `Trail Length: ${trailMax}`; trailLengthInput.addEventListener('input', () => { trailLabel.textContent = `Trail Length: ${trailLengthInput.value}`; }); const fadeInput = document.createElement('input'); fadeInput.type = 'range'; fadeInput.min = '5'; fadeInput.max = '2000'; fadeInput.step = '5'; fadeInput.value = fadeTime; const fadeLabel = document.createElement('label'); fadeLabel.textContent = `Fade Duration: ${fadeTime}ms`; fadeInput.addEventListener('input', () => { fadeLabel.textContent = `Fade Duration: ${fadeInput.value}ms`; }); const restartCheckbox = document.createElement('input'); restartCheckbox.type = 'checkbox'; const restartLabel = document.createElement('label'); restartLabel.appendChild(restartCheckbox); restartLabel.appendChild(document.createTextNode(' Start from beginning')); const rateSlider = document.createElement('input'); rateSlider.type = 'range'; rateSlider.min = '0.25'; rateSlider.max = '2'; rateSlider.step = '0.05'; rateSlider.value = '1'; const rateDisplay = document.createElement('div'); const updateRateDisplay = () => { let v = parseFloat(rateSlider.value); let label = v === 0.75 ? 'HT' : v === 1.5 ? 'DT' : v.toFixed(2) + 'x'; rateDisplay.textContent = `Playback: ${label}`; }; rateSlider.addEventListener('input', updateRateDisplay); updateRateDisplay(); const startBtn = document.createElement('button'); startBtn.textContent = 'Start'; startBtn.addEventListener('click', () => { const cursorURL = cursorInput.value.trim(); trailURL = trailInput.value.trim(); trailMax = parseInt(trailLengthInput.value.trim()) || 0; fadeTime = parseInt(fadeInput.value.trim()) || 150; const restart = restartCheckbox.checked; const rate = parseFloat(rateSlider.value); if (!cursorURL) { alert('Please enter a cursor image URL.'); return; } form.remove(); startPlayMode(cursorURL, restart, rate); }); form.appendChild(cursorInput); form.appendChild(defaultCursorBtn); form.appendChild(trailInput); form.appendChild(defaultTrailBtn); form.appendChild(trailLabel); form.appendChild(trailLengthInput); form.appendChild(fadeLabel); form.appendChild(fadeInput); form.appendChild(restartLabel); form.appendChild(rateSlider); form.appendChild(rateDisplay); form.appendChild(startBtn); document.body.appendChild(form); } function startPlayMode(cursorURL, restart, rate) { const video = document.querySelector('video'); const player = document.querySelector('#movie_player'); if (!video || !player) { alert('Video not found.'); return; } video.pause(); if (restart) video.currentTime = 0; video.playbackRate = rate; playModeActive = true; if (customCursorStyle) customCursorStyle.remove(); customCursorStyle = document.createElement('style'); customCursorStyle.textContent = ` * { cursor: url("${cursorURL}") 16 16, auto !important; } `; document.head.appendChild(customCursorStyle); if (customStyle) customStyle.remove(); customStyle = document.createElement('style'); customStyle.textContent = ` .ytp-chrome-bottom, .ytp-gradient-top, .ytp-gradient-bottom, .ytp-show-cards-title, .ytp-title, .ytp-pause-overlay, .ytp-chrome-top, .ytp-bezel { display: none !important; pointer-events: none !important; } `; document.head.appendChild(customStyle); trailContainer = document.querySelector('#movie_player') || document.body; if (trailURL && trailMax > 0) { document.addEventListener('pointermove', spawnTrailImage); } window.addEventListener('keydown', blockAllKeys, true); window.addEventListener('mousedown', blockClicks, true); window.addEventListener('click', blockClicks, true); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && playModeActive) { exitPlayMode(video); } }); document.addEventListener('fullscreenchange', () => { if (!document.fullscreenElement && playModeActive) { exitPlayMode(video); } }); setTimeout(() => { if (player.requestFullscreen) { player.requestFullscreen().catch(err => console.log('Fullscreen failed:', err)); } video.play().catch(err => console.log('Play failed:', err)); }, 100); } function spawnTrailImage(e) { if (!trailContainer) return; const trail = document.createElement('img'); trail.src = trailURL; trail.style.position = 'fixed'; trail.style.left = `${e.clientX}px`; trail.style.top = `${e.clientY}px`; trail.style.width = '32px'; trail.style.height = '32px'; trail.style.pointerEvents = 'none'; trail.style.zIndex = '10000'; trail.style.transition = `opacity ${fadeTime}ms linear`; trail.style.opacity = '1'; trailContainer.appendChild(trail); trailImages.push(trail); if (trailImages.length > trailMax) { const oldest = trailImages.shift(); oldest.style.opacity = '0'; setTimeout(() => oldest.remove(), fadeTime); } } function blockAllKeys(e) { if (playModeActive) { e.stopImmediatePropagation(); e.preventDefault(); } } function blockClicks(e) { if (playModeActive) { e.stopImmediatePropagation(); e.preventDefault(); } } function exitPlayMode(video) { playModeActive = false; if (document.fullscreenElement) document.exitFullscreen(); if (video) { video.pause(); video.playbackRate = 1; } if (customCursorStyle) { customCursorStyle.remove(); customCursorStyle = null; } if (customStyle) { customStyle.remove(); customStyle = null; } for (const img of trailImages) img.remove(); trailImages = []; trailContainer = null; document.removeEventListener('pointermove', spawnTrailImage); window.removeEventListener('keydown', blockAllKeys, true); window.removeEventListener('mousedown', blockClicks, true); window.removeEventListener('click', blockClicks, true); } function onYouTubeWatchPage() { if (!location.href.includes('/watch')) return; const checkReady = setInterval(() => { const video = document.querySelector('video'); if (video && !popupShown) { popupShown = true; createPopup(); clearInterval(checkReady); } }, 500); } window.addEventListener('load', onYouTubeWatchPage); const observer = new MutationObserver(() => { if ( location.href.includes('/watch') && !popupDisabled && !document.getElementById('osu-playalong-popup') && !document.getElementById('osu-playalong-config') ) { popupShown = false; onYouTubeWatchPage(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址