Add YouTube Video Progress

Add progress bar at bottom of YouTube video and progress text on the video page.

当前为 2018-03-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Add YouTube Video Progress
  3. // @namespace https://gf.qytechs.cn/en/users/85671-jcunews
  4. // @version 1.0.7
  5. // @license GNU AGPLv3
  6. // @description Add progress bar at bottom of YouTube video and progress text on the video page.
  7. // @author jcunews
  8. // @match https://www.youtube.com/*
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. //===== Configuration Start =====
  14. progressbarHeight = 3; //in pixels
  15. progressbarColor = "#fff"; //e.g. "#fff" or "#e0e0e0" or "cyan"
  16. progressbarElapsedColor = "#f00";
  17. contentLoadProcessDelay = 500; //number of milliseconds before processing dynamically loaded contents (increase if slow network/browser)
  18. //===== Configuration End =====
  19.  
  20. var timerWaitInfo, timerProgressMonitor, timerWaitPlayer, timerDoubleCheck;
  21.  
  22. function processInfo() {
  23. if (window.vidprogress || (location.pathname !== "/watch")) return;
  24. console.log(new Date());
  25. clearTimeout(timerWaitInfo);
  26. (function waitInfo(a, b) {
  27. if (a = document.querySelector("#info-contents #info, #watch7-user-header")) {
  28. b = document.createElement("SPAN");
  29. b.id = "vidprogress";
  30. b.innerHTML = '<span id="curq" style="font-weight:500"></span><span id="curtime" style="margin-left:2ex"></span>';
  31. b.style.cssText = "border:1px solid #ccc;border-radius:4px;padding:2px 5px;background:#eee;";
  32. if (window["body-container"]) {
  33. b.style.cssText += "margin-left:2ex";
  34. a.appendChild(b);
  35. } else {
  36. b.style.cssText += "margin-left:2ex;font-size:10pt";
  37. a.insertBefore(b, a.querySelector("#flex"));
  38. }
  39. } else timerWaitInfo = setTimeout(waitInfo, 200);
  40. })();
  41. }
  42.  
  43. function processPlayer() {
  44. function zerolead(n){
  45. return n > 9 ? n : "0" + n;
  46. }
  47.  
  48. function sec2hms(sec) {
  49. var c = sec % 60, d = Math.floor(sec / 60);
  50. return (d >= 60 ? zerolead(Math.floor(d / 60)) + ":" : "") + zerolead(d % 60) + ":" + zerolead(c);
  51. }
  52.  
  53. function updProgress(a, b, c, ls){
  54. a = window.movie_player;
  55. if (a && window.vidprogress2b && a.getCurrentTime) try {
  56. if (window.curtime) {
  57. b = a.getPlaybackQuality();
  58. switch (b) {
  59. case "light":
  60. case "tiny": c = "144p"; break;
  61. case "small": c = "240p"; break;
  62. case "medium": c = "360p"; break;
  63. case "large": c = "480p"; break;
  64. case "highres": c = "4320p"; break;
  65. default:
  66. if (ls = b.match(/^hd(\d+)/)) {
  67. c = ls[1] + "p";
  68. } else c = b;
  69. }
  70. curq.textContent = c;
  71. curq.title = b;
  72. }
  73. b = a.getCurrentTime();
  74. if (b >= 0) {
  75. ls = a.getDuration();
  76. if (!a.getVideoData().isLive) {
  77. if (window.curtime) {
  78. curtime.textContent = sec2hms(Math.floor(b)) + " / " + sec2hms(Math.floor(ls)) + " (" + Math.floor(b * 100 / ls) + "%)";
  79. }
  80. vidprogress2b.style.width = Math.ceil((b / ls) * vidprogress2.offsetWidth) + "px";
  81. } else {
  82. if (window.curtime) {
  83. curtime.textContent = "LIVE";
  84. }
  85. vidprogress2b.style.width = "100%";
  86. }
  87. } else {
  88. if (window.curtime) {
  89. curq.textContent = "";
  90. curtime.textContent = "";
  91. }
  92. vidprogress2b.style.width = "0px";
  93. }
  94. }catch(a){
  95. if (window.curtime) {
  96. curq.textContent = "[???]";
  97. curtime.textContent = "???";
  98. }
  99. vidprogress2b.style.width = "0px";
  100. }
  101. }
  102.  
  103. function resumeProgressMonitor() {
  104. if (timerProgressMonitor) return;
  105. updProgress();
  106. timerProgressMonitor = setInterval(updProgress, 200);
  107. }
  108.  
  109. function pauseProgressMonitor() {
  110. clearInterval(timerProgressMonitor);
  111. timerProgressMonitor = 0;
  112. updProgress();
  113. }
  114.  
  115. clearInterval(timerProgressMonitor);
  116. clearTimeout(timerWaitPlayer);
  117. clearInterval(timerDoubleCheck);
  118. (function waitPlayer() {
  119. if (!window.vidprogress2 && window.movie_player && (a = movie_player.parentNode.querySelector("video"))) {
  120. b = document.createElement("DIV");
  121. b.id = "vidprogress2";
  122. b.style.cssText = "opacity:.66;position:absolute;z-index:10;bottom:0;width:100%;height:" + progressbarHeight + "px;background:" + progressbarColor;
  123. b.innerHTML = '<div id="vidprogress2b" style="height:100%;background:' + progressbarElapsedColor + '"></div>';
  124. movie_player.appendChild(b);
  125. if (movie_player.getPlayerState() === 1) {
  126. resumeProgressMonitor();
  127. }
  128. //useful: onLoadedMetadata(), onStateChange(state), onPlayVideo(info), onReady(playerApi), onVideoAreaChange(), onVideoDataChange(info)
  129. //states: -1=notReady, 0=ended, 1=playing, 2=paused, 3=ready, 4=???, 5=notAvailable?
  130. movie_player.addEventListener("onLoadedMetadata", resumeProgressMonitor);
  131. movie_player.addEventListener("onStateChange", function(state) {
  132. if (state === 1) {
  133. resumeProgressMonitor();
  134. } else pauseProgressMonitor();
  135. });
  136. } else wpTimer = setTimeout(waitPlayer, 200);
  137. })();
  138.  
  139. function doubleCheck() {
  140. if (window.movie_player && movie_player.getPlayerState) {
  141. if (movie_player.getPlayerState() === 1) {
  142. resumeProgressMonitor();
  143. } else pauseProgressMonitor();
  144. }
  145. }
  146. if (!timerDoubleCheck) timerDoubleCheck = setInterval(doubleCheck, 500);
  147. }
  148.  
  149. addEventListener("yt-page-data-updated", processInfo);
  150. addEventListener("yt-player-released", processPlayer);
  151. addEventListener("load", function() {
  152. processInfo();
  153. processPlayer();
  154. });
  155. addEventListener("spfprocess", function() {
  156. setTimeout(function() {
  157. processInfo();
  158. processPlayer();
  159. }, contentLoadProcessDelay);
  160. });

QingJ © 2025

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