Youtube Highest Quality

Automatically selects the best available video quality on YouTube.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Youtube Highest Quality
// @author       tzshuhag
// @namespace    http://tampermonkey.net/
// @version      1.0
// @match        *://www.youtube.com/*
// @match        *://m.youtube.com/*
// @match        *://www.youtube-nocookie.com/*
// @exclude      *://www.youtube.com/live_chat*
// @homepageURL  https://tzshuhag.me
// @icon         https://raw.githubusercontent.com/tz-shuhag/YT-HD/refs/heads/main/128.png
// @grant        none
// @run-at       document-idle
// @license      MIT
// @description  Automatically selects the best available video quality on YouTube.
// ==/UserScript==
 
/* jshint esversion: 11 */
 
(async function () {
    'use strict';
 
    const QUALITIES = {
        highres: 4320,
        hd2160: 2160,
        hd1440: 1440,
        hd1080: 1080,
        hd720: 720,
        large: 480,
        medium: 360,
        small: 240,
        tiny: 144
    };
 
    const PREMIUM_INDICATOR_LABEL = "Premium";
 
    // Global variables
    let moviePlayer = null;
    let isIframe = false;
 
    async function setResolution() {
        if (!moviePlayer) {
            console.log('Movie player not found.');
            return;
        }
 
        // Debounce to prevent rapid calls
        let debounceTimer;
        if (debounceTimer) clearTimeout(debounceTimer);
        debounceTimer = setTimeout(async () => {
            try {
                const videoQualityData = moviePlayer.getAvailableQualityData();
                if (!videoQualityData.length) {
                    console.log('No quality data available, waiting for playback...');
                    const videoElement = moviePlayer.querySelector('video');
                    if (videoElement && videoElement.paused) {
                        videoElement.addEventListener('play', setResolution, { once: true });
                    }
                    return;
                }
 
                const availableQualities = moviePlayer.getAvailableQualityLevels();
                const highestQuality = availableQualities.reduce((max, q) => 
                    QUALITIES[q] > QUALITIES[max] ? q : max, availableQualities[0]);
                const premiumData = videoQualityData.find(q =>
                    q.quality === highestQuality &&
                    q.qualityLabel?.trim().endsWith(PREMIUM_INDICATOR_LABEL) &&
                    q.isPlayable
                );
 
                moviePlayer.setPlaybackQualityRange(highestQuality, highestQuality, premiumData?.formatId);
                console.log(`Set quality to: [${highestQuality}${premiumData ? ' Premium' : ''}]`);
            } catch (error) {
                console.error('Failed to set resolution:', error);
            }
        }, 100);
    }
 
    function processVideoLoad(event = null) {
        console.log('Processing video load...');
        moviePlayer = event?.target?.player_ ?? document.querySelector('#movie_player');
        if (moviePlayer) setResolution();
    }
 
    function addEventListeners() {
        if (window.location.hostname === 'm.youtube.com') {
            window.addEventListener('state-navigateend', processVideoLoad, true);
        } else {
            window.addEventListener('yt-player-updated', processVideoLoad, true);
        }
    }
 
    async function initialize() {
        if (window.self !== window.top) isIframe = true;
        window.addEventListener('pageshow', processVideoLoad, true);
        addEventListeners();
    }
 
    function hasGreasyMonkeyAPI() {
        return typeof GM !== 'undefined' || typeof GM_info !== 'undefined';
    }
 
    if (hasGreasyMonkeyAPI()) {
        initialize();
    } else {
        console.error('No Grease Monkey API detected.');
    }
})();