NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name HTML5 video time jump // @namespace html5-jump // @version 0.5 // @description hotkey duble "Ctrl" // @author raingart // @include http*://* // @run-at document-end // @license Apache-2.0 // ==/UserScript== /*jshint esversion: 6 */ // skip is not iframe //if (window.self === window.top) return; (function() { const sec_jump = 85; let video; document.addEventListener('play', captureActiveVideoElement, true); document.addEventListener('playing', registerShortcutKeys, { capture: true, once: true }); function captureActiveVideoElement(evt) { video = evt.target; } function registerShortcutKeys(evt) { /*{ label: 'alt', value: 18 }, { label: 'shift', value: 16 }, { label: 'ctrl', value: 17, selected: true },*/ doubleKeyPressListener(timeLeap.bind(video), 17); } function timeLeap() { let sec = Math.floor(sec_jump + this.currentTime); //console.debug('seekTo', sec); this.currentTime = sec; //showNotification(`${HMS_digit(sec)} (${sec_jump})`); showNotification(HMS_digit(sec)); } /* // Problems are possible if there are several video players on the page waitElement('video') .then(v => { doubleKeyPressListener(timeLeap.bind(v), 17); video = v; }); function waitElement(selector) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); }); }*/ function HMS_digit(ts = required()) { // format out "h:mm:ss" const sec = Math.abs(+ts), d = Math.floor(sec / 86400), h = Math.floor((sec % 86400) / 3600), m = Math.floor((sec % 3600) / 60), s = Math.floor(sec % 60); return (d ? `${d}d ` : '') + (h ? (d ? h.toString().padStart(2, '0') : h) + ':' : '') + (h ? m.toString().padStart(2, '0') : m) + ':' + s.toString().padStart(2, '0'); } function doubleKeyPressListener(callback, keyCodeFilter) { let pressed, isDoublePress, lastPressed = keyCodeFilter; const timeOut = () => setTimeout(() => isDoublePress = false, 500), handleDoublePresss = key => { // console.debug(key.key, 'pressed two times'); if (callback && typeof callback === 'function') return callback(key); }; function keyPress(evt) { if (['TEXTAREA', 'SELECT'].includes(evt.target.tagName) || (evt.target.tagName == 'INPUT' && ['email', 'text', 'password', 'search', 'url'].includes(evt.target.getAttribute('type'))) || evt.target.isContentEditable ) return; pressed = evt.keyCode; // console.debug('doubleKeyPressListener %s=>%s=%s', lastPressed, pressed, isDoublePress); if (isDoublePress && pressed === lastPressed) { isDoublePress = false; handleDoublePresss(evt); } else { isDoublePress = true; timeOut(); } if (!keyCodeFilter) lastPressed = pressed; } document.addEventListener('keyup', keyPress); } function showNotification(text) { if (typeof this.fate === 'number') clearTimeout(fate); this.notification = (this.notification || (function () { const el = document.createElement('div'); Object.assign(el.style, { position: 'fixed', top: '15px', left: '10px', 'z-index': 99999, 'background-color': 'rgba(0,0,0,.5)', padding: '8px 10px', 'border-radius': '3px', 'font-family': 'arial', 'font-size': '1.8em', 'font-weight': 'bold', color: '#fff', }); return document.body.appendChild(el); })()); this.notification.textContent = text; this.notification.style.opacity = 1; // this.notification.style.visibility = 'visible'; this.fate = setTimeout(() => { this.notification.style.transition = 'opacity 200ms ease-in'; this.notification.style.opacity = 0; // hud.style.visibility = 'hidden'; }, 800); //total 1s = 800ms + 200ms(hud.style.transition) } })();