Skip to content

Commit 30cb776

Browse files
authored
Typing fixes for the squeezelite provider (#2589)
1 parent 69b35e6 commit 30cb776

File tree

3 files changed

+21
-34
lines changed

3 files changed

+21
-34
lines changed

music_assistant/providers/squeezelite/multi_client_stream.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from music_assistant_models.media_items import AudioFormat
99

10-
from music_assistant.helpers.audio import get_ffmpeg_stream
10+
from music_assistant.helpers.ffmpeg import get_ffmpeg_stream
1111
from music_assistant.helpers.util import empty_queue
1212

1313
LOGGER = logging.getLogger(__name__)

music_assistant/providers/squeezelite/player.py

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
PlayerType,
2424
RepeatMode,
2525
)
26-
from music_assistant_models.errors import MusicAssistantError
26+
from music_assistant_models.errors import (
27+
InvalidCommand,
28+
MusicAssistantError,
29+
)
2730
from music_assistant_models.media_items import AudioFormat
2831

2932
from music_assistant.constants import (
@@ -34,7 +37,6 @@
3437
CONF_ENTRY_OUTPUT_CODEC,
3538
CONF_ENTRY_SUPPORT_CROSSFADE_DIFFERENT_SAMPLE_RATES,
3639
CONF_ENTRY_SYNC_ADJUST,
37-
CONF_SAMPLE_RATES,
3840
INTERNAL_PCM_FORMAT,
3941
VERBOSE_LOG_LEVEL,
4042
create_sample_rates_config_entry,
@@ -220,7 +222,7 @@ async def play_media(self, media: PlayerMedia) -> None:
220222
"""Handle PLAY MEDIA on the player."""
221223
if self.synced_to:
222224
msg = "A synced player cannot receive play commands directly"
223-
raise RuntimeError(msg)
225+
raise InvalidCommand(msg)
224226

225227
if not self.group_members:
226228
# Simple, single-player playback
@@ -234,32 +236,14 @@ async def play_media(self, media: PlayerMedia) -> None:
234236
return
235237

236238
# this is a syncgroup, we need to handle this with a multi client stream
237-
# Get the minimum supported sample rate across all group members (LCD)
238-
min_sample_rate = 192000 # Start high
239-
for member_id in [self.player_id, *self.group_members]:
240-
supported_rates_conf = cast(
241-
"list[tuple[str, str]]",
242-
await self.mass.config.get_player_config_value(
243-
member_id, CONF_SAMPLE_RATES, unpack_splitted_values=True
244-
),
245-
)
246-
if supported_rates_conf:
247-
member_max_rate = max(int(x[0]) for x in supported_rates_conf)
248-
min_sample_rate = min(min_sample_rate, member_max_rate)
249-
250-
# For queue streams, further cap to content sample rate
251-
if media.source_id and media.queue_item_id:
252-
queue_item = self.mass.player_queues.get_item(media.source_id, media.queue_item_id)
253-
min_sample_rate = min(
254-
min_sample_rate, queue_item.streamdetails.audio_format.sample_rate
255-
)
256-
239+
# Use a fixed 96kHz/24-bit format for syncgroup playback
257240
master_audio_format = AudioFormat(
258241
content_type=INTERNAL_PCM_FORMAT.content_type,
259-
sample_rate=min_sample_rate,
260-
bit_depth=INTERNAL_PCM_FORMAT.bit_depth, # 32-bit float for processing
242+
sample_rate=96000,
243+
bit_depth=24,
261244
channels=2,
262245
)
246+
263247
# select audio source
264248
audio_source = self.mass.streams.get_stream(media, master_audio_format)
265249
# start the stream task
@@ -307,7 +291,7 @@ async def set_members(
307291
"""Handle SET_MEMBERS command on the player."""
308292
if self.synced_to:
309293
# this should not happen, but guard anyways
310-
raise RuntimeError("Player is synced, cannot set members")
294+
raise InvalidCommand("Player is synced, cannot set members")
311295
if not player_ids_to_add and not player_ids_to_remove:
312296
# nothing to do
313297
return
@@ -329,7 +313,7 @@ async def set_members(
329313
if player_id == self.player_id or player_id in self.group_members:
330314
# nothing to do: player is already part of the group
331315
continue
332-
child_player: SqueezelitePlayer | None = self.mass.players.get(player_id)
316+
child_player = cast("SqueezelitePlayer | None", self.mass.players.get(player_id))
333317
if not child_player:
334318
# should not happen, but guard against it
335319
continue
@@ -421,7 +405,7 @@ async def _handle_play_url_for_slimplayer(
421405
"source_id": media.source_id,
422406
"queue_item_id": media.queue_item_id,
423407
}
424-
if queue := self.mass.player_queues.get(media.source_id):
408+
if media.source_id and (queue := self.mass.player_queues.get(media.source_id)):
425409
self.extra_data["playlist repeat"] = REPEATMODE_MAP[queue.repeat_mode]
426410
self.extra_data["playlist shuffle"] = int(queue.shuffle_enabled)
427411
await slimplayer.play_url(
@@ -509,6 +493,8 @@ async def _handle_player_cli_event(self, event: SlimEvent) -> None:
509493
# TODO: fix this in the aioslimproto lib
510494
event_data = cast("str", event.data)
511495
queue = self.mass.player_queues.get_active_queue(self.player_id)
496+
if not queue:
497+
return
512498
if event_data.startswith("button preset_") and event_data.endswith(".single"):
513499
preset_id = event_data.split("preset_")[1].split(".")[0]
514500
preset_index = int(preset_id) - 1
@@ -546,7 +532,9 @@ def _handle_sync(self) -> None:
546532
if not sync_master_id:
547533
# we only correct sync members, not the sync master itself
548534
return
549-
if not (sync_master := self.provider.slimproto.get_player(sync_master_id)):
535+
if not self._provider.slimproto or not (
536+
sync_master := self._provider.slimproto.get_player(sync_master_id)
537+
):
550538
return # just here as a guard as bad things can happen
551539

552540
if sync_master.state != SlimPlayerState.PLAYING:
@@ -571,8 +559,8 @@ def _handle_sync(self) -> None:
571559
sync_playpoints.clear()
572560

573561
diff = int(
574-
self.provider.get_corrected_elapsed_milliseconds(sync_master)
575-
- self.provider.get_corrected_elapsed_milliseconds(self.client)
562+
self._provider.get_corrected_elapsed_milliseconds(sync_master)
563+
- self._provider.get_corrected_elapsed_milliseconds(self.client)
576564
)
577565

578566
sync_playpoints.append(SyncPlayPoint(now, sync_master.player_id, diff))
@@ -621,7 +609,7 @@ async def _set_preset_items(self) -> None:
621609
self.player_id, f"preset_{preset_index}"
622610
):
623611
try:
624-
media_item = await self.mass.music.get_item_by_uri(preset_conf)
612+
media_item = await self.mass.music.get_item_by_uri(cast("str", preset_conf))
625613
preset_items.append(
626614
SlimPreset(
627615
uri=media_item.uri,

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ exclude = [
149149
'^music_assistant/providers/chromecast/.*$',
150150
'^music_assistant/providers/qobuz/.*$',
151151
'^music_assistant/providers/siriusxm/.*$',
152-
'^music_assistant/providers/squeezelite/.*$',
153152
'^music_assistant/providers/sonos/.*$',
154153
'^music_assistant/providers/snapcast/.*$',
155154
'^music_assistant/providers/ytmusic/.*$',

0 commit comments

Comments
 (0)