Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frontend-2.2.0 #1078

Merged
merged 3 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 18 additions & 53 deletions music_assistant/server/providers/dlna/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ def catch_request_errors(
"""Catch UpnpError errors."""

@functools.wraps(func)
async def wrapper(
self: _DLNAPlayerProviderT, *args: _P.args, **kwargs: _P.kwargs
) -> _R | None:
async def wrapper(self: _DLNAPlayerProviderT, *args: _P.args, **kwargs: _P.kwargs) -> _R | None:
"""Catch UpnpError errors and check availability before and after request."""
player_id = kwargs["player_id"] if "player_id" in kwargs else args[0]
dlna_player = self.dlnaplayers[player_id]
Expand All @@ -164,9 +162,7 @@ async def wrapper(
dlna_player.player.display_name,
)
if not dlna_player.available:
self.logger.warning(
"Device disappeared when trying to call %s", func.__name__
)
self.logger.warning("Device disappeared when trying to call %s", func.__name__)
return None
try:
return await func(self, *args, **kwargs)
Expand Down Expand Up @@ -287,9 +283,7 @@ async def handle_setup(self) -> None:
"""Handle async initialization of the provider."""
self.dlnaplayers = {}
self.lock = asyncio.Lock()
self.requester = AiohttpSessionRequester(
self.mass.http_session, with_sleep=True
)
self.requester = AiohttpSessionRequester(self.mass.http_session, with_sleep=True)
self.upnp_factory = UpnpFactory(self.requester, non_strict=True)
self.notify_server = DLNANotifyServer(self.requester, self.mass)
self.mass.create_task(self._run_discovery())
Expand Down Expand Up @@ -359,12 +353,8 @@ async def play_media(
- seek_position: Optional seek to this position.
- fade_in: Optionally fade in the item at playback start.
"""
use_flow_mode = await self.mass.config.get_player_config_value(
player_id, CONF_FLOW_MODE
)
enforce_mp3 = await self.mass.config.get_player_config_value(
player_id, CONF_ENFORCE_MP3
)
use_flow_mode = await self.mass.config.get_player_config_value(player_id, CONF_FLOW_MODE)
enforce_mp3 = await self.mass.config.get_player_config_value(player_id, CONF_ENFORCE_MP3)
url = await self.mass.streams.resolve_stream_url(
queue_item=queue_item,
output_codec=ContentType.MP3 if enforce_mp3 else ContentType.FLAC,
Expand Down Expand Up @@ -396,26 +386,20 @@ async def play_media(
await self.poll_player(dlna_player.udn)

@catch_request_errors
async def play_stream(
self, player_id: str, stream_job: MultiClientStreamJob
) -> None:
async def play_stream(self, player_id: str, stream_job: MultiClientStreamJob) -> None:
"""Handle PLAY STREAM on given player.

This is a special feature from the Universal Group provider.
"""
enforce_mp3 = await self.mass.config.get_player_config_value(
player_id, CONF_ENFORCE_MP3
)
enforce_mp3 = await self.mass.config.get_player_config_value(player_id, CONF_ENFORCE_MP3)
output_codec = ContentType.MP3 if enforce_mp3 else ContentType.FLAC
url = stream_job.resolve_stream_url(player_id, output_codec)
dlna_player = self.dlnaplayers[player_id]
# always clear queue (by sending stop) first
if dlna_player.device.can_stop:
await self.cmd_stop(player_id)
didl_metadata = create_didl_metadata(self.mass, url, None)
await dlna_player.device.async_set_transport_uri(
url, "Music Assistant", didl_metadata
)
await dlna_player.device.async_set_transport_uri(url, "Music Assistant", didl_metadata)
# Play it
await dlna_player.device.async_wait_for_can_play(10)
# optimistically set this timestamp to help in case of a player
Expand All @@ -431,9 +415,7 @@ async def play_stream(
await self.poll_player(dlna_player.udn)

@catch_request_errors
async def enqueue_next_queue_item(
self, player_id: str, queue_item: QueueItem
) -> None:
async def enqueue_next_queue_item(self, player_id: str, queue_item: QueueItem) -> None:
"""Handle enqueuing of the next queue item on the player."""
dlna_player = self.dlnaplayers[player_id]
url = await self.mass.streams.resolve_stream_url(
Expand Down Expand Up @@ -552,9 +534,7 @@ async def on_response(discovery_info: CaseInsensitiveDict) -> None:

# we iterate between using a regular and multicast search (if enabled)
if allow_network_scan and use_multicast:
await async_search(
on_response, target=(str(IPv4Address("255.255.255.255")), 1900)
)
await async_search(on_response, target=(str(IPv4Address("255.255.255.255")), 1900))
else:
await async_search(on_response)

Expand Down Expand Up @@ -590,10 +570,7 @@ async def _device_discovered(self, udn: str, description_url: str) -> None:
async with self.lock:
if dlna_player := self.dlnaplayers.get(udn):
# existing player
if (
dlna_player.description_url == description_url
and dlna_player.player.available
):
if dlna_player.description_url == description_url and dlna_player.player.available:
# nothing to do, device is already connected
return
# update description url to newly discovered one
Expand Down Expand Up @@ -649,14 +626,10 @@ async def _device_connect(self, dlna_player: DLNAPlayer) -> None:
return

# Connect to the base UPNP device
upnp_device = await self.upnp_factory.async_create_device(
dlna_player.description_url
)
upnp_device = await self.upnp_factory.async_create_device(dlna_player.description_url)

# Create profile wrapper
dlna_player.device = DmrDevice(
upnp_device, self.notify_server.event_handler
)
dlna_player.device = DmrDevice(upnp_device, self.notify_server.event_handler)

# Subscribe to event notifications
try:
Expand All @@ -670,9 +643,7 @@ async def _device_connect(self, dlna_player: DLNAPlayer) -> None:
# Don't leave the device half-constructed
dlna_player.device.on_event = None
dlna_player.device = None
self.logger.debug(
"Error while subscribing during device connect: %r", err
)
self.logger.debug("Error while subscribing during device connect: %r", err)
raise
else:
# connect was successful, update device info
Expand Down Expand Up @@ -701,13 +672,9 @@ def _handle_event(
for state_variable in state_variables:
# Force a state refresh when player begins or pauses playback
# to update the position info.
if (
state_variable.name == "TransportState"
and state_variable.value
in (
TransportState.PLAYING,
TransportState.PAUSED_PLAYBACK,
)
if state_variable.name == "TransportState" and state_variable.value in (
TransportState.PLAYING,
TransportState.PAUSED_PLAYBACK,
):
dlna_player.force_poll = True
self.mass.create_task(self.poll_player(dlna_player.udn))
Expand Down Expand Up @@ -739,9 +706,7 @@ def _set_player_features(self, dlna_player: DLNAPlayer) -> None:
"""Set Player Features based on config values and capabilities."""
dlna_player.player.supported_features = BASE_PLAYER_FEATURES
player_id = dlna_player.player.player_id
if self.mass.config.get_raw_player_config_value(
player_id, CONF_ENQUEUE_NEXT, False
):
if self.mass.config.get_raw_player_config_value(player_id, CONF_ENQUEUE_NEXT, False):
dlna_player.player.supported_features = (
*dlna_player.player.supported_features,
PlayerFeature.ENQUEUE_NEXT,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ server = [
"python-slugify==8.0.4",
"mashumaro==3.12",
"memory-tempfile==2.2.3",
"music-assistant-frontend==2.1.2",
"music-assistant-frontend==2.2.0",
"pillow==10.2.0",
"unidecode==1.3.8",
"xmltodict==0.13.0",
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ifaddr==0.2.0
jellyfin_apiclient_python==1.9.2
mashumaro==3.12
memory-tempfile==2.2.3
music-assistant-frontend==2.1.2
music-assistant-frontend==2.2.0
orjson==3.9.13
pillow==10.2.0
plexapi==4.15.9
Expand Down