bs.to and vivo enhancer

Wechselt automatisch zum vivo-Tab auf bs.to und auf vivo.XX kopiert es die Video-URL in den Zwischenspeicher oder leitet zur Videoquelle weiter

Version vom 22.07.2021. Aktuellste Version

// ==UserScript==
// @name           bs.to and vivo enhancer
// @author         xtrars
// @description    Wechselt automatisch zum vivo-Tab auf bs.to und auf vivo.XX kopiert es die Video-URL in den Zwischenspeicher oder leitet zur Videoquelle weiter
// @description:en Automatically switches to the vivo tab on bs.to and on vivo.XX it copies the video URL to the clipboard or redirects to the video source
// @include        https://bs.to/*
// @include        https://*.vivo.sx/*
// @include        https://*.vivo.st/*
// @include        https://vivo.sx/*
// @include        https://vivo.st/*
// @version        2.2
// @run-at         document-start
// @license        CC BY 4.0
// @namespace https://greasyforks.org/users/140785
// @grant    GM_setValue
// @grant    GM_getValue
// ==/UserScript==



class SiteHandler {

    isVivoTab() {
        let sVivoStr = '/Vivo';
        return document['location']['href'].search(sVivoStr) !== -1;
    }

    hasAnotherHoster() {
        let hosterRegex = /https:\/\/bs.to\/.*[0-9]{1,2}\/[0-9]{1,2}\-.*\/[a-z]*\/(?!Vivo).*/g;
        return document['location']['href'].search(hosterRegex) !== -1;
    }

    isEpisode() {
        let serieRegex = /[0-9]{1,2}\/[0-9]{1,2}\-/g;
        let bsRegex = /^(https:\/\/bs.to)/g;
        return document['location']['href'].search(bsRegex) !== -1 && document['location']['href'].search(serieRegex) !== -1;
    }

    isVivo() {
        let vivoRegex = /^(https:\/\/vivo.[a-z]{2,3}\/)/g;
        return document['location']['href'].search(vivoRegex) !== -1 && document.getElementsByTagName('video') && document.getElementsByTagName('video')[document.getElementsByTagName('video').length -1]
    }

    isReady() {
        return new Promise(result => {
            window.addEventListener('load', function() {
                result(true);
            });
        });
    }

    // thanks to xZaheer (https://greasyforks.org/de/scripts/400669-burningseries-autoplay/code)
    waitForElement(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) {
                return resolve(document.querySelector(selector));

            }

