B站小窗口视频功能显示

增强B站功能,B站小窗口视频的操作栏显示

// ==UserScript==
// @name            B站小窗口视频功能显示
// @description     增强B站功能,B站小窗口视频的操作栏显示
// @version         0.0.3
// @author          Grant Howard, Coulomb-G
// @copyright       2024, Grant Howard
// @license         MIT
// @match           *://*.bilibili.com/video/*
// @match           *://*.bilibili.com/bangumi/play/*
// @exclude         *://api.bilibili.com/*
// @exclude         *://api.*.bilibili.com/*
// @exclude         *://*.bilibili.com/api/*
// @exclude         *://member.bilibili.com/studio/bs-editor/*
// @exclude         *://t.bilibili.com/h5/dynamic/specification
// @exclude         *://bbq.bilibili.com/*
// @exclude         *://message.bilibili.com/pages/nav/header_sync
// @exclude         *://s1.hdslb.com/bfs/seed/jinkela/short/cols/iframe.html
// @exclude         *://open-live.bilibili.com/*
// @run-at          document-start
// @grant           unsafeWindow
// @grant           GM_getValue
// @grant           GM_setValue
// @grant           GM_deleteValue
// @grant           GM_info
// @grant           GM_xmlhttpRequest
// @grant           GM_registerMenuCommand
// @grant           GM_unregisterMenuCommand
// @grant           GM_addStyle
// @connect         raw.githubusercontent.com
// @connect         github.com
// @connect         cdn.jsdelivr.net
// @connect         cn.bing.com
// @connect         www.bing.com
// @connect         translate.google.cn
// @connect         translate.google.com
// @connect         localhost
// @connect         *
// @icon            https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/images/logo-small.png
// @icon64          https://cdn.jsdelivr.net/gh/the1812/Bilibili-Evolved@preview/images/logo.png
// @namespace https://greasyfork.org/users/734541
// ==/UserScript==

(() => {
  const console = (() => {
    const _console = window.console;
    return {
      log: (...args) => {
        _console.log(
          `%c ZAIZAI `,
          'padding: 2px 1px; border-radius: 3px; color: #fff; background: #42c02e; font-weight: bold;',
          ...args,
        );
      },
    };
  })();

  function waitTime(callback, options = { time: 500, isSetup: false }) {
    let timeout = null;
    return new Promise((resolve) => {
      if (options.isSetup) {
        let res = callback();
        if (res) resolve(res);
      }
      timeout = setInterval(() => {
        let res = callback();
        if (res) {
          clearInterval(timeout);
          resolve(res);
        }
      }, options.time);
    });
  }

  /**
   * 创建一个节流函数
   * @param {Function} func 需要节流的函数
   * @param {number} wait 函数执行的最小时间间隔
   * @param {boolean} [options={leading=true, trailing=true}] 配置对象
   * @returns {Function} 节流后的函数
   */
  function throttle(func, wait, options = {}) {
    let timeout = null;
    let context, args;
    let previousNow = 0;
    const { leading = true, trailing = true } = options;

    function wrapper() {
      // Save the context and arguments
      context = this;
      args = arguments;
      const previous = previousNow;
      const remaining = wait - (Date.now() - previous);
      const now = Date.now();

      if (remaining <= 0 || remaining > wait) {
        // 如果当前调用距离上次调用超过了wait时间,则立即执行
        clearTimeout(timeout);
        timeout = null;
        func.apply(context, args);
        previousNow = now;
      } else if (!timeout && trailing) {
        // 如果设置了trailing,则在wait时间结束时执行
        timeout = setTimeout(() => {
          func.apply(context, args);
          previousNow = now;
        }, remaining);
      }

      if (leading && !timeout) {
        // 如果设置了leading,则在第一次调用时立即执行
        func.apply(context, args);
        previousNow = now;
      }
    }

    return wrapper;
  }

  console.log('B站小窗口视频功能显示');

  const state = {
    is: false,
  };

  const onMouseover = async () => {
    if (state.is) {
      return;
    }
    state.is = true;
    const els = await waitTime(
      () => {
        const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask');

        const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity');
        const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom');
        if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) {
          return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom];
        }
      },
      {
        time: 0,
      },
    );
    els[0].style.opacity = 1;
    els[0].style.display = 'block';
    els[1].style.opacity = 1;
    els[1].style.display = 'block';
    els[2].style.opacity = 1;
    els[2].style.display = 'flex';
    console.log('onMouseover 显示');
    console.log(els);
  };

  const onMouseout = async (e) => {
    if (!state.is && e.tae) {
      return;
    }
    state.is = false;
    const els = await waitTime(
      () => {
        const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask');

        const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity');
        const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom');
        if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) {
          return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom];
        }
      },
      {
        time: 0,
      },
    );
    els[0].style.opacity = 0;
    els[0].style.display = 'none';
    els[1].style.opacity = 0;
    els[1].style.display = 'none';
    els[2].style.opacity = 0;
    els[2].style.display = 'none';
    console.log('onMouseout 隐藏');
    console.log(els);
  };

  window.onload = () => {
    window.addEventListener('resize', async () => {
      const { innerWidth, innerHeight } = window;
      if (innerWidth <= 565 && innerHeight <= 320) {
        window.addEventListener('mouseover', onMouseover);
        window.addEventListener('mouseout', onMouseout);
      } else if (innerWidth > 565 && innerHeight > 320) {
        window.removeEventListener('mouseover', onMouseover);
        window.removeEventListener('mouseout', onMouseout);
        state.is = false;

        /**
         * 放大后清空 style 不然b站原本的css不会生效
         */
        const els = await waitTime(
          () => {
            const bpxplayercontrolmask = document.querySelector('.bpx-player-control-mask');

            const bpxplayercontrolentity = document.querySelector('.bpx-player-control-entity');
            const bpxplayercontrolbottom = document.querySelector('.bpx-player-control-bottom');
            if (bpxplayercontrolmask && bpxplayercontrolentity && bpxplayercontrolbottom) {
              return [bpxplayercontrolmask, bpxplayercontrolentity, bpxplayercontrolbottom];
            }
          },
          {
            time: 0,
          },
        );
        els.forEach((item) => {
          item.style.cssText = '';
        });
      }

      if (innerWidth <= 520) {
        document.querySelector('.bpx-player-ctrl-time').style.display = 'none';
        document.querySelector('.bpx-player-ctrl-quality').style.display = 'none';
      } else {
        document.querySelector('.bpx-player-ctrl-time').style.display = 'block';
        document.querySelector('.bpx-player-ctrl-quality').style.display = 'block';
      }
    });
  };
})();