R34 Auto Max Quality

Automatically selects maximum available video quality on tab focus.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         R34 Auto Max Quality
// @namespace    r34-auto-max-quality
// @version      2.0
// @description  Automatically selects maximum available video quality on tab focus.
// @description:ru Автоматически выбирает максимальное доступное качество видео при фокусе вкладки.
// @author       Grok Assisted
// @match        https://rule34video.com/video/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=rule34video.com
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Максимальное желаемое качество — меняй здесь / Maximum desired quality — change here
    // 5 = 4K, 4 = 1080p, 3 = 720p, 2 = 480p, 1 = 360p
    const MAX_QUALITY = 4;

    const FORMATS = [5, 4, 3, 2, 1]; // Список форматов от высокого к низкому / Format list from high to low

    // Получает текущий выбранный формат из DOM / Gets currently selected format from DOM
    function getSelectedFormat() {
        const sel = document.querySelector('.fp-settings-list-item.is-selected a[data-format]');
        return sel ? parseInt(sel.getAttribute('data-format')) : 0;
    }

    // Определяет реальное качество по суффиксу src видео / Determines real quality from video src suffix
    function getRealFormatFromSrc() {
        const vid = document.querySelector('video.fp-engine');
        if (!vid || !vid.src) return 0;

        const src = vid.src;
        if (src.includes('_2160p.mp4')) return 5;
        if (src.includes('_1080p.mp4')) return 4;
        if (src.includes('_720p.mp4'))  return 3;
        if (src.includes('_480p.mp4'))  return 2;
        if (src.includes('_360.mp4'))   return 1;
        return 0;
    }

    // Находит самый высокий доступный формат ≤ MAX_QUALITY / Finds highest available format ≤ MAX_QUALITY
    function getMaxAvailable() {
        for (let fmt of FORMATS) {
            if (fmt > MAX_QUALITY) continue;
            if (document.querySelector(`a[data-format="${fmt}"]`)) return fmt;
        }
        return 1;
    }

    // Кликает по кнопке качества / Clicks quality button
    function clickQuality(fmt) {
        const btn = document.querySelector(`a[data-format="${fmt}"]`);
        if (!btn) return false;

        // Убираем tooltip, если курсор над timeline / Remove tooltip if cursor over timeline
        const timeline = document.querySelector('.fp-timeline');
        if (timeline) {
            timeline.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));
        }

        // Открываем меню качества, если оно закрыто / Open quality menu if closed
        const settingsBtn = document.querySelector('a.fp-settings');
        if (settingsBtn && !document.querySelector('.fp-settings-list.is-open')) {
            settingsBtn.click();
        }

        btn.click();
        console.log(`[R34-Q] Кликнули ${fmt}p / Clicked ${fmt}p`);
        return true;
    }

    // Основная функция синхронизации качества / Main quality sync function
    function syncQuality(attempt = 1) {
        if (document.visibilityState !== 'visible') return;

        const selected = getSelectedFormat();
        const real    = getRealFormatFromSrc();
        const target  = getMaxAvailable();

        console.log(`[R34-Q] Попытка ${attempt} | Выбрано: ${selected}, Реально: ${real}, Цель: ${target} / Attempt ${attempt} | Selected: ${selected}, Real: ${real}, Target: ${target}`);

        if (real === target) {
            console.log('[R34-Q] Качество совпало с максимумом / Quality matches max');
            return;
        }

        if (attempt > 20) {
            console.log('[R34-Q] Лимит попыток (20), останавливаюсь / Max attempts (20) reached, stopping');
            return;
        }

        if (clickQuality(target)) {
            setTimeout(() => syncQuality(attempt + 1), 1800);
        } else {
            setTimeout(() => syncQuality(attempt + 1), 1200);
        }
    }

    // Срабатывание при фокусе вкладки / Trigger on tab focus
    document.addEventListener('visibilitychange', () => {
        if (document.visibilityState === 'visible') {
            setTimeout(() => syncQuality(1), 1000);
        }
    });

    // Первичная проверка, если вкладка уже активна / Initial check if tab is already visible
    if (document.visibilityState === 'visible') {
        setTimeout(() => syncQuality(1), 4000);
    }

    console.log(`[R34-Q] Скрипт запущен, максимум: ${MAX_QUALITY}p / Script active, max: ${MAX_QUALITY}p`);
})();