diff --git a/index.html b/index.html
index 7a8f15d..1b2425c 100644
--- a/index.html
+++ b/index.html
@@ -420,37 +420,6 @@
-
-
-
-
-
Waiting for stream...
-
-
-
-
-
-
-
-
-
-
-
Connecting...
-
-
-
diff --git a/script.js b/script.js
index e41841c..4e4f0f6 100644
--- a/script.js
+++ b/script.js
@@ -1816,23 +1816,12 @@ window.addEventListener('DOMContentLoaded', () => {
updateManualGlow('A', settings.glowA);
updateManualGlow('B', settings.glowB);
- // Check if this is the listener page based on hostname or port
- const isListenerPort = window.location.port === '5001';
- const isListenerHostname = window.location.hostname.startsWith('music.') || window.location.hostname.startsWith('listen.');
- const urlParams = new URLSearchParams(window.location.search);
-
- if (isListenerPort || isListenerHostname || urlParams.get('listen') === 'true') {
- initListenerMode();
- }
-
- if (!isListenerPort && !isListenerHostname) {
- // Set stream URL to the listener domain
- const streamUrl = window.location.hostname.startsWith('dj.')
- ? `${window.location.protocol}//music.${window.location.hostname.split('.').slice(1).join('.')}`
- : `${window.location.protocol}//${window.location.hostname}:5001`;
- const streamInput = document.getElementById('stream-url');
- if (streamInput) streamInput.value = streamUrl;
- }
+ // Set stream URL in the streaming panel
+ const streamUrl = window.location.hostname.startsWith('dj.')
+ ? `${window.location.protocol}//music.${window.location.hostname.split('.').slice(1).join('.')}`
+ : `${window.location.protocol}//${window.location.hostname}:5001`;
+ const streamInput = document.getElementById('stream-url');
+ if (streamInput) streamInput.value = streamUrl;
});
// ========== LIVE STREAMING FUNCTIONALITY ==========
@@ -1843,94 +1832,13 @@ let streamProcessor = null;
let mediaRecorder = null;
let isBroadcasting = false;
let autoStartStream = false;
-let listenerAudioContext = null;
-let listenerGainNode = null;
-let listenerAnalyserNode = null;
-let listenerMediaElementSourceNode = null;
-let listenerVuMeterRunning = false;
-let listenerChunksReceived = 0;
-
-function startListenerVUMeter() {
- if (listenerVuMeterRunning) return;
- listenerVuMeterRunning = true;
-
- const draw = () => {
- if (!listenerVuMeterRunning) return;
- requestAnimationFrame(draw);
-
- const canvas = document.getElementById('viz-listener');
- if (!canvas || !listenerAnalyserNode) return;
-
- const ctx = canvas.getContext('2d');
- if (!ctx) return;
-
- // Keep canvas sized correctly for DPI
- const dpr = window.devicePixelRatio || 1;
- const rect = canvas.getBoundingClientRect();
- const targetW = Math.max(1, Math.floor(rect.width * dpr));
- const targetH = Math.max(1, Math.floor(rect.height * dpr));
- if (canvas.width !== targetW || canvas.height !== targetH) {
- canvas.width = targetW;
- canvas.height = targetH;
- }
-
- const analyser = listenerAnalyserNode;
- const bufferLength = analyser.frequencyBinCount;
- const dataArray = new Uint8Array(bufferLength);
- analyser.getByteFrequencyData(dataArray);
-
- const width = canvas.width;
- const height = canvas.height;
- const barCount = 32;
- const barWidth = width / barCount;
-
- ctx.fillStyle = '#0a0a12';
- ctx.fillRect(0, 0, width, height);
-
- // Listener uses the magenta hue (matches Deck B styling)
- const hue = 280;
- for (let i = 0; i < barCount; i++) {
- const freqIndex = Math.floor(Math.pow(i / barCount, 1.5) * bufferLength);
- const value = (dataArray[freqIndex] || 0) / 255;
- const barHeight = value * height;
-
- const lightness = 30 + (value * 50);
- const gradient = ctx.createLinearGradient(0, height, 0, height - barHeight);
- gradient.addColorStop(0, `hsl(${hue}, 100%, ${lightness}%)`);
- gradient.addColorStop(1, `hsl(${hue}, 100%, ${Math.min(lightness + 20, 80)}%)`);
-
- ctx.fillStyle = gradient;
- ctx.fillRect(i * barWidth, height - barHeight, barWidth - 2, barHeight);
- }
- };
-
- draw();
-}
let currentStreamMimeType = null;
-function getMp3FallbackUrl() {
- // Use same-origin so this works behind reverse proxies (e.g., Cloudflare) where :5001 may not be reachable.
- return `${window.location.origin}/stream.mp3`;
-}
-
// Initialise SocketIO connection
function initSocket() {
if (socket) return socket;
- // Log connection details
- const urlParams = new URLSearchParams(window.location.search);
- const isListenerMode =
- window.location.port === '5001' ||
- window.location.hostname.startsWith('music.') ||
- window.location.hostname.startsWith('listen.') ||
- urlParams.get('listen') === 'true';
-
- // If someone opens listener mode on the DJ dev port (:5000?listen=true),
- // use the listener backend (:5001). For proxied deployments (Cloudflare),
- // do NOT force a port (it may be blocked); stick to same-origin.
- const serverUrl = (isListenerMode && window.location.port === '5000')
- ? `${window.location.protocol}//${window.location.hostname}:5001`
- : window.location.origin;
+ const serverUrl = window.location.origin;
console.log(`CONNECT Initializing Socket.IO connection to: ${serverUrl}`);
console.log(` Protocol: ${window.location.protocol}`);
console.log(` Host: ${window.location.host}`);
@@ -2479,412 +2387,6 @@ function toggleAutoStream(enabled) {
localStorage.setItem('autoStartStream', enabled);
}
-// ========== LISTENER MODE ==========
-
-function initListenerMode() {
- console.log('STREAMPANEL Initializing listener mode (MP3 stream)...');
-
- // UI Feedback for listener
- const appContainer = document.querySelector('.app-container');
- const settingsBtn = document.querySelector('.settings-btn');
- const streamingBtn = document.querySelector('.streaming-btn');
- if (appContainer) appContainer.style.display = 'none';
- if (settingsBtn) settingsBtn.style.display = 'none';
- if (streamingBtn) streamingBtn.style.display = 'none';
-
- const startOverlay = document.getElementById('start-overlay');
- if (startOverlay) startOverlay.style.display = 'none';
-
- // Hide landscape prompt for listeners (not needed)
- const landscapePrompt = document.getElementById('landscape-prompt');
- if (landscapePrompt) landscapePrompt.style.display = 'none';
-
- const listenerMode = document.getElementById('listener-mode');
- if (listenerMode) listenerMode.style.display = 'flex';
-
- // Add atmospheric glow for listeners
- document.body.classList.add('listener-glow');
- document.body.classList.add('listening-active'); // For global CSS targeting
- updateGlowIntensity(settings.glowIntensity || 30);
-
- // AudioContext will be created when user enables audio to avoid suspension
-
- // ALWAYS create a fresh audio element to avoid MediaSource/MediaElementSource conflicts
- // This is critical for page refreshes - you can only create MediaElementSource once per element
- let audio;
-
- // Clean up old audio element if it exists
- if (window.listenerAudio) {
- console.log('CLEAN Cleaning up old audio element and AudioContext nodes');
- try {
- window.listenerAudio.pause();
- if (window.listenerAudio.src) {
- URL.revokeObjectURL(window.listenerAudio.src);
- }
- window.listenerAudio.removeAttribute('src');
- window.listenerAudio.remove(); // Remove from DOM
- } catch (e) {
- console.warn('Error cleaning up old audio:', e);
- }
-
- // Reset all AudioContext-related nodes
- if (listenerMediaElementSourceNode) {
- try {
- listenerMediaElementSourceNode.disconnect();
- } catch (e) { }
- listenerMediaElementSourceNode = null;
- }
- if (listenerAnalyserNode) {
- try {
- listenerAnalyserNode.disconnect();
- } catch (e) { }
- listenerAnalyserNode = null;
- }
- if (listenerGainNode) {
- try {
- listenerGainNode.disconnect();
- } catch (e) { }
- listenerGainNode = null;
- }
-
- window.listenerAudio = null;
- window.listenerMediaSource = null;
- window.listenerAudioEnabled = false;
- }
-
- // Create a new hidden media element.
- // For MP3 we can use a plain