Stick YouTube Progress Bar

Stick YouTube video progress bar to the player bottom

Mint 2023.05.16.. Lásd a legutóbbi verzió

// ==UserScript==
// @name          Stick YouTube Progress Bar
// @version       1.0.3
// @match         https://www.youtube.com/watch?v=**
// @match         https://www.youtube.com/live/**
// @author        peng-devs
// @namespace     https://greasyforks.org/users/57176
// @description   Stick YouTube video progress bar to the player bottom
// @icon          https://www.youtube.com/s/desktop/c1d331ff/img/favicon_48x48.png
// @grant         none
// @allFrames     true
// @license       MIT
// ==/UserScript==

const NAME = "Stick YouTube Progress Bar";

function main() {
  console.log(`[${NAME}] initializing...`);

  const observer = new MutationObserver((_) => {
    // 沒什麼意義,只是拿來判斷 control bar 初始化完了沒
    const progress_bar = document.querySelector(".ytp-progress-list");
    if (!progress_bar) return;

    // 如果是直播的話就不用了
    const live_badge = document.querySelector(".ytp-live-badge");
    if (live_badge && !live_badge.getAttribute("disabled")) {
      observer.disconnect();
      console.log(`[${NAME}] cancaled in livestream`);
      return;
    }

    stick_progress_bar();

    observer.disconnect();
    console.log(`[${NAME}] loaded`);
  });
  observer.observe(document.body, { childList: true, subtree: true });
}

function stick_progress_bar() {
  inject_custom_style(`

    #stick_progress {
      display: none;
      z-index: 32;
      position: absolute;
      bottom: 4px;
      width: 97.5%;
      height: 4px;
      margin: 0 1.25%;
      background-color: rgba(255, 255, 255, .2);
    }

    .stick_play_progress, .stick_load_progress {
      position: absolute;
      width: 100%;
      height: 100%;
    }

    .stick_play_progress, .stick_load_progress {
      transform-origin: left;
      transform: scaleX(0);
    }

    .stick_load_progress {
      z-index: 33;
      background-color: rgba(255, 255, 255, .4);
    }

    .stick_play_progress {
      z-index: 34;
      background-color: #f00;
    }

    .ytp-autohide #stick_progress {
      display: block;
    }
  `);

  const progress = document.createElement("div");
  progress.id = "stick_progress";

  const play_progress = document.createElement("div");
  play_progress.className = "stick_play_progress";
  progress.append(play_progress);

  const load_progress = document.createElement("div");
  load_progress.className = "stick_load_progress";
  progress.append(load_progress);

  const player = document.querySelector("#movie_player");
  player.append(progress);

  const video = document.querySelector("video");
  video.addEventListener("timeupdate", () => {
    // 只有在自動隱藏的時候才去更新進度條,不想浪費資源
    if (!movie_player.classList.contains("ytp-autohide")) return;

    const progress = video.currentTime / video.duration;
    play_progress.style.transform = `scaleX(${progress})`;

    const loaded_progress = video.buffered.end(0) / video.duration;
    load_progress.style.transform = `scaleX(${loaded_progress})`;
  });
}

function inject_custom_style(css) {
  const style = document.createElement("style");
  document.head.append(style);
  style.dataset.source = NAME;
  style.innerHTML = css;
}

main();
长期地址
遇到问题?请前往 GitHub 提 Issues。