feat: Enhance track ending detection and handling in MusicPlayerService
This commit is contained in:
@@ -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 = (
|
||||
|
||||
Reference in New Issue
Block a user