feat: streamlit api

This commit is contained in:
Radu C. Martin 2025-04-11 13:04:34 +02:00
parent bdf44bcd94
commit 573429acd2
3 changed files with 74 additions and 61 deletions

View file

@ -3,7 +3,7 @@ import time
from enum import Enum
import pygame
from pydantic import BaseModel
from pydantic import BaseModel, Field
class PlayerState(Enum):
@ -16,23 +16,26 @@ class Track(BaseModel):
artist: str
title: str
duration: int
filepath: str
filepath: str = Field(hidden=True) # don't show it in API responses
class Queue:
queue: list[Track]
def __init__(self) -> None:
self.queue: list[Track] = []
self._queue: list[Track] = []
def next(self) -> Track | None:
if len(self.queue) > 0:
return self.queue.pop(0)
if len(self._queue) > 0:
return self._queue.pop(0)
else:
return None
def add(self, track: Track) -> None:
self.queue.append(track)
self._queue.append(track)
def len(self) -> int:
return len(self._queue)
class MusicPlayer:
@ -47,67 +50,74 @@ class MusicPlayer:
self.thread.start()
# Music Player
self.queue: Queue = Queue()
self._current_track: Track | None = None
self.current_track: Track | None = None
self._state: PlayerState = PlayerState.Stopped
# State change flags
self._queue_changed: bool = False
self._track_changed: bool = False
def _loop(self):
while self._running:
for event in pygame.event.get():
if event.type == pygame.USEREVENT:
if self._current_track:
print(f"Track {self._current_track.title} ended")
if event.type == pygame.USEREVENT: # a song just ended
if self.current_track:
print(f"Track {self.current_track.title} ended")
self._play_next_track()
time.sleep(0.1)
def _load_track(self, track: Track):
with self.lock:
self.current_track = track
pygame.mixer.music.unload()
pygame.mixer.music.load(self.current_track.filepath)
self.current_track = track
pygame.mixer.music.unload()
pygame.mixer.music.load(self.current_track.filepath)
def _play_next_track(self):
next_track = self.queue.next()
if next_track:
self._load_track(next_track)
pygame.mixer.music.play()
self._state = PlayerState.Playing
def add_to_queue(self, track: Track):
self.queue.add(track)
with self.lock:
que_len = self.queue.len()
self.queue.add(track)
# If queue is empty and no corrent track, start playing
if que_len == 0 and not self.current_track:
self._play_next_track()
def play(self):
if self._current_track:
with self.lock:
with self.lock:
if self.current_track:
pygame.mixer.music.play()
else:
self._play_next_track()
self._state = PlayerState.Playing
self._state = PlayerState.Playing
else:
self._play_next_track()
def pause(self):
with self.lock:
pygame.mixer.music.pause()
self._state = PlayerState.Paused
print("Set player state to Paused")
self._state = PlayerState.Paused
def resume(self):
with self.lock:
pygame.mixer.music.unpause()
self._state = PlayerState.Playing
print("Set player state to Playing")
self._state = PlayerState.Playing
def stop(self):
with self.lock:
pygame.mixer.music.stop()
self._state = PlayerState.Stopped
self._current_track = None
self._state = PlayerState.Stopped
self.current_track = None
def shutdown(self):
self._running = False
self.thread.join()
pygame.mixer.quit()
with self.lock:
self._running = False
self.thread.join()
pygame.mixer.quit()
def get_queue(self) -> Queue:
return self.queue
return self.queue._queue
def set_volume(self, volume: float):
with self.lock:
@ -120,4 +130,4 @@ class MusicPlayer:
return self._state
def get_current_track(self) -> Track | None:
return self._current_track
return self.current_track