Add progress bar at bottom of YouTube video and progress text on the video page.
当前为
// ==UserScript==
// @name Add YouTube Video Progress
// @namespace https://greatest.deepsurf.us/en/users/85671-jcunews
// @version 1.0.8
// @license GNU AGPLv3
// @description Add progress bar at bottom of YouTube video and progress text on the video page.
// @author jcunews
// @match https://www.youtube.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
//===== Configuration Start =====
progressbarHeight = 3; //in pixels
progressbarColor = "#fff"; //e.g. "#fff" or "#e0e0e0" or "cyan"
progressbarElapsedColor = "#f00";
contentLoadProcessDelay = 0; //number of milliseconds before processing dynamically loaded contents (increase if slow network/browser)
//===== Configuration End =====
var timerWaitInfo, timerProgressMonitor, timerWaitPlayer, timerDoubleCheck;
function processInfo() {
if (window.vidprogress || (location.pathname !== "/watch")) return;
clearTimeout(timerWaitInfo);
(function waitInfo(a, b) {
if (a = document.querySelector("#info-contents #info, #watch7-user-header")) {
b = document.createElement("SPAN");
b.id = "vidprogress";
b.innerHTML = '<span id="curq" style="font-weight:500"></span><span id="curtime" style="margin-left:2ex"></span>';
b.style.cssText = "border:1px solid #ccc;border-radius:4px;padding:2px 5px;background:#eee;";
if (window["body-container"]) {
b.style.cssText += "margin-left:2ex";
a.appendChild(b);
} else {
b.style.cssText += "margin-left:2ex;font-size:10pt";
a.insertBefore(b, a.querySelector("#flex"));
}
} else timerWaitInfo = setTimeout(waitInfo, 200);
})();
}
function processPlayer() {
function zerolead(n){
return n > 9 ? n : "0" + n;
}
function sec2hms(sec) {
var c = sec % 60, d = Math.floor(sec / 60);
return (d >= 60 ? zerolead(Math.floor(d / 60)) + ":" : "") + zerolead(d % 60) + ":" + zerolead(c);
}
function updProgress(a, b, c, ls){
a = window.movie_player;
if (a && window.vidprogress2b && a.getCurrentTime) try {
if (window.curtime) {
b = a.getPlaybackQuality();
switch (b) {
case "light":
case "tiny": c = "144p"; break;
case "small": c = "240p"; break;
case "medium": c = "360p"; break;
case "large": c = "480p"; break;
case "highres": c = "4320p"; break;
default:
if (ls = b.match(/^hd(\d+)/)) {
c = ls[1] + "p";
} else c = b;
}
curq.textContent = c;
curq.title = b;
}
b = a.getCurrentTime();
if (b >= 0) {
ls = a.getDuration();
if (!a.getVideoData().isLive) {
if (window.curtime) {
curtime.textContent = sec2hms(Math.floor(b)) + " / " + sec2hms(Math.floor(ls)) + " (" + Math.floor(b * 100 / ls) + "%)";
}
vidprogress2b.style.width = Math.ceil((b / ls) * vidprogress2.offsetWidth) + "px";
} else {
if (window.curtime) {
curtime.textContent = "LIVE";
}
vidprogress2b.style.width = "100%";
}
} else {
if (window.curtime) {
curq.textContent = "";
curtime.textContent = "";
}
vidprogress2b.style.width = "0px";
}
}catch(a){
if (window.curtime) {
curq.textContent = "[???]";
curtime.textContent = "???";
}
vidprogress2b.style.width = "0px";
}
}
function resumeProgressMonitor() {
if (timerProgressMonitor) return;
updProgress();
timerProgressMonitor = setInterval(updProgress, 200);
}
function pauseProgressMonitor() {
clearInterval(timerProgressMonitor);
timerProgressMonitor = 0;
updProgress();
}
clearInterval(timerProgressMonitor);
timerProgressMonitor = 0;
clearTimeout(timerWaitPlayer);
timerWaitPlayer = 0;
clearInterval(timerDoubleCheck);
timerDoubleCheck = 0;
(function waitPlayer() {
if (!window.vidprogress2 && window.movie_player && (a = movie_player.parentNode.querySelector("video"))) {
b = document.createElement("DIV");
b.id = "vidprogress2";
b.style.cssText = "opacity:.66;position:absolute;z-index:10;bottom:0;width:100%;height:" + progressbarHeight + "px;background:" + progressbarColor;
b.innerHTML = '<div id="vidprogress2b" style="height:100%;background:' + progressbarElapsedColor + '"></div>';
movie_player.appendChild(b);
if (movie_player.getPlayerState() === 1) {
resumeProgressMonitor();
}
//useful: onLoadedMetadata(), onStateChange(state), onPlayVideo(info), onReady(playerApi), onVideoAreaChange(), onVideoDataChange(info)
//states: -1=notReady, 0=ended, 1=playing, 2=paused, 3=ready, 4=???, 5=notAvailable?
movie_player.addEventListener("onLoadedMetadata", resumeProgressMonitor);
movie_player.addEventListener("onStateChange", function(state) {
if (state === 1) {
resumeProgressMonitor();
} else pauseProgressMonitor();
});
} else timerWaitPlayer = setTimeout(waitPlayer, 200);
})();
function doubleCheck() {
if (window.movie_player && movie_player.getPlayerState) {
if (movie_player.getPlayerState() === 1) {
resumeProgressMonitor();
} else pauseProgressMonitor();
}
}
if (!timerDoubleCheck) timerDoubleCheck = setInterval(doubleCheck, 500);
}
addEventListener("yt-page-data-updated", processInfo);
addEventListener("yt-player-released", processPlayer);
addEventListener("load", function() {
processInfo();
processPlayer();
});
addEventListener("spfprocess", function() {
setTimeout(function() {
processInfo();
processPlayer();
}, contentLoadProcessDelay);
});