From 7298a71a6f961aeff3105b6078134b976912ef50 Mon Sep 17 00:00:00 2001 From: David Trattnig <david@subsquare.at> Date: Mon, 2 Oct 2023 16:01:27 +0200 Subject: [PATCH] refactor: play state as part of domain models --- src/aura_engine/engine.py | 19 +++----------- src/aura_engine/scheduling/domain.py | 35 ++++++++++++++++++++++--- src/aura_engine/scheduling/scheduler.py | 7 ++--- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/aura_engine/engine.py b/src/aura_engine/engine.py index add5809e..75fb027b 100644 --- a/src/aura_engine/engine.py +++ b/src/aura_engine/engine.py @@ -235,17 +235,6 @@ class Player: INSTANT = "instant" FADE = "fade" - class ItemPlayState(str, Enum): - """ - Play-state of a playlist item. - """ - - UNKNOWN = "unknown" - LOADING = "loading" - READY = "ready_to_play" - PLAYING = "playing" - FINISHED = "finished" - config = None logger = None channels = None @@ -286,7 +275,7 @@ class Player: """ is_queue = item.get_content_type() in ResourceClass.FILE.types metadata = ResourceUtil.generate_track_metadata(item, not is_queue) - item.status = Player.ItemPlayState.LOADING + item.status = PlaylistItem.PlayStatus.LOADING self.logger.debug(SU.pink(f"Loading item '{item}'")) uri = None is_ready = False @@ -316,7 +305,7 @@ class Player: is_ready = item.channel.load(uri, metadata=metadata) if is_ready: - item.status = Player.ItemPlayState.READY + item.status = PlaylistItem.PlayStatus.READY self.event_dispatcher.on_queue([item]) def preload_group(self, items: list(PlaylistItem)): @@ -349,14 +338,14 @@ class Player: for item in items: item.channel = free_channel - item.status = Player.ItemPlayState.LOADING + item.status = PlaylistItem.PlayStatus.LOADING self.logger.debug(SU.pink(f"Loading item '{item}'")) # Choose and save the input channel metadata = ResourceUtil.generate_track_metadata(item) file_path = ResourceUtil.source_to_filepath(item.source, self.config) if item.channel.load(file_path, metadata): - item.status = Player.ItemPlayState.READY + item.status = PlaylistItem.PlayStatus.READY self.event_dispatcher.on_queue(items) return channels diff --git a/src/aura_engine/scheduling/domain.py b/src/aura_engine/scheduling/domain.py index 722ac4f0..0e503aec 100644 --- a/src/aura_engine/scheduling/domain.py +++ b/src/aura_engine/scheduling/domain.py @@ -35,7 +35,6 @@ from typing import NamedTuple from aura_engine.base.utils import SimpleUtil from aura_engine.core.channels import GenericChannel -from aura_engine.engine import Player from aura_engine.resources import ResourceType, ResourceUtil from aura_engine.scheduling.utils import ItemQueueState @@ -294,11 +293,11 @@ class PlaylistItem: volume (int): Value from 0-100% indicating loudness. source (str): URI referencing the audio source. + play_status (PlaylistItem.PlayStatus): Play-out state, set when playing starts. play_start_time (int): UNIX epoch, when item actually started playing. \ Not necessary matching `start`. play_channel (GenericChannel): Play-out channel, set when item is starts playing. play_queue_state (ItemQueueState): Progress on queuing, set when item is queued. - play_status (Player.ItemPlayState): Play-out state, set when playing starts. """ @@ -309,13 +308,25 @@ class PlaylistItem: source: str duration: int volume: int + Metadata = NamedTuple("Metadata", [("artist", str), ("album", str), ("title", str)]) metadata: Metadata + class PlayStatus(str, enum.Enum): + """ + Play-state of a playlist item. + """ + + UNKNOWN = "unknown" + LOADING = "loading" + READY = "ready_to_play" + PLAYING = "playing" + FINISHED = "finished" + + play_status: PlayStatus play_start_time: int play_channel: GenericChannel play_queue_state: ItemQueueState - play_status: Player.ItemPlayState def __init__(self, source: str, duration: int, volume: int, metadata: Metadata): self.prev = None @@ -414,6 +425,24 @@ class PlaylistItem: else: return [] + def set_play_status(self, status: PlayStatus): + """ + Set the play-out status of the current item. + + Args: + status (PlayStatus): Info on the play status. + """ + self.play_status = status + + def get_play_status(self): + """ + Returns the play-out status. + + Returns: + PlayStatus: Info on the items is being played, buffered etc. + """ + return self.play_status + def __str__(self): """ String representation. diff --git a/src/aura_engine/scheduling/scheduler.py b/src/aura_engine/scheduling/scheduler.py index 54b02a85..387eda71 100644 --- a/src/aura_engine/scheduling/scheduler.py +++ b/src/aura_engine/scheduling/scheduler.py @@ -31,6 +31,7 @@ from aura_engine.control import EngineExecutor from aura_engine.core.channels import LoadSourceException from aura_engine.engine import Engine, Player from aura_engine.resources import ResourceClass, ResourceUtil +from aura_engine.scheduling.domain import PlaylistItem from aura_engine.scheduling.models import AuraDatabaseModel from aura_engine.scheduling.timetable import TimetableService from aura_engine.scheduling.utils import TimetableRenderer @@ -552,7 +553,7 @@ class PlayCommand(EngineExecutor): except LoadSourceException as e: self.logger.critical(SU.red(f"Could not preload items {items_str}"), e) - if items[-1].status != Player.ItemPlayState.READY: + if items[-1].status != PlaylistItem.PlayStatus.READY: msg = f"Items didn't reach 'ready' state during preloading (Items: {items_str})" self.logger.warning(SU.red(msg)) @@ -562,11 +563,11 @@ class PlayCommand(EngineExecutor): """ items_str = ResourceUtil.get_items_string(items) self.logger.info(SU.cyan(f"=== play('{items_str}') ===")) - if items[-1].status != Player.ItemPlayState.READY: + if items[-1].status != PlaylistItem.PlayStatus.READY: # Let 'em play anyway ... msg = f"PLAY: Item(s) not yet ready to be played" f" (Items: {items_str})" self.logger.critical(SU.red(msg)) - while items[-1].status != Player.ItemPlayState.READY: + while items[-1].status != PlaylistItem.PlayStatus.READY: self.logger.info("PLAY: Wait a little bit until preloading is done ...") time.sleep(2) -- GitLab