Youtube Live Clock

show present time of the livestream

اعتبارا من 05-12-2022. شاهد أحدث إصدار.

// ==UserScript==
// @name               Youtube Live Clock
// @name:zh-TW         Youtube Live Clock
// @namespace          https://greasyfork.org/scripts/453367
// @version            1.5.2
// @description        show present time of the livestream
// @description:zh-TW  顯示直播當下的時間
// @author             Derek
// @match              *://www.youtube.com/*
// @grant              none
// ==/UserScript==

//you can choose your ideal date format by changing the FORMAT's value below
let FORMAT = 1
/*
  1: 2022/10/31 06:37:10
  2: 10/31/2022 06:37:10
  3: 31/10/2022 06:37:10
  4: Mon 31/10/2022 06:37:10
  5: Monday 31/10/2022 06:37:10
*/

let $ = (element) => document.querySelector(element)
let $$ = (element) => document.querySelectorAll(element)
let abbr = {
  week: { Sun: 'Sunday', Mon: 'Monday', Tue: 'Tuesday', Wed: 'Wednesday', Thu: 'Thursday', Fri: 'Friday', Sat: 'Saturday' },
  month: { Jan: 'January', Feb: 'February', Mar: 'March', Apr: 'April', May: 'May', Jun: 'June', Jul: 'July', Aug: 'August', Sep: 'September', Oct: 'October', Nov: 'November', Dec: 'December' }
}
let twoDigit = (num) => {
  if (String(num).length === 2) return String(num)
  else return '0' + String(num)
}
let formatTime = (time) => {
  let second = time % 60
  let minute = (time - second) % 3600 / 60
  let hour = (time - minute * 60 - second) / 3600
  if (time < 3600) return `${minute}:${twoDigit(second)}`
  else return `${hour}:${twoDigit(minute)}:${twoDigit(second)}`
}
let dateFormat = (presentTime) => {
  let date = (presentTime).toString().split(' ')
  let year = date[3], month = twoDigit(presentTime.getMonth() + 1), day = date[2], week = date[0], time = date[4]
  switch (FORMAT) {
    case 1: return ` (${year}/${month}/${day} ${time})`
    case 2: return ` (${month}/${day}/${year} ${time})`
    case 3: return ` (${day}/${month}/${year} ${time})`
    case 4: return ` (${week} ${day}/${month}/${year} ${time})`
    case 5: return ` (${abbr.week[week]} ${day}/${month}/${year} ${time})`
  }
}
let getClock = () => {
  let liveClock = $('.present-time')
  if (!liveClock) {
      let timeDisplay = $$('.ytp-time-display')
      let clockElement = document.createElement('span')
      clockElement.setAttribute('class', 'present-time')
      timeDisplay[timeDisplay.length - 1].childNodes[1].appendChild(clockElement)
      liveClock = $('.present-time')
  }
  return liveClock
}
let updateTime = () => {
  try {
    let liveData = JSON.parse($('.ytd-player-microformat-renderer').textContent).publication
    if (liveData && !$('.html5-ypc-overlay')) {
        let progressBar = $$('.ytp-progress-bar')
        let progressTime = progressBar[progressBar.length - 1].getAttribute('aria-valuenow')
        if (liveData[0].endDate) {
          let presentTime = new Date(Date.parse(liveData[0].startDate) + progressTime * 1000)
          return dateFormat(presentTime)
        } else return formatTime(progressTime)
    } else return ''
  } catch { console.log('Youtube Live Clock: can\'t get liveData') }
}

let main = () => {
  if (window.location.href.includes('/watch?v=')) {
    $('.ytp-live-badge').style = 'margin-left: 10px'
    let observer = new MutationObserver(() => { getClock().textContent = updateTime() })
    observer.observe($('.ytp-progress-bar'), { attributes: true })
  }
}

document.addEventListener('yt-navigate-finish', main)