Skip to content

Instantly share code, notes, and snippets.

@WouterG
Last active January 4, 2024 09:40
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save WouterG/acf1e901324aed77f466626fb5d6611f to your computer and use it in GitHub Desktop.
Save WouterG/acf1e901324aed77f466626fb5d6611f to your computer and use it in GitHub Desktop.
Disable youtube volume normalization (allow true video 100% volume)
// ==UserScript==
// @name YouTube Disable Normalization
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Allows true 100% volume on youtube videos.
// @author Wouter Gerarts
// @match https://www.youtube.com/*
// @match https://youtube.com/*
// @grant none
// ==/UserScript==
var alwaysEnable = true;
(function() {
'use strict';
function baseElement() {
return document.querySelector('#content');
}
if (typeof fullVolumeButtonTaskId === 'number') {
console.log('clearing interval');
clearInterval(fullVolumeButtonTaskId);
}
function createFullVolumeButton() {
var el = document.createElement('button');
el.innerText = '100% Volume';
el.classList.add('full-volume-addon-button');
el.onclick = function() {
var video = baseElement().querySelector('video');
video.volume = 1;
};
return el;
}
function round (num, sig) {
var mult = Math.pow(10, sig);
return Math.round(num * mult) / mult;
}
var fullVolumeButtonTaskId = setInterval(function() {
if (baseElement().querySelector('video') === undefined) {
console.log('video element not found');
return;
}
if (baseElement().querySelector('.full-volume-addon-button') != undefined) {
console.log('full volume addon button already found');
clearInterval(fullVolumeButtonTaskId);
return;
}
var volumeSlider = baseElement().querySelector('.ytp-volume-slider-handle')
if (volumeSlider === undefined || volumeSlider === null) {
console.log('volumeSlider not found');
return;
}
var video = baseElement().querySelector('video');
var volumeSliderLeftStr = volumeSlider.style.left;
var volumeSliderLeft = volumeSliderLeftStr.substr(0, volumeSliderLeftStr.length - 2);
var volumeSliderValue = parseFloat(volumeSliderLeft) * 2.5;
console.log('Checking slider ' + round(volumeSliderValue / 100, 2).toString() + ' against value ' + round(video.volume, 2).toString());
if (alwaysEnable || volumeSliderValue / 100 > video.volume) {
var videoTitleElement = baseElement().querySelector('.ytd-video-primary-info-renderer');
videoTitleElement.appendChild(createFullVolumeButton());
} else {
console.log('volume slider did not meet criteria for Full Volume button');
}
}, 500);
})();
@abec2304
Copy link

https://gist.github.com/abec2304/2782f4fc47f9d010dfaab00f25e69c8a

I am working on a different approach. Could you help test my script?

@motsog
Copy link

motsog commented Apr 26, 2020

Hi thx for this. It wars really fine, but one little question is there an option I missed I don't always have to klick on the little button to normalize the audio to 100%?

@BoxPlox
Copy link

BoxPlox commented Aug 10, 2020

guys im new to github, how to use this script ?

@RamiYahyaRY
Copy link

guys im new to github, how to use this script ?

install the tampermonkey extension then copy this script by clicking on the RAW button at the top to get the entire thing. Add the entire code to tampermonkey as a new script, hard reload youtube (or restart chrome) then you'll find the 100% volume button below the video.

@OwO-master
Copy link

how to make it auto click when page is loaded?

@Dark3n89
Copy link

Thnak you, i working on code and make him little more cool, thank you ☻ https://ibb.co/qJ3mv06

@K2erdnA
Copy link

K2erdnA commented Mar 1, 2022

Hi is there a way to make it automatic? It sucks having to press the button everytime I go to a video

@OwO-master
Copy link

OwO-master commented May 9, 2022

Hi is there a way to make it automatic? It sucks having to press the button everytime I go to a video

I make a toggle button to auto apply 100% volume.
It's not perfect but you can try it.
https://github.com/OwO-master/YouTube-Disable-Normalization-with-auto-toggle
I added GM_setValue and GM_getValue to store the toggle info, and setInterval to check if the page url is changed.

@Saxombie
Copy link

