Better Youtube Volume

Replaces the volume slider with a version that offers more control at lower volumes

  1. // ==UserScript==
  2. // @name Better Youtube Volume
  3. // @version 1.0.4
  4. // @namespace https://fryzen.net/
  5. // @author HarbAlarm
  6. // @description Replaces the volume slider with a version that offers more control at lower volumes
  7. // @description:de Ersetzt den Lautstärkeregler durch eine Version, die mehr Kontrolle bei geringerer Lautstärke bietet
  8. // @license The Unlicense
  9. // @tag QOL
  10. // @match https://www.youtube.com/watch*
  11. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  12. // @grant unsafeWindow
  13. // @run-at document-idle
  14. // ==/UserScript==
  15.  
  16.  
  17. //let slider = '<input id="harbVol" type="range" onInput="harbVolume(event.target.value)"/>';
  18. let volSlider, volPanel, volControlHover, video
  19. let slider = document.createElement('input');
  20.  
  21. function init() {
  22. slider.id = 'harbVol';
  23. slider.type = 'range';
  24. slider.style.position = 'relative';
  25. //slider.style.top = '10px';
  26. //slider.style.right = '300px';
  27. slider.style.zIndex = '99999';
  28. slider.style.width = '80px';
  29. slider.style.marginTop = '15px';
  30. slider.oninput = function(e) { harbVolume(e.target.value) }
  31.  
  32. if (document.querySelectorAll('.ytp-volume-slider')) {
  33. volSlider = document.querySelector('.ytp-volume-slider')
  34. volSlider.style.display = 'none'
  35. }
  36.  
  37. if (document.querySelectorAll('.ytp-volume-panel')) {
  38. volPanel = document.querySelector('.ytp-volume-panel')
  39. volPanel.style.width = 'auto'
  40. //volPanel.style.overflow = 'hidden'
  41. }
  42.  
  43. if (document.querySelectorAll('.ytp-volume-control-hover')) {
  44. volControlHover = document.querySelector('.ytp-volume-control-hover')
  45. //volControlHover.style.width = 'auto'
  46. volControlHover.style.overflow = 'hidden'
  47. }
  48. update()
  49. }
  50.  
  51. function update() {
  52. document.querySelector('#title').appendChild(slider)
  53. }
  54.  
  55. function harbVolume(slider) {
  56. if (!video) { video = document.querySelector('video') }
  57. video.volume = bezier(0, 0, .25, 1, slider / 100);
  58. }
  59.  
  60. function bezier(p1, p2, p3, p4, t) {
  61. // https://javascript.info/bezier-curve
  62. return (1 - t) * (1 - t) * (1 - t) * p1 +
  63. 3 * (1 - t) * (1 - t) * t * p2 +
  64. 3 * (1 - t) * t*t * p3 + t*t*t * p4
  65. }
  66.  
  67. const mo = new MutationObserver(() => {
  68. mo.disconnect();
  69. if (!document.contains(slider)) {
  70. update()
  71. }
  72. observe();
  73. });
  74.  
  75. function observe() {
  76. mo.observe(document.body, {childList: true, subtree: true});
  77. }
  78.  
  79. (function() {
  80. document.querySelector(".ytp-volume-panel").appendChild(slider)
  81. // document.addEventListener("DOMContentLoaded", function(event){
  82. init()
  83. observe();
  84. // })
  85. })();