Focus always and replay if video is paused

To learn more faster and efficiently

目前为 2024-08-03 提交的版本。查看 最新版本

// ==UserScript==
// @name         Focus always and replay if video is paused
// @name:zh-TW   始終保持焦點並在視頻暫停時自動播放
// @namespace    http://tampermonkey.net/
// @version      0.4.0
// @description  To learn more faster and efficiently
// @description:zh-tw   此腳本旨在提高在線學習效率,透過自動保持視頻播放視窗的焦點並在視頻暫停時自動重播。適用於 `https://iedu.foxconn.com/*` 網站,能夠確保學習過程中視頻連續播放,無需手動干預,特別適合忙碌且希望提高學習效率的用戶。
// @author       pjiaquan
// @match        https://iedu.foxconn.com/public/user/*
// @match        https://iedu.foxconn.com/public/play/*
// @run-at       document-start
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @license      MIT
// ==/UserScript==
(function() {
    'use strict';

    window.onblur = null;
    window.blurred = false;
    let playingVideoTitle = "";
    let isClicked = false;

    document.hasFocus = () => true;
    window.onFocus = () => true;

    [
        "hidden",
        "mozHidden",
        "msHidden",
        "webkitHidden"
    ].forEach(prop_name => {
        Object.defineProperty(document, prop_name, {value: false});
    });

    Object.defineProperty(document, "visibilityState", {get: () => "visible"});
    Object.defineProperty(document, "webkitVisibilityState", {get: () => "visible"});

    document.onvisibilitychange = undefined;

    var event_handler = (event) => {
        if (["blur", "mouseleave", "mouseout"].includes(event.type) &&
            (event.target instanceof HTMLInputElement ||
             event.target instanceof HTMLAnchorElement ||
             event.target instanceof HTMLSpanElement)) {
            return; // exclude input, anchor, and span elements
        }
        event.preventDefault();
        event.stopPropagation();
        event.stopImmediatePropagation();
    };

    [
        "visibilitychange",
        "webkitvisibilitychange",
        "blur",
        "hasFocus",
        "mouseleave",
        "mouseout",
        "mozvisibilitychange",
        "msvisibilitychange"
    ].forEach(event_name => {
        window.addEventListener(event_name, event_handler, true);
        document.addEventListener(event_name, event_handler, true);
    });

    let videoData = {
        filename: null,
        waresMap: new Map()
    };

    // script1 functionality
    function updateVideoProgress() {

        if (!isVideoPlaying()) {
            console.log('Video is not playing!');
            startPlayingVideo();
        } else {

            var videoElement = document.getElementById('realvideo_html5_api');
            if (videoElement && videoElement.tagName === 'VIDEO') {
                const activeElement = document.querySelector('dl .active');

                // Check if the active element exists and log its title attribute or inner text
                if (activeElement) {
                    // console.log('Active element found:', activeElement);
                    // console.log('Title:', activeElement.getAttribute('title'));
                    playingVideoTitle = activeElement.getAttribute('title');
                    // console.log('Content:', activeElement.innerText);

                    //console.log('title: ', playingVideoTitle);
                } else {
                    console.log('No active element found');
                }

                // videoElement.muted();
                // console.log('#301: video is playing', videoElement);
                if(videoElement.src.indexOf("hdvideo") >= 0){
                    //console.log("您正在播放的是高清版本的");

                    var currentSrc = videoElement.src;

                    if(currentSrc.indexOf() >= 0) {
                        console.log('you are hd mode');

                        var newSrc = currentSrc.replace('hdvideo', 'sdvideo');

                        videoElement.src = newSrc;

                        // Load the new video source and mute it
                        videoElement.load();
                    }

                }

                if (window.wares && window.wares.length > 0) {
                    //console.log(window.wares);
                    var i = 0;
                    for(i = 0; i < window.wares.length; i++) {
                        if(window.wares[i].isComplete === "N") {

                            let v = window.wares[i];
                            let duration = v.duration;
                            let playtime = v.playtime;
                            let percentage = (playtime / duration) * 100;

                            console.log(`${window.wares[i].name} 沒完成, 剩下: ${percentage.toFixed(2)}%`);

                            //console.log(window.wares[i]);
                            //dianji(6,this);

                            // Find the element by its title attribute
                            // var myElement = document.querySelector('dd[title="六西格玛项目定义"]');
                            var myElement = document.querySelector(`dd[title="${window.wares[i].name}"]`);

                            if (myElement) {
                                // Trigger the click event on the element

                                // if(!isClicked) {
                                if(playingVideoTitle !== window.wares[i].name) {
                                    // isClicked = true;
                                    myElement.click();
                                }
                                break; // Exit the loop after the first click
                            } else {
                                console.log('Element not found');
                            }
                        }
                    }
                }
            }

        }
    }

    function setupVideoCheck() {
        //console.log('Page loaded, running script');
        setInterval(updateVideoProgress, 5000);

        // Create and style the button
        //         const button = document.createElement('button');
        //         button.textContent = 'Change Start Time';
        //         button.style.position = 'fixed';
        //         button.style.right = '20px';
        //         button.style.bottom = '20px';
        //         button.style.padding = '10px 20px';
        //         button.style.backgroundColor = '#007bff';
        //         button.style.color = '#fff';
        //         button.style.border = 'none';
        //         button.style.borderRadius = '5px';
        //         button.style.cursor = 'pointer';

        //         // Add click event listener to the button
        //         button.addEventListener('click', changeStartTime);

        //         // Append the button to the body
        //         document.body.appendChild(button);

        //         // Select the active dd element
        //         const activeElement = document.querySelector('dl .active');

        //         // Check if the active element exists and log its title attribute or inner text
        //         if (activeElement) {
        //             // console.log('Active element found:', activeElement);
        //             // console.log('Title:', activeElement.getAttribute('title'));
        //             playingVideoTitle = activeElement.getAttribute('title');
        //             // console.log('Content:', activeElement.innerText);
        //         } else {
        //             console.log('No active element found');
        //         }

        // Function to observe DOM changes and click the "确定" button
        function observeDOMChanges() {
            const targetNode = document.body;
            const config = { childList: true, subtree: true };

            const callback = function(mutationsList, observer) {
                for (let mutation of mutationsList) {
                    if (mutation.type === 'childList') {
                        const confirmButton = document.querySelector('.layui-layer-btn0');
                        if (confirmButton) {
                            confirmButton.click();
                            console.log('Clicked "确定" button');
                            observer.disconnect(); // Stop observing after the button is clicked
                            break;
                        }
                    }
                }
            };

            const observer = new MutationObserver(callback);
            observer.observe(targetNode, config);
        }

        // Start observing for DOM changes
        observeDOMChanges();
    }



    function isVideoPlaying() {
        var videoElement = document.getElementById('realvideo_html5_api');
        if (videoElement && videoElement.tagName === 'VIDEO') {
            // console.log(videoElement);

            if(videoElement.src.indexOf("hdvideo") >= 0){
                //console.log("您正在播放的是高清版本的");

                var currentSrc = videoElement.src;

                var newSrc = currentSrc.replace('hdvideo', 'sdvideo');

                videoElement.src = newSrc;

                // Load the new video source and mute it
                //videoElement.load();
            }

            // Extract the src attribute
            var videoSrc = videoElement.getAttribute("src");

            // Extract the filename from the src URL
            var videoFilename = videoSrc.split('/').pop().split('.')[0];

            // Save the filename to the videoData object
            videoData.filename = videoFilename;

            // Map the videoFilename with wares if needed
            if (window.wares && window.wares.length > 0) {

                window.wares.forEach((ware, index) => {
                    if(ware.name === playingVideoTitle) {
                        // const fiveMinutesInMs = 900000; // 5 minutes in milliseconds
                        // console.log('#1', ware.starttime);
                        // const newStartTime = ware.starttime - fiveMinutesInMs;
                        // ware.starttime = newStartTime;
                        // console.log('#2', ware.starttime);
                        // console.log(`Start time set to: ${new Date(newStartTime).toString()}`);
                        // console.log(ware);
                        //console.log(videoElement);
                    }
                    // console.log('First key:', ware);
                    // console.log('First value:', ware);
                    // console.log(firstValue.starttime);

                    videoData.waresMap.set(videoFilename, ware); // Example mapping
                });
            }

            // Output the filename or save it as needed
            if (videoData && videoData.waresMap) {
                const firstEntry = videoData.waresMap.entries().next().value;
                if (firstEntry) {
                    const [firstKey, firstValue] = firstEntry;

                    // const date = new Date(firstValue.starttime);
                    // console.log(date.toString());

                    if(firstValue.isComplete === "Y") {
                        return true;

                    }
                } else {
                    console.log('Map is empty');
                }
            }

            // var videoElement = document.getElementById('realvideo_html5_api');
            //             if (videoElement && videoElement.tagName === 'VIDEO') {
            //                 // videoElement.muted();
            //                 console.log('video: ', videoElement);
            //                 if(videoElement.src.indexOf("hdvideo") >= 0){
            //                     //console.log("您正在播放的是高清版本的");

            //                     var currentSrc = videoElement.src;

            //                     var newSrc = currentSrc.replace('hdvideo', 'sdvideo');

            //                     videoElement.src = newSrc;

            //                     // Load the new video source and mute it
            //                     videoElement.load();
            //                 }
            //             }

            //console.log('#300 ',videoElement.pause);
            // return videoElement.paused;

            return !videoElement.paused;
        } else {
            console.log('Video element not found or is not a video tag');
            return null;
        }
    }


    function startPlayingVideo() {
        var videoElement = document.getElementById('realvideo_html5_api');
        if (videoElement && videoElement.tagName === 'VIDEO') {
            // videoElement.muted();
            // console.log(videoElement.src);
            videoElement.play()
                .then(() => console.log("Video playback started"))
                .catch((error) => console.error("Error attempting to play video:", error));


            //             if (window.wares && window.wares.length > 0) {
            //                 //console.log(window.wares);
            //                 var i = 0;
            //                 for(i = 0; i < window.wares.length; i++) {
            //                     if(window.wares[i].isComplete === "N") {
            //                         console.log('這個課程還沒完成!', i);
            //                         console.log(window.wares[i]);
            //                         //dianji(6,this);

            //                         // Find the element by its title attribute
            //                         // var myElement = document.querySelector('dd[title="六西格玛项目定义"]');
            //                         var myElement = document.querySelector(`dd[title="${window.wares[i].name}"]`);

            //                         if (myElement) {
            //                             // Trigger the click event on the element
            //                             //myElement.click();
            //                             break; // Exit the loop after the first click
            //                         } else {
            //                             console.log('Element not found');
            //                         }
            //                     }
            //                 }
            //             }




        } else {
            console.log('Video element not found or is not a video tag');
        }
    }


    window.addEventListener('load', setupVideoCheck);

})();