Stop the stream manager and cancel all timers
(self)
| 1259 | self.transcode_process = None |
| 1260 | |
| 1261 | def stop(self): |
| 1262 | """Stop the stream manager and cancel all timers""" |
| 1263 | logger.info(f"Stopping stream manager for channel {self.channel_id}") |
| 1264 | |
| 1265 | self.stopping = True |
| 1266 | self._invalidate_ownership_cache() |
| 1267 | if self.buffer is not None: |
| 1268 | self.buffer.stopping = True |
| 1269 | |
| 1270 | # Cancel all buffer check timers |
| 1271 | for timer in list(self._buffer_check_timers): |
| 1272 | try: |
| 1273 | if timer and timer.is_alive(): |
| 1274 | timer.cancel() |
| 1275 | except Exception as e: |
| 1276 | logger.error(f"Error canceling buffer check timer for channel {self.channel_id}: {e}") |
| 1277 | |
| 1278 | self._buffer_check_timers.clear() |
| 1279 | |
| 1280 | # Set the flag first |
| 1281 | self.stop_requested = True |
| 1282 | |
| 1283 | # Close any active response connection |
| 1284 | if hasattr(self, 'current_response') and self.current_response: # CORRECT NAME |
| 1285 | try: |
| 1286 | self.current_response.close() # CORRECT NAME |
| 1287 | except Exception: |
| 1288 | pass |
| 1289 | |
| 1290 | # Also close the session |
| 1291 | if hasattr(self, 'current_session') and self.current_session: |
| 1292 | try: |
| 1293 | self.current_session.close() |
| 1294 | except Exception: |
| 1295 | pass |
| 1296 | |
| 1297 | # Explicitly close socket/transcode resources |
| 1298 | self._close_socket() |
| 1299 | |
| 1300 | # Set running to false to ensure thread exits |
| 1301 | self.running = False |
| 1302 | |
| 1303 | # Flush the final bitrate to DB on stop only if warmup completed and we have |
| 1304 | # a meaningful EMA. Short previews / channel hops that die during warmup do NOT |
| 1305 | # write anything, preserving any previously correct value in the database. |
| 1306 | if self._smoothed_output_bitrate is not None and self.current_stream_id: |
| 1307 | final_bitrate = self._smoothed_output_bitrate |
| 1308 | try: |
| 1309 | from ..services.channel_service import ChannelService |
| 1310 | ChannelService._update_stream_stats_in_db( |
| 1311 | self.current_stream_id, |
| 1312 | ffmpeg_output_bitrate=round(final_bitrate, 1) |
| 1313 | ) |
| 1314 | except Exception as e: |
| 1315 | logger.debug(f"Error flushing final bitrate to DB for channel {self.channel_id}: {e}") |
| 1316 | |
| 1317 | def update_url(self, new_url, stream_id=None, m3u_profile_id=None): |
| 1318 | """Update stream URL and reconnect with proper cleanup for both HTTP and transcode sessions""" |
no test coverage detected