- server.py: Increase ping_timeout 10->60, ping_interval 5->25 to prevent
frequent socket disconnects during audio streaming
- server.py: Guard dj_start() against reconnect loops - only clear pre-roll
and emit broadcast_started on a fresh broadcast, not on DJ reconnects
- listener.js: Add polling fallback to transports (websocket-only caused
silent failure on upgrade error), set reconnectionAttempts to Infinity
- script.js: Same transport fallback fix for DJ panel socket
- techdj_qt.py: Add _broadcast_started flag to StreamingWorker.on_connect
so streaming_started signal only fires once; reconnects resume silently.
Reset flag in stop_streaming() for clean next session.
- script.js: Remove ~500 lines of dead listener mode code (initListenerMode, enableListenerAudio, setListenerVolume, startListenerVUMeter, getMp3FallbackUrl, listener variables). Listener page now uses listener.js exclusively.
- script.js: Remove ?listen=true detection from DOMContentLoaded that could activate broken listener UI on DJ panel.
- script.js: Clean up initSocket() to remove dead listener mode detection logic.
- index.html: Remove dead #listener-mode div (now served by listener.html).
- server.py: Move 'abort' import to top-level Flask import instead of per-request import.
- techdj_qt.py: Fix StreamingWorker to create fresh socketio.Client on each streaming session, preventing stale socket state on reconnect.
- techdj_qt.py: Fix time.sleep(0.2) blocking GUI thread in stop_streaming() by removing it and using try/except for clean disconnect.
- Block DJ-only files (index.html, script.js, style.css) on listener server
- Disable Flask built-in static handler on listener (static_folder=None)
to prevent it from serving index.html before custom routes
- Add Cache-Control no-store headers to index route to prevent
nginx/browser from caching stale index.html for listener URL
- Created standalone listener.html, listener.js, listener.css
- Listener server now serves listener.html instead of index.html
- Eliminates flash of DJ panel when loading listener page
- setup_shared_routes() accepts index_file parameter
- Add config.example.json with all options: host, dj_port, listener_port,
dj_panel_password, secret_key, music_folder, stream_bitrate, max_upload_mb,
cors_origins, debug (copy to config.json to use)
- server.py: drive host/ports/secrets/CORS/upload limit from config.json;
fix serve_static to use allowlist only; move re import to top-level;
fix inconsistent indentation in login/logout/before_request handlers
- script.js: fix undefined decks.crossfader in updateUIFromMixerStatus;
declare mediaRecorder as a proper let variable
- techdj_qt.py: replace blocking time.sleep poll in YTDownloadWorker with
non-blocking QTimer; fix fragile or-chained lambda in recording reset
- Server-side: Added remote URL support in ffmpeg transcoder
- UI: Added relay controls in streaming panel with URL input
- Client: Added start/stop relay functions with socket communication
- Listener: Shows remote relay status in stream indicator