Youtube exact upload

Adds exact upload time to youtube videos

04.04.2021 itibariyledir. En son verisyonu görün.

// ==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.4
// @match          https://www.youtube.com/*
// @grant          none
// @namespace      https://greasyfork.dpdns.org/users/94906
// @license        WTFPL
// ==/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 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] ";
  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 YT_API_KEY = "YouTube API-Key";
  var BASE_URL = "https://www.googleapis.com/youtube/v3/videos?part=snippet,liveStreamingDetails,contentDetails,localizations,player,statistics,status&key=" + YT_API_KEY;
  var interval = null;
  var changeCheckTimer = null;
  var currentVideoId = null;
  //console.log("Language:" + document.getElementsByTagName("html")[0].getAttribute("lang"));
  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("date");
      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 += 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 += 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 += 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 += 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 += 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 += " - FSK 18";
    element.innerHTML = innerHTML;
    if (ongoing)
      updateOngoing(durationInMilliseconds);
    return ongoing;
  }
  function updateLiveContentWithChangeCheck(premiere, livestream, data, mom) {
    var ongoing = updateLiveContent(premiere, livestream, data, mom);
    /*document.getElementsByClassName('html5-main-video')[0].addEventListener('ended', function() {
      fetch('https://www.youtube.com/get_video_info?video_id=' + currentVideoId).then(function(response) {
        return response.text();
      }).then(function(video_info) {
        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);
          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 live = !isUndefinedOrNull(player_response) && player_response.videoDetails.isLive;
          if (ongoing)
          	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"));
    });*/
  }
  function getExactUploadDate() {
    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 ((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);
                fetch('https://www.youtube.com/get_video_info?video_id=' + currentVideoId).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
                    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>";
                    updateLiveContentWithChangeCheck(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();
  }
  //getExactUploadDate();
  //document.addEventListener('click', getExactUploadDate);
  //document.addEventListener('yt-page-data-updated', getExactUploadDate);
  document.addEventListener('yt-navigate-finish', getExactUploadDate);
})();
长期地址
遇到问题?请前往 GitHub 提 Issues,或加Q群1031348184

赞助商

Fishcpy

广告

Rainyun

注册一下就行

Rainyun

一年攒够 12 元