NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Crunchyroll Timestamp Previewer // @namespace http://tampermonkey.net/ // @version 0.2 // @description See the time on the progress bar before you click. // @author L1lith // @match http*://static.crunchyroll.com/vilos/player.* // @grant none // @license MIT // @run-at document-start // ==/UserScript== (function () { const registeredProgressDivs = [] let videoLength = null const progressDivListener = event => { const rootProgressDiv = document.querySelector('.vjs-progress-control') if (rootProgressDiv && !registeredProgressDivs.includes(rootProgressDiv)) { registeredProgressDivs.push(rootProgressDiv) addTimeScroller(rootProgressDiv) } } let findVideoLengthInterval = null const findVideoLength = () => { try { videoLength = document.querySelector('.vjs-duration-display').innerText.match(/[0-9]+:[0-9]+/)[0].split(':').map(string => parseInt(string)) videoLength = videoLength[0] + videoLength[1] / 60 } catch (error) { return } if (videoLength === 0) return videoLength = null clearInterval(findVideoLengthInterval) } function addTimeScroller(rootProgressDiv) { const retrieveProgressDiv = rootProgressDiv.querySelector('.vjs-play-progress') let timeDiv = null const moveListener = event => { if (timeDiv === null || videoLength === null) return let currentTimeString = retrieveProgressDiv.getAttribute('data-current-time') //.split(':').map(string => parseInt(string)) const progressHolder = rootProgressDiv.querySelector('.vjs-progress-holder') const xPercent = (event.pageX - progressHolder.getBoundingClientRect().left) / progressHolder.offsetWidth if (xPercent < 0 || xPercent > 1) return timeDiv.textContent = "" timeDiv.style.left = Math.round(xPercent * 10000) / 100 + "%" const targetTime = xPercent * videoLength const hour = Math.floor(targetTime) const seconds = Math.round((targetTime % 1) * 60) const formattedTime = [hour, seconds].map(value => value.toString()).map(value => value.length < 2 ? '0' + value : value).join(':') timeDiv.textContent = formattedTime } const mouseOverListener = () => { timeDiv = document.createElement('span') timeDiv.className = "scroll-time" timeDiv.style.fontSize = "2.5em" timeDiv.style.position = "absolute" timeDiv.style.bottom = "120%" timeDiv.style.left = "50%" timeDiv.style.zIndex = 100 timeDiv.style.color = "white" timeDiv.style.transform = "translate(-50%, 0%)" timeDiv.style.textShadow = "0 0 6px black" timeDiv.style.pointerEvents = "none" rootProgressDiv.querySelector('.vjs-progress-holder').appendChild(timeDiv) } const mouseOutListener = () => { if (timeDiv === null) return rootProgressDiv.querySelector('.vjs-progress-holder').removeChild(timeDiv) timeDiv = null } rootProgressDiv.addEventListener('mousemove', moveListener) rootProgressDiv.addEventListener('mouseover', mouseOverListener) rootProgressDiv.addEventListener('mouseout', mouseOutListener) return () => { rootProgressDiv.removeEventListener('mouseover', moveListener) rootProgressDiv.removeEventListener('mouseover', mouseOverListener) rootProgressDiv.removeEventListener('mouseout', mouseOutListener) } } function run() { findVideoLengthInterval = setInterval(findVideoLength, 150) document.addEventListener('mouseover', progressDivListener) } window.addEventListener('load', run) })();