From e7f6ef62c0d5cfed1d04f3ed9b59585ccbd0764b Mon Sep 17 00:00:00 2001 From: IV3JDV Date: Wed, 2 Sep 2026 10:31:22 +0200 Subject: [PATCH] Enable release resource --- index.html | 35 ++++++++++++++++------ static/app.js | 80 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 28 deletions(-) diff --git a/index.html b/index.html index d933fee..492c14c 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + DMR Web Receiver Pro

ARI FVG Web-Receiver

-
Selettore Talkgroup
@@ -86,11 +101,13 @@
- +
+ + +
Sistema in attesa...
-
Monitor Rete Globale
diff --git a/static/app.js b/static/app.js index 3265422..2ecdc1b 100644 --- a/static/app.js +++ b/static/app.js @@ -1,4 +1,4 @@ -console.log("App.js caricato - VU Meter & Click-to-Tune attivi!"); +console.log("App.js caricato - Soft Stop e Auto-Wakeup attivi!"); let ws = null; let audioCtx = null; @@ -8,6 +8,7 @@ let dataArray = null; let nextStartTime = 0; const connectBtn = document.getElementById('connectBtn'); +const stopBtn = document.getElementById('stopBtn'); const tgInput = document.getElementById('tgInput'); const setTgBtn = document.getElementById('setTgBtn'); const displayScreen = document.getElementById('displayScreen'); @@ -17,7 +18,7 @@ const volumeValue = document.getElementById('volumeValue'); const liveTrafficList = document.getElementById('liveTrafficList'); const vuMeterBar = document.getElementById('vuMeterBar'); -if(statusText) statusText.innerText = "✅ Sistema pronto. Clicca Avvia Ascolto."; +if(statusText) statusText.innerText = "✅ Sistema pronto. Clicca Avvia Ricevitore."; if(volumeSlider) { volumeSlider.addEventListener('input', (e) => { @@ -33,17 +34,30 @@ window.setQuickTg = function(valore) { }; function inviaCambioTG(nuovoTG) { - if (!nuovoTG || nuovoTG <= 0) return; + if (!nuovoTG || nuovoTG < 0) return; // Permette lo zero per lo stop interno + if (ws && ws.readyState === WebSocket.OPEN) { + // Se l'audio era stato fermato, lo riavvia automaticamente (Auto-Wakeup) + if (nuovoTG > 0 && audioCtx && audioCtx.state === 'suspended') { + audioCtx.resume(); + if(connectBtn) connectBtn.style.display = 'none'; + if(stopBtn) stopBtn.style.display = 'block'; + } + ws.send(JSON.stringify({ action: "cambia_tg", tg: nuovoTG })); - if(displayScreen) displayScreen.innerText = "SINTONIA..."; - if(statusText) statusText.innerText = "Sintonizzato su TG " + nuovoTG; + + if (nuovoTG > 0) { + if(displayScreen) { + displayScreen.innerText = "SINTONIA..."; + displayScreen.style.background = ""; + } + if(statusText) statusText.innerText = "Sintonizzato su TG " + nuovoTG; + } } else { if(statusText) statusText.innerText = "Pronto a sintonizzare TG " + nuovoTG + " (Avvia prima)"; } } -// --- VU METER LOOP --- function renderVUMeter() { requestAnimationFrame(renderVUMeter); if (!analyser || !vuMeterBar) return; @@ -55,12 +69,12 @@ function renderVUMeter() { sum += v * v; } let rms = Math.sqrt(sum / dataArray.length); - let percent = Math.min(100, rms * 500); // Moltiplicatore di sensibilità grafica + let percent = Math.min(100, rms * 500); vuMeterBar.style.width = percent + '%'; - if (percent > 85) vuMeterBar.style.background = '#e74c3c'; // Rosso saturo - else if (percent > 50) vuMeterBar.style.background = '#f1c40f'; // Giallo - else vuMeterBar.style.background = '#2ecc71'; // Verde standard + if (percent > 85) vuMeterBar.style.background = '#e74c3c'; + else if (percent > 50) vuMeterBar.style.background = '#f1c40f'; + else vuMeterBar.style.background = '#2ecc71'; } function playPCM320(arrayBuffer) { @@ -77,8 +91,6 @@ function playPCM320(arrayBuffer) { const source = audioCtx.createBufferSource(); source.buffer = buffer; - - // Collega al VU meter, che a sua volta è collegato al volume source.connect(analyser); const currentTime = audioCtx.currentTime; @@ -90,26 +102,54 @@ function playPCM320(arrayBuffer) { } } +function stopAudio() { + // Invia TG 0 per sganciare il flusso audio dal server mantenendo vivo il WebSocket + if (ws && ws.readyState === WebSocket.OPEN) { + inviaCambioTG(0); + } + + if (audioCtx && audioCtx.state !== 'suspended') { + audioCtx.suspend(); + } + + if(connectBtn) connectBtn.style.display = 'block'; + if(stopBtn) stopBtn.style.display = 'none'; + + if(displayScreen) { + displayScreen.innerText = "STANDBY"; + displayScreen.style.background = ""; + } + if(statusText) { + statusText.innerText = "Audio disattivato. Monitor di rete attivo."; + statusText.style.color = "#bdc3c7"; + } +} + function startAudio() { try { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - analyser = audioCtx.createAnalyser(); analyser.fftSize = 256; dataArray = new Uint8Array(analyser.frequencyBinCount); - gainNode = audioCtx.createGain(); - // Catena: Source -> Analyser(VU) -> Gain(Volume) -> Casse analyser.connect(gainNode); gainNode.connect(audioCtx.destination); if(volumeSlider) gainNode.gain.value = parseFloat(volumeSlider.value); - - renderVUMeter(); // Avvia l'animazione grafica + renderVUMeter(); } if (audioCtx.state === 'suspended') audioCtx.resume(); + + // Se il WebSocket è già aperto (uscita dallo stato di Stop) + if (ws && ws.readyState === WebSocket.OPEN) { + if(connectBtn) connectBtn.style.display = 'none'; + if(stopBtn) stopBtn.style.display = 'block'; + if(tgInput) inviaCambioTG(tgInput.value); + return; + } + if(statusText) statusText.innerText = "🔄 Connessione in corso..."; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; @@ -118,6 +158,7 @@ function startAudio() { ws.onopen = () => { if(connectBtn) connectBtn.style.display = 'none'; + if(stopBtn) stopBtn.style.display = 'block'; if(tgInput) inviaCambioTG(tgInput.value); }; @@ -132,12 +173,11 @@ function startAudio() { if (data.action === "display") { if(displayScreen) { displayScreen.innerText = data.text; - displayScreen.style.background = data.active ? "#e67e22" : "#1abc9c"; + displayScreen.style.background = data.active ? "#e67e22" : ""; } if(statusText) statusText.style.color = "#bdc3c7"; } - // CLICK-TO-TUNE IMPLEMENTATO QUI if (data.action === "global_traffic" && liveTrafficList) { if (!data.data || data.data.length === 0) { liveTrafficList.innerHTML = "Nessun traffico in corso..."; @@ -155,6 +195,7 @@ function startAudio() { ws.onclose = () => { if(statusText) statusText.innerText = "❌ Connessione persa."; if(connectBtn) connectBtn.style.display = 'block'; + if(stopBtn) stopBtn.style.display = 'none'; }; } catch (err) { @@ -163,6 +204,7 @@ function startAudio() { } if(connectBtn) connectBtn.addEventListener('click', startAudio); +if(stopBtn) stopBtn.addEventListener('click', stopAudio); if(setTgBtn) setTgBtn.addEventListener('click', () => { if(tgInput) inviaCambioTG(tgInput.value); }); if(tgInput) { tgInput.addEventListener('keypress', (e) => {