Greasy Fork镜像 还支持 简体中文。

YouTube - Time Remaining Counter

Displays the video's remaining time during playback

目前為 2018-05-27 提交的版本,檢視 最新版本

// ==UserScript==
// @name YouTube - Time Remaining Counter
// @description Displays the video's remaining time during playback
// @author wormboy
// @namespace patchmonkey
// @version 1.4.8
// @include https://www.youtube.com/*
// @require https://gf.qytechs.cn/scripts/368388-throttle-debounce/code/throttle-debounce.js?version=599402
// @run-at document-idle
// @noframes
// ==/UserScript==

const container = document.createElement('div')
container.id = 'progressContainer'
container.style.cssText = 'text-align:right;font-size:larger;color:#e91e63;margin-left:0.5em'

const updateDisplay = throttle(1000, function(event) {
  const { duration, currentTime } = event.target
  container.innerText = isNaN(duration) ? '' : HHMMSS(duration, currentTime)
})

function HHMMSS(length, time) {
  const currentTime = Math.round(time * 100) / 100
  const duration = Math.round(length * 100) / 100
  const sec_num = parseInt(duration - currentTime, 10)
  let hours = Math.floor(sec_num / 3600)
  let minutes = Math.floor((sec_num - (hours * 3600)) / 60)
  let seconds = sec_num - (hours * 3600) - (minutes * 60)
  if (hours < 10) hours = '0' + hours
  if (minutes < 10) minutes = '0' + minutes
  if (seconds < 10) seconds = '0' + seconds
  return `${hours}:${minutes}:${seconds}`
}

function* checkRecords(records, selector) {
  for (const { addedNodes } of records) {
    for (const el of addedNodes) {
      if (el instanceof HTMLElement && el.matches(selector)) {
        yield el
      }
    }
  }
}

function waitForElement(selector) {
  return new Promise(resolve => {
    const el = document.body.querySelector(selector)
    if (el) {
      resolve(el)
    } else {
      const obs = new MutationObserver(records => {
        for (const el of checkRecords(records, selector)) {
          resolve(el)
          obs.disconnect()
          break
        }
      })
      obs.observe(document.body, { childList: true, subtree: true })
    }
  })
}

async function watchLiveButton() {
  const live = await waitForElement('.ytp-time-display .ytp-button')
  const visible = getComputedStyle(live, null).display != 'none'
  container.style.display = visible ? 'none' : 'inline-block'
}

async function init() {
  const video = await waitForElement('#movie_player video')
  video.addEventListener('timeupdate', updateDisplay)
  const renderer = await waitForElement('yt-view-count-renderer')
  renderer.appendChild(container)
  await watchLiveButton()
  window.addEventListener('yt-navigate-finish', watchLiveButton)
}

if (window.location.pathname == '/watch') {
  init()
} else {
  window.addEventListener('yt-navigate-finish', function() {
    window.removeEventListener('yt-navigate-finish', arguments.callee)
    init()
  })
}

QingJ © 2025

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