您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
show duration for livestreams and present time for archives
当前为
- // ==UserScript==
- // @name Youtube Live Clock
- // @name:zh-TW Youtube Live Clock
- // @namespace https://greasyfork.org/scripts/453367
- // @version 1.6.3
- // @description show duration for livestreams and present time for archives
- // @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
- const 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
- */
- const $ = (element) => document.querySelector(element)
- const 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' }
- }
- const twoDigit = (num) => num.toString().padStart(2, '0')
- const timeFormat = (time) => {
- const second = time % 60
- const minute = Math.floor((time / 60) % 60)
- const hour = Math.floor(time / 3600)
- return hour > 0 ? `${hour}:${twoDigit(minute)}:${twoDigit(second)}` : `${minute}:${twoDigit(second)}`
- }
- const dateFormat = (presentTime) => {
- const [week, , day, year, time] = presentTime.toString().split(' ')
- const month = twoDigit(presentTime.getMonth() + 1)
- return {
- 1: ` (${year}/${month}/${day} ${time})`,
- 2: ` (${month}/${day}/${year} ${time})`,
- 3: ` (${day}/${month}/${year} ${time})`,
- 4: ` (${week} ${day}/${month}/${year} ${time})`,
- 5: ` (${abbr.week[week]} ${day}/${month}/${year} ${time})`
- } [FORMAT]
- }
- let liveBadge = null
- let timeDisplay = null
- let progressBar = null
- const waitElements = () => {
- return new Promise((resolve) => {
- const observer = new MutationObserver(() => {
- liveBadge = $('.ytp-live-badge')
- timeDisplay = $('.ytp-time-display')
- progressBar = $('.ytp-progress-bar')
- if (liveBadge && timeDisplay && progressBar) {
- observer.disconnect()
- resolve()
- }
- })
- observer.observe(document.body, { attributes: false, childList: true, subtree: true })
- })
- }
- const getLiveClock = () => {
- let clockElement = $('#present-time')
- if (!clockElement) {
- clockElement = document.createElement('span')
- clockElement.setAttribute('id', 'present-time')
- timeDisplay.childNodes[1].appendChild(clockElement)
- }
- return clockElement
- }
- const updateLiveTime = () => {
- const startDate = $('[itemprop="startDate"]')
- if (!startDate) { return '' }
- const startDateString = startDate.getAttribute('content')
- if (new Date().getTime() < new Date(startDateString).getTime()) { return '' }
- const endDate = $('[itemprop="endDate"]')
- const progressTime = progressBar.getAttribute('aria-valuenow')
- return endDate ? dateFormat(new Date(Date.parse(startDateString) + progressTime * 1000)) : timeFormat(progressTime)
- }
- const main = async () => {
- if (window.location.href.includes('/watch?v=')) {
- await waitElements()
- liveBadge.style = 'margin-left: 10px'
- const liveClock = getLiveClock()
- const observer = new MutationObserver(() => { liveClock.textContent = updateLiveTime() })
- observer.observe(progressBar, { attributes: true })
- }
- }
- document.addEventListener('yt-navigate-finish', main)