// ==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();
})();