视频完成自动下一个

检查视频进度,达到目标时间后点击下一节/章并尝试自动播放,无视频时直接跳过,执行一次后结束

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

// ==UserScript==
// @name         视频完成自动下一个
// @namespace    http://tampermonkey.net/
// @version      0.20
// @description  检查视频进度,达到目标时间后点击下一节/章并尝试自动播放,无视频时直接跳过,执行一次后结束
// @author       yhxwyzm
// @match        https://www.learnin.com.cn/*
// @grant        none
// @license      AGPL
// ==/UserScript==

(function() {
    'use strict';

    // 将时间字符串转换为秒数
    function timeToSeconds(timeStr) {
        const cleanedTime = timeStr.replace(/[^\d:]/g, '');
        const [hours, minutes, seconds] = cleanedTime.split(':').map(Number);
        return hours * 3600 + minutes * 60 + seconds;
    }

    // 模拟用户点击
    function simulateClick(element) {
        const event = new MouseEvent('click', { bubbles: true, cancelable: true, view: window });
        element.dispatchEvent(event);
    }

    // 自动播放视频
    function autoPlayVideo() {
        console.log('尝试自动播放视频...');
        const video = document.querySelector('video');
        if (video) {
            video.muted = true; // 静音播放
            const playPromise = video.play();
            if (playPromise !== undefined) {
                playPromise.then(() => {
                    console.log('静音自动播放成功');
                }).catch(error => {
                    console.error('静音自动播放失败', error);
                });
            }
        } else {
            console.log('未找到视频元素');
        }
    }

    // 检查视频进度或跳过无视频页面
    function checkVideoProgress() {
        console.log('检查页面状态...');

        const videoHint = document.querySelector('.video-hint');
        const nextButton = document.querySelector('.next-chapter button');

        console.log('下一节/章/页按钮:', nextButton ? nextButton.textContent.trim() : '未找到');

        if (!nextButton) {
            console.log('未找到下一节/章/页按钮,停止检查');
            return;
        }

        // 无视频情况:没有.video-hint,直接点击下一节/章/页
        if (!videoHint) {
            console.log('未找到.video-hint,视为无视频页面,直接点击下一节/章/页');
            simulateClick(nextButton);
            return;
        }

        // 有视频情况:检查时间进度
        const spans = videoHint.querySelectorAll('span');
        console.log('找到的span数量:', spans.length, '内容:', Array.from(spans).map(s => s.textContent.trim()));

        let targetTime = null;
        let currentTime = null;
        for (let i = 0; i < spans.length; i++) {
            const text = spans[i].textContent.trim();
            if (/^\d{2}:\d{2}:\d{2}$/.test(text)) {
                if (!targetTime) {
                    targetTime = text;
                } else if (!currentTime) {
                    currentTime = text;
                    break;
                }
            }
        }

        if (!targetTime || !currentTime) {
            console.log('未找到完整的时间对', { targetTime, currentTime });
            return;
        }

        console.log('目标时间:', targetTime, '当前时间:', currentTime);

        const targetSeconds = timeToSeconds(targetTime);
        const currentSeconds = timeToSeconds(currentTime);

        console.log('目标秒数:', targetSeconds, '当前秒数:', currentSeconds);

        if (currentSeconds >= targetSeconds) {
            console.log('时间条件满足,点击下一节/章/页按钮');
            simulateClick(nextButton);
            setTimeout(() => {
                autoPlayVideo();
            }, 3000); // 3秒延迟等待加载
        } else {
            console.log('时间尚未达到目标');
        }
    }

    // 启动单次检查
    function startSingleCheck() {
        console.log('启动单次检查...');
        checkVideoProgress();
    }

    // 初始化
    function init() {
        startSingleCheck(); // 启动单次检查
    }

    // 页面加载后启动
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        console.log('页面初始状态:', document.readyState);
        setTimeout(init, 3000);
    } else {
        window.addEventListener('load', () => {
            console.log('页面加载完成,开始初始化');
            setTimeout(init, 3000);
        });
    }

    // 监听SPA路由变化
    let lastUrl = location.href;
    new MutationObserver(() => {
        const currentUrl = location.href;
        if (currentUrl !== lastUrl) {
            console.log('检测到路由变化,重新初始化');
            lastUrl = currentUrl;
            setTimeout(init, 3000); // 路由变化后重新启动
        }
    }).observe(document.body, { childList: true, subtree: true });

    // 设置定时器,1分钟后再次执行
    setTimeout(() => {
        console.log('一分钟时间到,再次执行');
        init();
    }, 60000); // 60000毫秒 = 1分钟
})();

QingJ © 2025

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