Greasy Fork 支持简体中文。

YouTube Volume Mouse Controller

Control YouTube volume by mouse.

目前為 2019-01-01 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube Volume Mouse Controller
  3. // @namespace wddd
  4. // @version 1.2.0
  5. // @author wddd
  6. // @license MIT
  7. // @description Control YouTube volume by mouse.
  8. // @homepage https://github.com/wdwind/YouTubeVolumeMouseController
  9. // @match *://www.youtube.com/*
  10. // @require https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js
  11. // @run-at document-body
  12. // @noframes
  13. // ==/UserScript==
  14.  
  15. function run() {
  16. "use strict";
  17.  
  18. var player = $("video");
  19. var timer = 0;
  20.  
  21. // detect available wheel event
  22. var support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
  23. document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
  24. "DOMMouseScroll"; // let"s assume that remaining browsers are older Firefox
  25.  
  26. player.unbind(support).bind(support, function (event) {
  27. var originalEvent = event.originalEvent;
  28. var volume = player[0].volume;
  29. var volumeDelta = 0.05;
  30. var deltaY = 0;
  31.  
  32. if (support == "mousewheel") {
  33. deltaY = originalEvent.wheelDelta;
  34. } else {
  35. deltaY = originalEvent.deltaY || originalEvent.detail;
  36. }
  37.  
  38. volume += (deltaY > 0 ? -volumeDelta : volumeDelta);
  39.  
  40. if (player[0].muted) {
  41. // Unmute first
  42. $(".ytp-mute-button").click();
  43. }
  44.  
  45. player[0].volume = Math.max(0, Math.min(1, volume));
  46.  
  47. $(".ytp-volume-panel").attr("aria-valuenow", (player[0].volume * 100).toFixed(0));
  48. $(".ytp-volume-slider-handle").css({
  49. left: ((player[0].volume * 100) * 0.4) + "px"
  50. });
  51.  
  52. timer = showSlider(timer);
  53.  
  54. // Prevent the page to scroll
  55. return false;
  56. });
  57. }
  58.  
  59. function showSlider(timer) {
  60. if (timer) {
  61. clearTimeout(timer);
  62. }
  63.  
  64. var sliderBar = $("div#sliderBar");
  65. if (!sliderBar[0]) {
  66. $(".html5-video-container").append("<div id=\"sliderBar\"></div>");
  67. sliderBar = $("div#sliderBar");
  68. sliderBar.css({
  69. "width": "100%",
  70. "height": "20px",
  71. "position": "relative",
  72. "z-index": "9999",
  73. "text-align": "center",
  74. "color": "#fff",
  75. "font-size": "initial",
  76. "opacity": "0.9",
  77. "background-color": "rgba(0,0,0,0.2)",
  78. });
  79. }
  80.  
  81. sliderBar.css({
  82. "top": getSliderBarTopProp()
  83. });
  84.  
  85. sliderBar.fadeIn(100);
  86. timer = setTimeout(function () {
  87. sliderBar.fadeOut(700);
  88. }, 1000);
  89.  
  90. sliderBar.html("Volume: " + ($("video")[0].volume * 100).toFixed(0));
  91.  
  92. return timer;
  93. }
  94.  
  95. function getSliderBarTopProp() {
  96. var fullScreenTitle = $(".ytp-title");
  97. if (fullScreenTitle[0] && fullScreenTitle.is(":visible")) {
  98. return fullScreenTitle.height();
  99. }
  100.  
  101. var videoTop = $("video")[0].getBoundingClientRect().top;
  102. var headerBoundingBox = $("#masthead-positioner, #masthead-container")[0].getBoundingClientRect();
  103. var headerTop = headerBoundingBox.top;
  104. var headerHeight = headerBoundingBox.height;
  105.  
  106. var overlap = (headerHeight + headerTop > 0) ? Math.max(0, headerHeight - videoTop) : 0;
  107.  
  108. return overlap;
  109. }
  110.  
  111. /**
  112. * YouTube use Javascript to navigate between pages. So the script will not work:
  113. * 1. If the script only includes/matches the sub pages (like the video page www.youtube.com/watch?v=...)
  114. * 2. And the user navigates to the sub page from a page which is not included/matched by the script
  115. *
  116. * In the above scenario, the script will not be executed.
  117. *
  118. * To run the script in all cases,
  119. * 1. Include/match the whole YouTube host
  120. * 2. Detect Javascript events, and run the script appropriately
  121. *
  122. * Details:
  123. * * https://stackoverflow.com/questions/32275387/recall-tampermonkey-script-when-page-location-changes/32277150#32277150
  124. * * https://stackoverflow.com/questions/34077641/how-to-detect-page-navigation-on-youtube-and-modify-html-before-page-is-rendered
  125. * * https://github.com/1c7/Youtube-Auto-Subtitle-Download/blob/master/Youtube-Subtitle-Downloader/Tampermonkey.js#L122-L152
  126. */
  127.  
  128. // trigger when navigating to new material design page
  129. window.addEventListener("yt-navigate-finish", function () {
  130. if (window.location.href.includes("/watch?v=")) {
  131. run();
  132. }
  133. });
  134.  
  135. // trigger when navigating to the old page
  136. window.addEventListener("spfdone", function () {
  137. if (window.location.href.includes("/watch?v=")) {
  138. run();
  139. }
  140. });
  141.  
  142. // trigger when directly loading the page
  143. window.addEventListener("DOMContentLoaded", function () {
  144. if (window.location.href.includes("/watch?v=")) {
  145. run();
  146. }
  147. });