您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fixes youtube video repeating when watching in playlist + refreshing page if video stopped downloading
当前为
// ==UserScript== // @name Loop Fix // @description Fixes youtube video repeating when watching in playlist + refreshing page if video stopped downloading // @version 0.1.11 // @author 0vC4 // @namespace https://greasyfork.org/users/670183 // @match *://*.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @run-at document-start // @license MIT // @grant none // ==/UserScript== (() => { function blockEvents(condition, ...events) { events = events.flat(); const tag = window.EventTarget.prototype; tag._add = tag.addEventListener; tag.addEventListener = function (name, callback, options) { if (!events.includes(name)) return tag._add.call(this, name, callback, options); function cb(e) { if (!condition.call(this)) return; callback.call(this, e); }; tag._add.call(this, name, cb, options); }; } blockEvents(function() { return !this.loop; // have loop = block events }, 'pause', 'timeupdate', 'waiting'); })(); const log = window.console.log; window.loopState = localStorage.getItem('loopState') ?? false; function clicking(e) { window.loopState = JSON.parse(this.ariaChecked); }; let created = false; let refreshing = false; let loaded = false; let oldVid = null; const maxPing = 500; const blob = new window.Blob([`setTimeout(() => postMessage(0), ${maxPing});`]); const workerScript = window.URL.createObjectURL(blob); const script = window.trustedTypes && window.trustedTypes.createPolicy ? window.trustedTypes.createPolicy('timeout', {createScriptURL: str => str}).createScriptURL(workerScript) : workerScript; window.setInterval(()=>{ const vid = window.document.querySelector('video.html5-main-video'); if (vid) { // to prevent false detecting when changing video if (vid != oldVid) { loaded = false; oldVid = vid; } if (!created) { created = true; localStorage.removeItem('loopState'); // refresh if no data for half sec const callback = () => { if (!loaded && vid.readyState === window.HTMLMediaElement.HAVE_NOTHING) { localStorage.setItem('loopState', window.loopState); window.location.href = window.location.href; } }; new window.Worker(script).onmessage = callback; } // apply loopState after .src or page refresh if (vid.loop != window.loopState) vid.loop = window.loopState; // to prevent early page refresh if (vid.readyState === window.HTMLMediaElement.HAVE_CURRENT_DATA) loaded = true; //else if (!loaded) console.log(vid.readyState); const noData = vid.readyState === window.HTMLMediaElement.HAVE_CURRENT_DATA || vid.readyState === window.HTMLMediaElement.HAVE_METADATA; let noNewData = +vid.currentTime.toFixed(0) >= +vid.buffered.end(0).toFixed(0) - 2; if (loaded && !refreshing && noData && !seeking && !vid.paused && +vid.currentTime.toFixed(0) >= +vid.buffered.end(0).toFixed(0) - 2) { localStorage.setItem('loopState', window.loopState); window.location.href = window.location.href.split('?')[0] + '?t=' + (+vid.currentTime.toFixed(0) + 1) + '&' + window.location.href.split('?')[1]; refreshing = true; } } // attach loop click detector const repeat = window.document.querySelectorAll('.ytp-menuitem[tabindex="-1"]')[0]; if (repeat && repeat.onclick != clicking) { repeat.onclick = clicking } });