Greasy Fork

Greasy Fork is available in English.

视频播放保持焦点 + 播放完提醒(安全二合一)

模拟页面聚焦,防止视频暂停 + 播放结束提醒,适用于雨课堂等平台,风险极低

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         视频播放保持焦点 + 播放完提醒(安全二合一)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  模拟页面聚焦,防止视频暂停 + 播放结束提醒,适用于雨课堂等平台,风险极低
// @match        *://*.yuketang.cn/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    // You might need to change these selectors based on your course website.
    // Use your browser's developer tools (F12) to inspect the video player and find the correct selector for the play button.
    // Common selectors might be:
    // 'button.play-button'
    // 'div.video-player-controls .play'
    // 'video' // Sometimes just interacting with the video element itself works
    // 'button[aria-label="Play"]'
    const PLAY_BUTTON_SELECTORS = [
        'button.play-button',
        'div.video-player-controls .play',
        'button[aria-label="Play"]',
        'button[title="Play"]',
        'a.play-button',
        'div[role="button"].play-button',
        // Add more potential selectors here based on your website
        'video', // Include video element itself as a fallback
    ];

    // How often to check for the play button (in milliseconds)
    const CHECK_INTERVAL = 1000; // Check every 1 second

    // How long to keep checking for the play button (in milliseconds)
    const MAX_CHECK_TIME = 30000; // Stop checking after 30 seconds

    // --- Auto Play Logic ---
    let checkAttempts = 0;
    const autoPlayInterval = setInterval(() => {
        checkAttempts++;
        if (checkAttempts * CHECK_INTERVAL > MAX_CHECK_TIME) {
            console.log('AutoPlay script: Max check time reached, stopping auto play check.');
            clearInterval(autoPlayInterval);
            return;
        }

        let playButtonClicked = false;
        for (const selector of PLAY_BUTTON_SELECTORS) {
            const element = document.querySelector(selector);
            if (element) {
                console.log(`AutoPlay script: Found element with selector "${selector}"`, element);
                // Check if it's a video element and if it's paused
                if (element.tagName === 'VIDEO') {
                     if (element.paused) {
                         console.log('AutoPlay script: Video is paused, attempting to play.');
                         element.play().then(() => {
                             console.log('AutoPlay script: Video play() successful.');
                             playButtonClicked = true;
                             clearInterval(autoPlayInterval); // Stop checking once played
                         }).catch(error => {
                             console.warn('AutoPlay script: Video play() failed:', error);
                             // Continue checking if play failed, maybe it's not ready yet
                         });
                     } else {
                         console.log('AutoPlay script: Video is already playing.');
                         playButtonClicked = true;
                         clearInterval(autoPlayInterval); // Stop checking if already playing
                     }
                } else {
                    // Assume it's a button or clickable element
                    console.log('AutoPlay script: Found potential play button, attempting to click.');
                    element.click();
                    console.log('AutoPlay script: Clicked element.');
                    playButtonClicked = true;
                    clearInterval(autoPlayInterval); // Stop checking once clicked
                }

                if (playButtonClicked) {
                    break; // Exit the loop if we found and interacted with an element
                }
            }
        }

        if (playButtonClicked) {
             console.log('AutoPlay script: Auto play action performed.');
        } else {
             console.log(`AutoPlay script: Play button not found after ${checkAttempts} attempts.`);
        }

    }, CHECK_INTERVAL);


    // --- Prevent Pause on Blur Logic ---
    // This part tries to trick the website into thinking the tab is always visible.
    // It overrides document.hidden and document.visibilityState properties.
    // Note: This might not work on all websites, as some might use other methods to detect focus.

    console.log('AutoPlay script: Attempting to prevent pause on blur.');

    // Store original properties
    const originalDocumentHidden = Object.getOwnPropertyDescriptor(Document.prototype, 'hidden');
    const originalDocumentVisibilityState = Object.getOwnPropertyDescriptor(Document.prototype, 'visibilityState');

    // Override properties if they exist
    if (originalDocumentHidden && originalDocumentHidden.configurable) {
        Object.defineProperty(Document.prototype, 'hidden', {
            get: function() { return false; }, // Always report as not hidden
            configurable: true // Allow redefining later if needed
        });
        console.log('AutoPlay script: Overrode document.hidden');
    } else {
         console.warn('AutoPlay script: Could not override document.hidden');
    }

    if (originalDocumentVisibilityState && originalDocumentVisibilityState.configurable) {
         Object.defineProperty(Document.prototype, 'visibilityState', {
            get: function() { return 'visible'; }, // Always report as visible
            configurable: true // Allow redefining later if needed
         });
         console.log('AutoPlay script: Overrode document.visibilityState');
    } else {
         console.warn('AutoPlay script: Could not override document.visibilityState');
    }

    // You might also need to simulate 'focus' or 'visibilitychange' events periodically
    // This is more complex and might not be necessary depending on the website.
    // Example (uncomment and adapt if needed):
    /*
    setInterval(() => {
        try {
            window.dispatchEvent(new Event('focus'));
            document.dispatchEvent(new Event('visibilitychange'));
        } catch (e) {
            console.warn('AutoPlay script: Failed to dispatch events:', e);
        }
    }, 5000); // Dispatch events every 5 seconds
    */


    console.log('AutoPlay script: Initialization complete.');

})();