Skip to content

Instantly share code, notes, and snippets.

@abec2304
Last active May 11, 2024 08:55
Show Gist options
  • Save abec2304/2782f4fc47f9d010dfaab00f25e69c8a to your computer and use it in GitHub Desktop.
Save abec2304/2782f4fc47f9d010dfaab00f25e69c8a to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name No YouTube Volume Normalization
// @namespace https://gist.github.com/abec2304
// @match https://www.youtube.com/*
// @grant none
// @version 2.1
// @author abec2304
// @description Enjoy YouTube videos at their true volume
// @inject-into content
// @run-at document-start
// @allFrames true
// ==/UserScript==
(function(recurse) {
// try in case script ran later than document-start
if(!recurse())
return;
// fallback to waiting for video element to be added
const videoObserver = new MutationObserver(function(records) {
records.forEach(function(mutation) {
Array.prototype.forEach.call(mutation.addedNodes, function(node) {
if("VIDEO" === node.tagName) {
videoObserver.disconnect();
recurse();
}
});
});
})
// begin waiting
videoObserver.observe(document.documentElement, {
subtree: true,
childList: true
});
})(function() {
// get volume bar element
const volumeElement = document.querySelector(".ytp-volume-panel");
// get video element
const videoElement = document.querySelector(".html5-main-video");
// if elements weren't found, don't continue
if(!volumeElement || !videoElement)
return 1;
// get volume set function and bind to video element
const setVolume = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, "volume").set.bind(videoElement);
// define convenience function
function ytSetVolume(widget) {
const newVolume = widget.getAttribute("aria-valuenow") / 100;
setVolume(newVolume);
}
// determine index of video element for non-sandboxed world
const globalIndex = [].slice.call(document.getElementsByTagName("video")).indexOf(videoElement);
// define function for shadowing the volume field
const volumeShadow = function(targetIndex) {
const targetVideo = document.getElementsByTagName("video")[targetIndex];
Object.defineProperty(targetVideo, "volume", {
value: 42
});
}
// inject shadowing script (this breaks the volume bar; fixed below)
const contextScript = document.createElement("script");
contextScript.id = "ytvolfix2";
contextScript.textContent = "(" + volumeShadow+ ")(" + globalIndex + ")";
contextScript.onload = function() {
// remove script after execution
this.parentElement.removeChild(this);
};
(document.head || document.documentElement).appendChild(contextScript);
// define observer for volume bar change
const volumeObserver = new MutationObserver(function(records) {
ytSetVolume(records[0].target);
});
// register observer to make volume bar function
volumeObserver.observe(volumeElement, {
attributes: true,
attributeFilter: ["aria-valuenow"]
});
// set volume to current value of bar
ytSetVolume(volumeElement);
});
@V-Coba
Copy link

V-Coba commented Mar 11, 2023

I wouldn't take the word of a person who claims that macOS supports smooth scrolling when connecting third-party mice to the Mac, and who has not provided any proof of his words.

@abec2304
Copy link
Author

Some notes:

This should go without saying but please be kind to each other.

The initial version of my script would fail in certain circumstances, as mentioned in an earlier comment. The current version should work fine and today I added a line to allow it to run under frames, i.e. embedded player instances.

The method that h264ify uses to "disable" volume normalization is reactively changing the player volume, which may cause a blip of lowered volume when YouTube attempts to engage normalization. My script instead hides volume control from YouTube's code, hence the additional code to restore the functionality of the volume bar.

My script is fairly minimal. It doesn't provide an option to disable itself, nor does it modify the text displayed under "Stats for nerds". So it's always enabled.

I believe DRC could be disabled with a userscript (or extension) - last time I saw DRC, YouTube was still returning regular audio stream URLs alongside those for DRC; it's just a matter of making the player use them. This is beyond the scope of my script.

As other commenters gathered, some YouTube videos simply have low volume and disabling normalization won't make a difference. I would like to make a script to address this, but it would be a separate script.

@LordKobra
Copy link

Thanks for the script! I was running Firefox with PulseAudio and noticed how the Volume Tab in PulseAudio always lowered to 66% when skipping through the video. Because my volume is always set to 100% and controlled by external DAC, it was quite annoying. Neither PulseAudio nor Firefox provided adequate solutions to this (e.g. blocking the control), in fac this bug is open for 5 years: https://bugzilla.mozilla.org/show_bug.cgi?id=1422637
So this script really saves the day!

@paul5917
Copy link

paul5917 commented May 29, 2023

https://gist.github.com/fa7ad/fa995474f5cb9fe91fb209686881373d
I used the script from this link and yours at the same time, and everything sounds at the right volume.
Automatically, even without pressing a button!

@V-Coba
Copy link

V-Coba commented May 29, 2023

This script alone is enough to make everything work automatically 😉

@AshleighTheCutie
Copy link

FINALLY AFTER YEARS OF SEARCHING AFTER IRIDIUM NUKED ITSELF, MY MUSIC SOUNDS GOOD AGAIN

@Eisys
Copy link

Eisys commented Oct 26, 2023

@AshleighTheCutie Check out Nova Youtube. https://github.com/raingart/Nova-YouTube-extension

It includes the function of this script and many many more things, similar to Iridium.

@antoniu200
Copy link

antoniu200 commented Nov 17, 2023

Ahoy, guys!
DRC is back! It is present on YouTube for Android as "Stable volume" and it is optional.
I am curious whether or not this is present on PC browsers and whether it is optional there as well.
Screenshot_20231117-162753_YouTube~2

EDIT 2: It seems like DRC is not present at all on music, as far as I can tell (for now):
Screenshot_20231117-171429_YouTube~2
Screenshot_20231117-171445_YouTube~2

EDIT 3: I don't see any option on PC to enable it. YouTube links also does not identify more than 2 audio streams (AAC and Opus).

@epicfacethe3rd
Copy link

this script isn't working for me, any advice on how to fix this?
thanks

@Comitant
Copy link

Comitant commented Mar 1, 2024

Is there a script out there that removes DRC? This script is no longer effective for removing normalization, at least for me since everything is DRC normalized.

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