// ==UserScript== // @name Loud media detector // @namespace extteen.github.io // @version 1.0 // @author Extteen // @description Userscript for detecting loud media, like 'G. Allows resuming and adjusting the threshold. // @match *://soyjak.st/* // @grant none // ==/UserScript== (function() { 'use strict'; if (window._LOUD_MEDIA_DETECTOR_ACTIVE_) return; window._LOUD_MEDIA_DETECTOR_ACTIVE_ = true; // i will add this to spe too so i want to prevent double detection or something const DEFAULT_THRESHOLD = 0.6; const CHECK_INTERVAL = 50; let threshold = parseFloat(localStorage.getItem("loudmedia_threshold")) || DEFAULT_THRESHOLD; const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const monitored = new WeakSet(); const allowedMedia = new WeakSet(); function saveThreshold(value) { threshold = value; localStorage.setItem("loudmedia_threshold", value); } function createOverlay(media, peak) { if (media.__algOverlay) return; const overlay = document.createElement("div"); media.__algOverlay = overlay; overlay.style.position = "absolute"; overlay.style.top = "10px"; overlay.style.left = "10px"; overlay.style.background = "#FF0000"; overlay.style.color = "white"; overlay.style.padding = "10px"; overlay.style.zIndex = 999999; overlay.style.fontSize = "14px"; overlay.innerHTML = `
Loud audio detected, media paused. Peak: ${peak.toFixed(2)} (limit: ${threshold})
`; overlay.querySelector("#resume").onclick = () => { allowedMedia.add(media); overlay.remove(); media.play(); }; overlay.querySelector("#adjust").onclick = () => { const input = prompt("Set loudness threshold (0.1 - 1.0):", threshold); if (!input) return; const value = Math.min(1, Math.max(0.1, parseFloat(input))); saveThreshold(value); alert("[Loud media detector userscript] Loud threshold set to: " + value); overlay.remove(); }; media.parentElement.style.position = "relative"; media.parentElement.appendChild(overlay); } function monitorMedia(media) { if (monitored.has(media)) return; monitored.add(media); try { const source = audioContext.createMediaElementSource(media); const analyser = audioContext.createAnalyser(); analyser.fftSize = 2048; source.connect(analyser); analyser.connect(audioContext.destination); const buffer = new Float32Array(analyser.fftSize); setInterval(() => { if (media.paused || media.muted) return; if (allowedMedia.has(media)) return; analyser.getFloatTimeDomainData(buffer); let peak = 0; for (let i = 0; i < buffer.length; i++) { const val = Math.abs(buffer[i]); if (val > peak) peak = val; } if (peak > threshold) { media.pause(); createOverlay(media, peak); } }, CHECK_INTERVAL); } catch (e) { console.warn("Audio hook failed:", e); } } function scan() { document.querySelectorAll("video, audio").forEach(monitorMedia); } new MutationObserver(scan).observe(document.body, { childList: true, subtree: true }); scan(); document.addEventListener("click", () => { audioContext.resume(); }, { once: true }); })();