您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Control video scaleX on /watch and tile count
// ==UserScript== // @name YouTube Wide Mode + Fix // @version 1.4 // @match https://www.youtube.com/* // @grant GM_addStyle // @namespace https://gf.qytechs.cn/users/1029007 // @description Control video scaleX on /watch and tile count // ==/UserScript== (function () { 'use strict'; const SCALE_KEY = 'yt-wide-scaleX'; const TILE_KEY = 'yt-tile-count'; let scaleX = parseFloat(localStorage.getItem(SCALE_KEY)) || 1.3; let tilesPerRow = parseInt(localStorage.getItem(TILE_KEY)) || 4; let lastScaleBeforeFullscreen = scaleX; GM_addStyle(` html, body { scrollbar-width: none; -ms-overflow-style: none; } body::-webkit-scrollbar { display: none; } #yt-wide-control, #yt-tile-control { display: flex; align-items: center; gap: 6px; margin-right: 10px; background: transparent !important; } .yt-editable-label { cursor: pointer; color: var(--yt-spec-text-primary, #fff); font-size: 14px; } .yt-editable-input { width: 60px; padding: 2px 4px; font-size: 14px; background: transparent !important; border: none !important; outline: none; color: var(--yt-spec-text-primary, #fff); font-family: inherit; display: none; } .yt-control:hover .yt-editable-label { text-decoration: underline; } `); function calculateAutoScale(video) { const flexy = document.querySelector('ytd-watch-flexy[theater]'); if (!flexy || !video) return scaleX; const containerWidth = flexy.clientWidth; const videoNaturalWidth = video.videoWidth; if (!containerWidth || !videoNaturalWidth) return scaleX; const currentDisplayedWidth = video.clientWidth; if (!currentDisplayedWidth) return scaleX; const requiredScale = containerWidth / currentDisplayedWidth; return Math.min(Math.max(requiredScale, 1.0), 2.0); } function applyScale(value = scaleX, auto = false) { const video = document.querySelector('ytd-watch-flexy[theater] #movie_player video'); if (video) { const targetScale = auto ? calculateAutoScale(video) : value; video.style.transition = 'none'; video.style.transform = `scaleX(${targetScale})`; video.style.transformOrigin = 'center center'; if (auto) { const label = document.querySelector('#yt-wide-control .yt-editable-label'); if (label) label.textContent = `ScaleX: ${targetScale.toFixed(2)}`; } } } const videoObserver = new MutationObserver(() => { const video = document.querySelector('ytd-watch-flexy[theater] #movie_player video'); if (video) applyScale(undefined, true); }); function observeVideo() { const moviePlayer = document.querySelector('ytd-watch-flexy[theater] #movie_player'); if (moviePlayer) { videoObserver.disconnect(); videoObserver.observe(moviePlayer, { childList: true, subtree: true, }); const video = moviePlayer.querySelector('video'); if (video) { applyScale(); } else { const tmpObserver = new MutationObserver(() => { const vid = moviePlayer.querySelector('video'); if (vid) { applyScale(undefined, true); tmpObserver.disconnect(); } }); tmpObserver.observe(moviePlayer, { childList: true, subtree: true }); } } } function updateTiles() { let style = document.getElementById('tile-style'); if (!style) { style = document.createElement('style'); style.id = 'tile-style'; document.head.appendChild(style); } style.textContent = ` ytd-rich-grid-renderer { --ytd-rich-grid-items-per-row: ${tilesPerRow} !important; } `; } function preventScrollOnWheel(input) { input.addEventListener('wheel', e => { e.stopPropagation(); }, { passive: false }); } function waitForTargetElement(selector, callback) { const interval = setInterval(() => { const target = document.querySelector(selector); if (target) { clearInterval(interval); callback(target); } }, 50); } function createEditableControl(id, labelText, value, onChange) { if (document.getElementById(id)) return; const container = document.createElement('div'); container.id = id; container.className = 'yt-control'; const label = document.createElement('span'); label.className = 'yt-editable-label'; label.textContent = `${labelText}: ${value}`; const input = document.createElement('input'); input.className = 'yt-editable-input'; input.type = 'number'; input.step = '0.01'; input.value = value; preventScrollOnWheel(input); label.addEventListener('click', () => { label.style.display = 'none'; input.style.display = 'inline'; input.focus(); input.select(); }); input.addEventListener('blur', () => { const newValue = parseFloat(input.value); if (!isNaN(newValue)) { onChange(newValue); label.textContent = `${labelText}: ${newValue.toFixed(2)}`; if (!document.fullscreenElement && labelText === 'ScaleX') { lastScaleBeforeFullscreen = newValue; } } label.style.display = 'inline'; input.style.display = 'none'; }); input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { input.blur(); } }); container.appendChild(label); container.appendChild(input); return container; } function setup() { const path = window.location.pathname; const isWatch = path.startsWith('/watch'); const isMainOrSubs = path === '/' || path === '/feed/subscriptions'; waitForTargetElement('#end', (target) => { if (isWatch) { if (!document.getElementById('yt-wide-control')) { const scaleControl = createEditableControl( 'yt-wide-control', 'ScaleX', scaleX, (newValue) => { scaleX = newValue; localStorage.setItem(SCALE_KEY, newValue.toFixed(2)); lastScaleBeforeFullscreen = newValue; applyScale(); } ); target.insertBefore(scaleControl, target.firstChild); applyScale(); observeVideo(); } } else { const wideControl = document.getElementById('yt-wide-control'); if (wideControl) wideControl.remove(); videoObserver.disconnect(); } if (isMainOrSubs) { if (!document.getElementById('yt-tile-control')) { const tileControl = createEditableControl( 'yt-tile-control', 'Tiles', tilesPerRow, (newValue) => { tilesPerRow = parseInt(newValue) || 1; localStorage.setItem(TILE_KEY, tilesPerRow); updateTiles(); } ); tileControl.querySelector('input').step = '1'; tileControl.querySelector('input').min = '1'; target.insertBefore(tileControl, target.firstChild); updateTiles(); } } else { const tileControl = document.getElementById('yt-tile-control'); if (tileControl) tileControl.remove(); } }); } document.addEventListener('fullscreenchange', () => { const isFullscreen = !!document.fullscreenElement; if (isFullscreen) { lastScaleBeforeFullscreen = scaleX; applyScale(1.0); } else { applyScale(lastScaleBeforeFullscreen); } }); const pageObserver = new MutationObserver(() => { setup(); }); pageObserver.observe(document.body, { childList: true, subtree: true }); window.addEventListener('yt-navigate-finish', setup); setup(); const theaterObserver = new MutationObserver(mutations => { for (const mutation of mutations) { if (mutation.type === 'attributes' && mutation.attributeName === 'theater') { const isTheater = mutation.target.hasAttribute('theater'); if (isTheater) { applyScale(undefined, true); observeVideo(); } } } }); waitForTargetElement('ytd-watch-flexy', target => { theaterObserver.observe(target, { attributes: true }); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址