diff --git a/app/services/music_player_service.py b/app/services/music_player_service.py index c498d1b..af7ebe4 100644 --- a/app/services/music_player_service.py +++ b/app/services/music_player_service.py @@ -60,6 +60,8 @@ class MusicPlayerService: self._track_play_tracked = ( False # Flag to track if current track play has been logged ) + self._cumulative_play_time = 0 # Cumulative time actually played for current track + self._last_position_update = 0 # Last position for calculating continuous play time def start_vlc_instance(self) -> bool: """Start a VLC instance with Python bindings.""" @@ -232,6 +234,9 @@ class MusicPlayerService: self._track_play_tracked = ( False # Reset play tracking for new track ) + # Reset cumulative play time tracking for new track + self._cumulative_play_time = 0 + self._last_position_update = 0 return True return False except Exception as e: @@ -656,22 +661,34 @@ class MusicPlayerService: elif self.is_playing and not old_playing: self._track_ending_handled = False - # Track play event when song reaches 20% completion (but only once per track load) - # Only track if playing, haven't tracked yet, have valid duration, and reached threshold + # Update cumulative play time for continuous listening tracking + if self.is_playing and old_playing and self.current_time > 0: + # Calculate time elapsed since last update (but cap it to prevent huge jumps from seeking) + if self._last_position_update > 0: + time_diff = self.current_time - self._last_position_update + # Only add time if it's a reasonable progression (not a big jump from seeking) + if 0 <= time_diff <= (self.sync_interval * 1000 * 2): # Max 2x sync interval + self._cumulative_play_time += time_diff + + self._last_position_update = self.current_time + elif self.is_playing and not old_playing: + # Just started playing, initialize position tracking + self._last_position_update = self.current_time if self.current_time > 0 else 0 + + # Track play event when cumulative listening reaches 20% of track duration if ( self.is_playing and not self._track_play_tracked and self.duration > 0 - and self.current_time > 0 # Ensure we have valid playback time - and self.current_time >= (self.duration * PLAY_COMPLETION_THRESHOLD) + and self._cumulative_play_time >= (self.duration * PLAY_COMPLETION_THRESHOLD) ): current_track = self.get_current_track() if current_track: self._track_sound_play(current_track["id"]) self._track_play_tracked = True logger.info( - f"Tracked play for '{current_track['title']}' at {self.current_time}ms " - f"({(self.current_time/self.duration)*100:.1f}% completion)" + f"Tracked play for '{current_track['title']}' after {self._cumulative_play_time}ms " + f"cumulative listening ({(self._cumulative_play_time/self.duration)*100:.1f}% of track)" ) # Emit updates if state changed significantly or periodically