            const observer = new MutationObserver(mutations => {
                if (document.querySelector(selector)) {
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true,
            });
        });
    }

    // thanks to xZaheer (https://greasyforks.org/de/scripts/400669-burningseries-autoplay/code)
    async clickPlay() {
        let playerElem = document.querySelector('section.serie .hoster-player');
        if(playerElem) {
            let clickEvent = new Event('click');
            clickEvent.which = 1;
            clickEvent.pageX = 1;
            clickEvent.pageY = 1;
            playerElem.dispatchEvent(clickEvent);
            //let elem = await this.waitForElement('.hoster-player a').catch(() => {});
            //window.open(elem.href);
        }
    }

    buildButton() {
        const style = document.createElement('style');
        style.innerHTML = `
  @keyframes shake {
  10%, 90% {transform: translate3d(-.5px, 0, 0);}
  20%, 80% {transform: translate3d(1px, 0, 0);}
  30%, 50%, 70% {transform: translate3d(-2px, 0, 0);}
  40%, 60% {transform: translate3d(2px, 0, 0);}
}
.onoffswitch {
    position: relative; width: 350px;
    -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.onoffswitch-label {
    width: 350px;
    display: block;
    overflow: hidden;
    cursor: pointer;
    border: 2px solid transparent;
    border-radius: 20px;
}
.onoffswitch-inner {
    display: block; width: 200%; margin-left: -100%;
    transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
    display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
    font-size: 10px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
    box-sizing: border-box;
}
.onoffswitch-inner:before {
content: "Video-URL in die Zwischenablage kopieren und Tab schließen";
    padding-left: 14px;
    background-color: #2FB536;
    color: #FFFFFF;
    text-align: start;
}
.onoffswitch-inner:after {
    content: "Vivo Autoplay aktivieren";
    padding-right: 14px;
    background-color: #12A6F6; color: #FFFFF1;
    text-align: end;
}
.onoffswitch-switch {
    display: block; width: 23px; margin: 3.5px;
    background: #FFFFF2;
    position: absolute; top: 0; bottom: 0;
    right: 314px;
    border: 2px solid #999999; border-radius: 20px;
    transition: all 0.3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
    margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
    right: 0px;
}

#xtrars-btn {
   position: absolute;
   bottom: 100px;
   right: 18px;
   background: #12a6f6;
   border-radius: 50%;
   width: 70px;
   height: 70px;
   line-height: 81px;
   text-align: center;
   cursor: pointer;
   animation: shake 1s ease 1s 1 normal;
}
#xtrars-menu {
   right: 175px;
}
  `;
        document.head.appendChild(style);

        const button = document.createElement("div");
        button['innerHTML'] = '<div id="xtrars-btn">' +
            '<i id="xtrars-btn-icon" class="fas fa-cogs fa-2x" style="color:white;"></i>' +
            '</div>';
        button['style'] = 'position: relative; height: 0;'
        document.getElementById('sp_left').appendChild(button);

        const menu = document.createElement("div");
        menu['innerHTML'] = '<div class="onoffswitch"><input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="xtrars-onoffswitch" tabindex="0"><label class="onoffswitch-label" for="xtrars-onoffswitch"><span class="onoffswitch-inner"></span><span class="onoffswitch-switch"></span></label></div>';
        menu['style'] = 'display: none;';
        menu['id'] = 'xtrars-menu';
        document.getElementById('xtrars-btn').appendChild(menu);
        document.getElementById('xtrars-onoffswitch').checked = GM_getValue('bCloseTabAfterCopyToClipboard');

        button.addEventListener('mouseover', () => {
            menu['style'] = 'display: block; position: absolute; bottom: 10px; height: 50px; width: 50px; line-height: normal;'
            document.getElementById('xtrars-btn')['style'] = 'background: transparent;';
        });

        button.addEventListener('mouseleave', () => {
            menu['style'] = 'display: none;';
            document.getElementById('xtrars-btn')['style'] = 'background: #12a6f6;';
        });

        menu.addEventListener('change', () => {
            GM_setValue('bCloseTabAfterCopyToClipboard', document.getElementById('xtrars-onoffswitch').checked)
        });
    }
}


(async function() {
    'use strict';

    let siteHandler = new SiteHandler();
    if (await siteHandler.isReady().catch(() => {}) && siteHandler.isVivo()) {
        // thanks to Wissidi dom (https://greasyforks.org/de/scripts/28779-zu-vivo-video-navigieren/code)
        let sSrc = document.getElementsByTagName('video')[document.getElementsByTagName('video').length -1]['currentSrc'];

        if (GM_getValue('bCloseTabAfterCopyToClipboard')) {
            navigator.clipboard.writeText(sSrc);
            window.close();
        } else {
            window['location'].replace(sSrc);
        }
    }

    if (siteHandler.isEpisode()) {
        if (!siteHandler.hasAnotherHoster() && !siteHandler.isVivoTab()) {
            document['location'].replace(document['location']['href'] + '/Vivo');
        }

        if (!siteHandler.hasAnotherHoster() && siteHandler.isVivoTab() && await siteHandler.waitForElement('#sp_left').catch(() => {})) {
            siteHandler.buildButton();
            siteHandler.clickPlay();
            // TODO Einstellungsmöglichkeiten erweitern (Vollbild, automatisch Tab wählen, etc)
        }
    }

    let video;
    if (video = await siteHandler.waitForElement('html > head + body > video').catch(() => {})) {
        video.requestFullscreen().catch(() => {
            video.style.width = "100%";
            video.style.height = "100%";
            document.body.style.margin = "0px";
        });
    }
    // TODO tab am Ende schließen
})();
长期地址
遇到问题?请前往 GitHub 提 Issues。