unlock lpsg videos

unlock lpsg video access. may need to manually switch video format since I can't figure that part out. Also load all images ASAP instead of having to scroll to them. Also added a button on top left to hide user info, so you can browse the page more quickly.

// ==UserScript==
// @name         unlock lpsg videos
// @namespace    MBing
// @version      5.0
// @description  unlock lpsg video access. may need to manually switch video format since I can't figure that part out. Also load all images ASAP instead of having to scroll to them. Also added a button on top left to hide user info, so you can browse the page more quickly.
// @author       MBing
// @match        https://www.lpsg.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=lpsg.com
// @grant        none
// @license            MIT
// ==/UserScript==

(function() {
    'use strict';

    //#隐藏用户信息的部分
    // 用于存储用户的选择状态
    const storageKey = 'hideUserInfo';

    // 动态获取当前的隐藏状态
    function getIsHidden() {
        return localStorage.getItem(storageKey) === 'true';
    }

    // 添加开关按钮
    const toggleButton = document.createElement('button');
    toggleButton.style.position = 'fixed';
    toggleButton.style.top = '10px';
    toggleButton.style.left = '10px';
    toggleButton.style.zIndex = '999999';
    toggleButton.style.padding = '5px 10px';
    toggleButton.style.fontSize = '14px';
    toggleButton.style.backgroundColor = '#4CAF50';
    toggleButton.style.color = 'white';
    toggleButton.style.border = 'none';
    toggleButton.style.borderRadius = '5px';
    toggleButton.style.cursor = 'pointer';

    // 初始按钮文本
    toggleButton.textContent = getIsHidden() ? 'Show User Info' : 'Hide User Info';

    // 添加按钮到页面
    document.body.appendChild(toggleButton);

    // 切换隐藏状态的函数
    function toggleVisibility() {
        const newState = !getIsHidden(); // 获取新的状态

        // 更新本地存储
        localStorage.setItem(storageKey, newState.toString());

        // 更新按钮文本
        toggleButton.textContent = newState ? 'Show User Info' : 'Hide User Info';

        // 更新元素的显示状态
        document.querySelectorAll('.message-userExtras').forEach(element => {
            element.style.display = newState ? 'none' : '';
        });
    }

    // 初始状态设置
    if (getIsHidden()) {
        document.querySelectorAll('.message-userExtras').forEach(element => {
            element.style.display = 'none';
        });
    }

    // 绑定点击事件
    toggleButton.addEventListener('click', toggleVisibility);


    //#改变图片加载速度的部分
    // 获取所有包含 lazy loading 的图片
    const images = document.querySelectorAll('img[loading="lazy"]');

    // 遍历所有懒加载图片,将其 loading 属性更改为 "eager"
    images.forEach(img => {
        img.loading = 'eager'; // 立刻加载图片
    });


    //#替换视频的部分
    var easterEggPoster = document.getElementsByClassName("video-easter-egg-poster");
    var volume=0.0;
    var autoSwitchInterval=2500
    var videoDiv=[];
    var imageUrl;
    var newDiv;
    var baseVideoUrl;

    if(easterEggPoster.length==0){
        //console.log("官方时间,无需替换");
        return;
    }else if(easterEggPoster.length>5){
        autoSwitchInterval=5000;
    }

    // 控制是否继续切换后缀
    let shouldContinue = true;

    //替换预览照片为视频播放器
    for (let i=easterEggPoster.length-1;i>-1;i--){
        let videoUrl
        imageUrl =easterEggPoster[i].children[0].src;
        videoUrl=imageUrl.replace("attachments/posters","video").replace("/lsvideo/thumbnails","lsvideo/videos").replace(".jpg",".mp4");


        videoDiv[i]=`<video onloadstart="this.volume=${volume}" style="width:750px; max-height: 750px;" controls=\"\" data-xf-init=\"video-init\" data-poster=\"${imageUrl}\" class=\"\" style=\"\" poster=\"${imageUrl}\"><source data-src=\"${videoUrl}\" src=\"${videoUrl}\"><div class=\"bbMediaWrapper-fallback\">Your browser is not able to display this video.</div></video>`;
        //void(easterEggPoster[i].innerHTML=videoDiv[i]);

        newDiv = document.createElement("div");
        newDiv.setAttribute("class","newVideoDiv");
        newDiv.innerHTML=videoDiv[i];
        easterEggPoster[i].parentElement.parentElement.append(newDiv);
        //console.log("正在插入第几条:"+i+",url:"+videoUrl)
        easterEggPoster[i].parentElement.parentElement.append(createButton("mov",i));
        easterEggPoster[i].parentElement.parentElement.append(createButton("m4v",i));
        easterEggPoster[i].parentElement.parentElement.append(createButton("mp4",i));
    }

    //删除easterEggPoster
    for (let i=easterEggPoster.length-1;i>-1;i--){
        easterEggPoster[i].parentElement.parentElement.removeChild(easterEggPoster[i].parentElement);
    }

    //删除video-easter-egg-blocker
    var easterEggBlocker = document.getElementsByClassName("video-easter-egg-blocker");
    for (let i=easterEggBlocker.length-1;i>-1;i--){
        easterEggBlocker[i].parentElement.removeChild(easterEggBlocker[i]);
    }

    //删除video-easter-egg-overlay
    var easterEggOverlay = document.getElementsByClassName("video-easter-egg-overlay");
    for (let i=easterEggOverlay.length-1;i>-1;i--){
        easterEggOverlay[i].parentElement.removeChild(easterEggOverlay[i]);
    }

    //调小音量
    var allVideoPlayers = document.getElementsByTagName('video');
    for (let i=allVideoPlayers.length-1;i>-1;i--){
        allVideoPlayers[i].volume = volume;
    }

    // 延时后开始检查视频
    setTimeout(checkVideosAndUpdate, autoSwitchInterval);


    //创建按钮
    function createButton(format,entryId){
        var inp;
        inp = document.createElement("input");
        inp.type = "button";
        inp.value = format;
        inp.id = entryId;
        inp.addEventListener('click', function () {
            //点击任何手动切换后缀按钮,即停止自动切换后缀
            shouldContinue = false;
            //console.log('停止切换后缀');
            //切换后缀
            var oldUrl = document.getElementsByClassName("newVideoDiv")[this.id].innerHTML;
            document.getElementsByClassName("newVideoDiv")[this.id].innerHTML=oldUrl.replaceAll("mp4",format).replaceAll("m4v",format).replaceAll("mov",format);
        });
        return inp;
    }


    // 定义一个函数,用于遍历所有 video 元素并检查其 readyState
    function checkVideosAndUpdate() {
        // 如果点击了停止按钮,则不再继续执行
        if (!shouldContinue) return;

        // 获取页面上所有的 video 元素
        const videoElements = document.querySelectorAll('video');

        let allLoaded = true;
        let failCount=0;
        // 遍历所有 video 元素
        videoElements.forEach(videoElement => {
            // 获取当前视频的 readyState
            const state = videoElement.readyState;

            // 如果视频的 readyState 不是 4(HAVE_ENOUGH_DATA),说明视频还没有加载完成
            if (state !== 4) {
                failCount+=1;
                allLoaded = false;

                // 获取视频中的所有 source 标签
                const sources = videoElement.querySelectorAll('source');
                sources.forEach(source => {
                    // 获取当前 source 的 src 和 data-src 属性
                    const currentSrc = source.src || source.getAttribute('data-src');

                    // 根据原视频格式替换为对应的新格式
                    let newSrc = currentSrc;
                    if (currentSrc.endsWith('.mp4')) {
                        newSrc = currentSrc.replace('.mp4', '.mov');
                    } else if (currentSrc.endsWith('.mov')) {
                        newSrc = currentSrc.replace('.mov', '.m4v');
                    } else if (currentSrc.endsWith('.m4v')) {
                        newSrc = currentSrc.replace('.m4v', '.mp4');
                    }

                    // 更新 source 的 src 和 data-src 属性为新的链接
                    //console.log(`替换视频链接: ${currentSrc} 为 ${newSrc}`);
                    source.src = newSrc;
                    source.setAttribute('data-src', newSrc);
                });

                // 重新加载视频
                videoElement.load();
            }
        });

        // 如果还有未加载完成的 video,则延时 2 秒再次执行
        if (!allLoaded) {
            //console.log(failCount+"条视频加载失败,稍后切换后缀重试");
            setTimeout(checkVideosAndUpdate, autoSwitchInterval);
        } else {
            //console.log("所有视频都已加载完成!");
        }
    }


})();