Autoplayer

Autoplayer for https://iwatchsouthparkonline.cc

As of 2025-08-17. See the latest version.

// ==UserScript==
// @name            Autoplayer
// @namespace       https://github.com/Bjufen
// @version         0.10
// @description     Autoplayer for https://iwatchsouthparkonline.cc
// @match           *://*.iwatchsouthparkonline.cc/episode/*
// @match           *://vidmoly.net/*
// @match           *://*.vidmoly.net/*
// @grant           GM_registerMenuCommand
// @grant           GM_unregisterMenuCommand
// @grant           GM_setValue
// @grant           GM_getValue
// @license         MIT
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY_RANDOM  = 'isRandomEnabled';
    const STORAGE_KEY_AUTOPLAY  = 'isAutoPlayEnabled';

    let isRandomEnabled = GM_getValue(STORAGE_KEY_RANDOM, false);
    let isAutoPlayEnabled = GM_getValue(STORAGE_KEY_AUTOPLAY, true);

    let findVideoInterval = null;
    let videoPlayerElement = null;

    const onVideoEnded = () => {
        console.log('Autoplayer: Video has finished playing!');
        if (isRandomEnabled) {
            try {
                const randomButton = document.querySelector('a.random_ep');
                if (randomButton) {
                    randomButton.click();
                } else {
                    console.error("Autoplayer: Could not find the random episode button.");
                }
            } catch (e) {
                console.error("Autoplayer: Failure in random episode selector, if the issue persists, please open an issue in the repository's github page with the error attached", e);
            }
        }
    };

    const setupVideoPlayer = (video) => {
        console.log('Autoplayer: Video player found!', video);
        videoPlayerElement = video;
        videoPlayerElement.addEventListener('ended', onVideoEnded);
        console.log('Autoplayer: Event listener attached.');
    };

    const startVideoSearch = () => {
        if (findVideoInterval) return;

        console.log('Autoplayer: Starting video search...');
        findVideoInterval = setInterval(() => {
            const video = document.querySelector('video.jw-video');
            if (video) {
                setupVideoPlayer(video);
                clearInterval(findVideoInterval);
                findVideoInterval = null;
            }
        }, 1000);
    };

    const stopVideoSearch = () => {
        if (findVideoInterval) {
            clearInterval(findVideoInterval);
            findVideoInterval = null;
            console.log('Autoplayer: Stopped searching for video.');
        }
        if (videoPlayerElement) {
            videoPlayerElement.removeEventListener('ended', onVideoEnded);
            videoPlayerElement = null;
            console.log('Autoplayer: Event listener removed.');
        }
    };

    const updateAllMenuCommands = (firstRun = false) => {
        if (!firstRun) {
            GM_unregisterMenuCommand('✅ Autoplay Enabled');
            GM_unregisterMenuCommand('❌ Autoplay Disabled');
            GM_unregisterMenuCommand('▶️ Next Episode');
            GM_unregisterMenuCommand('🔀 Random Episode');
        }

        const autoPlayLabel = isAutoPlayEnabled ? '✅ Autoplay Enabled' : '❌ Autoplay Disabled';
        GM_registerMenuCommand(autoPlayLabel, toggleAutoPlayState);

        const randomLabel = isRandomEnabled ? '🔀 Random Episode' : '▶️ Next Episode';
        GM_registerMenuCommand(randomLabel, toggleRandomState);
    };

    const toggleRandomState = () => {
        isRandomEnabled = !isRandomEnabled;
        GM_setValue(STORAGE_KEY_RANDOM, isRandomEnabled)
        updateAllMenuCommands();
    };

    const toggleAutoPlayState = () => {
        isAutoPlayEnabled = !isAutoPlayEnabled;
        GM_setValue(STORAGE_KEY_AUTOPLAY, isAutoPlayEnabled);
        updateAllMenuCommands();
        if (isAutoPlayEnabled) {
            startVideoSearch();
        } else {
            stopVideoSearch();
        }
    };

    updateAllMenuCommands(true);

    if (isAutoPlayEnabled) {
        startVideoSearch();
    } else {
        console.log('Autoplayer: Autoplay is disabled on page load.');
    }
})();