Twitch: Twitch Volume Control

Changes the volume of the Twitch player with the mouse wheel and shows the percentage of volume on the screen when the cursor hovers over the video.

  1. // ==UserScript==
  2. // @name Twitch: Twitch Volume Control
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Changes the volume of the Twitch player with the mouse wheel and shows the percentage of volume on the screen when the cursor hovers over the video.
  6. // @author FerNikoMF
  7. // @match https://www.twitch.tv/*
  8. // @grant none
  9. // @license MIT
  10. // @icon https://i.postimg.cc/4xH3j145/Mediamodifier-Design-Template.png
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Function for creating and displaying an overlay with a volume percentage
  17. function showVolumeOverlay(video, volume) {
  18. let overlay = document.getElementById('volume-overlay');
  19. if (!overlay) {
  20. overlay = document.createElement('div');
  21. overlay.id = 'volume-overlay';
  22. // Styles for the overlay
  23. overlay.style.position = 'fixed';
  24. overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  25. overlay.style.color = 'white';
  26. overlay.style.padding = '5px 10px';
  27. overlay.style.borderRadius = '5px';
  28. overlay.style.fontSize = '16px';
  29. overlay.style.zIndex = 9999;
  30. overlay.style.pointerEvents = 'none';
  31. document.body.appendChild(overlay);
  32. }
  33. // Updating the text with the current volume percentage
  34. overlay.textContent = Math.round(volume * 100) + '%';
  35.  
  36. // Calculating the player's position to place the overlay in the center of the video
  37. const rect = video.getBoundingClientRect();
  38. overlay.style.left = (rect.left + rect.width / 2) + 'px';
  39. overlay.style.top = (rect.top + rect.height / 2) + 'px';
  40. overlay.style.transform = 'translate(-50%, -50%)';
  41. overlay.style.display = 'block';
  42.  
  43. // If the hiding timer is already running, clear it
  44. if (overlay.hideTimeout) {
  45. clearTimeout(overlay.hideTimeout);
  46. }
  47. // Hiding the overlay after 1 second
  48. overlay.hideTimeout = setTimeout(() => {
  49. overlay.style.display = 'none';
  50. }, 1000);
  51. }
  52.  
  53. // Function for setting a handler for the wheel event
  54. function addVolumeWheelControl(video) {
  55. if (!video) return;
  56.  
  57. video.addEventListener('wheel', function(event) {
  58. // Getting the coordinates of the player
  59. const rect = video.getBoundingClientRect();
  60.  
  61. // Check that the cursor is above the video
  62. if (
  63. event.clientX < rect.left ||
  64. event.clientX > rect.right ||
  65. event.clientY < rect.top ||
  66. event.clientY > rect.bottom
  67. ) {
  68. return;
  69. }
  70.  
  71. // Canceling the standard behavior (for example, scrolling the page)
  72. event.preventDefault();
  73.  
  74. const step = 0.05; // volume change step
  75. // If the wheel is scrolled down, turn down the volume, otherwise increase
  76. if (event.deltaY > 0) {
  77. video.volume = Math.max(video.volume - step, 0);
  78. } else {
  79. video.volume = Math.min(video.volume + step, 1);
  80. }
  81. // Display the current volume as a percentage
  82. showVolumeOverlay(video, video.volume);
  83. }, { passive: false });
  84. }
  85.  
  86. // A function for searching for the <video> tag and installing a handler
  87. function init() {
  88. const video = document.querySelector('video');
  89. if (video) {
  90. addVolumeWheelControl(video);
  91. }
  92. }
  93.  
  94. // Initialize immediately, and also monitor changes in the DOM (for example, when loading the player dynamically)
  95. init();
  96.  
  97. // An observer for tracking the addition of new elements (for example, when changing the channel)
  98. const observer = new MutationObserver(() => {
  99. const video = document.querySelector('video');
  100. if (video) {
  101. addVolumeWheelControl(video);
  102. }
  103. });
  104.  
  105. observer.observe(document.body, { childList: true, subtree: true });
  106. })();