Greasy Fork

Greasy Fork is available in English.

B站视频观看总进度

给B站多P视频下方添加一个总进度

当前为 2022-03-11 提交的版本,查看 最新版本

// ==UserScript==
// @name         B站视频观看总进度
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  给B站多P视频下方添加一个总进度
// @author       汐涌及岸
// @match        https://www.bilibili.com/video/*
// @icon         https://www.bilibili.com/favicon.ico
// @grant        none
// ==/UserScript==

//格式化
const HHmmss = second => [Math.floor(second/3600),Math.floor(second/60)%60,second%60].map(n=>n.toString().padStart(2,0)).join(':')
//进度解析
const durationHelper = {
  async request(){
    const data = await fetch('https://api.bilibili.com/x/web-interface/view?bvid=' + window.bvid).then(resp => resp.json()).then(json => json.data)
    return data.ugc_season ? durationHelper.episodesAdapte(data) : durationHelper.pagesAdapte(data)
  },
  //分P
  pagesAdapte(data) {
    if (data.pages.length <= 1) return null
    const p = parseInt(new URLSearchParams(location.search).get('p')) || 1
    const multi = data.pages.map(p => p.duration)
    const before = p > 1 ? multi.slice(0, p - 1).reduce((t, d) => t + d) : 0
    return { total: data.duration, multi, before}
  },
  //合集
  episodesAdapte(data) {
    const eps = data.ugc_season.sections[0].episodes
    if (eps.length <= 1) return null
    let multi = []
    let total = 0, before = 0
    let isBefore = true
    for (const ep of eps) {
      if (ep.bvid == window.bvid) isBefore = false
      const duration = ep.page.duration
      multi.push(duration)
      total += duration
      if (isBefore) {
        before += duration
      }
    }
    return { multi, total, before }
  },
}
//进度条管理
const totalProgress = {
  data:null,
  el:null,
  async init(){
    totalProgress.createEl()
    totalProgress.data = await durationHelper.request()
    totalProgress.setContent()
    //进度条刷新
    window.player.addEventListener(bPlayer.events.progressUpdate,totalProgress.setContent)
    //切换分P时重新获取数据
    new MutationObserver(totalProgress.init).observe(document.querySelector('.bilibili-player-video'),{ attributes: true, childList: true, subtree: true })
  },
  //创建标签
  createEl(){
    if (document.getElementById('video-total-progress')) return
    const el = document.createElement('span')
    el.id = 'video-total-progress'
    el.style.color = '#eee'
    el.style.paddingLeft = '12px'
    document.querySelector('.bilibili-player-video-time').insertAdjacentElement('beforebegin',el)
    totalProgress.el = el
  },
  //设置内容
  setContent(){
    const { before,total } = totalProgress.data
    const now = parseInt(window.player.getCurrentTime())+before
    totalProgress.el.innerHTML = `<b>总进度</b> ${HHmmss(now)} / ${HHmmss(total)} (${((now/total)*100).toFixed(2)}%) <b>当前</b> `
  }
}
//等待播放器加载完成
let waitPlayerLoad = setInterval(() => { if(!window.player) return; totalProgress.init(); clearInterval(waitPlayerLoad)}, 1000);