YouTube HD

Automatically sets YouTube video resolution to highest available based on player size and network speed.

目前为 2023-05-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         YouTube HD
// @namespace    youtubeHD
// @description  Automatically sets YouTube video resolution to highest available based on player size and network speed.
// @version      1
// @author       EmersonxD
// @grant        none
// @license      MIT
// @match        https://www.youtube.com/*
// ==/UserScript==

(function() {
    "use strict";
    let currentResolution = "hd1080";
    const availableResolutions = ["highres", "hd2880", "hd2160", "hd1440", "hd1080", "hd720", "large", "medium", "small", "tiny"];
    const resolutionSizes = [4320, 2880, 2160, 1440, 1080, 720, 480, 360, 270, 270];
    let playerSize = "";
    let previousVideoId = 0;

    function getVideoId(e) {
        const t = /(?:v=)([\w\-]+)/.exec(e.getVideoUrl());
        return t ? t[1] : "ERROR: idMatch failed; youtube changed something";
    }

    function setResolution(e, t) {
        if ("undefined" == typeof e.getPlaybackQuality) return void window.setTimeout(setResolution, 100, e, t);
        const r = getVideoId(e);
        if (r !== previousVideoId) {
            previousVideoId = r;
            const n = e.getPlaybackQuality(),
                i = currentResolution;
            if (t.indexOf(i) >= t.indexOf(n)) {
                return "undefined" != typeof e.setPlaybackQualityRange && e.setPlaybackQualityRange(i), void e.setPlaybackQuality(i);
            }
            const a = t.indexOf(i),
                s = t.length - 1;
            let o = Math.max(t.indexOf(n), 0);
            const l = e.getAvailableQualityLevels();
            while (o < s && !l.includes(t[a])) o++, a++;
            if (n !== t[o]) {
                const i = getVideoId(e);
                if (!i.includes("ERROR")) {
                    const r = e.getCurrentTime();
                    e.loadVideoById(i, r, t[o]);
                }
            }
            "undefined" != typeof e.setPlaybackQualityRange && e.setPlaybackQualityRange(t[o]), e.setPlaybackQuality(t[o]);
        }
        const c = localStorage.getItem("yt-player-quality");
        (!c || -1 === c.indexOf(currentResolution)) && (localStorage.setItem("yt-player-quality", JSON.stringify({
            data: currentResolution
        })), console.log("Stored Resolution: " + currentResolution));
    }

    function setTheaterMode() {
        if (-1 === window.location.href.indexOf("/watch")) return;
        const e = document.getElementsByTagName("body")[0];
        e.classList.contains("watch-stage-mode") || e.classList.add("watch-stage-mode");
        const t = unwrapObject(document.getElementById("movie_player"));
        playerSize = t.style.width + "," + t.style.height, t.style.width = "100%";
        const r = document.createElement("button");
        r.className = "yt-uix-button yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip", r.setAttribute("data-tooltip-text", "Theater Mode"), r.setAttribute("data-tooltip-timer", "1200"), r.innerHTML = '<span class="yt-uix-button-icon-wrapper"><span class="yt-uix-button-icon yt-uix-button-icon-theater-mode yt-sprite"></span></span>', r.addEventListener("click", function() {
            const e = unwrapObject(document.getElementById("movie_player"));
            "100%" === e.style.width ? e.style.width = playerSize.split(",")[0] : e.style.width = "100%"
        }), document.getElementsByClassName("ytp-right-controls")[0].appendChild(r)
    }

    function unwrapObject(e) {
        let t = e;
        while (t.parentNode && -1 === t.classList.value.indexOf("html5-video-container") && -1 === t.classList.value.indexOf("ytp-player")) t = t.parentNode;
        return t
    }

    function main() {
        setTheaterMode();
        const e = unwrapObject(document.getElementById("movie_player"));
        setInterval(setResolution, 1e3, e, availableResolutions)
    }

    main();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址