Skip to content

Instantly share code, notes, and snippets.

@netux
Last active July 17, 2023 21:48
Show Gist options
  • Save netux/52f9df29aee6723b6e437ef4be319dc6 to your computer and use it in GitHub Desktop.
Save netux/52f9df29aee6723b6e437ef4be319dc6 to your computer and use it in GitHub Desktop.
BandCamp Volume Slider - because BandCamp is not a real site without this
// ==UserScript==
// @name BandCamp volume slider
// @namespace netux.site:bandcamp-volume.slider
// @version 1.1
// @description Add an always visible volume slider to BandCamp
// @author You
// @match https://*.bandcamp.com/**
// @icon https://www.google.com/s2/favicons?sz=64&domain=bandcamp.com
// @grant none
// ==/UserScript==
const audioEls = document.getElementsByTagName("audio");
const styleEl = document.createElement("style");
styleEl.id = "bandcamp-volume-slider-styles";
styleEl.textContent = `
#bandcamp-volume-slider {
position: fixed;
bottom: 1rem;
right: 1rem;
width: 2rem;
z-index: 999999;
opacity: 0.5;
transition opacity 100ms linear;
display: flex;
flex-direction: column;
color: white;
text-shadow: 0 0 1px black;
align-items: center;
}
#bandcamp-volume-slider:hover {
opacity: 1;
}
#bandcamp-volume-slider input[type="range"] {
width: 100%;
appearance: slider-vertical;
writing-mode: bt-lr;
}
`;
document.head.appendChild(styleEl);
const sliderContainerEl = document.createElement("div");
sliderContainerEl.id = 'bandcamp-volume-slider';
document.body.appendChild(sliderContainerEl);
const sliderVolumeIconEl = document.createElement("span")
sliderVolumeIconEl.innerText = "🔊";
sliderContainerEl.appendChild(sliderVolumeIconEl);
const sliderInputEl = document.createElement("input");
sliderInputEl.type = "range";
sliderInputEl.min = 0;
sliderInputEl.max = 1;
sliderInputEl.step = 0.01;
sliderInputEl.setAttribute("orient", "vertical");
sliderInputEl.value = localStorage.getItem("bandcamp-volume-slider-value") ?? 0.5;
sliderContainerEl.appendChild(sliderInputEl);
function getFormattedVolume() {
return `${(sliderInputEl.value * 100).toFixed(0)}%`;
}
const sliderVolumeValueEl = document.createElement("span");
sliderVolumeValueEl.innerText = getFormattedVolume();
sliderContainerEl.appendChild(sliderVolumeValueEl);
function perceivedVolumeFromRealVolume(vol) {
return Math.pow(vol, 2)
}
function applyVolume() {
for (const audioEl of audioEls) {
audioEl.volume = Math.pow(parseFloat(sliderInputEl.value), 2);
}
}
sliderInputEl.addEventListener("input", () => {
applyVolume();
sliderInputEl.title = getFormattedVolume();
sliderVolumeValueEl.innerText = getFormattedVolume();
localStorage.setItem("bandcamp-volume-slider-value", Math.min(parseFloat(sliderInputEl.value), 0.75).toString());
});
setInterval(applyVolume, 100);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment