Use the mouse wheel to adjust the volume. Middle-click to mute or unmute the player. Volume slider always visible.
- // ==UserScript==
- // @name Kick Volume Wheel Control
- // @namespace https://github.com/pabli24
- // @version 1.0.2
- // @description Use the mouse wheel to adjust the volume. Middle-click to mute or unmute the player. Volume slider always visible.
- // @author Pabli
- // @license MIT
- // @match https://kick.com/*
- // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgdmlld0JveD0iMCAwIDc1IDc1Ij4NCjxwYXRoIGQ9Ik0zOS4zODksMTMuNzY5IEwyMi4yMzUsMjguNjA2IEw2LDI4LjYwNiBMNiw0Ny42OTkgTDIxLjk4OSw0Ny42OTkgTDM5LjM4OSw2Mi43NSBMMzkuMzg5LDEzLjc2OXoiIHN0eWxlPSJzdHJva2U6IzUzZmMxODtzdHJva2Utd2lkdGg6NTtzdHJva2UtbGluZWpvaW46cm91bmQ7ZmlsbDojNTNmYzE4OyIvPg0KPHBhdGggZD0iTTQ4LDI3LjZhMTkuNSwxOS41IDAgMCAxIDAsMjEuNE01NS4xLDIwLjVhMzAsMzAgMCAwIDEgMCwzNS42TTYxLjYsMTRhMzguOCwzOC44IDAgMCAxIDAsNDguNiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzUzZmMxODtzdHJva2Utd2lkdGg6NTtzdHJva2UtbGluZWNhcDpyb3VuZCIvPg0KPC9zdmc+
- // @grant none
- // ==/UserScript==
- (function() {
- "use strict";
- const CONFIG = {
- VOLUME_STEP: 1,
- SHOW_CONTROLS_ON_SCROLL: true,
- SLIDER_ALWAYS_VISIBLE: true,
- HIDE_CURSOR_DELAY: 4000
- };
- function setCookie(name, value, days) {
- const date = new Date();
- date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
- document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/`;
- }
- function prevent(e) {
- e.preventDefault();
- e.stopPropagation();
- e.stopImmediatePropagation();
- }
- const observer = new MutationObserver(mutations => {
- const video = document.getElementById("video-player");
- if (!video) return;
- wheel(video);
- });
- observer.observe(document.body, { childList: true, subtree: true });
- function wheel(video) {
- const videoDiv = document.querySelector("#injected-embedded-channel-player-video > div");
- if (videoDiv.hasAttribute("kpvolume")) return;
- videoDiv.setAttribute("kpvolume", "");
- videoDiv.addEventListener("wheel", (event) => {
- prevent(event);
- if (CONFIG.SHOW_CONTROLS_ON_SCROLL === true) {
- const showEvent = new Event('mousemove');
- videoDiv.dispatchEvent(showEvent);
- }
- if (video.muted && videoDiv.getAttribute("kpvolume")) {
- video.muted = false;
- setTimeout(() => {
- video.volume = videoDiv.getAttribute("kpvolume");
- slider();
- }, 50)
- } else if (event.deltaY < 0) {
- video.volume = Math.min(1, video.volume + (CONFIG.VOLUME_STEP / 100)); // Increase volume
- } else if (event.deltaY > 0) {
- video.volume = Math.max(0, video.volume - (CONFIG.VOLUME_STEP / 100)); // Decrease volume
- }
- setTimeout(slider, 50);
- setTimeout(() => setCookie("volume", video.volume, 365), 3000);
- });
- let hideCursorTimeout;
- videoDiv.addEventListener("mousemove", (event) => {
- setTimeout(() => {
- muteBtn();
- slider();
- }, 50)
- setTimeout(() => setCookie("volume", video.volume, 365), 3000);
- if (videoDiv.contains(event.target)) {
- videoDiv.style.cursor = 'default';
- if (hideCursorTimeout) clearTimeout(hideCursorTimeout);
- hideCursorTimeout = setTimeout(() => {
- videoDiv.style.cursor = 'none';
- }, CONFIG.HIDE_CURSOR_DELAY);
- }
- });
- videoDiv.addEventListener("mouseenter", (event) => {
- setTimeout(() => setCookie("volume", video.volume, 365), 100);
- });
- function slider() {
- const controls = videoDiv.querySelector('div > div.z-controls');
- if (!controls) return;
- const sliderFill = controls.querySelector('span[style*="right:"]'); // style="left: 0%; right: 40%;"
- const videoVolume = Math.round(video.volume * 100);
- sliderFill.style.right = `${100 - videoVolume}%`;
- const sliderThumb = controls.querySelector('span[style*="transform: var(--radix-slider-thumb-transform)"]'); // left: calc(40% + 1.6px);
- const offset = 8 + (videoVolume / 100) * -16;
- sliderThumb.style.left = `calc(${videoVolume}% + ${offset}px)`;
- const sliderValuenow = controls.querySelector('span[aria-valuenow]'); // aria-valuenow="40"
- sliderValuenow.setAttribute("aria-valuenow", videoVolume);
- const sliderP = controls.querySelector('.group\\/volume .betterhover\\:group-hover\\/volume\\:flex');
- sliderP.setAttribute("playervolume", videoVolume + "%");
- }
- function muteBtn() {
- const muteButton = document.querySelector('#injected-embedded-channel-player-video > div > div.z-controls .group\\/volume > button');
- if (!muteButton) return;
- muteButton.addEventListener("click", (event) => {
- prevent(event);
- mute();
- });
- }
- function mute() {
- if (video.muted) {
- video.muted = false;
- setTimeout(() => {
- video.volume = videoDiv.getAttribute("kpvolume");
- slider();
- }, 50)
- } else {
- videoDiv.setAttribute("kpvolume", video.volume);
- video.muted = true;
- }
- }
- videoDiv.addEventListener("mousedown", ({ button }) => {
- if (event.button === 1) {
- prevent(event);
- mute();
- }
- });
- document.addEventListener("keydown", (event) => {
- if ((event.key === 'M' || event.key === 'm') && event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA' && event.target.isContentEditable !== true) {
- prevent(event);
- mute();
- }
- });
- }
- let styles = `
- #injected-embedded-channel-player-video > div > div.z-controls .group\\/volume .betterhover\\:group-hover\\/volume\\:flex::after {
- content: attr(playervolume);
- font-weight: 600;
- font-size: .875rem;
- line-height: 1.25rem;
- margin-left: .5rem;
- width: 4ch;
- }`
- if (CONFIG.SLIDER_ALWAYS_VISIBLE === true) {
- styles += `
- #injected-embedded-channel-player-video > div > div.z-controls .group\\/volume .betterhover\\:group-hover\\/volume\\:flex {
- display: flex;
- align-items: center;
- }`
- }
- const styleSheet = document.createElement("style");
- styleSheet.textContent = styles;
- document.head.appendChild(styleSheet);
- })();