This commit is contained in:
@@ -68,15 +68,19 @@ class PlayerState:
|
||||
"duration": self.current_sound_duration,
|
||||
"index": self.current_sound_index,
|
||||
"current_sound": self._serialize_sound(self.current_sound),
|
||||
"playlist": {
|
||||
"id": self.playlist_id,
|
||||
"name": self.playlist_name,
|
||||
"length": self.playlist_length,
|
||||
"duration": self.playlist_duration,
|
||||
"sounds": [
|
||||
self._serialize_sound(sound) for sound in self.playlist_sounds
|
||||
],
|
||||
} if self.playlist_id else None,
|
||||
"playlist": (
|
||||
{
|
||||
"id": self.playlist_id,
|
||||
"name": self.playlist_name,
|
||||
"length": self.playlist_length,
|
||||
"duration": self.playlist_duration,
|
||||
"sounds": [
|
||||
self._serialize_sound(sound) for sound in self.playlist_sounds
|
||||
],
|
||||
}
|
||||
if self.playlist_id
|
||||
else None
|
||||
),
|
||||
}
|
||||
|
||||
def _serialize_sound(self, sound: Sound | None) -> dict[str, Any] | None:
|
||||
@@ -103,6 +107,14 @@ class PlayerService:
|
||||
self.db_session_factory = db_session_factory
|
||||
self.state = PlayerState()
|
||||
self._vlc_instance = vlc.Instance()
|
||||
|
||||
if self._vlc_instance is None:
|
||||
msg = (
|
||||
"VLC instance could not be created. "
|
||||
"Ensure VLC is installed and accessible."
|
||||
)
|
||||
raise RuntimeError(msg)
|
||||
|
||||
self._player = self._vlc_instance.media_player_new()
|
||||
self._is_running = False
|
||||
self._position_thread: threading.Thread | None = None
|
||||
@@ -125,7 +137,8 @@ class PlayerService:
|
||||
|
||||
# Start position tracking thread
|
||||
self._position_thread = threading.Thread(
|
||||
target=self._position_tracker, daemon=True,
|
||||
target=self._position_tracker,
|
||||
daemon=True,
|
||||
)
|
||||
self._position_thread.start()
|
||||
|
||||
@@ -155,9 +168,9 @@ class PlayerService:
|
||||
"""Play audio at specified index or current position."""
|
||||
# Check if we're resuming from pause
|
||||
is_resuming = (
|
||||
index is None and
|
||||
self.state.status == PlayerStatus.PAUSED and
|
||||
self.state.current_sound is not None
|
||||
index is None
|
||||
and self.state.status == PlayerStatus.PAUSED
|
||||
and self.state.current_sound is not None
|
||||
)
|
||||
|
||||
if is_resuming:
|
||||
@@ -179,7 +192,14 @@ class PlayerService:
|
||||
}
|
||||
|
||||
await self._broadcast_state()
|
||||
logger.info("Resumed playing sound: %s", self.state.current_sound.name)
|
||||
logger.info(
|
||||
"Resumed playing sound: %s",
|
||||
(
|
||||
self.state.current_sound.name
|
||||
if self.state.current_sound
|
||||
else "Unknown"
|
||||
),
|
||||
)
|
||||
else:
|
||||
logger.error("Failed to resume playback: VLC error code %s", result)
|
||||
return
|
||||
@@ -204,6 +224,10 @@ class PlayerService:
|
||||
return
|
||||
|
||||
# Load and play media (new track)
|
||||
if self._vlc_instance is None:
|
||||
logger.error("VLC instance is not initialized. Cannot play media.")
|
||||
return
|
||||
|
||||
media = self._vlc_instance.media_new(str(sound_path))
|
||||
self._player.set_media(media)
|
||||
|
||||
@@ -354,7 +378,9 @@ class PlayerService:
|
||||
and previous_playlist_id != current_playlist.id
|
||||
):
|
||||
await self._handle_playlist_id_changed(
|
||||
previous_playlist_id, current_playlist.id, sounds,
|
||||
previous_playlist_id,
|
||||
current_playlist.id,
|
||||
sounds,
|
||||
)
|
||||
elif previous_current_sound_id:
|
||||
await self._handle_same_playlist_track_check(
|
||||
@@ -432,7 +458,9 @@ class PlayerService:
|
||||
self._clear_current_track()
|
||||
|
||||
def _update_playlist_state(
|
||||
self, current_playlist: Playlist, sounds: list[Sound],
|
||||
self,
|
||||
current_playlist: Playlist,
|
||||
sounds: list[Sound],
|
||||
) -> None:
|
||||
"""Update basic playlist state information."""
|
||||
self.state.playlist_id = current_playlist.id
|
||||
@@ -464,7 +492,6 @@ class PlayerService:
|
||||
"""Get current player state."""
|
||||
return self.state.to_dict()
|
||||
|
||||
|
||||
def _get_next_index(self, current_index: int) -> int | None:
|
||||
"""Get next track index based on current mode."""
|
||||
if not self.state.playlist_sounds:
|
||||
@@ -497,11 +524,7 @@ class PlayerService:
|
||||
prev_index = current_index - 1
|
||||
|
||||
if prev_index < 0:
|
||||
return (
|
||||
playlist_length - 1
|
||||
if self.state.mode == PlayerMode.LOOP
|
||||
else None
|
||||
)
|
||||
return playlist_length - 1 if self.state.mode == PlayerMode.LOOP else None
|
||||
return prev_index
|
||||
|
||||
def _position_tracker(self) -> None:
|
||||
@@ -535,10 +558,7 @@ class PlayerService:
|
||||
|
||||
def _update_play_time(self) -> None:
|
||||
"""Update play time tracking for current sound."""
|
||||
if (
|
||||
not self.state.current_sound_id
|
||||
or self.state.status != PlayerStatus.PLAYING
|
||||
):
|
||||
if not self.state.current_sound_id or self.state.status != PlayerStatus.PLAYING:
|
||||
return
|
||||
|
||||
sound_id = self.state.current_sound_id
|
||||
@@ -577,10 +597,8 @@ class PlayerService:
|
||||
sound_id,
|
||||
tracking["total_time"],
|
||||
self.state.current_sound_duration,
|
||||
(
|
||||
tracking["total_time"]
|
||||
/ self.state.current_sound_duration
|
||||
) * 100,
|
||||
(tracking["total_time"] / self.state.current_sound_duration)
|
||||
* 100,
|
||||
)
|
||||
self._schedule_async_task(self._record_play_count(sound_id))
|
||||
|
||||
@@ -596,7 +614,8 @@ class PlayerService:
|
||||
if sound:
|
||||
old_count = sound.play_count
|
||||
await sound_repo.update(
|
||||
sound, {"play_count": sound.play_count + 1},
|
||||
sound,
|
||||
{"play_count": sound.play_count + 1},
|
||||
)
|
||||
logger.info(
|
||||
"Updated sound %s play_count: %s -> %s",
|
||||
|
||||
Reference in New Issue
Block a user