视频5minutes回顾提醒(跨平台版Bilibili➕Youtube)

每5分钟暂停视频并提醒回顾内容(支持B站和YouTube)

  1. // ==UserScript==
  2. // @name 视频5minutes回顾提醒(跨平台版Bilibili➕Youtube)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description 每5分钟暂停视频并提醒回顾内容(支持B站和YouTube)
  6. // @author Zane
  7. // @match https://www.bilibili.com/video/*
  8. // @match https://www.youtube.com/watch*
  9. // @grant GM_addStyle
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // 样式定义(合并保留公共样式)
  17. GM_addStyle(`
  18. .review-reminder {
  19. position: fixed;
  20. top: 50%;
  21. left: 50%;
  22. transform: translate(-50%, -50%);
  23. background: rgba(0, 0, 0, 0.8);
  24. color: white;
  25. padding: 20px;
  26. border-radius: 8px;
  27. z-index: 9999;
  28. text-align: center;
  29. display: none;
  30. opacity: 1;
  31. transition: opacity 0.5s ease-out;
  32. }
  33. .review-reminder.fade-out {
  34. opacity: 0;
  35. }
  36. .review-reminder h3 {
  37. color: white;
  38. margin-bottom: 10px;
  39. }
  40. .reminder-toggle {
  41. position: fixed;
  42. bottom: 20px;
  43. right: 20px;
  44. z-index: 9999;
  45. padding: 10px;
  46. background: rgba(0, 0, 0, 0.7);
  47. color: white;
  48. border: none;
  49. border-radius: 4px;
  50. cursor: pointer;
  51. }
  52. `);
  53.  
  54. // 创建提醒UI(安全方式)
  55. const reminderDiv = document.createElement('div');
  56. reminderDiv.className = 'review-reminder';
  57. const h3 = document.createElement('h3');
  58. h3.textContent = '已观看5分钟';
  59. const p1 = document.createElement('p');
  60. p1.textContent = '请回顾一下刚才学习的内容';
  61. const p2 = document.createElement('p');
  62. p2.className = 'hint';
  63. p2.textContent = '(按空格继续播放)';
  64. reminderDiv.appendChild(h3);
  65. reminderDiv.appendChild(p1);
  66. reminderDiv.appendChild(p2);
  67.  
  68. // 创建开关按钮
  69. const toggleButton = document.createElement('button');
  70. toggleButton.className = 'reminder-toggle';
  71. toggleButton.textContent = '提醒: 开启';
  72. toggleButton.onclick = toggleReminder;
  73.  
  74. let isReminderEnabled = true;
  75. let timer = null;
  76. let videoElement = null;
  77.  
  78. // 平台配置
  79. const platformConfig = {
  80. 'bilibili': {
  81. playerContainerSelector: '.bpx-player-video-perch',
  82. videoSelector: '.bpx-player-video-wrap video'
  83. },
  84. 'youtube': {
  85. playerContainerSelector: '#movie_player',
  86. videoSelector: '#movie_player video'
  87. }
  88. };
  89.  
  90. // 初始化函数(整合两个版本)
  91. function init() {
  92. const currentPlatform = window.location.hostname.includes('bilibili') ? 'bilibili' : 'youtube';
  93. const config = platformConfig[currentPlatform];
  94.  
  95. // 查找元素
  96. const playerContainer = document.querySelector(config.playerContainerSelector);
  97. videoElement = document.querySelector(config.videoSelector);
  98.  
  99. if (playerContainer && videoElement) {
  100. // 注入元素
  101. playerContainer.appendChild(reminderDiv);
  102. document.body.appendChild(toggleButton);
  103.  
  104. // 启动功能
  105. startTimer();
  106. setupVideoListeners();
  107.  
  108. // YouTube需要监听URL变化
  109. if (currentPlatform === 'youtube') {
  110. watchPageChanges();
  111. }
  112. } else {
  113. setTimeout(init, 1000);
  114. }
  115. }
  116.  
  117. // 视频事件监听(公共逻辑)
  118. function setupVideoListeners() {
  119. videoElement.addEventListener('play', () => {
  120. if (!timer) startTimer();
  121. });
  122. videoElement.addEventListener('pause', stopTimer);
  123. }
  124.  
  125. // 计时器逻辑(公共)
  126. function startTimer() {
  127. if (!isReminderEnabled || timer) return;
  128. timer = setTimeout(showReminder, 5 * 60 * 1000); // 改为5分钟
  129. // timer = setTimeout(showReminder, 5 * 1000); // 测试
  130. }
  131.  
  132. function stopTimer() {
  133. if (timer) {
  134. clearTimeout(timer);
  135. timer = null;
  136. }
  137. }
  138.  
  139. // 显示提醒(公共)
  140. function showReminder() {
  141. if (!isReminderEnabled) return;
  142. videoElement.pause();
  143. reminderDiv.style.display = 'block';
  144. reminderDiv.classList.remove('fade-out');
  145. }
  146.  
  147. // 键盘事件(公共)
  148. document.addEventListener('keydown', function(event) {
  149. if (event.code === 'Space' && reminderDiv.style.display === 'block') {
  150. event.preventDefault();
  151. reminderDiv.classList.add('fade-out');
  152. setTimeout(() => {
  153. reminderDiv.style.display = 'none';
  154. reminderDiv.classList.remove('fade-out');
  155. videoElement.play();
  156. startTimer();
  157. }, 500);
  158. }
  159. });
  160.  
  161. // 开关功能(公共)
  162. function toggleReminder() {
  163. isReminderEnabled = !isReminderEnabled;
  164. toggleButton.textContent = `提醒: ${isReminderEnabled ? '开启' : '关闭'}`;
  165. isReminderEnabled ? (videoElement.paused || startTimer()) : stopTimer();
  166. }
  167.  
  168. // YouTube URL变化监听(仅YouTube需要)
  169. function watchPageChanges() {
  170. let lastUrl = location.href;
  171. new MutationObserver(() => {
  172. if (location.href !== lastUrl) {
  173. lastUrl = location.href;
  174. init();
  175. }
  176. }).observe(document, {subtree: true, childList: true});
  177. }
  178.  
  179. // 启动脚本
  180. if (document.readyState === 'loading') {
  181. document.addEventListener('DOMContentLoaded', init);
  182. } else {
  183. setTimeout(init, 1000);
  184. }
  185. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址