動畫瘋 影片播放速度

2021/7/25 下午5:48:09

// ==UserScript==
// @name        動畫瘋 影片播放速度
// @namespace   Violentmonkey Scripts
// @match       https://ani.gamer.com.tw/animeVideo.php
// @grant       GM_setValue
// @grant       GM_getValue
// @version     1.5
// @author      bigiCrab
// @description 2021/7/25 下午5:48:09
// 1. 自動使用上次的撥放速度
// 2. 滑鼠在影片上時,(ctrl或shift)+滾輪調整撥放速度(0.1~16)
// 3. 指標在右下撥放速度按鈕時,可以使用滾輪調整撥放速度
// 4. 點擊右下播放速度按鈕,將速度設為1x
// ==/UserScript==


  let console = makeLocalConsole(window.console,"😂playback😂");
  function makeLocalConsole(_ogConsole,_preFix){
    let console = {};
    for(let i in _ogConsole){
      if(_ogConsole.hasOwnProperty(i)){
        console[i] = function(){_ogConsole[i].call(this, _preFix, ...arguments)}
      }
    }
    return console;
  }

// 存速度key值
const VIDEO_PLAYBACK_RATE = "bigi_videoPlayBackRate";
// videojs 載很慢
$(window.unsafeWindow).load(() => {
  main();
});
async function main() {
  //   等到videojs 出現
  while (window.unsafeWindow?.videojs === undefined) {
    console.error("video element not found");
    await sleep(500);
  }
  let ani_video = videojs.getPlayer("ani_video");
  //   等到video出現
  while (ani_video === undefined) {
    ani_video = videojs.getPlayer("ani_video");
    // TODO 找他的API
    console.log("video js: ", ani_video);
    await sleep(500);
  }
  // test_trackAllEvent();

  loadAndTrackSavePlayRate();

  scrollToAdjustSpeed();

  function loadAndTrackSavePlayRate() {
    ani_video.on("playing", (e) => {
      if (ani_video.currentSrc().includes("gamer_ad")) {
        console.log("廣告中 不加速");
        ani_video.playbackRate(1);
        return;
      }
      //   apply play rate
      var lastTimePlayBackRate = GM_getValue(VIDEO_PLAYBACK_RATE, null);
      if (lastTimePlayBackRate !== null) {
        console.log(`設定為上次的撥放速度:${lastTimePlayBackRate}`);
        ani_video.playbackRate(lastTimePlayBackRate);
      }
    });
    //   save play rate
    ani_video.on("ratechange", (e) => {
      let newestRate = ani_video.playbackRate();
      console.log(`撥放速度變動..存起來:${newestRate}`);
      GM_setValue(VIDEO_PLAYBACK_RATE, newestRate);
    });
  }

  function scrollToAdjustSpeed() {
    const speedStap = 0.1;
    // 影片上用 (ctrl||shift)+wheel
    $("video").on("wheel", (event) => {
      if (event.shiftKey || event.ctrlKey) {
        event.preventDefault();
        // console.log("shift捲動", event.originalEvent);
        handleWheelEventPlaybackRate(event);
      }
    });
    // 指標在playbackRate時可以用滾輪調整
    let playEle = ani_video?.controlBar
      ?.getChildById("controlBarR")
      ?.getChildById("playbackRateMenuButton")?.el_;
    $(playEle).on("wheel", (event) => {
      event.preventDefault();
      handleWheelEventPlaybackRate(event);
    });
    $(playEle).on("click", (event) => {
      event.preventDefault();
      ani_video.playbackRate(1);
    });

    function handleWheelEventPlaybackRate(event) {
      let speedVector = event.originalEvent.deltaY < 0 ? 1 : -1;
      let newestRate = ani_video.playbackRate();
      let calcSpeed =
        Math.round((newestRate + speedVector * speedStap) * 100) / 100;
      calcSpeed = Math.min(Math.max(0.1, calcSpeed), 16);
      ani_video.playbackRate(calcSpeed);
    }
  }

  // 看videojs有甚麼狀態可用
  function test_trackAllEvent() {
    //   找到的都在上面
    let events = [
      "subtitles",
      "captions",
      "descriptions",
      "chapters",
      "metadata",
      "none",
      "metadata",
      "auto",
      "alternative",
      "captions",
      "descriptions",
      "main",
      "main-desc",
      "sign",
      "subtitles",
      "translation",
      "commentary",
      "onchange",
      "onaddtrack",
      "onremovetrack",
      "onchange",
      "onaddtrack",
      "onremovetrack",
      "oncuechange",
      "onenter",
      "onexit",
      "loadstart",
      // "progress",
      "suspend",
      "abort",
      "error",
      "emptied",
      "stalled",
      "loadedmetadata",
      "loadeddata",
      "canplay",
      "canplaythrough",
      "playing",
      "waiting",
      "seeking",
      "seeked",
      "ended",
      "durationchange",
      // "timeupdate",
      "play",
      "pause",
      "ratechange",
      "resize",
      "volumechange",
      "error",
      "change",
      "addtrack",
      "removetrack",
      "cuechange",
      "error",
      "load",
      "enter",
      "exit",
    ];
    ani_video.on(events, (e) => {
      console.log(e);
    });
  }
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}