Twitch Player Quality Changer

Automatically change the quality of the Twitch player to your liking.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name            Twitch Player Quality Changer
// @description     Automatically change the quality of the Twitch player to your liking.
// @namespace       https://github.com/ramhaidar/Twitch-Player-Quality-Changer
// @version         0.0.7
// @author          ramhaidar
// @homepageURL     https://github.com/ramhaidar/Twitch-Player-Quality-Changer
// @icon            https://www.google.com/s2/favicons?sz=64&domain=twitch.tv
// @license         MIT
// @match           https://www.twitch.tv/*
// @match           https://player.twitch.tv/*
// @grant           none
// @run-at          document-end
// ==/UserScript==

(function () {
    'use strict';

    // Set the desired auto-quality.
    /* Available Quality Options:
       - 1080p60
       - 936p60
       - 720p60
       - 720p
       - 480p
       - 360p
       - 160p
    */
    const PreferedQuality = "480p"; // Change this to your Prefered Quality

    const AllQuality = ["1080p60", "936p60", "720p60", "720p", "480p", "360p", "160p"];
    const PreferredIndex = AllQuality.indexOf(PreferedQuality);

    // A function that waits for an element to exist in the DOM and then executes a callback function.
    function waitForElement(selector, maxAttempts = 10, callback) {
        let attempts = 0;
        const intervalId = setInterval(function () {
            const element = document.querySelector(selector);
            if (element) {
                clearInterval(intervalId);
                callback(element);
            } else {
                attempts++;
                if (attempts >= maxAttempts) {
                    clearInterval(intervalId);
                    console.warn('Element ' + selector + ' not found after ' + maxAttempts + ' attempts');
                }
            }
        }, 500);
    }

    // Get the element that indicates if a channel is live or offline.
    const elem = document.querySelector('.tw-channel-status-text-indicator, .channel-status-info');

    // A callback function to execute when the element is found.
    function onElementFound(elem) {
        console.warn('Element found:', elem);
        main();
    }

    // A function that waits until the element exists in the DOM, then executes a callback function.
    function waitUntilElementExists(elem, callback) {
        elem = document.querySelector('.tw-channel-status-text-indicator, .channel-status-info');
        if (elem !== null) {
            callback(elem);
        } else {
            setTimeout(function () {
                waitUntilElementExists(elem, callback);
            }, 500);
        }
    }

    waitUntilElementExists(elem, onElementFound);

    function main() {

        // Check if the channel is live or offline.
        if (document.querySelector('.tw-channel-status-text-indicator')?.textContent === "LIVE" || document.querySelector('.channel-status-info')?.textContent === "Offline") {
            console.warn("Channel is live or offline.");

            let settingsButton = null;
            let settingsMenuButton = null;

            // Click the settings button.
            waitForElement('[data-a-target="player-settings-button"]', 25, function (element) {
                settingsButton = element;
                settingsButton.click();
            });

            // Click the quality settings button.
            waitForElement('[data-a-target="player-settings-menu-item-quality"]', 25, function (element) {
                settingsMenuButton = element;
                settingsMenuButton.click();
            });

            // Wait for the quality options to load and select the preferred quality option.
            waitForElement('[data-a-target="tw-radio"]', 25, function (element) {
                const inputs = document.querySelectorAll('input[type="radio"]');
                var qualityFound = false;

                var inputsx = document.querySelectorAll('input[type="radio"]')
                for (let i = 0; i < inputsx.length; i++) {
                    if (inputsx[i].parentNode.textContent.includes(AllQuality[PreferredIndex])) {
                        qualityFound = true;
                    }
                }

                console.warn("Preferred Quality Found: " + qualityFound);

                // If the preferred quality is available, select it.
                if (qualityFound == true) {
                    for (let i = 0; i < inputs.length; i++) {
                        const label = inputs[i].parentNode.querySelector('label');
                        if (label && label.textContent.trim().includes(AllQuality[PreferredIndex])) {
                            inputs[i].checked = true;
                            inputs[i].click();

                            console.warn("Quality Used: " + inputs[i].parentNode.querySelector('label').textContent);

                            // Click the settings button again.
                            waitForElement('[data-a-target="player-settings-button"]', Infinity, function (element) {
                                var settingsButton = element;
                                settingsButton.click();
                                console.warn("Clicked Settings Button");
                            });
                        }
                    }
                }

                // If the preferred quality is not available, select the lowest available quality.
                if (qualityFound == false) {
                    var lastQualityIndex = AllQuality.length - 1;

                    var lastInputIndex = inputsx.length - 1;
                    inputsx[lastInputIndex].checked = true;
                    inputsx[lastInputIndex].click();

                    console.warn("Quality Used: " + inputsx[lastInputIndex].parentNode.querySelector('label').textContent);

                    // Click the settings button again.
                    waitForElement('[data-a-target="player-settings-button"]', Infinity, function (element) {
                        var settingsButton = element;
                        settingsButton.click();
                        console.warn("Clicked Settings Button");
                    });
                }
            });
        } else {
            console.warn("Can't detect whether Channel is live or offline.");
        }
    }
})();