您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Make YouTube Player 480px Size
当前为
/* Resize the YouTube player to 480px size. Copyright (C) 2021 Runio This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/> */ // ==UserScript== // @name YouTube Sizer // @author Runio // @namespace namespace_runio // @version 1.32 // @description Make YouTube Player 480px Size // @match https://www.youtube.com/* // @match https://youtu.be/* // @exclude-match https://www.youtube.com/ // @exclude-match https://www.youtube.com/tv* // @exclude-match https://www.youtube.com/embed/* // @exclude-match https://www.youtube.com/live_chat* // @run-at document-end // @grant GM_setValue // @grant GM_getValue // @compatible Firefox version >= 69 // @compatible Chrome version >= 64 // @icon https://i.imgur.com/KJeLd60.png // @license GPL-3.0+ // @noframes // ==/UserScript== "use strict"; //================================================================== //Local Storage Functions if (window.frameElement) throw new Error("Stopped JavaScript."); function set_pref(preference, new_value) { GM_setValue(preference, new_value); } function get_pref(preference) { return GM_getValue(preference); } function init_pref(preference, new_value) { var value = get_pref(preference); if (value == null) { set_pref(preference, new_value); value = new_value; } return value; } //================================================================== init_pref("yt-resize", false); //================================================================== // Global Booleans var scrub_bool = false; var button_done = false; var pref_done = false; var resize_done = false; //================================================================== // Global Variables var max_width = 480; // Max Width of Video var aspect_ratio = 16/9; // Aspect Ratio var shortcut_key = "r"; // Shortcut Key var smaller_string = "ytd-watch-flexy[flexy_] #primary.ytd-watch-flexy:not([theater]):not([fullscreen]) {max-width: calc("+max_width+"px * "+aspect_ratio+") !important;"; var css_ytresize = ".ytp-big-mode .ytp-chrome-controls .ytp-resize-button {display: none !important;} .ytp-chrome-bottom {max-width: calc(100% - 24px);width: calc(100% - 24px);}"; //================================================================== window.addEventListener("yt-navigate-start", () => { startScript(); }); window.addEventListener("yt-page-data-updated", () => { startScript(); }); //================================================================== // Start Script function startScript() { 'use strict'; if (document.readyState == "complete" || document.readyState == "loaded" || document.readyState == "interactive") { startMethods(); } else { document.addEventListener("DOMContentLoaded", function() { startMethods(); }); } } //================================================================== function startMethods() { window.ytd_video = document.getElementById("ytd-player"); window.movie_player = document.getElementById("movie_player"); window.outer = document.getElementById("player-container-outer"); window.video = document.getElementsByTagName("video")[0]; window.ytd_flexy = document.getElementsByTagName("ytd-watch-flexy")[0]; if (pref_done == false) { if (get_pref("yt-resize")) { addSmaller(smaller_string); } autoResizeVideo(); addCss(css_ytresize); pref_done = true; } } //================================================================== //Scrubber Event Listener function getComputedTranslateXY(obj) { const transArr = []; if (!window.getComputedStyle) return; const style = getComputedStyle(obj), transform = style.transform || style.webkitTransform || style.mozTransform; let mat = transform.match(/^matrix3d\((.+)\)$/); if (mat) return parseFloat(mat[1].split(', ')[13]); mat = transform.match(/^matrix\((.+)\)$/); mat ? transArr.push(parseFloat(mat[1].split(', ')[4])) : 0; mat ? transArr.push(parseFloat(mat[1].split(', ')[5])) : 0; return transArr; } function scrubListener() { var elem = document.querySelector(".ytp-progress-bar-container > .ytp-progress-bar"); elem.addEventListener('timeupdate', function(elem) { var event = new CustomEvent('scrubber'); elem.dispatchEvent(event); }); elem.addEventListener('scrubber', function() { var scrub = document.querySelector(".ytp-progress-bar > .ytp-scrubber-container"); var progress = document.querySelector(".ytp-progress-list > .ytp-hover-progress"); var numericValue = window.getComputedStyle(progress, null).getPropertyValue('left').match(/\d+/); if (scrub) { if (Math.floor(getComputedTranslateXY(scrub)[0]) == parseInt(numericValue[0])) { scrub_bool = true; } return (scrub_bool); } else { return false; } }); } //================================================================== function isInViewport(video, element) { var rect = element.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom >= video.clientHeight && rect.right >= video.clientWidth ); } function isCentered(element1, element2) { var rect = element1.getBoundingClientRect(); var rect2 = element2.getBoundingClientRect(); var centered = { outer: rect.left + rect.width / 2, inner: rect2.left + rect2.width / 2, }; return ( Math.floor(centered.outer) == Math.floor(centered.inner) ); } function addCss(cssString) { var head = document.getElementsByTagName('head')[0]; var newCss = document.createElement('style'); newCss.type = "text/css"; newCss.setAttribute("id", "yt-css"); newCss.innerHTML = cssString; head.appendChild(newCss); } function addSmaller(cssString) { var head = document.getElementsByTagName('head')[0]; var newCss = document.createElement('style'); newCss.type = "text/css"; newCss.setAttribute("id", "small-player"); newCss.innerHTML = cssString; head.appendChild(newCss); } function injectJs(link) { var scr = document.createElement('script'); scr.type = "text/javascript"; scr.innerHTML = link; document.getElementsByTagName('head')[0].appendChild(scr); } function show_resize_button_tooltip(btn, show = true) { var bbcr = btn.getBoundingClientRect(); // Get button position var tooltip_horiz_cen = bbcr.left + bbcr.width / 2; // Tooltip horizontal center var tooltip_top_offset = 57; // Height above the button for the tooltip var tooltip_top = bbcr.top + bbcr.height / 2 - tooltip_top_offset; // Tooltip top var tooltip = document.getElementById("ytd-resize-tt"); var html_player = document.getElementsByClassName("html5-video-player")[0]; var tooltip_text_wrapper = document.createElement("div"); var tooltip_text, tooltip_width; if (document.fullscreenElement) { // Check if Fullscreen tooltip_top_offset = 75; } if (!tooltip) { // Create Tooltip if it doesn't exist. tooltip = document.createElement("div"); tooltip_text = document.createElement("span"); tooltip.setAttribute("class", "ytp-tooltip ytp-bottom"); tooltip.setAttribute("id", "ytd-resize-tt"); tooltip.style.setProperty("position", "fixed"); tooltip_text_wrapper.setAttribute("class", "ytp-tooltip-text-wrapper"); tooltip_text.setAttribute("class", "ytp-tooltip-text"); tooltip_text.setAttribute("id", "ytd-resize-tt-text"); tooltip.appendChild(tooltip_text_wrapper); tooltip_text_wrapper.appendChild(tooltip_text); html_player.appendChild(tooltip); } else { // Get Tooltip text if exists tooltip_text = document.getElementById("ytd-resize-tt-text"); } if (show) { // Show tooltip.style.setProperty("top", tooltip_top + "px"); tooltip_text.innerHTML = btn.getAttribute("aria-label"); tooltip.style.removeProperty("display"); // Show the Tooltip tooltip_width = tooltip.getBoundingClientRect().width; tooltip.style.setProperty("left", tooltip_horiz_cen - tooltip_width / 2 + "px"); btn.removeAttribute("title"); } else { // Hide tooltip.style.setProperty("display", "none"); tooltip_text.innerHTML = ""; btn.setAttribute("title", btn.getAttribute("aria-label")); } } function createResize() { var ytd = { height: movie_player.clientHeight, width: movie_player.clientWidth, }; ytd_video.player_.setInternalSize(ytd.width, ytd.height); return; } function buttonScript() { var key_script = ` function keyPress() { document.addEventListener("keydown", function(e) { if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return; if (/^(?:input|textarea|select|button)$/i.test(e.target.tagName)) return; if (/(?:contenteditable-root)/i.test(e.target.id)) return; if (e.key == "` + shortcut_key.toLowerCase() + `" || e.key == "` + shortcut_key.toUpperCase() + `") { e.preventDefault(); e.stopPropagation(); document.getElementById("ytd-player").focus(); resizeScript(); } return; }); document.querySelector(".ytp-right-controls > .ytp-resize-button.ytp-button").onclick = function foo() { resizeScript(); }; } function resizeScript() { let splayer = document.getElementById("small-player"); let ytvideo = document.getElementById("ytd-player"); let ytplayer = document.getElementById("movie_player"); if (document.head.contains(splayer)) { splayer.parentNode.removeChild(splayer); ytvideo.player_.setInternalSize(ytplayer.clientWidth, ytplayer.clientHeight); } else { var head = document.getElementsByTagName("head")[0]; var newCss = document.createElement("style"); newCss.type = "text/css"; newCss.setAttribute("id", "small-player"); newCss.innerHTML = "ytd-watch-flexy[flexy_] #primary.ytd-watch-flexy:not([theater]):not([fullscreen]) {max-width: calc(`+max_width+`px * `+aspect_ratio+`) !important;}"; head.appendChild(newCss); ytvideo.player_.setInternalSize(ytplayer.clientWidth, ytplayer.clientHeight); } } if (key_done == false) { keyPress(); key_done = true; }`; injectJs(key_script); } /*Create Resize Button*/ function controlResize() { if (!button_done) { var abtn = document.querySelector("#movie_player > div.ytp-chrome-bottom > div.ytp-chrome-controls > div.ytp-right-controls"); var btn = document.createElement("button"); btn.innerHTML = '<svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%"><use class="ytp-svg-shadow" ></use>\ <path d="M25,17 L25,17 L25,17 Z M29,25 L29,10.98 C29,9.88 28.1,9 27,9 L9,9 C7.9,9 7,9.88 7,10.98 L7,25\ C7,26.1 7.9,27 9,27 L27,27 C28.1,27 29,26.1 29,25 L29,25 Z M27,25.02 L9,25.02 L9,10.97 L27,10.97\ L27,25.02 L27,25.02 Z" fill="#fff" fill-rule="evenodd" >\ </path></svg></button>'; btn.className += "ytp-resize-button ytp-button"; btn.setAttribute("id", "ytp-resize-button"); btn.setAttribute("data-tooltip-target-id", "ytp-resize-button"); btn.setAttribute("aria-label", "Resize (" + shortcut_key + ")"); btn.setAttribute("title", "Resize (" + shortcut_key + ")"); abtn.insertBefore(btn, abtn.lastChild); buttonScript(); // Inject button script /*Tooltip Event Handlers*/ btn.addEventListener("mouseover", function() { show_resize_button_tooltip(btn, true); }); btn.addEventListener("mouseout", function() { show_resize_button_tooltip(btn, false); }); btn.addEventListener("focus", function() { show_resize_button_tooltip(btn, true); }); btn.addEventListener("blur", function() { show_resize_button_tooltip(btn, false); }); button_done = true return; } } /*Viewport Observer*/ function viewObserver() { let resizeObserver = new ResizeObserver((entries) => { window.requestAnimationFrame(() => { if (!Array.isArray(entries) || !entries.length) { // Check Animation Frame return; } for (let entry of entries) { if (isInViewport(video, ytd_flexy) && !isCentered(video, movie_player)) { // Check Top Viewport and Centered if (!isInViewport(video, movie_player) || !scrub_bool) { // Check Video Player Size and Scrubber if (entry.contentRect.height != max_width) { // Check Max Width createResize(); } } } } }); for (let entry of entries) {console.log("Player Size: " + entry.contentRect.height + " x " + entry.contentRect.width);} }); // observe the given element for changes resizeObserver.observe(video); } /*Saves Size Setting*/ function sizeObserver() { // Select the node that will be observed for mutations const targetNode = document.head; // Options for the observer (which mutations to observe) const config = { attributes: true, childList: true, subtree: true }; // Callback function to execute when mutations are observed const callback = function(mutationsList, observer) { // Use traditional 'for loops' for IE 11 for (let mutation of mutationsList) { if (mutation.removedNodes.length >= 1) { if (mutation.removedNodes[0].id == "small-player") { set_pref("yt-resize", false); // Set resize to false } } else if (mutation.addedNodes.length >= 1) { if (mutation.addedNodes[0].id == "small-player") { set_pref("yt-resize", true); // Set resize to true } } } }; // Create an observer instance linked to the callback function const observer = new MutationObserver(callback); // Start observing the target node for configured mutations observer.observe(targetNode, config); } function autoResizeVideo() { if (outer !== "null") { injectJs('let key_done = false;'); // Global Variable scrubListener(); // Add Scrubber Listener sizeObserver(); // Size Observer viewObserver(); // Resize Observer window.addEventListener("yt-action", () => { // Adds Resize Button if (window.location.href.indexOf('youtube.com/watch') != -1) { if (video !== "null" && !resize_done) { controlResize(); resize_done = true; } } }); video.addEventListener("canplay", () => { // Resize on video load setTimeout(function(){ createResize(); }, 500); }); window.addEventListener("fullscreenchange", () => { if (!document.fullscreenElement) { // Check if leaving fullscreen createResize(); } }); } else { alert("player-container-outer not found"); } }