Professional Audio Enhancer: Dolby Atmos, 3D Surround, & Bass Boost.
// ==UserScript==
// @name 🎧 YouTube Audio Enhancer Pro V7.3
// @namespace http://tampermonkey.net/
// @version 7.3
// @description Professional Audio Enhancer: Dolby Atmos, 3D Surround, & Bass Boost.
// @author Moryata
// @match https://www.youtube.com/*
// @match https://music.youtube.com/*
// @grant none
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @license MIT
// @run-at document-end
// ==/UserScript==
(function () {
'use strict';
const STORAGE_KEY = 'yt_audio_enhancer_data_v7';
const CONFIG = {
tabHeight: 40,
snapThreshold: 50,
presets: {
dolby: { bass: 14, mid: -4, treble: 12, clarity: 9, surround: 35, volume: 130 },
cinema: { bass: 10, mid: -2, treble: 8, clarity: 7, surround: 20, volume: 120 },
hifi: { bass: 5, mid: 0, treble: 8, clarity: 4, surround: 0, volume: 100 },
bass: { bass: 18, mid: -2, treble: 4, clarity: 6, surround: 5, volume: 115 },
reset: { bass: 0, mid: 0, treble: 0, clarity: 5, surround: 0, volume: 100 }
},
defaults: {
active: true,
dockY: 150,
dockSide: 'right',
vals: { volume: 100, surround: 0, bass: 0, mid: 0, treble: 0, clarity: 5 }
}
};
function loadSettings() {
const saved = localStorage.getItem(STORAGE_KEY);
if (saved) {
try {
const parsed = JSON.parse(saved);
return {
...CONFIG.defaults,
...parsed,
vals: { ...CONFIG.defaults.vals, ...(parsed.vals || {}) }
};
} catch (e) { return CONFIG.defaults; }
}
return CONFIG.defaults;
}
const savedState = loadSettings();
const state = {
ctx: null,
source: null,
nodes: {},
active: savedState.active,
isDragging: false,
dockY: Math.max(0, Math.min(window.innerHeight - 50, savedState.dockY)),
dockSide: savedState.dockSide,
expanded: false,
videoElement: null,
vals: savedState.vals
};
function saveSettings() {
const dataToSave = {
active: state.active,
dockY: state.dockY,
dockSide: state.dockSide,
vals: state.vals
};
localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
}
// ========== UI CONSTRUCTION ==========
function createDock() {
if (document.getElementById('ae-dock')) return null;
const dock = document.createElement('div');
dock.id = 'ae-dock';
dock.className = state.dockSide;
dock.style.top = `${state.dockY}px`;
// SVG Icon Headphone
const iconSVG = `
<svg viewBox="0 0 24 24" width="22" height="22" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 18v-6a9 9 0 0 1 18 0v6"></path>
<path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path>
</svg>
`;
dock.innerHTML = `
<style>
#ae-dock {
position: fixed; z-index: 2147483647;
font-family: 'Segoe UI', sans-serif; display: flex; align-items: flex-start;
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
#ae-dock.right { right: 0; flex-direction: row; }
#ae-dock.left { left: 0; flex-direction: row-reverse; }
#ae-dock.right.hidden { transform: translateX(92%); opacity: 0.6; }
#ae-dock.left.hidden { transform: translateX(-92%); opacity: 0.6; }
#ae-dock.hidden:hover { transform: translateX(0); opacity: 1; }
/* TAB STYLING - ICON FIX */
.tab {
width: 42px; height: 42px; background: #0f0f0f; color: #fff;
display: flex; justify-content: center; align-items: center;
cursor: pointer;
box-shadow: 0 4px 15px rgba(0,0,0,0.5);
border: 1px solid #333;
z-index: 2;
transition: all 0.3s ease;
}
#ae-dock.right .tab { border-radius: 8px 0 0 8px; border-right: none; border-left: 3px solid #666; }
#ae-dock.left .tab { border-radius: 0 8px 8px 0; border-left: none; border-right: 3px solid #666; }
/* Indikator Status (Warna Icon) */
.tab svg { transition: all 0.3s; stroke: #aaa; }
.tab.connected { border-color: #00ff00; box-shadow: 0 0 15px rgba(0,255,0,0.2); }
.tab.connected svg { stroke: #00ff00; filter: drop-shadow(0 0 3px #00ff00); }
.tab.error { border-color: #ff0000; }
.tab.error svg { stroke: #ff0000; }
/* Panel */
.panel {
width: 260px; background: rgba(10, 10, 10, 0.96);
backdrop-filter: blur(12px); color: #eee;
padding: 16px; display: none;
border: 1px solid #333;
box-shadow: 0 10px 30px rgba(0,0,0,0.8);
}
#ae-dock.right .panel { border-radius: 0 0 0 12px; border-right: none; }
#ae-dock.left .panel { border-radius: 0 0 12px 0; border-left: none; }
#ae-dock.expanded .panel { display: block; }
/* Controls */
.row { display: flex; justify-content: space-between; font-size: 11px; margin-bottom: 5px; color: #bbb; font-weight: 600; }
.val-disp { color: #fff; font-family: monospace; }
input[type=range] {
width: 100%; height: 4px; background: #333; margin-bottom: 14px;
cursor: pointer; accent-color: #3ea6ff; appearance: none; border-radius: 2px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none; width: 12px; height: 12px; background: #fff; border-radius: 50%;
transition: transform 0.1s;
}
input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.3); background: #3ea6ff; }
.btn-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 10px; }
button {
background: rgba(255,255,255,0.05); color: #ccc; border: 1px solid transparent;
padding: 8px 0; border-radius: 4px; cursor: pointer;
font-size: 10px; font-weight: 700; transition: 0.2s;
}
button:hover { background: rgba(255,255,255,0.15); color: #fff; }
button[data-p="dolby"] { border-color: #00e5ff; color: #00e5ff; }
button[data-p="dolby"]:hover { background: #00e5ff; color: #000; box-shadow: 0 0 10px rgba(0,229,255,0.3); }
.header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; padding-bottom: 12px; margin-bottom: 12px; }
.toggle-switch { position: relative; width: 34px; height: 18px; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #333; transition: .3s; border-radius: 18px; }
.slider:before { position: absolute; content: ""; height: 12px; width: 12px; left: 3px; bottom: 3px; background-color: #888; transition: .3s; border-radius: 50%; }
input:checked + .slider { background-color: #3ea6ff; }
input:checked + .slider:before { transform: translateX(16px); background-color: #fff; }
</style>
<div class="tab" id="ae-tab">${iconSVG}</div>
<div class="panel">
<div class="header">
<span style="font-weight:800; font-size:13px; color:#fff;">AUDIO ENHANCER PRO</span>
<label class="toggle-switch">
<input type="checkbox" id="ae-toggle" ${state.active ? 'checked' : ''}>
<span class="slider"></span>
</label>
</div>
<div style="font-size:9px; color:#666; margin-bottom:8px; letter-spacing:0.5px;" id="ae-status">INITIALIZING ENGINE...</div>
${slider('volume', 'PRE-AMP', state.vals.volume, 0, 200, '%')}
${slider('surround', '3D SURROUND', state.vals.surround, 0, 100, '%')}
${slider('bass', 'SUB BASS', state.vals.bass, -20, 20, 'dB')}
${slider('mid', 'VOCAL', state.vals.mid, -20, 20, 'dB')}
${slider('treble', 'DETAIL', state.vals.treble, -20, 20, 'dB')}
${slider('clarity', 'ADAPTIVE COMP', state.vals.clarity, 0, 10, '')}
<div class="btn-grid">
<button data-p="dolby">DOLBY</button>
<button data-p="cinema">CINEMA</button>
<button data-p="hifi">HI-FI</button>
<button data-p="bass">BASS</button>
<button data-p="reset" style="color:#ff5555">RESET</button>
</div>
</div>
`;
document.body.appendChild(dock);
return {
dock,
tab: dock.querySelector('.tab'),
panel: dock.querySelector('.panel'),
status: document.getElementById('ae-status'),
inputs: dock.querySelectorAll('input[type=range]')
};
}
function slider(id, label, val, min, max, unit) {
return `<div class="row"><span>${label}</span><span id="val-${id}" class="val-disp">${val}</span></div>
<input type="range" id="sl-${id}" min="${min}" max="${max}" value="${val}">`;
}
// ========== INTERACTION ==========
function initInteraction(ui) {
let startX, startY, startTop;
let isDown = false;
let hasMoved = false;
ui.tab.addEventListener('pointerdown', (e) => {
e.preventDefault();
isDown = true;
hasMoved = false;
startY = e.clientY;
startX = e.clientX;
startTop = state.dockY;
ui.tab.setPointerCapture(e.pointerId);
});
ui.tab.addEventListener('pointermove', (e) => {
if (!isDown) return;
const deltaY = e.clientY - startY;
const deltaX = e.clientX - startX;
if (Math.abs(deltaY) > 5 || Math.abs(deltaX) > 5) {
hasMoved = true;
state.isDragging = true;
let newY = startTop + deltaY;
newY = Math.max(0, Math.min(window.innerHeight - 42, newY));
state.dockY = newY;
ui.dock.style.top = `${newY}px`;
if (e.clientX < CONFIG.snapThreshold) {
state.dockSide = 'left';
} else if (e.clientX > window.innerWidth - CONFIG.snapThreshold) {
state.dockSide = 'right';
}
ui.dock.className = `${state.dockSide} ${state.expanded ? 'expanded' : ''}`;
}
});
ui.tab.addEventListener('pointerup', (e) => {
isDown = false;
state.isDragging = false;
ui.tab.releasePointerCapture(e.pointerId);
if (!hasMoved) {
state.expanded = !state.expanded;
ui.dock.className = `${state.dockSide} ${state.expanded ? 'expanded' : 'hidden'}`;
} else {
saveSettings();
ui.dock.className = `${state.dockSide} ${state.expanded ? 'expanded' : 'hidden'}`;
}
});
ui.panel.addEventListener('mousedown', e => e.stopPropagation());
}
// ========== AUDIO ENGINE ==========
function initAudio(video, ui) {
if (!ui) return;
if (state.source && state.videoElement === video) return;
try {
if (!state.ctx) {
const AudioContext = window.AudioContext || window.webkitAudioContext;
state.ctx = new AudioContext();
}
if (state.ctx.state === 'suspended') state.ctx.resume();
if (!video.crossOrigin) video.crossOrigin = "anonymous";
try {
state.source = state.ctx.createMediaElementSource(video);
} catch (e) { return; }
state.videoElement = video;
state.nodes.bass = state.ctx.createBiquadFilter();
state.nodes.bass.type = 'lowshelf';
state.nodes.bass.frequency.value = 100;
state.nodes.mid = state.ctx.createBiquadFilter();
state.nodes.mid.type = 'peaking';
state.nodes.mid.frequency.value = 1000;
state.nodes.mid.Q.value = 0.8;
state.nodes.treble = state.ctx.createBiquadFilter();
state.nodes.treble.type = 'highshelf';
state.nodes.treble.frequency.value = 8000;
state.nodes.gain = state.ctx.createGain();
state.nodes.compressor = state.ctx.createDynamicsCompressor();
state.nodes.compressor.knee.value = 30;
state.nodes.compressor.attack.value = 0.003;
updateRouting();
updateAudioParams(true);
// Visual Update for Success
ui.tab.classList.add('connected');
ui.tab.classList.remove('error');
ui.status.innerText = "ENGINE ONLINE";
ui.status.style.color = "#00ff00";
} catch (e) {
// Visual Update for Error
ui.tab.classList.add('error');
ui.status.innerText = "CORS/SECURITY ERROR";
ui.status.style.color = "#ff0000";
}
}
function updateRouting() {
if (!state.source || !state.nodes.bass) return;
try { state.source.disconnect(); state.nodes.compressor.disconnect(); } catch(e){}
if (state.active) {
state.source.connect(state.nodes.bass);
state.nodes.bass.connect(state.nodes.mid);
state.nodes.mid.connect(state.nodes.treble);
state.nodes.treble.connect(state.nodes.gain);
state.nodes.gain.connect(state.nodes.compressor);
state.nodes.compressor.connect(state.ctx.destination);
} else {
state.source.connect(state.ctx.destination);
}
}
function updateAudioParams() {
if (!state.nodes.bass) return;
const vals = state.vals;
state.nodes.bass.gain.setTargetAtTime(vals.bass, state.ctx.currentTime, 0.1);
state.nodes.mid.gain.setTargetAtTime(vals.mid, state.ctx.currentTime, 0.1);
const trebleTotal = vals.treble + (vals.surround * 0.12);
state.nodes.treble.gain.setTargetAtTime(trebleTotal, state.ctx.currentTime, 0.1);
state.nodes.gain.gain.setTargetAtTime(vals.volume / 100, state.ctx.currentTime, 0.1);
state.nodes.compressor.threshold.value = -12 - (vals.clarity * 3);
state.nodes.compressor.ratio.value = 1 + (vals.clarity * 1.5);
state.nodes.compressor.release.value = 0.2 + (vals.surround * 0.006);
}
// ========== INIT ==========
const ui = createDock();
if (ui) {
initInteraction(ui);
document.getElementById('ae-toggle').addEventListener('change', (e) => {
state.active = e.target.checked;
updateRouting();
ui.status.innerText = state.active ? "ENGINE ONLINE" : "BYPASSED";
ui.status.style.color = state.active ? "#00ff00" : "#666";
saveSettings();
});
ui.inputs.forEach(el => {
el.addEventListener('input', (e) => {
const id = e.target.id.replace('sl-', '');
const val = parseFloat(e.target.value);
document.getElementById(`val-${id}`).innerText = val;
state.vals[id] = val;
updateAudioParams();
saveSettings();
});
el.addEventListener('dblclick', (e) => {
e.target.value = e.target.defaultValue;
e.target.dispatchEvent(new Event('input'));
});
});
document.querySelectorAll('button').forEach(b => {
b.addEventListener('click', (e) => {
const p = CONFIG.presets[e.target.dataset.p];
if (p) {
Object.keys(p).forEach(k => {
const el = document.getElementById(`sl-${k}`);
if(el) {
el.value = p[k];
document.getElementById(`val-${k}`).innerText = p[k];
state.vals[k] = p[k];
}
});
updateAudioParams();
saveSettings();
}
});
});
setInterval(() => {
const video = document.querySelector('video');
if (video) initAudio(video, ui);
}, 1000);
}
})();