Client starting and stopping from gui

This commit is contained in:
Christoph Stahl 2024-10-10 16:05:04 +02:00
parent 089de1ff93
commit 95e8157277
4 changed files with 25 additions and 15 deletions

View file

@ -42,8 +42,8 @@ pymediainfo = { version = "^6.1.0", optional = true }
pyyaml = { version = "^6.0.1", optional = true } pyyaml = { version = "^6.0.1", optional = true }
alt-profanity-check = {version = "^1.4.1", optional = true} alt-profanity-check = {version = "^1.4.1", optional = true}
pyqt6 = {version="^6.7.1", optional = true} pyqt6 = {version="^6.7.1", optional = true}
mpv = "^1.0.7" mpv = {versions="^1.0.7", optional = true}
qasync = "^0.27.1" qasync = {versions="^0.27.1", optional = true}
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
types-pyyaml = "^6.0.12.12" types-pyyaml = "^6.0.12.12"
@ -54,7 +54,7 @@ requirements-parser = "^0.11.0"
[tool.poetry.extras] [tool.poetry.extras]
client = ["minio", "pillow", "qrcode", "pymediainfo", "pyyaml", "pyqt6"] client = ["minio", "pillow", "qrcode", "pymediainfo", "pyyaml", "pyqt6", "mpv", "qasync"]
server = ["alt-profanity-check"] server = ["alt-profanity-check"]
[build-system] [build-system]

View file

@ -118,6 +118,7 @@ class State:
class Client: class Client:
def __init__(self, config: dict[str, Any]): def __init__(self, config: dict[str, Any]):
self.is_running = False
self.sio = socketio.AsyncClient(json=jsonencoder) self.sio = socketio.AsyncClient(json=jsonencoder)
self.loop: Optional[asyncio.AbstractEventLoop] = None self.loop: Optional[asyncio.AbstractEventLoop] = None
self.skipped = [] self.skipped = []
@ -452,7 +453,6 @@ class Client:
:type config: dict[str, Any] :type config: dict[str, Any]
:rtype: None :rtype: None
""" """
print("Starting client")
self.loop = asyncio.get_running_loop() self.loop = asyncio.get_running_loop()
@ -487,10 +487,12 @@ class Client:
asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, self.signal_handler) asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, self.signal_handler)
try: try:
self.is_running = True
await self.sio.wait() await self.sio.wait()
except asyncio.CancelledError: except asyncio.CancelledError:
pass pass
finally: finally:
self.is_running = False
if self.player is not None: if self.player is not None:
self.player.mpv.terminate() self.player.mpv.terminate()

View file

@ -3,6 +3,7 @@ from io import BytesIO
import sys import sys
import logging import logging
from logging.handlers import QueueListener from logging.handlers import QueueListener
from logging.handlers import QueueHandler
# from multiprocessing import Process, Queue # from multiprocessing import Process, Queue
from queue import Queue from queue import Queue
@ -58,6 +59,7 @@ import platformdirs
from . import resources # noqa from . import resources # noqa
from .client import Client, create_async_and_start_client, default_config from .client import Client, create_async_and_start_client, default_config
from .log import logger
from .sources import available_sources from .sources import available_sources
from .config import ( from .config import (
@ -632,6 +634,7 @@ class SyngGui(QMainWindow):
self.loop = asyncio.get_event_loop() self.loop = asyncio.get_event_loop()
self.syng_server: Optional[threading.Thread] = None self.syng_server: Optional[threading.Thread] = None
self.syng_client: Optional[threading.Thread] = None self.syng_client: Optional[threading.Thread] = None
self.client: Optional[Client] = None
self.syng_client_logging_listener: Optional[QueueListener] = None self.syng_client_logging_listener: Optional[QueueListener] = None
self.configfile = os.path.join(platformdirs.user_config_dir("syng"), "config.yaml") self.configfile = os.path.join(platformdirs.user_config_dir("syng"), "config.yaml")
@ -751,16 +754,14 @@ class SyngGui(QMainWindow):
dump(config, f, Dumper=Dumper) dump(config, f, Dumper=Dumper)
def check_if_client_is_running(self) -> None: def check_if_client_is_running(self) -> None:
if self.syng_client is None: if self.client is None:
self.timer.stop() self.timer.stop()
return return
if not self.syng_client.is_alive(): if not self.client.is_running:
print("Client is not running") self.client = None
self.syng_client = None
self.set_client_button_start() self.set_client_button_start()
else: else:
print("Client is running")
self.set_client_button_stop() self.set_client_button_stop()
def set_client_button_stop(self) -> None: def set_client_button_stop(self) -> None:
@ -770,7 +771,7 @@ class SyngGui(QMainWindow):
self.startbutton.setText("Save and Start") self.startbutton.setText("Save and Start")
def start_syng_client(self) -> None: def start_syng_client(self) -> None:
if self.syng_client is None or not self.syng_client.is_alive(): if self.client is None or not self.client.is_running:
self.save_config() self.save_config()
config = self.gather_config() config = self.gather_config()
queue: Queue[logging.LogRecord] = Queue() queue: Queue[logging.LogRecord] = Queue()
@ -783,6 +784,7 @@ class SyngGui(QMainWindow):
# self.syng_client = multiprocessing.Process( # self.syng_client = multiprocessing.Process(
# target=create_async_and_start_client, args=[config, queue] # target=create_async_and_start_client, args=[config, queue]
# ) # )
logger.addHandler(QueueHandler(queue))
self.client = Client(config) self.client = Client(config)
asyncio.run_coroutine_threadsafe(self.client.start_client(config), self.loop) asyncio.run_coroutine_threadsafe(self.client.start_client(config), self.loop)
# self.syng_client = threading.Thread( # self.syng_client = threading.Thread(
@ -794,7 +796,7 @@ class SyngGui(QMainWindow):
self.set_client_button_stop() self.set_client_button_stop()
else: else:
self.client.quit_callback() self.client.quit_callback()
self.syng_client.join(1.0) # self.syng_client.join(1.0)
self.set_client_button_start() self.set_client_button_start()
# def start_syng_server(self) -> None: # def start_syng_server(self) -> None:

View file

@ -79,7 +79,10 @@ class Player:
f"{__dirname__}/static/background20perc.png", 3, sub_file=f"python://{stream_name}" f"{__dirname__}/static/background20perc.png", 3, sub_file=f"python://{stream_name}"
) )
await loop.run_in_executor(None, self.mpv.wait_for_property, "eof-reached") try:
await loop.run_in_executor(None, self.mpv.wait_for_property, "eof-reached")
except mpv.ShutdownError:
self.quit_callback()
def play_image(self, image: str, duration: int, sub_file: Optional[str] = None) -> None: def play_image(self, image: str, duration: int, sub_file: Optional[str] = None) -> None:
for property, value in self.default_options.items(): for property, value in self.default_options.items():
@ -113,9 +116,12 @@ class Player:
else: else:
self.mpv.loadfile(video) self.mpv.loadfile(video)
self.mpv.pause = False self.mpv.pause = False
await loop.run_in_executor(None, self.mpv.wait_for_property, "eof-reached") try:
self.mpv.image_display_duration = 0 await loop.run_in_executor(None, self.mpv.wait_for_property, "eof-reached")
self.mpv.play(f"{__dirname__}/static/background.png") self.mpv.image_display_duration = 0
self.mpv.play(f"{__dirname__}/static/background.png")
except mpv.ShutdownError:
self.quit_callback()
def skip_current(self) -> None: def skip_current(self) -> None:
self.mpv.image_display_duration = 0 self.mpv.image_display_duration = 0