Plex Ambilight

Adds an ambient light effect to the Plex web player to prevent OLED burn-in and enhance immersion.

当前为 2025-08-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         Plex Ambilight
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Adds an ambient light effect to the Plex web player to prevent OLED burn-in and enhance immersion.
// @author       Rick Khakis
// @match        https://app.plex.tv/*
// @grant        none
// @run-at       document-idle
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const settings = {
        blur: 50,
        scale: 1.1,
        opacity: 0.7,
    };

    let videoElement = null;
    let canvasElement = null;
    let animationFrameId = null;

    function draw() {
        if (videoElement && !videoElement.paused && !videoElement.ended && canvasElement) {
            try {
                const context = canvasElement.getContext('2d');
                context.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
            } catch (error) {
                console.error('Plex Ambilight: Draw error.', error);
                stopAnimation();
            }
        }
        if (animationFrameId !== null) {
            animationFrameId = requestAnimationFrame(draw);
        }
    }

    const stopAnimation = () => {
         if (animationFrameId) {
             console.log('Plex Ambilight: Video stopped, pausing animation.');
             cancelAnimationFrame(animationFrameId);
             animationFrameId = null;
         }
    };

    function setupAmbilight(video) {
        const playerContainer = video.closest('.Player-fullPlayerContainer-wBDz23');
        if (!playerContainer) {
            console.error('Plex Ambilight: Could not find the main player container.');
            return;
        }

        const insertionPoint = playerContainer.parentElement;
        if (!insertionPoint) {
            console.error('Plex Ambilight: Could not find the insertion point for the canvas.');
            return;
        }

        if (insertionPoint.querySelector('.ambilight-canvas')) {
            return;
        }

        console.log('Plex Ambilight: Video element found. Setting up canvas.', video);
        videoElement = video;

        video.style.backgroundColor = 'transparent';
        playerContainer.style.backgroundColor = 'transparent';

        canvasElement = document.createElement('canvas');
        canvasElement.classList.add('ambilight-canvas');

        canvasElement.style.position = 'absolute';
        canvasElement.style.top = '0';
        canvasElement.style.left = '0';
        canvasElement.style.width = '100%';
        canvasElement.style.height = '100%';
        canvasElement.style.zIndex = '1012';

        canvasElement.style.filter = `blur(${settings.blur}px)`;
        canvasElement.style.transform = `scale(${settings.scale})`;
        canvasElement.style.opacity = `${settings.opacity}`;

        insertionPoint.prepend(canvasElement);

        video.addEventListener('play', () => {
            console.log('Plex Ambilight: Video playing, starting animation.');
            if (animationFrameId === null) {
                animationFrameId = requestAnimationFrame(draw);
            }
        });

        video.addEventListener('pause', stopAnimation);
        video.addEventListener('ended', stopAnimation);
    }

    console.log('Plex Ambilight: Script loaded. Watching for video player...');

    const observer = new MutationObserver((mutations) => {
        const videoNode = document.querySelector('video.HTMLMedia-mediaElement-u17S9P');
        if (videoNode) {
            setupAmbilight(videoNode);
        }
    });

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

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址