Hopefully fixed lockup bug.

This commit is contained in:
Storm Dragon
2025-08-16 19:57:19 -04:00
parent 022b9ba048
commit c86921ea65
5 changed files with 228 additions and 111 deletions

View File

@@ -547,8 +547,7 @@ class MumbleBot:
elif self.on_interrupting or len(raw_music) < self.pcm_buffer_size:
self.mumble.sound_output.add_sound(
audioop.mul(self._fadeout(raw_music, self.stereo, fadein=False), 2, self.volume_helper.real_volume))
self.thread.kill()
self.thread = None
self._cleanup_ffmpeg_process()
time.sleep(0.1)
self.on_interrupting = False
else:
@@ -557,7 +556,7 @@ class MumbleBot:
time.sleep(0.1)
if not self.is_pause and not raw_music:
self.thread = None
self._cleanup_ffmpeg_process()
# bot is not paused, but ffmpeg thread has gone.
# indicate that last song has finished, or the bot just resumed from pause, or something is wrong.
if self.read_pcm_size < self.pcm_buffer_size \
@@ -703,12 +702,14 @@ class MumbleBot:
def clear(self):
# Kill the ffmpeg thread and empty the playlist
self.interrupt()
self._cleanup_ffmpeg_process() # Ensure proper cleanup
var.playlist.clear()
self.wait_for_ready = False
self.log.info("bot: music stopped. playlist trashed.")
def stop(self):
self.interrupt()
self._cleanup_ffmpeg_process() # Ensure proper cleanup
self.is_pause = True
if len(var.playlist) > 0:
self.wait_for_ready = True
@@ -716,6 +717,34 @@ class MumbleBot:
self.wait_for_ready = False
self.log.info("bot: music stopped.")
def _cleanup_ffmpeg_process(self):
"""Properly cleanup FFmpeg process and associated resources"""
if self.thread:
try:
# Check if process is already terminated to avoid double cleanup
if self.thread.poll() is None: # Process is still running
self.thread.terminate() # Send SIGTERM first
try:
self.thread.wait(timeout=2) # Wait up to 2 seconds for graceful exit
except sp.TimeoutExpired:
self.log.warning("bot: FFmpeg process didn't terminate gracefully, killing forcefully")
self.thread.kill() # Force kill if it doesn't terminate
self.thread.wait() # Wait for process to be reaped
else:
# Process already terminated, just wait to reap it
self.thread.wait()
except Exception as e:
self.log.error(f"bot: Error cleaning up FFmpeg process: {e}")
finally:
# Close stderr pipe if it exists
if self.thread_stderr:
try:
self.thread_stderr.close()
self.thread_stderr = None
except Exception as e:
self.log.error(f"bot: Error closing stderr pipe: {e}")
self.thread = None
def interrupt(self):
# Kill the ffmpeg thread
if self.thread:
@@ -728,6 +757,7 @@ class MumbleBot:
def pause(self):
# Kill the ffmpeg thread
self.interrupt()
self._cleanup_ffmpeg_process() # Ensure proper cleanup
self.is_pause = True
self.song_start_at = -1
if len(var.playlist) > 0: