YouTube Always show progress bar - Forked

Always show progress bar

目前为 2021-11-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         YouTube Always show progress bar - Forked
// @version      2021.07.27
// @author       Xiao
// @description  Always show progress bar
// @match        *://www.youtube.com/*
// @allFrames    true
// @grant        unsafeWindow
// @namespace https://gf.qytechs.cn/users/5802
// ==/UserScript==

//original: https://gf.qytechs.cn/en/scripts/30046-youtube-always-show-progress-bar

let css = `
  .ytp-autohide .ytp-chrome-bottom {
    opacity: 1 !important;
  }

  .ytp-autohide .ytp-chrome-bottom .ytp-progress-bar-container[alwaysshow="true"] {
    bottom:-1px;
  }

  .ytp-autohide .ytp-chrome-bottom > :not(.ytp-progress-bar-container[alwaysshow="true"]) {
    display: none;
  }
`;

let style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);

let eventHandlers = [];

let timeupdateListener;
let progressListener;
let video;

setTimeout(run, 2000);

addEventListener('yt-navigate-finish', function() {
  video = document.querySelector('video');
  if (video) {
    eventHandlers[0]?.removeEventListener('timeupdate', eventHandlers[1]);
    eventHandlers[0]?.removeEventListener('progress', eventHandlers[2]);
    setTimeout(run, 2000);
  }
});

function run () {
  if (document.querySelector('#movie_player.ad-showing')) {
    setTimeout(run, 2000);
    return;
  }

  video = document.querySelector('video');
  if (!video?.src || !document.querySelector('.html5-video-player:not(.addedupdateevents)'))
    return;

  let videoData = Object.values((unsafeWindow.ytPubsubPubsubInstance.i || unsafeWindow.ytPubsubPubsubInstance.subscriptions_).find(exportFunction(a => a?.player, unsafeWindow)).player.app).find(exportFunction(a => a?.videoData, unsafeWindow)).videoData;
  document.querySelector('.ytp-progress-bar-container').setAttribute('alwaysshow', !videoData.isLivePlayback);

  video.className += ' addedupdateevents';
  let player = document.getElementById('movie_player');
  let progressbars = document.querySelectorAll('.ytp-play-progress');
  let loadbars = document.querySelectorAll('.ytp-load-progress');

  let chap = videoData.multiMarkersPlayerBarRenderer?.markersMap[0].value.chapters;

  if (chap?.length) {
    let chars = [];
    let cap;
    let capstart;
    let capduration;
    let lastusedcapprog;
    let lastusedcapbuf;

    for (let i = 0; i < chap.length; i++) {
      chars.push(chap[i].chapterRenderer.timeRangeStartMillis / 1000);
    }

    timeupdateListener = () => {
      if (!player.classList.contains('ytp-autohide'))
        return;

      for (let i = 0; i < chars.length; i++) {
        let ts = chars[i];
        if (ts < video.currentTime  || !capduration) {
          cap = i;
          capstart = ts;
          capduration = ((chars[i + 1] ? chars[i + 1] : video.duration) - ts);
        } else {
          break;
        }
      }

      if (cap > lastusedcapprog)
        progressbars[lastusedcapprog].style.transform = 'scaleX(1)';

      lastusedcapprog = cap;

      progressbars[cap].style.transform = 'scaleX(' + ((video.currentTime - capstart) / capduration) + ')';
    };
    video.addEventListener('timeupdate', timeupdateListener);

    progressListener = () => {
      if (!player.classList.contains('ytp-autohide') || !video.buffered.length)
        return;

      let buff = video.buffered.end(video.buffered.length - 1);

      for (let i = 0; i < chars.length; i++) {
        let ts = chars[i];
        if (ts < buff  || !capduration) {
          cap = i;
          capstart = ts;
          capduration = ((chars[i + 1] ? chars[i + 1] : video.duration) - ts);
        } else {
          break;
        }
      }

      if (cap > lastusedcapbuf)
        loadbars[lastusedcapbuf].style.transform = 'scaleX(1)';

      lastusedcapbuf = cap;

      loadbars[cap].style.transform = 'scaleX(' + ((buff - capstart) / capduration) + ')';
    };
    video.addEventListener('progress', progressListener);
    eventHandlers = [video, timeupdateListener, progressListener];
  } else {
    timeupdateListener = function () {
      if (player.classList.contains('ytp-autohide'))
        progressbars[0].style.transform = 'scaleX(' + (video.currentTime / video.duration) + ')';
    };
    video.addEventListener('timeupdate', timeupdateListener);

    progressListener = function () {
      if (player.classList.contains('ytp-autohide') && video.buffered.length)
        loadbars[0].style.transform = 'scaleX(' + (video.buffered.end(video.buffered.length - 1) / video.duration) + ')';
    };
    video.addEventListener('progress', progressListener);
    eventHandlers = [video, timeupdateListener, progressListener];
  }
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址