YouTube touch skip with two fingers

Youtube skip video in seconds by using two fingers

  1. // ==UserScript==
  2. // @name YouTube touch skip with two fingers
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Youtube skip video in seconds by using two fingers
  6. // @author Brunkage
  7. // @match https://www.youtube.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. if (window===window.top) {
  15. waitForSelector("ytd-player", (container) => {
  16.  
  17. var started = false;
  18. var startPos = null;
  19. var displayEle = null;
  20. var stepsPrPx = 20;
  21. var moved = 0;
  22.  
  23. container.addEventListener("touchstart", (evt) => {
  24. var fingerAmount = evt.touches.length;
  25.  
  26. if (!started && fingerAmount === 2) {
  27. started = true;
  28. startPos = getTouchMin(evt.touches);
  29. moved = movedInSecs(evt.touches);
  30. preventAndStop(evt);
  31. addDisplay(container);
  32. updateDisplay(getTouchAvg(evt.touches), moved);
  33. }
  34. });
  35.  
  36. document.body.addEventListener("touchmove", (evt) => {
  37. if (started) {
  38. preventAndStop(evt);
  39. moved = movedInSecs(evt.touches);
  40. updateDisplay(getTouchAvg(evt.touches), moved);
  41. }
  42. });
  43.  
  44. document.body.addEventListener("touchend", (evt) => {
  45. var fingerAmount = evt.touches.length;
  46.  
  47. if (started && fingerAmount === 0) {
  48. getYTPlayer((player) => {
  49. player.seekBy(moved);
  50. });
  51. removeDisplay();
  52. started = false;
  53. startPos = null;
  54. preventAndStop(evt);
  55. }
  56. });
  57.  
  58. function movedInSecs(touches) {
  59. return Math.floor(getMoved(getTouchMin(touches)).x / stepsPrPx);
  60. }
  61.  
  62. function getMoved(endPos) {
  63. return {
  64. x: endPos.x - startPos.x,
  65. y: endPos.y - startPos.y
  66. }
  67. }
  68.  
  69. function getTouchMin(touches) {
  70. var min = {
  71. x: Infinity,
  72. y: Infinity
  73. }
  74.  
  75. for (let touch of touches) {
  76. if (min.x > touch.pageX) {
  77. min.x = Math.floor(touch.pageX);
  78. }
  79. if (min.y > touch.pageY) {
  80. min.y = Math.floor(touch.pageY);
  81. }
  82. }
  83.  
  84. return min;
  85. }
  86.  
  87. function getTouchAvg(touches) {
  88. var avg = {
  89. x: 0,
  90. y: 0
  91. }
  92.  
  93. for (let touch of touches) {
  94. avg.x += touch.pageX;
  95. avg.y += touch.pageY;
  96. }
  97.  
  98. avg.x = avg.x / touches.length;
  99. avg.y = avg.y / touches.length;
  100.  
  101. return avg;
  102. }
  103.  
  104. function preventAndStop(evt) {
  105. if (evt.preventDefault) {
  106. evt.preventDefault();
  107. }
  108.  
  109. if (evt.stopPropagation) {
  110. evt.stopPropagation();
  111. }
  112. }
  113.  
  114. function removeDisplay() {
  115. document.body.removeChild(displayEle);
  116. }
  117.  
  118. function updateDisplay(coords, seekTo) {
  119. displayEle.style.top = coords.y + "px";
  120. displayEle.style.left = coords.x + "px";
  121. displayEle.getElementsByTagName("skip-display-seek-to")[0].innerText = seekTo + "s";
  122. }
  123.  
  124. function addDisplay() {
  125. displayEle = document.createElement("skip-display");
  126. displayEle.style.transform = "translate(-120%, -120%)";
  127. displayEle.style.display = "block";
  128. displayEle.style.pointerEvents = "none";
  129. displayEle.style.position = "fixed"
  130. displayEle.style.width = "100px";
  131. displayEle.style.height = "100px";
  132.  
  133. var bg = document.createElement("skip-display-bg");
  134. bg.style.width = "100%";
  135. bg.style.position = "absolute";
  136. bg.style.left = "0";
  137. bg.style.height = "100%";
  138. bg.style.display = "block";
  139. bg.style.background = "black";
  140. bg.style.borderRadius = "50%";
  141. bg.style.filter = "blur(42px)";
  142.  
  143. var seekTo = document.createElement("skip-display-seek-to");
  144. seekTo.style.transform = "translateY(-50%)";
  145. seekTo.style.textAlign = "center";
  146. seekTo.style.display = "block";
  147. seekTo.style.position = "absolute";
  148. seekTo.style.width = "100%";
  149. seekTo.style.top = "50%";
  150. seekTo.style.fontSize = "42px";
  151. seekTo.style.color = "white"
  152.  
  153. displayEle.appendChild(bg);
  154. displayEle.appendChild(seekTo);
  155. document.body.appendChild(displayEle);
  156. }
  157. });
  158. }
  159.  
  160.  
  161. function waitForSelector(selector, onPresent) {
  162. var result = document.querySelector(selector);
  163. if (result) {
  164. onPresent(result);
  165. }
  166. else {
  167. setTimeout(() => {
  168. waitForSelector(selector, onPresent);
  169. }, 80);
  170. }
  171. }
  172.  
  173. function getYTPlayer(onDone) {
  174. document.querySelector("ytd-player").getPlayerPromise().then(function(player) { onDone(player) });
  175. }
  176. })();

QingJ © 2025

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