Source code for andesite.models.player

"""Player models.

Attributes:
    MixerMap (Dict[str, MixerPlayer]): (Type alias) Mapping from player id to `MixerPlayer`
"""

import abc
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, Optional, cast

from andesite.transform import RawDataType, from_centi, from_milli, map_build_all_values_from_raw, \
    map_build_values_from_raw, map_convert_values, \
    map_convert_values_from_milli, map_convert_values_to_milli, to_centi, to_milli, transform_input
from .filters import FilterMap

__all__ = ["PlayerFrameStats", "BasePlayer", "MixerPlayer", "MixerMap", "Player"]


[docs]@dataclass class PlayerFrameStats: """Frame statistics of a player.""" loss: int success: int usable: bool
[docs]@dataclass class BasePlayer(abc.ABC): """Abstract class for Andesite players. See Also: - `Player` - `MixerPlayer` Attributes: time (datetime): current utc datetime on the node position (Optional[float]): position of the current playing track, or `None` if nothing is playing paused (bool): whether or not the player is paused volume (float): the volume of the player filters (FilterMap): map of filter name -> filter settings for each filter present frame (PlayerFrameStats) Player frame stats """ time: datetime position: Optional[float] paused: bool volume: float filters: FilterMap frame: PlayerFrameStats @property def live_position(self) -> Optional[float]: """Interpolated version of :py:attr:`position` based on the time that has passed. Returns: `None` if there is no position attribute, equal to position if the player is paused, and interpolated otherwise. """ if not self.position: return None if self.paused: return self.position return self.position + (datetime.utcnow() - self.time).total_seconds() @classmethod def __transform_input__(cls, data: RawDataType) -> None: map_convert_values_from_milli(data, "position") map_convert_values(data, volume=from_centi) map_build_values_from_raw(data, filters=FilterMap, frame=PlayerFrameStats) time_float = from_milli(int(data["time"])) data["time"] = datetime.utcfromtimestamp(time_float) @classmethod def __transform_output__(cls, data: RawDataType) -> None: map_convert_values_to_milli(data, "position") map_convert_values(data, volume=to_centi) data["time"] = to_milli(cast(datetime, data["time"]).timestamp())
[docs]@dataclass class MixerPlayer(BasePlayer): """Player used by `Player` as a mixer player. See Also: `BasePlayer` """ ...
MixerMap = Dict[str, MixerPlayer]
[docs]@dataclass class Player(BasePlayer): """ Attributes: mixer (MixerMap): map of mixer player id -> mixer player mixer_enabled (bool): whether or not the mixer is the current source of audio """ mixer: MixerMap mixer_enabled: bool @classmethod def __transform_input__(cls, data: RawDataType) -> RawDataType: data = transform_input(super(), data) map_build_all_values_from_raw(data["mixer"], MixerPlayer) return data