feat: Enhance track ending detection and handling in MusicPlayerService

This commit is contained in:
JSC
2025-07-08 13:36:51 +02:00
parent 193bd5ebf4
commit 2e464dc977

View File

@@ -38,10 +38,11 @@ class MusicPlayerService:
self.current_time = 0
self.duration = 0
self.last_sync_time = 0
self.sync_interval = 1.0 # seconds
self.sync_interval = 0.5 # seconds (increased frequency to catch track endings)
self.lock = threading.Lock()
self._sync_thread = None
self._stop_sync = False
self._track_ending_handled = False # Flag to prevent duplicate ending triggers
def start_vlc_instance(self) -> bool:
"""Start a VLC instance with Python bindings."""
@@ -183,6 +184,8 @@ class MusicPlayerService:
if media:
self.player.set_media(media)
self.current_track_index = index
# Reset track ending flag when loading a new track
self._track_ending_handled = False
return True
return False
except Exception as e:
@@ -229,6 +232,9 @@ class MusicPlayerService:
if not self.player:
return False
# Reset track ending flag when starting playback
self._track_ending_handled = False
result = self.player.play()
if result == 0: # Success
self.is_playing = True
@@ -521,17 +527,47 @@ class MusicPlayerService:
# Get volume
self.volume = self.player.audio_get_volume()
# Check if track ended and handle auto-advance
if state == vlc.State.Ended and self.play_mode in [
"continuous",
"loop-playlist",
"random",
]:
# Enhanced track ending detection
track_ended = False
# Check for ended state
if state == vlc.State.Ended:
track_ended = True
logger.info(f"Track ended via VLC State.Ended, mode: {self.play_mode}")
# Also check if we're very close to the end (within 500ms) and not playing
elif (self.duration > 0 and self.current_time > 0 and
self.current_time >= (self.duration - 500) and
not self.is_playing and old_playing):
track_ended = True
logger.info(f"Track ended via time check, mode: {self.play_mode}")
# Handle track ending based on play mode (only if not already handled)
if track_ended and not self._track_ending_handled:
self._track_ending_handled = True
if self.play_mode == "loop-one":
logger.info("Restarting track for loop-one mode")
# Stop first, then reload and play
self.player.stop()
# Reload the current track
if (self.current_track_index < len(self.playlist_files)):
media = self.instance.media_new(
self.playlist_files[self.current_track_index]
)
self.player.set_media(media)
self.player.play()
# Reset the flag after a short delay to allow for new track
self._track_ending_handled = False
elif self.play_mode in ["continuous", "loop-playlist", "random"]:
logger.info(f"Advancing to next track for {self.play_mode} mode")
self.next_track()
elif state == vlc.State.Ended and self.play_mode == "loop-one":
# Restart the same track
self.player.set_position(0)
self.play()
# Reset the flag after track change
self._track_ending_handled = False
# Reset the flag if we're playing again (new track started)
elif self.is_playing and not old_playing:
self._track_ending_handled = False
# Emit updates if state changed significantly or periodically
state_changed = (