Greasy Fork is available in English.

Jellyfin Aspect Ratio Adjuster

Добавляет кнопку для переключения между соотношением сторон 16:9 и 21:9 в плеере Jellyfin

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name            Jellyfin Aspect Ratio Adjuster
// @name:ru         Регулятор соотношения сторон для Jellyfin
// @namespace       http://tampermonkey.net/
// @version         1.3
// @description:en  Adds a button to toggle between 16:9 and 21:9 aspect ratio in Jellyfin player
// @description:ru  Добавляет кнопку для переключения между соотношением сторон 16:9 и 21:9 в плеере Jellyfin
// @author          Shaman_Lesnoy
// @match           https://domain.com/web/*
// @grant           none
// @license         GPL-3.0
// @description Добавляет кнопку для переключения между соотношением сторон 16:9 и 21:9 в плеере Jellyfin
// ==/UserScript==

(function() {
    'use strict';

    function addScaleButton() {
        if (document.querySelector('#scaleButton')) return;

        let scaleButton = document.createElement('button');
        scaleButton.id = 'scaleButton';
        scaleButton.textContent = '21:9';
        scaleButton.style.position = 'absolute';
        scaleButton.style.top = '24px';
        scaleButton.style.right = '100px';
        scaleButton.style.padding = '5px 10px';
        scaleButton.style.fontSize = '16px';
        scaleButton.style.fontWeight = 'bold';
        scaleButton.style.fontFamily = 'Verdana, sans-serif';
        scaleButton.style.backgroundColor = 'transparent';
        scaleButton.style.color = '#fff';
        scaleButton.style.border = 'none';
        scaleButton.style.borderRadius = '5px';
        scaleButton.style.cursor = 'pointer';
        scaleButton.style.zIndex = '9999';
        scaleButton.style.opacity = '0';
        scaleButton.style.transition = 'opacity 0.3s ease';

        scaleButton.addEventListener('mouseover', function() {
            scaleButton.style.backgroundColor = 'rgba(0, 164, 220, 0.2)';
            scaleButton.style.color = '#00A4DC';
        });
        scaleButton.addEventListener('mouseout', function() {
            scaleButton.style.backgroundColor = 'transparent';
            scaleButton.style.color = '#fff';
        });

        document.body.appendChild(scaleButton);

        function setAspectRatio(isWide) {
            let videoElement = document.querySelector('video');
            if (videoElement) {
                if (isWide) {
                    videoElement.style.transition = 'all 0.5s ease';
                    videoElement.style.transform = 'scale(1.35)';
                    videoElement.style.transformOrigin = 'center';
                } else {
                    videoElement.style.transition = 'all 0.5s ease';
                    videoElement.style.transform = 'scale(1)';
                }
            }
        }

        let isWide = false;

        scaleButton.addEventListener('click', function() {
            isWide = !isWide;
            if (isWide) {
                scaleButton.textContent = '16:9';
            } else {
                scaleButton.textContent = '21:9';
            }
            setAspectRatio(isWide);
        });

        let inactivityTimer;
        function startInactivityTimer() {
            clearTimeout(inactivityTimer);
            inactivityTimer = setTimeout(function() {
                scaleButton.style.opacity = '0';
            }, 3000);
        }

        document.body.addEventListener('mousemove', function() {
            scaleButton.style.opacity = '1';
            startInactivityTimer();
        });

        document.body.addEventListener('mouseenter', function() {
            scaleButton.style.opacity = '1';
            startInactivityTimer();
        });

        startInactivityTimer();
    }

    function removeScaleButton() {
        let scaleButton = document.querySelector('#scaleButton');
        if (scaleButton) {
            scaleButton.remove();
        }
    }

    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (document.querySelector('video')) {
                addScaleButton();
            } else {
                removeScaleButton();
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });

})();