This commit is contained in:
2025-11-25 13:06:07 -05:00
parent 476c4e6e51
commit 85298b861d
3 changed files with 54 additions and 33 deletions

View File

@@ -80,9 +80,9 @@ class LyricSearch(FastAPI):
)
for endpoint, handler in self.endpoints.items():
times: int = 20
times: int = 5
seconds: int = 2
rate_limit: tuple[int, int] = (2, 3) # Default; (Times, Seconds)
rate_limit: tuple[int, int] = (times, seconds) # Default; (Times, Seconds)
_schema_include = endpoint in ["lyric/search"]
if (

View File

@@ -307,7 +307,7 @@ class Radio(FastAPI):
}
)
async def album_art_handler(
def album_art_handler(
self, request: Request, track_id: Optional[int] = None,
station: Station = "main"
) -> Response:
@@ -371,6 +371,14 @@ class Radio(FastAPI):
ret_obj.pop("file_path")
return JSONResponse(content=ret_obj)
def _bg_cache_art(self, track_id: int, file_path: str):
try:
album_art = self.radio_util.get_album_art(track_id=track_id)
if not album_art:
self.radio_util.cache_album_art(track_id, file_path)
except Exception as e:
logging.error(f"Background art cache error: {e}")
async def radio_get_next(
self,
data: ValidRadioNextRequest,
@@ -448,13 +456,7 @@ class Radio(FastAPI):
logging.info("radio_get_next Exception: %s", str(e))
traceback.print_exc()
try:
album_art = self.radio_util.get_album_art(track_id=next["id"])
if not album_art:
self.radio_util.cache_album_art(next["id"], next["file_path"])
except Exception as e:
logging.info("radio_get_next Exception: %s", str(e))
traceback.print_exc()
background_tasks.add_task(self._bg_cache_art, next["id"], next["file_path"])
return JSONResponse(content=next)
@@ -496,9 +498,13 @@ class Radio(FastAPI):
},
)
search: bool = self.radio_util.search_db(
loop = asyncio.get_running_loop()
search: bool = await loop.run_in_executor(
None,
lambda: self.radio_util.search_db(
artistsong=artistsong, artist=artist, song=song, station=data.station
)
)
if data.alsoSkip:
await self.radio_util._ls_skip(data.station)
return JSONResponse(content={"result": search})
@@ -764,7 +770,22 @@ class Radio(FastAPI):
logging.info(f"[LRC] Starting fetch for {station}: {artist} - {title}")
# Try SR first with timeout
# Try LRCLib first with timeout
try:
async with asyncio.timeout(10.0): # 10 second timeout
logging.info("[LRC] Trying LRCLib")
lrclib_result = await self.lrclib.search(artist, title, plain=False, raw=True)
if lrclib_result and lrclib_result.lyrics and isinstance(lrclib_result.lyrics, str):
logging.info("[LRC] Found from LRCLib")
return lrclib_result.lyrics, "LRCLib"
except asyncio.TimeoutError:
logging.warning("[LRC] LRCLib fetch timed out")
except Exception as e:
logging.error(f"[LRC] LRCLib fetch error: {e}")
logging.info("[LRC] LRCLib fetch completed without results")
# Try SR as fallback with timeout
try:
async with asyncio.timeout(10.0): # 10 second timeout
lrc = await self.sr_util.get_lrc_by_artist_song(
@@ -778,21 +799,6 @@ class Radio(FastAPI):
except Exception as e:
logging.error(f"[LRC] SR fetch error: {e}")
logging.info("[LRC] SR fetch completed without results")
# Try LRCLib as fallback with timeout
try:
async with asyncio.timeout(10.0): # 10 second timeout
logging.info("[LRC] Trying LRCLib fallback")
lrclib_result = await self.lrclib.search(artist, title, plain=False)
if lrclib_result and lrclib_result.lyrics and isinstance(lrclib_result.lyrics, str):
logging.info("[LRC] Found from LRCLib")
return lrclib_result.lyrics, "LRCLib"
except asyncio.TimeoutError:
logging.warning("[LRC] LRCLib fetch timed out")
except Exception as e:
logging.error(f"[LRC] LRCLib fetch error: {e}")
logging.info("[LRC] No lyrics found from any source")
return None, "None"
except Exception as e:
@@ -804,11 +810,21 @@ class Radio(FastAPI):
try:
async with self.lrc_cache_locks[station]:
self.lrc_cache.pop(station, None)
lrc, source = await self._fetch_and_cache_lrc(station, track_json)
async with self.lrc_cache_locks[station]:
# Verify we are still on the same song
current_track = self.radio_util.now_playing.get(station)
if current_track and current_track.get("uuid") == track_json.get("uuid"):
if lrc:
self.lrc_cache[station] = lrc
else:
self.lrc_cache[station] = None
else:
logging.info(f"[LRC] Discarding fetch result for {station} as track changed.")
return
if lrc:
await self.broadcast_lrc(station, lrc, source)
except Exception as e:

View File

@@ -26,6 +26,7 @@ class LRCLib:
song: str,
plain: Optional[bool] = True,
duration: Optional[int] = None,
raw: bool = False,
) -> Optional[LyricsResult]:
"""
LRCLib Local Database Search
@@ -34,6 +35,7 @@ class LRCLib:
song (str): the song to search
plain (bool): return plain lyrics (True) or synced lyrics (False)
duration (int): optional track duration for better matching
raw (bool): return raw LRC string instead of parsed object (only for synced)
Returns:
Optional[LyricsResult]: The result, if found - None otherwise.
"""
@@ -119,6 +121,9 @@ class LRCLib:
logging.info("No synced lyrics available on %s", self.label)
return None
returned_lyrics = best_match.synced_lyrics
if raw:
lrc_obj = returned_lyrics
else:
lrc_obj = self.datautils.create_lrc_object(returned_lyrics)
# Calculate match confidence