From 47089cc7cb58047c32c4b239656f0bf74bcd597e Mon Sep 17 00:00:00 2001 From: codey Date: Fri, 26 Sep 2025 12:36:20 -0400 Subject: [PATCH] Add LRC caching mechanism to optimize fetching and broadcasting of lyrics --- endpoints/radio.py | 48 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/endpoints/radio.py b/endpoints/radio.py index 8dd5894..c0d0c92 100644 --- a/endpoints/radio.py +++ b/endpoints/radio.py @@ -632,7 +632,19 @@ class Radio(FastAPI): artist: Optional[str] = track_data.get("artist") title: Optional[str] = track_data.get("song") # Changed from "title" to "song" duration: Optional[int] = track_data.get("duration") - + + # Check if LRC is already cached + cached_lrc = self.lrc_cache.get(station) + if cached_lrc: + logging.info("LRC found in cache, sending immediately.") + lrc_data: dict = { + "type": "lrc", + "data": cached_lrc, + "source": "Cache" + } + await websocket.send_text(json.dumps(lrc_data)) + return + if artist and title: logging.info(f"Fetching LRC for {artist} - {title} (duration: {duration})") lrc: Optional[str] = await self.sr_util.get_lrc_by_artist_song( @@ -646,7 +658,7 @@ class Radio(FastAPI): lrc = lrclib_result.lyrics source = "LRCLib" logging.info("LRC found via LRCLib fallback") - self.lrc_cache[station] = lrc + self.lrc_cache[station] = lrc # Cache the LRC for future use logging.info(f"LRC fetched: {lrc is not None}") if lrc: lrc_data: dict = { @@ -663,12 +675,34 @@ class Radio(FastAPI): """Broadcast LRC data to all connected clients for a station asynchronously.""" if station not in self.active_connections: return - + try: artist: Optional[str] = track_data.get("artist") title: Optional[str] = track_data.get("song") # Changed from "title" to "song" duration: Optional[int] = track_data.get("duration") - + + # Check if LRC is already cached + cached_lrc = self.lrc_cache.get(station) + if cached_lrc: + logging.info("LRC found in cache, broadcasting immediately.") + lrc_data: dict = { + "type": "lrc", + "data": cached_lrc, + "source": "Cache" + } + disconnected_clients = set() + for websocket in self.active_connections[station]: + try: + await websocket.send_text(json.dumps(lrc_data)) + except Exception as e: + logging.warning(f"Failed to send LRC to client: {e}") + disconnected_clients.add(websocket) + + # Remove failed connections + for websocket in disconnected_clients: + self.active_connections[station].discard(websocket) + return + if artist and title: logging.info(f"Broadcasting LRC fetch for {artist} - {title} (duration: {duration})") lrc: Optional[str] = await self.sr_util.get_lrc_by_artist_song( @@ -682,7 +716,7 @@ class Radio(FastAPI): lrc = lrclib_result.lyrics source = "LRCLib" logging.info("LRC found via LRCLib fallback") - self.lrc_cache[station] = lrc + self.lrc_cache[station] = lrc # Cache the LRC for future use logging.info(f"LRC fetched for broadcast: {lrc is not None}") if lrc: lrc_data: dict = { @@ -690,7 +724,7 @@ class Radio(FastAPI): "data": lrc, "source": source } - + # Send to all connected clients disconnected_clients = set() for websocket in self.active_connections[station]: @@ -699,7 +733,7 @@ class Radio(FastAPI): except Exception as e: logging.warning(f"Failed to send LRC to client: {e}") disconnected_clients.add(websocket) - + # Remove failed connections for websocket in disconnected_clients: self.active_connections[station].discard(websocket)