您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Перемотка видео стрелками и восстановление по автору и времени
// ==UserScript== // @name Telegram Web — перемотка + сохранение прогресса видео // @version 1.0 // @description Перемотка видео стрелками и восстановление по автору и времени // @match https://web.telegram.org/* // @grant none // @namespace https://greasyfork.org/users/789838 // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'tg_video_progress'; const loadProgress = () => JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}'); const saveProgress = obj => localStorage.setItem(STORAGE_KEY, JSON.stringify(obj)); const isVisible = el => el.offsetParent !== null && el.offsetWidth > 0 && el.offsetHeight > 0 && window.getComputedStyle(el).visibility !== 'hidden'; // Обработчик стрелок document.addEventListener('keydown', e => { if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') { const videos = Array.from(document.querySelectorAll('video')).filter(isVisible); if (videos.length) { const v = videos[0]; v.currentTime += (e.key === 'ArrowRight' ? 5 : -5); e.stopPropagation(); e.preventDefault(); } } }, true); // Слежение за media-viewer const observer = new MutationObserver(() => { const nameEl = document.querySelector('.media-viewer-name .peer-title'); const dateEl = document.querySelector('.media-viewer-date'); const video = document.querySelector('video'); if (!nameEl || !dateEl || !video) return; const name = nameEl.textContent.trim(); const date = dateEl.textContent.trim(); const key = `${name} @ ${date}`; const store = loadProgress(); if (store[key] && !video.dataset.restored) { video.currentTime = store[key]; video.dataset.restored = '1'; } if (!video.dataset.listened) { video.dataset.listened = '1'; setInterval(() => { if (!video.paused && !video.ended) { store[key] = video.currentTime; saveProgress(store); } }, 2000); } }); observer.observe(document.body, { childList: true, subtree: true }); })();