YouTube Split

Устанавливает сплит по времени, выводит панель управления в clarify-box и, при достижении порога, показывает оверлей "СПЛИТ НЕ ОПЛАЧЕН" с кнопкой продления (+ 1 минута)

当前为 2025-02-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube Split
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @author ChatGPT
  6. // @match *://www.youtube.com/watch*
  7. // @grant none
  8. // @description Устанавливает сплит по времени, выводит панель управления в clarify-box и, при достижении порога, показывает оверлей "СПЛИТ НЕ ОПЛАЧЕН" с кнопкой продления (+ 1 минута)
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Глобальные переменные
  15. let splitMinutes = null; // Значение сплита в минутах
  16. let video = null; // Элемент видео
  17. let overlay = null; // Элемент оверлея
  18. let splitTriggered = false; // Флаг, что сплит активирован
  19.  
  20. // Обновление отображения значения сплита в спинере
  21. function updateSplitDisplay() {
  22. const inputField = document.getElementById("split-input");
  23. if (inputField && splitMinutes !== null) {
  24. inputField.value = splitMinutes;
  25. }
  26. }
  27.  
  28. // Создание панели управления сплитом внутри элемента "clarify-box"
  29. function addControlPanel() {
  30. const clarifyBox = document.getElementById("clarify-box");
  31. if (!clarifyBox) return;
  32. if (document.getElementById("split-control-panel")) return; // панель уже существует
  33.  
  34. // Создаем контейнер панели (под тёмную тему)
  35. const panel = document.createElement("div");
  36. panel.id = "split-control-panel";
  37. panel.style.cssText = "margin-top: 10px; padding: 10px; background: #181818; border: 1px solid #373737; display: flex; align-items: center; gap: 10px; color: #fff;";
  38.  
  39. // Кнопка "НАЧАТЬ СПЛИТ"
  40. const setButton = document.createElement("button");
  41. setButton.textContent = "НАЧАТЬ СПЛИТ";
  42. setButton.style.cssText = "padding: 5px 10px; font-size: 16px; cursor: pointer; background: #303030; color: #fff; border: 1px solid #444; border-radius: 4px;";
  43. setButton.addEventListener("click", function() {
  44. const inputField = document.getElementById("split-input");
  45. const inputVal = parseInt(inputField.value, 10);
  46. if (!isNaN(inputVal) && inputVal >= 0) {
  47. splitMinutes = inputVal;
  48. video.pause(); // Останавливаем видео
  49. splitTriggered = true;
  50. showOverlay(); // Показываем оверлей
  51. } else {
  52. alert("Введите корректное число минут.");
  53. }
  54. });
  55.  
  56. // Метка "СПЛИТ (мин):"
  57. const label = document.createElement("span");
  58. label.textContent = "СПЛИТ (мин):";
  59. label.style.cssText = "font-size: 16px;";
  60.  
  61. // Кнопка уменьшения (стрелка вниз)
  62. const decrementButton = document.createElement("button");
  63. decrementButton.textContent = "↓";
  64. decrementButton.style.cssText = "padding: 5px; font-size: 16px; cursor: pointer; background: #303030; color: #fff; border: 1px solid #444; border-radius: 4px;";
  65. decrementButton.addEventListener("click", function() {
  66. const inputField = document.getElementById("split-input");
  67. let currentVal = parseInt(inputField.value, 10);
  68. if (!isNaN(currentVal) && currentVal > 0) {
  69. inputField.value = currentVal - 1;
  70. updateSplitTime();
  71. }
  72. });
  73.  
  74. // Поле ввода (spinner) для установки минут сплита
  75. const inputField = document.createElement("input");
  76. inputField.type = "number";
  77. inputField.id = "split-input";
  78. inputField.value = "0";
  79. inputField.min = "0";
  80. inputField.style.cssText = "width: 60px; text-align: center; font-size: 16px; background: #303030; color: #fff; border: 1px solid #444; border-radius: 4px;";
  81. inputField.addEventListener("change", updateSplitTime);
  82.  
  83. // Кнопка увеличения (стрелка вверх)
  84. const incrementButton = document.createElement("button");
  85. incrementButton.textContent = "↑";
  86. incrementButton.style.cssText = "padding: 5px; font-size: 16px; cursor: pointer; background: #303030; color: #fff; border: 1px solid #444; border-radius: 4px;";
  87. incrementButton.addEventListener("click", function() {
  88. const inputField = document.getElementById("split-input");
  89. let currentVal = parseInt(inputField.value, 10);
  90. if (!isNaN(currentVal)) {
  91. inputField.value = currentVal + 1;
  92. updateSplitTime();
  93. }
  94. });
  95.  
  96. // Собираем панель
  97. panel.appendChild(setButton);
  98. panel.appendChild(label);
  99. panel.appendChild(decrementButton);
  100. panel.appendChild(inputField);
  101. panel.appendChild(incrementButton);
  102.  
  103. // Вставляем панель в "clarify-box"
  104. clarifyBox.appendChild(panel);
  105. }
  106.  
  107. // Обновление значения сплита при изменении в спинере
  108. function updateSplitTime() {
  109. const inputField = document.getElementById("split-input");
  110. const newVal = parseInt(inputField.value, 10);
  111. if (!isNaN(newVal)) {
  112. splitMinutes = newVal;
  113. updateSplitDisplay();
  114. // Если видео остановлено из-за сплита и текущее время стало меньше нового порога,
  115. // убираем оверлей и продолжаем воспроизведение
  116. if (video && splitTriggered && video.currentTime < splitMinutes * 60) {
  117. video.play();
  118. splitTriggered = false;
  119. removeOverlay();
  120. }
  121. }
  122. }
  123.  
  124. // Проверка времени видео – если текущее время достигло или превысило порог, останавливаем видео и показываем оверлей
  125. function checkSplitCondition() {
  126. if (!video || splitMinutes === null) return;
  127. const thresholdSeconds = splitMinutes * 60;
  128. if (video.currentTime >= thresholdSeconds && !splitTriggered) {
  129. video.pause();
  130. splitTriggered = true;
  131. showOverlay();
  132. }
  133. // Если сплит активирован, но пользователь увеличил его и текущее время стало меньше порога,
  134. // возобновляем воспроизведение
  135. if (splitTriggered && video.currentTime < thresholdSeconds) {
  136. video.play();
  137. splitTriggered = false;
  138. removeOverlay();
  139. }
  140. }
  141.  
  142. // Функция показа полноэкранного оверлея с надписями
  143. function showOverlay() {
  144. if (overlay) return;
  145. overlay = document.createElement("div");
  146. overlay.style.cssText = `
  147. position: fixed;
  148. top: 0;
  149. left: 0;
  150. width: 100%;
  151. height: 100%;
  152. background: rgba(0, 0, 0, 0.95);
  153. color: white;
  154. display: flex;
  155. flex-direction: column;
  156. justify-content: center;
  157. align-items: center;
  158. z-index: 99999;
  159. `;
  160.  
  161. // Надпись с предупреждением
  162. const warningMessage = document.createElement("div");
  163. warningMessage.textContent = "⚠️ НУЖНО ДОНАТНОЕ ТОПЛИВО ⚠️";
  164. warningMessage.style.cssText = "font-size: 48px; margin-bottom: 20px;";
  165.  
  166. // Надпись "СПЛИТ НЕ ОПЛАЧЕН"
  167. const splitMessage = document.createElement("div");
  168. splitMessage.textContent = "СПЛИТ НЕ ОПЛАЧЕН";
  169. splitMessage.style.cssText = "font-size: 64px; font-weight: bold; margin-bottom: 30px;";
  170.  
  171. // Кнопка для продления сплита (увеличение на 1 минуту)
  172. const extendButton = document.createElement("button");
  173. extendButton.textContent = "+ 1 минута - 300 рублей";
  174. extendButton.style.cssText = "padding: 10px 20px; font-size: 24px; cursor: pointer; background: #ff4500; border: none; color: white; border-radius: 4px;";
  175. extendButton.addEventListener("click", function() {
  176. extendSplit();
  177. });
  178.  
  179. // Собираем оверлей
  180. overlay.appendChild(warningMessage);
  181. overlay.appendChild(splitMessage);
  182. overlay.appendChild(extendButton);
  183.  
  184. document.body.appendChild(overlay);
  185. }
  186.  
  187. // Удаление оверлея
  188. function removeOverlay() {
  189. if (overlay) {
  190. overlay.remove();
  191. overlay = null;
  192. }
  193. }
  194.  
  195. // Продление сплита – увеличение на 1 минуту
  196. function extendSplit() {
  197. if (splitMinutes === null) return;
  198. splitMinutes += 1;
  199. updateSplitDisplay();
  200. // Если текущее время стало меньше нового порога, убираем оверлей и продолжаем воспроизведение
  201. if (video.currentTime < splitMinutes * 60) {
  202. removeOverlay();
  203. video.play();
  204. splitTriggered = false;
  205. } else {
  206. alert("Продление недостаточно для продолжения воспроизведения. Продлите сплит ещё раз.");
  207. }
  208. }
  209.  
  210. // Инициализация скрипта
  211. function init() {
  212. video = document.querySelector("video");
  213. if (!video) return;
  214. addControlPanel();
  215. setInterval(checkSplitCondition, 500);
  216. }
  217.  
  218. // Ждем загрузки страницы
  219. setTimeout(init, 3000);
  220. setInterval(addControlPanel, 2000);
  221. })();