From 1d6fbd0bda2a699d66bf7e3b8aba47f1d7401e8b Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Fri, 27 Jun 2025 07:47:56 +0100 Subject: [PATCH] add tabgroup to mainframe add pause, split and add chapter buttons to Recorder tab - they are not implemented yet add timeouts on requests + handle them add obs connected status message on GUI load --- src/simple_recorder/gui.py | 93 +++++++++++++++++++++++++++++++++--- src/simple_recorder/start.py | 31 ++++++------ src/simple_recorder/stop.py | 19 ++++---- 3 files changed, 114 insertions(+), 29 deletions(-) diff --git a/src/simple_recorder/gui.py b/src/simple_recorder/gui.py index c797676..ed97cd5 100644 --- a/src/simple_recorder/gui.py +++ b/src/simple_recorder/gui.py @@ -1,6 +1,7 @@ import logging import FreeSimpleGUI as fsg +import obsws_python as obsws from .errors import SimpleRecorderError from .start import Start @@ -17,17 +18,75 @@ class SimpleRecorderWindow(fsg.Window): self.password = password fsg.theme(theme) - layout = [ - [fsg.Text("Enter recording filename:")], - [fsg.InputText("", key="-FILENAME-")], - [fsg.Button("Start Recording"), fsg.Button("Stop Recording")], - [fsg.Text("Status: Not started", key="-OUTPUT-")], + try: + with obsws.ReqClient( + host=self.host, port=self.port, password=self.password, timeout=3 + ) as client: + resp = client.get_version() + status_message = f"Connected to OBS {resp.obs_version} ✓" + except (ConnectionRefusedError, TimeoutError): + status_message = "Failed to connect to OBS. Is it running?" + + recorder_layout = [ + [fsg.Text("Enter recording filename:", key="-PROMPT-")], + [fsg.InputText("default_name", key="-FILENAME-", focus=True, size=(45, 1))], + [ + fsg.Button("Start", key="Start Recording", size=(10, 1)), + fsg.Button("Stop", key="Stop Recording", size=(10, 1)), + fsg.Button("Pause", key="Pause Recording", size=(10, 1)), + ], + [ + fsg.Button("Split", key="Split Recording", size=(10, 1)), + fsg.Button("Add Chapter", key="Add Chapter", size=(10, 1)), + ], ] - super().__init__("Simple Recorder", layout, finalize=True) + + frame = fsg.Frame( + "", + recorder_layout, + relief=fsg.RELIEF_SUNKEN, + ) + + recorder_tab = fsg.Tab( + "Recorder", + [ + [frame], + [ + fsg.Text( + f"Status: {status_message}", + key="-OUTPUT-", + text_color="white" + if status_message.startswith("Connected") + else "red", + ) + ], + ], + ) + + settings_layout = [ + [fsg.Text("Enter the filepath for the recording:")], + [fsg.InputText("", key="-FILEPATH-", size=(45, 1))], + ] + + settings_tab = fsg.Tab("Settings", settings_layout) + + mainframe = [ + [fsg.TabGroup([[recorder_tab, settings_tab]])], + ] + + super().__init__("Simple Recorder", mainframe, finalize=True) self["-FILENAME-"].bind("", " || RETURN") self["Start Recording"].bind("", " || RETURN") self["Stop Recording"].bind("", " || RETURN") + self["-FILENAME-"].bind("", " || KEYPRESS") + self["-FILENAME-"].update(select=True) + self["Add Chapter"].bind("", " || FOCUS") + self["Add Chapter"].bind("", " || FOCUS") + self["Add Chapter"].bind("", " || LEAVE") + self["Add Chapter"].bind("", " || LEAVE") + self["Add Chapter"].bind("", " || RIGHT_CLICK") + async def run(self): while True: event, values = self.read() @@ -65,7 +124,27 @@ class SimpleRecorderWindow(fsg.Window): f"Error: {e.raw_message}", text_color="red" ) + case ["Add Chapter", "FOCUS" | "LEAVE" as focus_event]: + if focus_event == "FOCUS": + self["-OUTPUT-"].update( + "Right-click to set a chapter name", text_color="white" + ) + else: + self["-OUTPUT-"].update("", text_color="white") + + case ["Add Chapter", "RIGHT_CLICK"]: + _ = fsg.popup_get_text( + "Enter chapter name:", + "Add Chapter", + default_text="unnamed", + ) + + case ["Pause Recording" | "Split Recording" | "Add Chapter"]: + self["-OUTPUT-"].update( + "This feature is not implemented yet", text_color="orange" + ) + case _: - self.logger.warning(f"Unhandled event: {e}") + self.logger.debug(f"Unhandled event: {e}") self.close() diff --git a/src/simple_recorder/start.py b/src/simple_recorder/start.py index ff797a9..68ae720 100644 --- a/src/simple_recorder/start.py +++ b/src/simple_recorder/start.py @@ -29,18 +29,21 @@ class Start(Command): if not self.filename: raise SimpleRecorderError("Recording name cannot be empty.") - with obsws.ReqClient( - host=self.host, port=self.port, password=self.password - ) as client: - resp = client.get_record_status() - if resp.output_active: - raise SimpleRecorderError("Recording is already active.") + try: + with obsws.ReqClient( + host=self.host, port=self.port, password=self.password, timeout=3 + ) as client: + resp = client.get_record_status() + if resp.output_active: + raise SimpleRecorderError("Recording is already active.") - filename = f"{self.filename} {self.get_timestamp()}" - client.set_profile_parameter( - "Output", - "FilenameFormatting", - filename, - ) - client.start_record() - print(f"Recording started with filename: {highlight(filename)}") + filename = f"{self.filename} {self.get_timestamp()}" + client.set_profile_parameter( + "Output", + "FilenameFormatting", + filename, + ) + client.start_record() + print(f"Recording started with filename: {highlight(filename)}") + except TimeoutError: + raise SimpleRecorderError("Failed to connect to OBS. Is it running?") diff --git a/src/simple_recorder/stop.py b/src/simple_recorder/stop.py index 66efcde..a618d47 100644 --- a/src/simple_recorder/stop.py +++ b/src/simple_recorder/stop.py @@ -15,12 +15,15 @@ class Stop(Command): @override async def run(self): - with obsws.ReqClient( - host=self.host, port=self.port, password=self.password - ) as client: - resp = client.get_record_status() - if not resp.output_active: - raise SimpleRecorderError("Recording is not active.") + try: + with obsws.ReqClient( + host=self.host, port=self.port, password=self.password, timeout=3 + ) as client: + resp = client.get_record_status() + if not resp.output_active: + raise SimpleRecorderError("Recording is not active.") - client.stop_record() - print(highlight("Recording stopped successfully.")) + client.stop_record() + print(highlight("Recording stopped successfully.")) + except TimeoutError: + raise SimpleRecorderError("Failed to connect to OBS. Is it running?")