Paramount Plus Auto Next Episode

Automatically plays the next episode on Paramount Plus

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Paramount Plus Auto Next Episode
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Automatically plays the next episode on Paramount Plus
// @author       woky
// @match        https://www.paramountplus.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Configuration
    const CHECK_INTERVAL = 3000; // Check every 3 seconds
    const COUNTDOWN_THRESHOLD = 15; // Seconds remaining to trigger next episode
    const NEXT_EPISODE_SELECTOR = '.next-episode-button, [data-testid="next-episode-button"], .up-next-button';

    let isChecking = false;
    let countdownTimer = null;

    function findNextEpisodeButton() {
        // Try multiple selectors since Paramount Plus might change their class names
        const selectors = [
            '.next-episode-button',
            '[data-testid="next-episode-button"]',
            '.up-next-button',
            'button:contains("Next Episode")',
            'button:contains("Play Next")',
            'button:contains("Continue Watching")'
        ];

        for (const selector of selectors) {
            const button = document.querySelector(selector);
            if (button && isVisible(button)) {
                return button;
            }
        }

        // Fallback: look for buttons with specific text content
        const buttons = document.querySelectorAll('button');
        for (const button of buttons) {
            if (button.textContent && 
                (button.textContent.includes('Next Episode') || 
                 button.textContent.includes('Play Next') ||
                 button.textContent.includes('Continue Watching')) &&
                isVisible(button)) {
                return button;
            }
        }

        return null;
    }

    function isVisible(element) {
        return element.offsetWidth > 0 && element.offsetHeight > 0 && 
               window.getComputedStyle(element).visibility !== 'hidden';
    }

    function checkForCountdown() {
        // Look for countdown elements that indicate when next episode will play
        const countdownElements = document.querySelectorAll('[class*="countdown"], [class*="timer"]');
        
        for (const element of countdownElements) {
            const text = element.textContent || '';
            const match = text.match(/(\d+)/);
            if (match) {
                const seconds = parseInt(match[1]);
                if (seconds <= COUNTDOWN_THRESHOLD) {
                    return true;
                }
            }
        }

        // Also check for progress bars that might indicate end of episode
        const progressBars = document.querySelectorAll('progress, [role="progressbar"]');
        for (const bar of progressBars) {
            if (bar.value !== undefined && bar.max !== undefined) {
                const progress = (bar.value / bar.max) * 100;
                if (progress > 95) {
                    return true;
                }
            }
        }

        return false;
    }

    function tryPlayNextEpisode() {
        if (isChecking) return;
        isChecking = true;

        const nextButton = findNextEpisodeButton();
        const shouldTrigger = checkForCountdown();

        if (nextButton && shouldTrigger) {
            console.log('Auto-playing next episode on Paramount Plus');
            nextButton.click();
            
            // Also try to click any "play" button that might appear
            setTimeout(() => {
                const playButton = document.querySelector('.play-button, [data-testid="play-button"]');
                if (playButton && isVisible(playButton)) {
                    playButton.click();
                }
            }, 1000);
        }

        isChecking = false;
    }

    function monitorVideoProgress() {
        // Check video element directly for near-end state
        const video = document.querySelector('video');
        if (video && !video.paused) {
            const remaining = video.duration - video.currentTime;
            if (remaining <= COUNTDOWN_THRESHOLD && remaining > 0) {
                const nextButton = findNextEpisodeButton();
                if (nextButton) {
                    console.log('Video near end, preparing to play next episode');
                    // Don't click immediately, wait for the UI to show the next episode prompt
                }
            }
        }
    }

    function startMonitoring() {
        if (countdownTimer) {
            clearInterval(countdownTimer);
        }

        countdownTimer = setInterval(() => {
            tryPlayNextEpisode();
            monitorVideoProgress();
        }, CHECK_INTERVAL);
    }

    // Start monitoring when page loads
    window.addEventListener('load', startMonitoring);
    
    // Also start when DOM is ready if page is already loaded
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        setTimeout(startMonitoring, 1000);
    }

    // Restart monitoring when navigating within the site (SPA)
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            setTimeout(startMonitoring, 2000); // Wait a bit for new content to load
        }
    }).observe(document, {subtree: true, childList: true});

    console.log('Paramount Plus Auto Next Episode script loaded');
})();