await self._handle_cmd_resume(player_id, source, media)
@api_command("players/cmd/seek")
+ @handle_player_command
async def cmd_seek(self, player_id: str, position: int) -> None:
"""Handle SEEK command for given player.
await player.seek(position)
@api_command("players/cmd/next")
+ @handle_player_command
async def cmd_next_track(self, player_id: str) -> None:
"""Handle NEXT TRACK command for given player."""
player = self._get_player_with_redirect(player_id)
raise UnsupportedFeaturedException(msg)
@api_command("players/cmd/previous")
+ @handle_player_command
async def cmd_previous_track(self, player_id: str) -> None:
"""Handle PREVIOUS TRACK command for given player."""
player = self._get_player_with_redirect(player_id)
# Confirmed external source takeover
self.logger.info(
- "External source '%s' took over on %s while grouped via protocol %s - "
+ "External source '%s' took over on %s while playing via protocol %s - "
"clearing active output protocol and ungrouping",
new_source,
player.display_name,
return # nothing to do
# ungroup player at power off
- player_was_synced = player.state.synced_to is not None
+ player_was_synced = bool(player.state.synced_to or player.group_members)
if player.type == PlayerType.PLAYER and not powered:
# ungroup player if it is synced (or is a sync leader itself)
# NOTE: ungroup will be ignored if the player is not grouped or synced
)
return
+ # this should not happen, but in case a player_id of a protocol player is used,
+ # auto-resolve it to the parent player
+ if player.protocol_parent_id and (
+ protocol_parent := self._players.get(player.protocol_parent_id)
+ ):
+ player = protocol_parent
+ if "player_id" in kwargs:
+ kwargs["player_id"] = protocol_parent.player_id
+ else:
+ args = (protocol_parent.player_id, *args[1:]) # type: ignore[assignment]
+ self.logger.info(
+ "Auto-resolved protocol player %s to linked parent %s for command %s",
+ player_id,
+ protocol_parent.player_id,
+ fn.__name__,
+ )
+
current_user = get_current_user()
if (
current_user
)
async def execute() -> None:
- async with self._player_throttlers[player_id]:
+ async with self._player_throttlers[player.player_id]:
try:
await fn(self, *args, **kwargs)
except Exception as err: