From 7ae894cdfd31069f9026be82b275f5e2a13c21a5 Mon Sep 17 00:00:00 2001 From: Christoph Stahl Date: Mon, 23 Jun 2025 23:55:14 +0200 Subject: [PATCH] Added configuration options for "Next Up Box" (Issue #13) --- syng/client.py | 11 ++++++----- syng/gui.py | 5 +++++ syng/player_libmpv.py | 14 +++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/syng/client.py b/syng/client.py index 2f4d479..f4c5ed9 100644 --- a/syng/client.py +++ b/syng/client.py @@ -81,13 +81,14 @@ def default_config() -> dict[str, Optional[int | str]]: "server": "https://syng.rocks", "room": "", "preview_duration": 3, + "next_up_position": "top", "secret": None, "last_song": None, "waiting_room_policy": None, "key": None, "buffer_in_advance": 2, - "qr_box_size": 5, - "qr_position": "bottom-right", + "qr_box_size": 7, + "qr_position": "top-right", "show_advanced": False, "log_level": "info", } @@ -121,6 +122,8 @@ class State: * `preview_duration` (`Optional[int]`): The duration in seconds the playback client shows a preview for the next song. This is accounted for in the calculation of the ETA for songs later in the queue. + * `next_up_position` (`str`): The position of the "next up" box on the screen. + Possible values are: top or bottom. * `last_song` (`Optional[datetime.datetime]`): A timestamp, defining the end of the queue. * `waiting_room_policy` (Optional[str]): One of: @@ -168,9 +171,7 @@ class Client: self.currentLock = asyncio.Semaphore(0) self.buffer_in_advance = config["config"]["buffer_in_advance"] self.player = Player( - f"{config['config']['server']}/{config['config']['room']}", - 1 if config["config"]["qr_box_size"] < 1 else config["config"]["qr_box_size"], - QRPosition.from_string(config["config"]["qr_position"]), + config["config"], self.quit_callback, self.state.queue, ) diff --git a/syng/gui.py b/syng/gui.py index 7f7eb98..9a99ae4 100644 --- a/syng/gui.py +++ b/syng/gui.py @@ -483,6 +483,11 @@ class GeneralConfig(OptionFrame): self.add_int_option( "preview_duration", "Preview duration in seconds", int(config["preview_duration"]) ) + self.add_int_option( + "next_up_time", + "Time remaining before Next Up Box is shown", + int(config["next_up_time"]), + ) self.add_string_option( "key", "Key for server (if necessary)", config["key"], is_password=True ) diff --git a/syng/player_libmpv.py b/syng/player_libmpv.py index 5c03569..f44e94e 100644 --- a/syng/player_libmpv.py +++ b/syng/player_libmpv.py @@ -2,7 +2,7 @@ import asyncio from enum import Enum import locale import sys -from typing import Callable, Iterable, Optional, cast +from typing import Any, Callable, Iterable, Optional, cast from qrcode.main import QRCode import mpv import os @@ -34,13 +34,12 @@ class QRPosition(Enum): class Player: def __init__( self, - qr_string: str, - qr_box_size: int, - qr_position: QRPosition, + config: dict[str, Any], quit_callback: Callable[[], None], queue: Optional[list[Entry]] = None, ) -> None: locale.setlocale(locale.LC_ALL, "C") + qr_string = f"{config['server']}/{config['room']}" self.queue = queue if queue is not None else [] self.base_dir = f"{os.path.dirname(__file__)}/static" @@ -49,8 +48,9 @@ class Player: self.closing = False self.mpv: Optional[mpv.MPV] = None self.qr_overlay: Optional[mpv.ImageOverlay] = None - self.qr_box_size = qr_box_size - self.qr_position = qr_position + self.qr_box_size = 1 if config["qr_box_size"] < 1 else config["qr_box_size"] + self.qr_position = QRPosition.from_string(config["qr_position"]) + self.next_up_time = config.get("next_up_time", 20) self.update_qr( qr_string, ) @@ -91,7 +91,7 @@ class Player: if self.mpv is None: print("MPV is not initialized", file=sys.stderr) return - hidden = value is None or value > 30 + hidden = value is None or value > self.next_up_time if len(self.queue) < 2: return