diff --git a/listener.js b/listener.js index d7b7741..cd0f15b 100644 --- a/listener.js +++ b/listener.js @@ -93,9 +93,11 @@ function initSocket() { console.log(`[LISTENER] Initializing Socket.IO connection to: ${serverUrl}`); socket = io(serverUrl, { - transports: ['websocket'], + transports: ['websocket', 'polling'], reconnection: true, - reconnectionAttempts: 10 + reconnectionAttempts: Infinity, + reconnectionDelay: 1000, + reconnectionDelayMax: 10000 }); socket.on('connect', () => { diff --git a/script.js b/script.js index 4e4f0f6..52171b5 100644 --- a/script.js +++ b/script.js @@ -1844,9 +1844,11 @@ function initSocket() { console.log(` Host: ${window.location.host}`); socket = io(serverUrl, { - transports: ['websocket'], + transports: ['websocket', 'polling'], reconnection: true, - reconnectionAttempts: 10 + reconnectionAttempts: Infinity, + reconnectionDelay: 1000, + reconnectionDelayMax: 10000 }); socket.on('connect', () => { diff --git a/server.py b/server.py index 8d0bc05..8af94d8 100644 --- a/server.py +++ b/server.py @@ -586,8 +586,8 @@ dj_socketio = SocketIO( cors_allowed_origins=CONFIG_CORS, async_mode='eventlet', max_http_buffer_size=CONFIG_MAX_UPLOAD_MB * 1024 * 1024, - ping_timeout=10, - ping_interval=5, + ping_timeout=60, + ping_interval=25, logger=CONFIG_DEBUG, engineio_logger=CONFIG_DEBUG ) @@ -611,6 +611,7 @@ def stop_broadcast_after_timeout(): @dj_socketio.on('start_broadcast') def dj_start(data=None): + was_already_active = broadcast_state.get('active', False) broadcast_state['active'] = True session['is_dj'] = True print("BROADCAST: ACTIVE") @@ -625,13 +626,20 @@ def dj_start(data=None): is_mp3_input = True broadcast_state['is_mp3_input'] = is_mp3_input - # Clear pre-roll for fresh start - with _mp3_lock: - _mp3_preroll.clear() - - _start_transcoder_if_needed(is_mp3_input=is_mp3_input) - - listener_socketio.emit('broadcast_started', namespace='/') + if not was_already_active: + # Fresh broadcast start - clear pre-roll and start transcoder cleanly + with _mp3_lock: + _mp3_preroll.clear() + _start_transcoder_if_needed(is_mp3_input=is_mp3_input) + # Tell listeners a new broadcast has begun (triggers audio player reload) + listener_socketio.emit('broadcast_started', namespace='/') + else: + # DJ reconnected mid-broadcast - just ensure transcoder is alive + # Do NOT clear pre-roll or trigger listener reload + print("BROADCAST: DJ reconnected - resuming existing broadcast") + _start_transcoder_if_needed(is_mp3_input=is_mp3_input) + + # Always send current status so any waiting listeners get unblocked listener_socketio.emit('stream_status', {'active': True}, namespace='/') @dj_socketio.on('get_listener_count') @@ -687,8 +695,8 @@ listener_socketio = SocketIO( cors_allowed_origins=CONFIG_CORS, async_mode='eventlet', max_http_buffer_size=CONFIG_MAX_UPLOAD_MB * 1024 * 1024, - ping_timeout=10, - ping_interval=5, + ping_timeout=60, + ping_interval=25, logger=CONFIG_DEBUG, engineio_logger=CONFIG_DEBUG ) diff --git a/techdj_qt.py b/techdj_qt.py index 74377e5..7063d6c 100644 --- a/techdj_qt.py +++ b/techdj_qt.py @@ -812,11 +812,18 @@ class StreamingWorker(QThread): self.stream_url = "" self.is_running = False self.ffmpeg_proc = None + self._broadcast_started = False def on_connect(self): print("[SOCKET] Connected to DJ server") - self.sio.emit('start_broadcast', {'format': 'mp3', 'bitrate': '128k'}) - self.streaming_started.emit() + if not self._broadcast_started: + self._broadcast_started = True + self.sio.emit('start_broadcast', {'format': 'mp3', 'bitrate': '128k'}) + self.streaming_started.emit() + else: + # Reconnected mid-stream - server handles resume gracefully + print("[SOCKET] Reconnected - resuming existing broadcast") + self.sio.emit('start_broadcast', {'format': 'mp3', 'bitrate': '128k'}) def on_disconnect(self): print("[SOCKET] Disconnected from DJ server") @@ -878,6 +885,7 @@ class StreamingWorker(QThread): def stop_streaming(self): self.is_running = False + self._broadcast_started = False if self.ffmpeg_proc: try: self.ffmpeg_proc.terminate() except: pass