Youtube - tag title

Tag tab's title to add more informations: duration, channel, date, age, ...

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         Youtube - tag title
// @namespace    https://github.com/Procyon-b
// @version      0.5.6
// @description  Tag tab's title to add more informations: duration, channel, date, age, ...
// @author       Achernar
// @match        https://www.youtube.com/*
// @noframes
// @run-at  document-start
// @grant   GM_setValue
// @grant   GM_getValue
// ==/UserScript==

(function() {
"use strict";
// à

var defConf={
    format: '%d %s %T %s %c %s_t0(s)',
    sep: '✦'
    },
  cfg=defConf,
  format=cfg.format,
  loaded;

function tryUntil(F, TO=150, c=-1, fail) {
  if (!c--) {
    fail && fail();
    return;
    }
  try{F();}catch(e){setTimeout(function(){tryUntil(F,TO,c,fail);}, TO)}
  }

function load() {
  if (loaded) return;
  cfg=GM_getValue('config', null);

  if (!cfg || !cfg.format) {
    GM_setValue('config', defConf);
    cfg=defConf;
    }
  
  let sv=false;
  for (let k in defConf) {
    if ( !(k in cfg) ) {
      cfg[k]=defConf[k];
      sv=true;
      }
    }
  if (sv) {
    GM_setValue('config', cfg);
    }
  format=cfg.format;
  loaded=true;
  }

tryUntil(load, 0, 100);


const max=20, delay=1000, initialDelay=100;
var c=max, loop=false;
var vids={};

function getInitialInfo() {
  var r, t, t0, c, d, T, ID= (/v=([^&]+)/.exec(location.search)) || (/^\/shorts\/([^\/]+)/.exec(location.pathname));
  ID= ID && ID[1];

  if (!ID) return;

  r=vids[ID];

  function fromContext() {
    let RE, js=document.querySelector('script:not([src])[type="application/ld+json"]');
    if (js) {
      try{js=JSON.parse(js.textContent);
      }catch(e){js={};}
      if ( (RE = /^[^\?]+\?v=(.+)$/.exec(js['@id'])) && (RE[1] == ID) ) {
        id=RE[1];
        T=js.name;
        c=js.author;
        d=js.duration;
        t0=new Date(js.uploadDate);
        return T && c && d && t0;
        }
      }
    }

  if (!r) {
    if (!yt) return -1;
    if (!ytInitialPlayerResponse) return;
    var v=ytInitialPlayerResponse.videoDetails;
    if (!v) return;
    var id=v.videoId;
    if (id == ID) {
      T=v.title,
      c=v.author,
      d=ytInitialPlayerResponse.streamingData?.formats?.[0]?.approxDurationMs;
      t=ytInitialPlayerResponse.streamingData?.formats?.[0]?.lastModified;
      t0=ytInitialPlayerResponse.microformat?.playerMicroformatRenderer?.publishDate;
      }
    if ( !(T && c && d && t0) ) fromContext();
    if ( (ID == id) && d) r=vids[id]={T,c,d,t,t0};
    }

  if (r && !r.Tt) {
    let ytid=ytInitialData?.contents?.twoColumnWatchNextResults?.results?.results?.contents;
    let id=findK(ytid, 'videoId');
    if (!ytid) ;
    else if (id==ID) {
      r.Tt=findK(ytid, ['title','text']);
      r.Ct=findK(ytid, ['owner','text']);
      vids[id]=r;
      }
    else try{
      ytid=ytInitialData?.contents?.twoColumnWatchNextResults?.secondaryResults?.secondaryResults?.results[0].itemSectionRenderer.contents;
      for (let i=0, LVM; LVM=ytid[i]?.lockupViewModel; i++) {
        let id=LVM.contentId;
        if (id == ID) {
          r.Tt=findK(LVM, ['title','content']);
          r.Ct=findK(LVM, ['metadataRows', '0', 'content'] ).trim();
          vids[id]=r;
          break;
          }
        }
      }catch(e){}
    }

  return r;
  }


function getNfo(a) {
  if ( (location.pathname != '/watch') && !location.pathname.startsWith('/shorts/') ) {
    return;
    }
  if (loop) {
    return;
    }
  c=max;
  loopGetNfo(a);
  }

function findK(o, k, K) {
  if ( k && (typeof k == 'object') && k.length) return findK(o, k.shift(), k);
  var r;
  if (!k) return;
  if (o === null || typeof o !== 'object') return;
  if (Object.prototype.hasOwnProperty.call(o, k)) {
    r=o[k];
    if (K && K.length) {
      r=findK(r, K.shift(), K);
      }
    }
  else {
   for (let i in o) {
    let V=findK(o[i], k, K);
    if (V !== undefined) return V;
    }
   }

  return r;
}

function loopGetNfo(a) {
  var t, ts, t0, t0s, T, C, D, D2, Tt, Ct;
  if (!loop) {
    let R=getInitialInfo() || {};
    if ( (a == 1) && (R==-1) ) {
      setTimeout(function(){
        loopGetNfo(a);
        }, 100);
      return;
      }
    t=R.t;
    t0=R.t0;
    C=R.c;
    D=R.d;
    T=R.T;
    Tt=R.Tt;
    Ct=R.Ct;
    }
  
  if (!T) {
    loop=false;
    try{
      T=document.querySelector('#title h1').innerText;
      D=document.querySelector('.ytp-chrome-controls .ytp-time-duration').innerText;
      D2=document.querySelector('body > div[id^="watch"][id$="-content"] meta[itemprop="duration"]')?.content;
      C=document.querySelector('#upload-info #channel-name').innerText;
    }catch(e){
      let dl= c==max ? initialDelay : delay;
      if ( (c-- > 0) && (a !== 1) ) {
        loop=true;
        setTimeout(loopGetNfo, dl);
        }
      else c=max;
      return;
      }
    }
  if (!T.trim()) return;

  c=max;
  var d=dur(!D || (D=='0:00') ? D2 : D);
  
  if (t) try {
    let d=new Date(t / 1000);
    let diff=Date.now() - t.slice(0,-3);
    d=new Date( (t / 1000) - (60000 * d.getTimezoneOffset()) );
    t=d.toISOString().split('.')[0].slice(0,-3);
    if (diff) t=t+' ('+dur(diff,true)+')';
    }catch(e){ t=0; }
    
  if (t0) try {
    let d=new Date(t0);
    t0=d.getTime();
    let diff=Date.now() - t0;
    d=new Date( t0 - (60000 * d.getTimezoneOffset()) );
    t0=d.toISOString().split('.')[0].slice(0,-3);
    if (diff) t0=t0+' ('+dur(diff,true)+')';
    }catch(e){ t0=0; }

  function tt(m, s0, spc, z, s1, d) {
    var s='', T;
    if (s0) s+='%s'+(spc?' ':'');
    if (z) {
      if (!t0) return '';
      T=t0;
      }
    else {
      if (!t) return '';
      T=t;
      }
    T=T.replace('T', s1?'%s':'.');
    if (d) T=T.split(' ')[1];
    return s+T;
    }

  var NT=trm( format
        .replace(/%T/g, trm(Tt || T))
        .replace(/%d/g, trm(d))
        .replace(/%c/g, trm(Ct || C))
        
        .replace(/%(s)?(_)?t(0)?(\(s\))?(\(d\))?/g, tt)

        .replace(/%s/g, cfg.sep)
        );


  if (document.title != NT) {
    document.title=NT;
    }
  }

function trm(s) {
  if (typeof s == 'string') return s.trim().replace(/\s+/g, ' ');
  }

function dur(s, full=false) {
  function s2dur(s) {
    let t=parseInt(s/1000);
    S=t%60;
    t=parseInt(t/60);
    M=t%60;
    if (full) {
      t=parseInt(t/60);
      H=t%24;
      d=parseInt(t/24);
      }
    else H=parseInt(t/60);
    }

  var re,r, H,M,S,d;
  if (re=/^(?:(\d*):)?(\d+):(\d+)$/.exec(s)) {
    H=re[1] || 0;
    M=re[2] || 0;
    S=re[3];
    }
  else if (s > 0) {
    s2dur(s);
    }
  else {
    if ( re=/^PT(?:(\d+)M)?(\d+)S$/.exec(s) ) {
      H=parseInt(re[1] || '0');
      S=parseInt(re[2] || '0');
      s2dur( (H * 60 + S) * 1000);
      }
    }

  if (!full) {
    if (S > 44) M++;
    if (M == 60) {
      H++;
      M=0;
      }
    }
  if (H == 0) H='';
  if (!full && !H && !M && !S) M='??';
  else if (!full && !H && (M == 0) ) M=1;
  M=('00'+M).substr(-2);

  if (full) {
    let m, y;
    r='';
    
    y=parseInt(d/365);
    if (y) d=d%365;
    m=parseInt(d/30);
    d=d%30;
    if (y || m) H=M='';
    else if (d && !H) H='0';
    
    if (y) r+=y+'y';
    if (m) r+=m+'m';
    
    r+=(d ? d+'d' : '')+( (H || d) ? H : '')+(!d ? (H?':':'')+M : '');
    }
  else r=H+':'+M;
  return r;
  }

var inited=0;

function init() {
  if (inited++) return true;
  try{load();}catch(e){}

  var obs=new MutationObserver(function(mutL){
    getNfo();
    });
  tryUntil( function(){
    obs.observe(document.querySelector('html > head > title'), {childList:true, subtree:true});
    }, undefined, 50);

  getNfo(1);
  }

if (document.readyState != 'loading') init();
else {
  document.addEventListener('DOMContentLoaded', init);
  document.addEventListener('load', init);
  window.addEventListener('load', init);
  }

})();