I don't think this will work with the new 'music destroying" DRC normalization style (which is not really "normalization" but plane dynamics compression).
We are doomed now.

@TheBSODAndWSODFan
Copy link

TheBSODAndWSODFan commented Sep 10, 2022

i made disable youtube loudness normalization work on new layout
image

// ==UserScript==
// @name         YouTube Disable Normalization (New Layout)
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Allows true 100% volume on youtube videos.
// @author       Wouter Gerarts
// @match        https://www.youtube.com/*
// @match        https://youtube.com/*
// @grant        none
// ==/UserScript==

var alwaysEnable = true;

(function() {
    'use strict';

    function baseElement() {
        return document.querySelector('#content');
    }

    if (typeof fullVolumeButtonTaskId === 'number') {
        console.log('clearing interval');
        clearInterval(fullVolumeButtonTaskId);
    }

    function createFullVolumeButton() {
        var el = document.createElement('button');
        el.innerText = '100% Volume';
        el.classList.add('full-volume-addon-button');
        el.onclick = function() {
            var video = baseElement().querySelector('video');
            video.volume = 1;
        };
        return el;
    }

    function round (num, sig) {
        var mult = Math.pow(10, sig);
        return Math.round(num * mult) / mult;
    }

    var fullVolumeButtonTaskId = setInterval(function() {
        if (baseElement().querySelector('video') === undefined) {
            console.log('video element not found');
            return;
        }
        if (baseElement().querySelector('.full-volume-addon-button') != undefined) {
            console.log('full volume addon button already found');
            clearInterval(fullVolumeButtonTaskId);
            return;
        }
        var volumeSlider = baseElement().querySelector('.ytp-volume-slider-handle')
        if (volumeSlider === undefined || volumeSlider === null) {
            console.log('volumeSlider not found');
            return;
        }
        var video = baseElement().querySelector('video');
        var volumeSliderLeftStr = volumeSlider.style.left;
        var volumeSliderLeft = volumeSliderLeftStr.substr(0, volumeSliderLeftStr.length - 2);
        var volumeSliderValue = parseFloat(volumeSliderLeft) * 2.5;
        console.log('Checking slider ' + round(volumeSliderValue / 100, 2).toString() + ' against value ' + round(video.volume, 2).toString());
        if (alwaysEnable || volumeSliderValue / 100 > video.volume) {
            // var videoTitleElement = baseElement().querySelector('h1.ytd-watch-metadata.style-scope');
            var videoTitleElement = baseElement().querySelector('#description');
            videoTitleElement.appendChild(createFullVolumeButton());
        } else {
            console.log('volume slider did not meet criteria for Full Volume button');
        }
    }, 500);
})();

@TheBSODAndWSODFan
Copy link

version 0.2 only work on new layout, if you still have old layout, use 0.1 version of script

@fa7ad
Copy link

fa7ad commented Dec 12, 2022

I was going to post this patch for the new UI but looks like @TheBSODAndWSODFan already made a new script. I went with a different selector, but essentially does the same thing

63c63,64
<             var videoTitleElement = baseElement().querySelector('.ytd-video-primary-info-renderer');
---
>             //var videoTitleElement = baseElement().querySelector('.ytd-video-primary-info-renderer');
>             var videoTitleElement = baseElement().querySelector('#title');

@tigre7575
Copy link

None of these are working for me any more and I'm seeing the message "volumeSlider not found" in the console log. Could someone help me out. Thanks

@fa7ad
Copy link

fa7ad commented May 23, 2023

@tigre7575 my version of the script still seems to work, you can give that a try and see if it works for you.

My fork: https://gist.github.com/fa7ad/fa995474f5cb9fe91fb209686881373d

@tigre7575
Copy link

@fa7ad Thanks for the reply. After testing out your version I figured out that this seems to be an issue with Firefox and Youtube most likely, as these scripts still work in Chrome but not in Firefox.

@fa7ad
Copy link

fa7ad commented May 23, 2023

Weird, I'm on Firefox as well. Maybe its the extension you are using to run userscripts? I'm using Violentmonkey, might be worth a shot if you still want to use Firefox

@tigre7575
Copy link

Thanks for sharing that. I created a new blank profile and it works, so my FF profile is just broken which I've seen before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment