Youtube Scroll Volume

Use the scroll wheel to adjust volume of youtube videos

目前為 2020-05-08 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Youtube Scroll Volume
  3. // @namespace https://greasyfork.org/users/649
  4. // @version 1.1.9
  5. // @description Use the scroll wheel to adjust volume of youtube videos
  6. // @author Adrien Pyke
  7. // @match *://www.youtube.com/*
  8. // @grant GM_addStyle
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_registerMenuCommand
  12. // @require https://gitcdn.link/repo/kufii/My-UserScripts/fa4555701cf5a22eae44f06d9848df6966788fa8/libs/gm_config.js
  13. // @require https://gitcdn.link/repo/fuzetsu/userscripts/b38eabf72c20fa3cf7da84ecd2cefe0d4a2116be/wait-for-elements/wait-for-elements.js
  14. // @require https://gitcdn.link/repo/kufii/quick-query.js/2993f91ae90f3b2aff4af7e9ce0b08504f5c8060/dist/window/qq.js
  15. // ==/UserScript==
  16.  
  17. (() => {
  18. 'use strict';
  19.  
  20. const { q } = window.QuickQuery;
  21.  
  22. const Util = {
  23. bound: (num, min, max) => Math.max(Math.min(num, max), min)
  24. };
  25.  
  26. const Config = GM_config([
  27. { key: 'reverse', label: 'Reverse Scroll', default: false, type: 'bool' },
  28. { key: 'horizontal', label: 'Use Horizontal Scroll', default: false, type: 'bool' },
  29. { key: 'step', label: 'Change By', default: 5, type: 'number', min: 1, max: 100 },
  30. { key: 'hud', label: 'Display HUD', default: true, type: 'bool' },
  31. {
  32. key: 'requireShift',
  33. label: 'Only handle scroll if holding "Shift" key',
  34. default: false,
  35. type: 'bool'
  36. }
  37. ]);
  38. GM_registerMenuCommand('Youtube Scroll Volume Settings', Config.setup);
  39.  
  40. let config = Config.load();
  41. Config.onsave = (newConf) => (config = newConf);
  42.  
  43. GM_addStyle(/* css */ `
  44. .YSV_hud {
  45. display: flex;
  46. flex-direction: column;
  47. justify-content: flex-end;
  48. align-items: center;
  49. position: absolute;
  50. top: 0;
  51. bottom: 0;
  52. left: 0;
  53. right: 0;
  54. opacity: 0;
  55. transition: opacity 500ms ease 0s;
  56. z-index: 10;
  57. pointer-events: none;
  58. }
  59. .YSV_bar {
  60. background-color: #444;
  61. border: 2px solid white;
  62. width: 80%;
  63. max-width: 600px;
  64. margin-bottom: 10%;
  65. }
  66. .YSV_progress {
  67. transition: width 100ms ease-out 0s;
  68. background-color: #888;
  69. height: 20px;
  70. }
  71. `);
  72.  
  73. const createHud = () => {
  74. const hud = document.createElement('div');
  75. hud.classList.add('YSV_hud');
  76. hud.innerHTML = '<div class="YSV_bar"><div class="YSV_progress"></div></div>';
  77. return hud;
  78. };
  79.  
  80. waitForElems({
  81. sel: 'ytd-player',
  82. onmatch(node) {
  83. let id;
  84.  
  85. const hud = createHud();
  86. const progress = q(hud).q('.YSV_progress');
  87. node.appendChild(hud);
  88.  
  89. const showHud = (volume) => {
  90. clearTimeout(id);
  91. progress.style.width = `${volume}%`;
  92. hud.style.opacity = 1;
  93. id = setTimeout(() => (hud.style.opacity = 0), 800);
  94. };
  95.  
  96. node.onwheel = (e) => {
  97. if (config.requireShift && !e.shiftKey) return;
  98. const player = node.getPlayer();
  99. const dir =
  100. ((config.horizontal ? -e.deltaX : e.deltaY) > 0 ? -1 : 1) * (config.reverse ? -1 : 1);
  101.  
  102. const vol = Util.bound(player.getVolume() + config.step * dir, 0, 100);
  103. if (vol > 0 && player.isMuted()) player.unMute();
  104. player.setVolume(vol);
  105. if (config.hud) showHud(vol);
  106.  
  107. e.preventDefault();
  108. e.stopImmediatePropagation();
  109. };
  110. }
  111. });
  112. })();