您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds exact upload time to youtube videos
当前为
// ==UserScript== // @name Youtube exact upload // @name:de YouTube exakter Hochladezeitpunkt // @description Adds exact upload time to youtube videos // @description:de Fügt YouTube-Videos den exakten Hochladezeitpunkt mit Uhrzeit hinzu // @require https://cdn.jsdelivr.net/npm/[email protected]/HackTimer.min.js // @require http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js // @version 0.13 // @match https://www.youtube.com/* // @grant none // @namespace https://gf.qytechs.cn/users/94906 // @license MIT // ==/UserScript== // HackTimer is for making setInterval work in background tabs // moment is for formatting and comparing dates and times (function() { 'use strict'; console.log("YT EXACT UPLOAD LOADED"); var YT_API_KEY = "YouTube API-Key"; var AGE_RESTRICTED = " - FSK 18"; var SHOW_REFRESH = true; var REFRESH_TIMESTAMP = "⟳"; var SHOW_UNDERLINE_ON_TIMESTAMP = false; var BASE_URL = "https://www.googleapis.com/youtube/v3/videos?part=snippet,liveStreamingDetails,contentDetails,localizations,player,statistics,status&key=" + YT_API_KEY; if (document.getElementsByTagName("html")[0].getAttribute("lang").startsWith("de")) { var DATE_PATTERN = "DD.MM.YYYY"; // https://momentjs.com/docs/#/parsing/string-format/ var TIME_PATTERN = "HH:mm:ss [Uhr]"; // https://momentjs.com/docs/#/parsing/string-format/ var DATETIME_COMBINE_PATTERN = " [um] "; // https://momentjs.com/docs/#/parsing/string-format/ var SCHEDULED_LIVESTREAM_START = "Livestream geplant für: "; var SCHEDULED_PREMIERE_START = "Premiere geplant für: "; var ONGOING_LIVESTREAM_START = "Aktiver Livestream seit "; var ONGOING_PREMIERE_START = "Aktive Premiere seit "; var ENDED_LIVESTREAM_START = "Livestream von "; var ENDED_PREMIERE_START = "Premiere von "; var DATETIME_UNTIL_PATTERN = " bis "; var SINCE = "Seit"; var TODAY_AT = "Heute um "; } else { var DATE_PATTERN = "DD.MM.YYYY"; // https://momentjs.com/docs/#/parsing/string-format/ var TIME_PATTERN = "HH:mm:ss"; // https://momentjs.com/docs/#/parsing/string-format/ var DATETIME_COMBINE_PATTERN = " [at] "; // https://momentjs.com/docs/#/parsing/string-format/ var SCHEDULED_LIVESTREAM_START = "Livestream scheduled for: "; var SCHEDULED_PREMIERE_START = "Premiere scheduled for: "; var ONGOING_LIVESTREAM_START = "Active Livestream since "; var ONGOING_PREMIERE_START = "Active Premiere since "; var ENDED_LIVESTREAM_START = "Livestream from "; var ENDED_PREMIERE_START = "Premiere from "; var DATETIME_UNTIL_PATTERN = " until "; var SINCE = "Since"; var TODAY_AT = "Today at "; } var interval = null; var changeCheckTimer = null; var currentVideoId = null; function genUrl(){ const urlParams = new URLSearchParams(window.location.search); if(urlParams.get("v") != null){ return BASE_URL + "&id=" + urlParams.get("v"); }else { return ""; } } function isUndefinedOrNull(obj) { return obj == undefined || obj == null; } function sleep(milliseconds) { return new Promise(resolve => setTimeout(resolve, milliseconds)); } function formatMilliseconds(milliseconds, joinString, showDays, showHours, showMinutes, showSeconds, showMilliseconds, pad, hideDaysOnNull) { let result = ''; let days = Math.floor(milliseconds / (1000 * 60 * 60 * 24)); let hours = Math.floor((milliseconds / (1000 * 60 * 60)) % 24); let minutes = Math.floor((milliseconds / (1000 * 60)) % 60); let seconds = Math.floor((milliseconds / 1000) % 60); milliseconds = milliseconds % 1000; if (showDays) { if (days < 1 && hideDaysOnNull) { } else { if (result != '') result += joinString; if (pad) { if (days < 10) result += '0' + days; else result += days; } else result += days; } } if (showHours) { if (result != '') result += joinString; if (pad) result += ('0' + hours).slice(-2); else result += hours; } if (showMinutes) { if (result != '') result += joinString; if (pad) result += ('0' + minutes).slice(-2); else result += minutes; } if (showSeconds) { if (result != '') result += joinString; if (pad) result += ('0' + seconds).slice(-2); else result += seconds; } if (showMilliseconds) { if (result != '') result += joinString; if (pad) result += ('00' + milliseconds).slice(-3); else result += milliseconds; } return result; } function updateOngoing(durationInMilliseconds) { if (!isUndefinedOrNull(interval)) { clearInterval(interval); interval = null; } let duration = durationInMilliseconds; interval = setInterval(function() { duration += 500; document.getElementById("ongoing-video-duration").innerHTML = formatMilliseconds(duration, ':', true, true, true, true, false, true, true); }, 500); } async function updateLiveContent(premiere, livestream, data, mom) { var element = null; while (isUndefinedOrNull(element)) { element = document.getElementById("info-strings"); await sleep(200); } var durationInMilliseconds = null; var ongoing = false; var innerHTML = "<span id=\"dot\" class=\"style-scope ytd-video-primary-info-renderer\"></span>"; if (!premiere && !livestream) { // normal video if (mom.isSame(moment(), 'day')) // today innerHTML += TODAY_AT + mom.format(TIME_PATTERN); else innerHTML += mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); } else { if (isUndefinedOrNull(data.items[0].liveStreamingDetails.actualStartTime)) { // planned mom = moment(data.items[0].liveStreamingDetails.scheduledStartTime); if (mom.isSame(moment(), 'day')) { // today if (livestream) innerHTML += SCHEDULED_LIVESTREAM_START + mom.format(TIME_PATTERN); else if (premiere) innerHTML += SCHEDULED_PREMIERE_START + mom.format(TIME_PATTERN); else innerHTML += TODAY_AT + mom.format(TIME_PATTERN); } else { if (livestream) innerHTML += SCHEDULED_LIVESTREAM_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else if (premiere) innerHTML += SCHEDULED_PREMIERE_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else innerHTML += TODAY_AT + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); } } else { // ongoing / ended mom = moment(data.items[0].liveStreamingDetails.actualStartTime); var endTime = null; if (!isUndefinedOrNull(data.items[0].liveStreamingDetails.actualEndTime)) endTime = moment(data.items[0].liveStreamingDetails.actualEndTime); if (endTime == null) { // ongoing ongoing = true; durationInMilliseconds = moment.duration(moment().diff(mom)).asMilliseconds(); if (mom.isSame(moment(), 'day')) { // today if (livestream) innerHTML += ONGOING_LIVESTREAM_START + mom.format(TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; else if (premiere) innerHTML += ONGOING_PREMIERE_START + mom.format(TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; else innerHTML += SINCE + " " + mom.format(TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; } else { if (livestream) innerHTML += ONGOING_LIVESTREAM_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; else if (premiere) innerHTML += ONGOING_PREMIERE_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; else innerHTML += SINCE + " " + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + " (<span id=\"ongoing-video-duration\">" + formatMilliseconds(durationInMilliseconds, ':', true, true, true, true, false, true, true) + "</span>)"; } } else { // ended if (mom.isSame(endTime, 'day')) { // start date and end date are the same if (mom.isSame(moment(), 'day')) { // today if (livestream) innerHTML += ENDED_LIVESTREAM_START + mom.format(TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(TIME_PATTERN); else if (premiere) innerHTML += ENDED_PREMIERE_START + mom.format(TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(TIME_PATTERN); else innerHTML += TODAY_AT + mom.format(TIME_PATTERN); } else { if (livestream) innerHTML += ENDED_LIVESTREAM_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(TIME_PATTERN); else if (premiere) innerHTML += ENDED_PREMIERE_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(TIME_PATTERN); else innerHTML += mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(TIME_PATTERN); } } else { if (mom.isSame(moment(), 'day')) { // today if (livestream) innerHTML += ENDED_LIVESTREAM_START + mom.format(TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else if (premiere) innerHTML += ENDED_PREMIERE_START + mom.format(TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else innerHTML += TODAY_AT + mom.format(TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); } else { if (livestream) innerHTML += ENDED_LIVESTREAM_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else if (premiere) innerHTML += ENDED_PREMIERE_START + mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); else innerHTML += mom.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN) + DATETIME_UNTIL_PATTERN + endTime.format(DATE_PATTERN + DATETIME_COMBINE_PATTERN + TIME_PATTERN); } } } } } var contentRating = data.items[0].contentDetails.contentRating; if (!isUndefinedOrNull(contentRating.ytRating) && contentRating.ytRating == 'ytAgeRestricted') innerHTML += AGE_RESTRICTED; if (SHOW_REFRESH) { if (SHOW_UNDERLINE_ON_TIMESTAMP) innerHTML += " <span id=\"dot\" class=\"style-scope ytd-video-primary-info-renderer\"></span> <span style=\"color: var(--yt-spec-text-secondary); text-decoration: underline var(--yt-spec-text-secondary); cursor: pointer;\" onclick=\"document.dispatchEvent(new Event('refresh-clicked'));\">" + REFRESH_TIMESTAMP + "</span>"; else innerHTML += " <span id=\"dot\" class=\"style-scope ytd-video-primary-info-renderer\"></span> <span style=\"color: var(--yt-spec-text-secondary); cursor: pointer;\" onclick=\"document.dispatchEvent(new Event('refresh-clicked'));\">" + REFRESH_TIMESTAMP + "</span>"; } element.innerHTML = innerHTML; if (ongoing) updateOngoing(durationInMilliseconds); let dislikeButtonText = document.getElementsByTagName('yt-formatted-string'); for (let i = 0; i < dislikeButtonText.length; i++) { if (dislikeButtonText[i].innerHTML == 'Mag ich nicht' || dislikeButtonText[i].innerHTML.toLowerCase() == 'dislike') { if (dislikeButtonText[i].hasOwnProperty('remove')) dislikeButtonText[i].remove(); else dislikeButtonText[i].parentNode && dislikeButtonText[i].parentNode.removeChild(dislikeButtonText[i]); // Polyfill break; } } let formattedString = document.getElementById('formatted-snippet-text'); if (!formattedString) formattedString = document.getElementById('formatted-snippet'); formattedString.id = 'formatted-snippet'; let dateTimeValueElem = document.querySelector('#formatted-snippet :nth-child(3)'); dateTimeValueElem.innerHTML = innerHTML; return ongoing; } function getExactUploadDate(forceRefresh = false) { var abort = false; const processEvent = async () => { await sleep(500); const urlParams = new URLSearchParams(window.location.search); if (urlParams.get("v") != null){ let videoId = urlParams.get("v"); if (videoId == currentVideoId) { abort = true; } else { currentVideoId = videoId; } } if (forceRefresh) abort = false; if ((YT_API_KEY != "" || typeof YT_API_KEY != "undefined") && !abort) { var url = genUrl(); if (url != "") { fetch(url).then(function(response) { return response.json(); }).then(function(data) { if (data.pageInfo.totalResults > 0) { const addTime = async () => { var mom = moment(data.items[0].snippet.publishedAt); console.log(mom); let payload = { context: { client: { clientName: 'WEB', clientVersion: '2.20210614.06.00', originalUrl: window.location.href, platform: 'DESKTOP', clientFormFactor: 'UNKNOWN_FORM_FACTOR', mainAppWebInfo: { graftUrl: '/watch?v=' + currentVideoId, webDisplayMode: 'WEB_DISPLAY_MODE_BROWSER', isWebNativeShareAvailable: false } }, user: { lockedSafetyMode: false }, request: { useSsl: true } }, videoId: currentVideoId, racyCheckOk: false, contentCheckOk: false }; fetch('https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'/*InnerTube-API-Key*/, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }).then(function(response) { return response.text(); }).then(function(video_info) { if (!isUndefinedOrNull(interval)) { clearInterval(interval); interval = null; } if (!isUndefinedOrNull(changeCheckTimer)) { clearInterval(changeCheckTimer); changeCheckTimer = null; } try { /*let player_response = decodeURIComponent(video_info); let urlParams = new URLSearchParams(player_response); if (urlParams.get("player_response") != null) { player_response = urlParams.get("player_response"); } player_response = JSON.parse(player_response);// data.items[0].status.privacyStatus = "public" -> Öffentliches Video*/ let player_response = JSON.parse(video_info); var premiere = !isUndefinedOrNull(player_response) && !player_response.videoDetails.isLiveContent; premiere = premiere && !isUndefinedOrNull(data.items[0].liveStreamingDetails); var livestream = !isUndefinedOrNull(player_response) && player_response.videoDetails.isLiveContent; var innerHTML = "<span id=\"dot\" class=\"style-scope ytd-video-primary-info-renderer\">•</span>"; updateLiveContent(premiere, livestream, data, mom); } catch (ex) { console.error(ex); } }).catch(error => console.error("YOUTUBE EXACT UPLOAD ERROR: " + error, "\nget_video_info doesn't seem to work")); }; addTime(); }; }).catch(error => console.error("YOUTUBE EXACT UPLOAD ERROR: " + error, "\nINVALID API KEY?")); } } else { if(!abort) console.error("YOUTUBE EXACT UPLOAD ERROR: Undefined api key"); } } processEvent(); } function refreshEventListener() { getExactUploadDate(true); } //getExactUploadDate(); //document.addEventListener('click', getExactUploadDate); //document.addEventListener('yt-page-data-updated', getExactUploadDate); //document.addEventListener('yt-navigate-finish', getExactUploadDate); document.addEventListener('refresh-clicked', refreshEventListener); //<video style="width: 853px; height: 480px; left: 0px; top: 0px;" tabindex="-1" class="video-stream html5-main-video" src="blob:https://www.youtube.com/0976da77-cfd4-4922-ad9e-383d88a12200"></video> /*function main() { let videoStream = document.getElementsByClassName('video-stream'); if (videoStream.length < 1) { setTimeout(() => main(), 500); } else { console.log('video-stream:', videoStream[0]); // videoStream[0].addEventListener('loadeddata', (event) => console.log(`Loaded ${event.target.src}`)); //videoStream[0].addEventListener('loadeddata', (event) => getExactUploadDate()); videoStream[0].addEventListener('durationchange', (event) => getExactUploadDate()); } }*/ function main() { let ytdPlayer = document.getElementById('ytd-player'); if (!ytdPlayer) { setTimeout(() => main(), 500); } else { ytdPlayer.addEventListener('yt-player-updated', (event) => getExactUploadDate()); } } main(); if (new URLSearchParams(window.location.search).get("v") != null) { getExactUploadDate(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址