您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
When playing a Facebook video, this script stores the current time (minus ten seconds) so that when the page is refreshed (be-it after reopening the browser or manual refresh) or after it gets reset due to bad internet connection, the video resumes from where it stopped.
// ==UserScript== // @description When playing a Facebook video, this script stores the current time (minus ten seconds) so that when the page is refreshed (be-it after reopening the browser or manual refresh) or after it gets reset due to bad internet connection, the video resumes from where it stopped. // @name Facebook - Video Resume // @namespace https://www.facebook.com // @include https://www.facebook.com/* // @version 3 // @grant GM.getValue // @grant GM.setValue // @grant GM.notification // @run-at document-idle // ==/UserScript== const {max, floor} = Math; const interval = 2e3; var intervalId; const rewind = 10; window.eval(`const _wr = (type) => { const orig = history[type]; return function() { const rv = orig.apply(this, arguments); const e = new Event(type); e.arguments = arguments; window.dispatchEvent(e); return rv; }; }; history.pushState = _wr('pushState'), history.replaceState = _wr('replaceState'); `); String.prototype.firstMatch = function(regexp) { const match = this.match(regexp); return match && match[1]; } const isVideoPath = (location) => /\/.*\/videos(\/.*)?\/\d+/.test(location.pathname) || /v=\d+/.test(location.search); var location = window.location; const getVideoId = () => location.pathname.firstMatch(/\/.*\/videos(?:\/.*)?\/(\d+)/) || location.search.firstMatch(/v=(\d+)/); const getTimeKey = () => `${getVideoId()}fb-video`; const setTime = (time) => GM.setValue(getTimeKey(), time); const getTime = () => GM.getValue(getTimeKey()); const initialize = (video) => { console.debug(getTimeKey(), video); if (video) { getTime().then(time => { video.currentTime = time; }); intervalId = setInterval(() => { const time = max(0, floor(video.currentTime) - rewind); //console.debug(time); setTime(time); }, interval); video.addEventListener('error', (e) => { clearInterval(intervalId); setTimeout(() => initialize(video), 1e3); }); video.addEventListener('ended', (e) => { setTime(0); }); } } if (isVideoPath(location)) { initialize(document.querySelector('video')); } const pathChanged = (e) => { location = window.location; clearInterval(intervalId); } new MutationObserver(ms => { const nodes = ms.flatMap(m => Array.from(m.addedNodes)).filter(n => n.querySelector) const video = nodes.map(n => n.querySelector('video')).find(v => v); if (isVideoPath(location) && video) { console.debug(video); clearInterval(intervalId); initialize(video); } }).observe(document.body, {childList: true, subtree: true}); window.addEventListener('pushState', pathChanged); window.addEventListener('replaceState', pathChanged); window.addEventListener('popstate', pathChanged); window.addEventListener('beforeunload', (e) => clearInterval(intervalId));
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址