From d1068dec2a1f2d4485dbf489685d45f9cfbb5c72 Mon Sep 17 00:00:00 2001 From: Marvin Schenkel Date: Mon, 29 Sep 2025 21:33:32 +0200 Subject: [PATCH] Few smart fades fixes (#2442) --- music_assistant/controllers/music.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/music_assistant/controllers/music.py b/music_assistant/controllers/music.py index f7bd003a..33e609d0 100644 --- a/music_assistant/controllers/music.py +++ b/music_assistant/controllers/music.py @@ -3,7 +3,6 @@ from __future__ import annotations import asyncio -import json import logging import os import shutil @@ -67,7 +66,8 @@ from music_assistant.helpers.api import api_command from music_assistant.helpers.compare import compare_strings, compare_version, create_safe_string from music_assistant.helpers.database import DatabaseConnection from music_assistant.helpers.datetime import utc_timestamp -from music_assistant.helpers.json import json_loads, serialize_to_json +from music_assistant.helpers.json import json_dumps, json_loads, serialize_to_json +from music_assistant.helpers.smart_fades import SMART_CROSSFADE_DURATION from music_assistant.helpers.tags import split_artists from music_assistant.helpers.uri import parse_uri from music_assistant.helpers.util import TaskManager, parse_title_and_version @@ -846,16 +846,23 @@ class MusicController(CoreController): """Store Smart Fades BPM analysis for a track in db.""" if not (provider := self.mass.get_provider(provider_instance_id_or_domain)): return - if analysis.bpm <= 0 or analysis.confidence < 0: - # skip invalid values + if ( + analysis.duration <= 0.75 * SMART_CROSSFADE_DURATION + or analysis.bpm <= 0 + or analysis.confidence < 0 + ): + # skip invalid values, we skip analysis that were performed on + # a short amount of audio as those are often unreliable return + beats_json = await asyncio.to_thread(lambda: json_dumps(analysis.beats.tolist())) + downbeats_json = await asyncio.to_thread(lambda: json_dumps(analysis.downbeats.tolist())) values = { "fragment": analysis.fragment.value, "item_id": item_id, "provider": provider.lookup_key, "bpm": analysis.bpm, - "beats": json.dumps(analysis.beats.tolist()), - "downbeats": json.dumps(analysis.downbeats.tolist()), + "beats": beats_json, + "downbeats": downbeats_json, "confidence": analysis.confidence, "duration": analysis.duration, } @@ -879,11 +886,13 @@ class MusicController(CoreController): }, ) if db_row and db_row["bpm"] > 0: + beats = await asyncio.to_thread(lambda: np.array(json_loads(db_row["beats"]))) + downbeats = await asyncio.to_thread(lambda: np.array(json_loads(db_row["downbeats"]))) return SmartFadesAnalysis( fragment=SmartFadesAnalysisFragment(db_row["fragment"]), bpm=float(db_row["bpm"]), - beats=np.array(json.loads(db_row["beats"])), - downbeats=np.array(json.loads(db_row["downbeats"])), + beats=beats, + downbeats=downbeats, confidence=float(db_row["confidence"]), duration=float(db_row["duration"]), ) -- 2.34.1