您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
增强Youtube使用体验
// ==UserScript== // @name YoutubePlus - 显评论昵称/100%音量增强/一键倍速按钮/自动切换Premium画质/删除迷你播放器按钮 // @namespace https://github.com/xlch88/YoutubePlus // @author Dark495 (https://dark495.me/) // @version 2025-02-18 // @license WTFPL // @description 增强Youtube使用体验 // @author Dark495 // @match https://www.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_openInTab // ==/UserScript== (function () { "use strict"; let player; let volumePanel; let volumeSlider; let commentWatcher; const functions = { maxVolume: { name: "真正100%音量", enable: true, }, speedButton: { name: "一键倍速按钮", enable: true, }, speed3Button: { name: "3倍速按钮(需先开启倍速按钮)", enable: false, }, premiumQuality: { name: "自动切换会员画质", enable: true, }, hidePiPButton: { name: "隐藏画中画/迷你播放器按钮", enable: true, }, showNickname: { name: "显示评论者昵称", enable: true, }, hideCeElement: { name: "半透明结尾的推荐视频/作者", enable: true, }, }; let menuIds = []; for (const key of Object.keys(functions)) { functions[key].enable = GM_getValue(`function_${key}_enable`, functions[key].enable); } function registerMenu() { menuIds.forEach((v) => { GM_unregisterMenuCommand(v); }); menuIds = []; menuIds.push( GM_registerMenuCommand(`😘 当前版本 ${GM_info.script.version}`, function () { window.GM_openInTab("https://gf.qytechs.cn/zh-CN/scripts/486375", { active: true, insert: true, setParent: true, }); }) ); for (const [key, info] of Object.entries(functions)) { menuIds.push(GM_registerMenuCommand(`${info.enable ? "✅" : "❌"} ${info.name}`, () => menuEvent(key))); } } function menuEvent(key) { functions[key].enable = !functions[key].enable; GM_setValue(`function_${key}_enable`, functions[key].enable); switch (key) { case "maxVolume": if (functions.maxVolume.enable) { setVolume(); } else { volumeSlider.style.backgroundColor = "white"; document.querySelector("#movie_player").setVolume(document.querySelector("#movie_player").getVolume()); } break; case "speedButton": if (functions.speedButton.enable) { addSpeedButton(); } else { document.querySelector(".ytp-speed-button").remove(); } break; case "speed3Button": if (functions.speed3Button.enable) { document.body.classList.add("ytp-show-speed3button"); } else { document.body.classList.remove("ytp-show-speed3button"); } break; case "premiumQuality": if (functions.premiumQuality.enable) { switchToPremiumQuality(); } break; case "hidePiPButton": if (functions.hidePiPButton.enable) { hidePiPButton(); } else { document.body.classList.remove("ytp-hide-pip-button"); } break; case "showNickname": if (functions.showNickname.enable) { registerCommentWatcher(); } else { commentWatcher.disconnect(); commentWatcher = null; } break; case "hideCeElement": if (functions.hideCeElement.enable) { document.body.classList.add("ytp-hide-ce-element"); } else { document.body.classList.remove("ytp-hide-ce-element"); } break; } registerMenu(); } if (!document.querySelector("style.youtube-plus-style")) { const speedButtonSvg = `<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1737240990275" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4235" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 512a53.44 53.44 0 0 1-17.4 39.413333L131.933333 882a52.833333 52.833333 0 0 1-35.713333 14 53.84 53.84 0 0 1-21.76-4.666667A52.666667 52.666667 0 0 1 42.666667 842.593333V181.406667A53.333333 53.333333 0 0 1 131.926667 142l362.666666 330.6A53.44 53.44 0 0 1 512 512z m451.933333-39.413333L601.26 142A53.333333 53.333333 0 0 0 512 181.406667v661.186666a52.666667 52.666667 0 0 0 31.793333 48.793334 53.84 53.84 0 0 0 21.76 4.666666 52.833333 52.833333 0 0 0 35.713334-14l362.666666-330.6a53.333333 53.333333 0 0 0 0-78.826666z" fill="#ffffff" p-id="4236"></path></svg>`; const style = document.createElement("style"); style.className = "youtube-plus-style"; style.textContent = ` div.ytp-speed-button{ display:flex; } span.ytp-speed-button{ width: 48px; height: 48px; display: flex; justify-content: center; align-items: center; position: relative; cursor: pointer; } span.ytp-speed-button::before{ content: ""; background:url('data:image/svg+xml;utf8,${encodeURIComponent(speedButtonSvg)}'); width: 20px; height: 20px; background-size: contain; } span.ytp-speed-button::after{ content: "1x"; position: absolute; top: -7px; left: 28px; font-size: 12px; transform: scale(0.8); color: white; pointer-events: none; text-align: left; } span.ytp-speed-button-active::after{ color: red; } span.ytp-speed-button-05x::after{ content: "0.5x"; } span.ytp-speed-button-1x::after{ content: "1x"; } span.ytp-speed-button-15x::after{ content: "1.5x"; } span.ytp-speed-button-2x::after{ content: "2x"; } span.ytp-speed-button-3x{ display: none; } span.ytp-speed-button-3x::after{ content: "3x"; } .yt-plus-nickname{ color: #0f0f0f; } .yt-plus-username{ color: rgba(0, 0, 0, 0.4); margin-left: 5px; } ytd-author-comment-badge-renderer[creator] .yt-plus-nickname{ color:unset; } ytd-author-comment-badge-renderer[creator] .yt-plus-username{ color:unset; opacity: 0.4; } body.ytp-hide-pip-button .ytp-pip-button{ display:none!important; } body.ytp-hide-pip-button .ytp-miniplayer-button{ display:none!important; } body.ytp-hide-pip-button .ytp-size-button{ display:none!important; } body.ytp-show-speed3button .ytp-speed-button-3x{ display:flex; } body.ytp-hide-ce-element .ytp-ce-element{ opacity: 0.3!important; } body.ytp-hide-ce-element .ytp-ce-element.ytp-ce-element-hover{ opacity: 1!important; } `; document.head.appendChild(style); } // ===================================================================================================== function registerCommentWatcher() { if (commentWatcher) { commentWatcher.disconnect(); } commentWatcher = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (mutation.type === "childList") { mutation.addedNodes.forEach((v) => { if (v?.tagName?.toLowerCase() === "ytd-comment-view-model") { let author = v.querySelector("#author-comment-badge"), url, username; if (author && author.childElementCount > 0) { url = author.querySelector("a#name").href; username = author.querySelector("yt-formatted-string").title; author = author.querySelector("yt-formatted-string"); } else { author = v.querySelector("#author-text"); url = author.href; username = author.querySelector("span").innerText.trim(); } fetch(url) .then((v) => { return v.text(); }) .then((v) => { const result = /<meta property="og:title" content="(.*?)">/.exec(v); if (result) { const nicknameNode = document.createElement("span"); nicknameNode.textContent = result[1]; nicknameNode.className = "yt-plus-nickname"; const usernameNode = document.createElement("span"); usernameNode.textContent = username; usernameNode.className = "yt-plus-username"; author.replaceChildren(nicknameNode, usernameNode); } }) .catch((e) => { console.log("change name error", e); }); } }); } } }); commentWatcher.observe(document.querySelector("ytd-comments #contents"), { childList: true, subtree: true, }); } function hidePiPButton() { document.body.classList.add("ytp-hide-pip-button"); } function setVolume() { if (!functions.maxVolume.enable) return; if (parseInt(volumePanel.getAttribute("aria-valuenow")) === 100) { volumeSlider.style.backgroundColor = "red"; if (player.volume !== 1) { player.volume = 1; console.log("[Youtube真正100%音量] 设置成功!", player, parseInt(volumePanel.getAttribute("aria-valuenow"))); } } else { volumeSlider.style.backgroundColor = "white"; } } function switchToPremiumQuality() { const qualityList = []; if (unsafeWindow?.ytInitialPlayerResponse?.playabilityStatus?.paygatedQualitiesMetadata?.qualityDetails) { unsafeWindow.ytInitialPlayerResponse.playabilityStatus.paygatedQualitiesMetadata.qualityDetails.forEach((v) => { qualityList.push(v.key); }); console.log("[YoutubePlus]", "获取到会员画质列表:", qualityList); } else { console.log("[YoutubePlus]", "此视频无会员画质或未开通会员。"); } const nowQuality = document.querySelector("#movie_player").getPlaybackQualityLabel().replace(" Premium", ""); // 嗯,会骗,实际上根本就没切 console.log("[YoutubePlus]", "当前画质:", nowQuality); if (qualityList.includes(`${nowQuality} Premium`)) { document.querySelector(".ytp-settings-button").click(); if (!document.querySelector(".ytp-quality-menu")) { document.querySelector(".ytp-panel-menu .ytp-menuitem:last-of-type").click(); } const qualityList = {}; document.querySelector(".ytp-quality-menu .ytp-panel-menu").childNodes.forEach((v, i) => { const name = v.querySelector("span").firstChild.textContent.trim(); qualityList[name] = i; }); document.querySelector(".ytp-quality-menu .ytp-panel-menu").childNodes[qualityList[`${nowQuality} Premium`]].click(); console.log("[YoutubePlus]", "切换到画质:", `${nowQuality} Premium`); } } function addSpeedButton() { if (document.querySelector(".ytp-speed-button")) return; const controls = document.getElementsByClassName("ytp-left-controls")[0]; let speedButtonActive = 0; try { speedButtonActive = parseFloat(JSON.parse(sessionStorage.getItem("yt-player-playback-rate")).data); } catch {} const speedButtonDiv = document.createElement("div"); speedButtonDiv.className = "ytp-speed-button"; const speedButtons = []; for (let speed of [0.5, 1, 1.5, 2, 3]) { const speedButton = document.createElement("span"); speedButton.className = `ytp-speed-button ytp-speed-button-${speed.toString().replace(".", "")}x`; speedButtonDiv.appendChild(speedButton); speedButton.onclick = () => { if (speed > 2) { player.playbackRate = speed; console.log("[YoutubePlus]", "超级倍速:", speed); } else { player.playbackRate = speed; // 设置为3倍速后需要用这个还原 console.log("[YoutubePlus]", "普通倍速:", speed); document.querySelector("#movie_player").setPlaybackRate(speed); sessionStorage.setItem( "yt-player-playback-rate", JSON.stringify({ data: speed.toString(), creation: new Date().getTime(), }) ); } speedButtons.forEach((v) => { v.classList.remove("ytp-speed-button-active"); }); speedButton.classList.add("ytp-speed-button-active"); }; if (speedButtonActive === speed) speedButton.classList.add("ytp-speed-button-active"); speedButtons.push(speedButton); } controls.parentNode.insertBefore(speedButtonDiv, controls.nextSibling); } setInterval(() => { player = document.getElementsByClassName("video-stream")[0]; volumePanel = document.getElementsByClassName("ytp-volume-panel")[0]; volumeSlider = document.getElementsByClassName("ytp-volume-slider-handle")[0]; if (player && volumePanel && volumeSlider) { if (!player.isHookYoutubePlus) { player.isHookYoutubePlus = true; player.addEventListener("volumechange", () => { setVolume(); }); if (functions.speedButton.enable) { addSpeedButton(); } if (functions.premiumQuality.enable) { switchToPremiumQuality(); } if (functions.hidePiPButton.enable) { hidePiPButton(); } if (functions.speed3Button.enable) { document.body.classList.add("ytp-show-speed3button"); } if (functions.hideCeElement.enable) { document.body.classList.add("ytp-hide-ce-element"); } } let comment = document.querySelector("ytd-comments #contents"); if (comment) { if (!comment.isHookYoutubePlus_Comment) { comment.isHookYoutubePlus_Comment = true; if (functions.showNickname.enable) { registerCommentWatcher(); } } } setVolume(); } }, 300); registerMenu(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址