您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Keeps YouTube progressbar visible all the time.
当前为
// ==UserScript== // @name YouTube Permanent ProgressBar // @namespace http://tampermonkey.net/ // @version 0.1 // @description Keeps YouTube progressbar visible all the time. // @author Can Kurt // @match *://www.youtube.com/* // @license MIT // ==/UserScript== var permanentProgressBar = { setup : function(){ // keep progressBar visible with css document.querySelector(".ytp-chrome-bottom").style.cssText = "opacity: 1 !important;"; }, prettifyVideoTime : function(video){ let seconds = "" + Math.floor(video.currentTime%60); let minutes = "" + Math.floor((video.currentTime%3600)/60); let hours = "" + Math.floor(video.currentTime/3600); if(video.currentTime/60 > 60){ return `${hours}:${minutes.padStart(2, '0')}:${seconds.padStart(2, '0')}`; } else{ return `${minutes}:${seconds.padStart(2, '0')}`; } }, getDuration : function(video, type){ if(type === "PROGRESSBAR"){ return video.currentTime; } else if(type === "BUFFERBAR"){ return video.buffered.end(video.buffered.length-1); } }, updateCurrentTimeField : function(player){ const video = player.querySelector("video"); const currentTime = player.querySelector(".ytp-time-current"); if (!video || !currentTime) { return; } currentTime.innerText = permanentProgressBar.prettifyVideoTime(video); }, updateProgressBar : function(player){ // works only on chapterless (old) videos const video = player.querySelector("video"); const progressBar = player.querySelector(".ytp-play-progress"); const bufferBar = player.querySelector(".ytp-load-progress"); if (!video || !progressBar || !bufferBar) { return; } progressBar.style.transform = `scaleX(${video.currentTime/video.duration})`; bufferBar.style.transform = `scaleX(${video.buffered.end(video.buffered.length-1)/video.duration})`; }, updateProgressBarWithChapters : function(player, type){ // YouTube api does not provides current time in chapters // this function finds current time in the chapter by finding the ratio between total video duration and total width of the chapters div const video = player.querySelector("video"); // there can be multiple chapters const progressBarWidthsCollection = player.getElementsByClassName("ytp-progress-bar-padding"); // select progress or bufferBar let progressBarChaptersCollection; if(type === "PROGRESSBAR"){ progressBarChaptersCollection = player.getElementsByClassName("ytp-play-progress"); } if(type === "BUFFERBAR"){ progressBarChaptersCollection = player.getElementsByClassName("ytp-load-progress"); } // quit if elements does not exists if (!video || !progressBarWidthsCollection || !progressBarChaptersCollection) { return; } // find the ratio between total video duration and total width of the chapters div let totalProgressBarWidth = 0; for (let i = 0; i < progressBarWidthsCollection.length; i++) { totalProgressBarWidth += progressBarWidthsCollection[i].offsetWidth; } const durationWidthRatio = video.duration/totalProgressBarWidth; // loop inside chapters let chaptersPixelWidthUntilCurrentChapter = 0; for (let i = 0; i < progressBarWidthsCollection.length; i++) { // if current time is bigger than durationWidthRatio * (chapters pixel width including current one) scale the current chapter to 1 because we passed it if(permanentProgressBar.getDuration(video, type) > durationWidthRatio*(chaptersPixelWidthUntilCurrentChapter + progressBarWidthsCollection[i].offsetWidth)){ progressBarChaptersCollection[i].style.transform = "scaleX(1)"; // increase the current chapters location by adding last watched chapter chaptersPixelWidthUntilCurrentChapter += progressBarWidthsCollection[i].offsetWidth; } // If not, it means that we are on this chapter. // Find the appropriate size for the chapter and scale it else{ // current time let currentTimeInChapterInSeconds = permanentProgressBar.getDuration(video, type) - (durationWidthRatio*chaptersPixelWidthUntilCurrentChapter); // total chapter time let currentChapterLengthInSeconds = durationWidthRatio*progressBarWidthsCollection[i].offsetWidth; let currentChapterTimeRatio = currentTimeInChapterInSeconds / currentChapterLengthInSeconds progressBarChaptersCollection[i].style.transform = `scaleX(${currentChapterTimeRatio})`; break; } } }, update : function(){ const player = document.querySelector(".html5-video-player"); if (!player) { return; } // update video timer permanentProgressBar.updateCurrentTimeField(player); // update progressBars permanentProgressBar.updateProgressBarWithChapters(player, "PROGRESSBAR"); permanentProgressBar.updateProgressBarWithChapters(player, "BUFFERBAR"); }, start : function(){ permanentProgressBar.setup(); setInterval(permanentProgressBar.update, 500); } } permanentProgressBar.start();