Youtube Playlist Duration

Shows the duration of youtube playlists.

  1. // ==UserScript==
  2. // @name Youtube Playlist Duration
  3. // @description Shows the duration of youtube playlists.
  4. // @namespace https://gf.qytechs.cn/users/1142347
  5. // @version 1.0
  6. // @author Caassiiee
  7. // @icon https://www.youtube.com/favicon.ico
  8. // @match *://*.youtube.com/*
  9. // @noframes
  10. // @license GPL-3.0-only
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. let interval = null;
  17.  
  18. function attachTimesContainer() {
  19. let sibling = document.querySelector('.metadata-stats');
  20. const container = document.createElement('div');
  21. container.className = 'metadata-stats ytd-playlist-byline-renderer';
  22. const totalTimeSpan = document.createElement('span');
  23. totalTimeSpan.id = 'total-time';
  24. totalTimeSpan.className = 'byline-item style-scope ytd-playlist-byline-renderer';
  25. container.appendChild(totalTimeSpan);
  26. sibling.parentNode.insertBefore(container, sibling.nextSibling);
  27. }
  28.  
  29. function attachTimesInterval() {
  30. getTimes();
  31. interval = setInterval(function () {
  32. getTimes();
  33. }, 1000);
  34. }
  35.  
  36. function getTimes() {
  37. let totalTime = [0, 0, 0];
  38. console.log('getTimes');
  39.  
  40. document.querySelectorAll('ytd-playlist-video-list-renderer #time-status').forEach(function (span) {
  41. let time = span.innerText;
  42. let times = time.split(':');
  43. while (times.length < 3) {
  44. times.unshift(0);
  45. }
  46. for (let i = 0; i < times.length; i++) {
  47. const parsed = parseInt(times[i]);
  48. times[i] = isNaN(parsed) ? 0 : parsed;
  49. totalTime[i] += times[i];
  50. }
  51. for (let i = totalTime.length - 1; i >= 0; i--) {
  52. if (i !== 0) {
  53. while (totalTime[i] > 59) {
  54. totalTime[i - 1]++;
  55. totalTime[i] -= 60;
  56. }
  57. }
  58. }
  59. });
  60.  
  61. for (let i = 0; i < totalTime.length; i++) {
  62. if (i !== 0 && totalTime[i] < 10) {
  63. totalTime[i] = '0' + totalTime[i].toString();
  64. } else {
  65. totalTime[i] = totalTime[i].toString();
  66. }
  67. }
  68.  
  69. let totalTimeString = totalTime.join(':');
  70. document.querySelector('#total-time').innerText = totalTimeString;
  71. }
  72.  
  73. document.addEventListener('yt-navigate-finish', () => {
  74. const main = document.querySelector('ytd-browse[role="main"]');
  75. if (main) {
  76. const meta = main.querySelector('.metadata-stats');
  77. if (meta) {
  78. const totalTimeSpan = document.querySelector('#total-time');
  79. if (totalTimeSpan) {
  80. totalTimeSpan.innerText = '';
  81. } else {
  82. attachTimesContainer();
  83. }
  84. attachTimesInterval();
  85. } else {
  86. clearInterval(interval);
  87. }
  88. } else {
  89. clearInterval(interval);
  90. }
  91. });
  92. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址