Merge pull request #43 from onyx-and-iris/fix-disconnect

Add disconnect() methods. Default ws timeout to None for event thread.
This commit is contained in:
Adem 2024-01-21 15:45:06 +03:00 committed by GitHub
commit 9402f2e472
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 71 additions and 47 deletions

View File

@ -17,6 +17,12 @@ class Observer:
print(f"Registered events: {self._client.callback.get()}") print(f"Registered events: {self._client.callback.get()}")
self.running = True self.running = True
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self._client.disconnect()
def on_current_program_scene_changed(self, data): def on_current_program_scene_changed(self, data):
"""The current program scene has changed.""" """The current program scene has changed."""
print(f"Switched to scene {data.scene_name}") print(f"Switched to scene {data.scene_name}")
@ -31,13 +37,11 @@ class Observer:
def on_exit_started(self, _): def on_exit_started(self, _):
"""OBS has begun the shutdown process.""" """OBS has begun the shutdown process."""
print(f"OBS closing!") print("OBS closing!")
self._client.unsubscribe()
self.running = False self.running = False
if __name__ == "__main__": if __name__ == "__main__":
observer = Observer() with Observer() as observer:
while observer.running: while observer.running:
time.sleep(0.1) time.sleep(0.1)

View File

@ -1,6 +1,7 @@
import inspect import inspect
import keyboard import keyboard
import obsws_python as obs import obsws_python as obs
@ -10,6 +11,12 @@ class Observer:
self._client.callback.register(self.on_current_program_scene_changed) self._client.callback.register(self.on_current_program_scene_changed)
print(f"Registered events: {self._client.callback.get()}") print(f"Registered events: {self._client.callback.get()}")
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self._client.disconnect()
@property @property
def event_identifier(self): def event_identifier(self):
return inspect.stack()[1].function return inspect.stack()[1].function
@ -31,9 +38,8 @@ def set_scene(scene, *args):
if __name__ == "__main__": if __name__ == "__main__":
req_client = obs.ReqClient() with obs.ReqClient() as req_client:
observer = Observer() with Observer() as observer:
keyboard.add_hotkey("0", version) keyboard.add_hotkey("0", version)
keyboard.add_hotkey("1", set_scene, args=("START",)) keyboard.add_hotkey("1", set_scene, args=("START",))
keyboard.add_hotkey("2", set_scene, args=("BRB",)) keyboard.add_hotkey("2", set_scene, args=("BRB",))

View File

@ -9,6 +9,8 @@ LEVELTYPE = IntEnum(
start=0, start=0,
) )
DEVICE = "Desktop Audio"
def on_input_mute_state_changed(data): def on_input_mute_state_changed(data):
"""An input's mute state has changed.""" """An input's mute state has changed."""
@ -32,15 +34,14 @@ def on_input_volume_meters(data):
def main(): def main():
client = obs.EventClient(subs=(obs.Subs.LOW_VOLUME | obs.Subs.INPUTVOLUMEMETERS)) with obs.EventClient(
subs=(obs.Subs.LOW_VOLUME | obs.Subs.INPUTVOLUMEMETERS)
) as client:
client.callback.register([on_input_volume_meters, on_input_mute_state_changed]) client.callback.register([on_input_volume_meters, on_input_mute_state_changed])
while cmd := input("<Enter> to exit>\n"): while _ := input("Press <Enter> to exit\n"):
if not cmd: pass
break
if __name__ == "__main__": if __name__ == "__main__":
DEVICE = "Desktop Audio"
main() main()

View File

@ -1,9 +1,8 @@
import json import json
import logging import logging
import time import threading
from threading import Thread
from websocket import WebSocketTimeoutException from websocket import WebSocketConnectionClosedException, WebSocketTimeoutException
from .baseclient import ObsClient from .baseclient import ObsClient
from .callback import Callback from .callback import Callback
@ -20,8 +19,6 @@ logger = logging.getLogger(__name__)
class EventClient: class EventClient:
DELAY = 0.001
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
defaultkwargs = {"subs": Subs.LOW_VOLUME} defaultkwargs = {"subs": Subs.LOW_VOLUME}
@ -38,6 +35,12 @@ class EventClient:
self.callback = Callback() self.callback = Callback()
self.subscribe() self.subscribe()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self.disconnect()
def __repr__(self): def __repr__(self):
return type( return type(
self self
@ -49,33 +52,40 @@ class EventClient:
return type(self).__name__ return type(self).__name__
def subscribe(self): def subscribe(self):
worker = Thread(target=self.trigger, daemon=True) self.base_client.ws.settimeout(None)
worker.start() stop_event = threading.Event()
self.worker = threading.Thread(
target=self.trigger, daemon=True, args=(stop_event,)
)
self.worker.start()
def trigger(self): def trigger(self, stop_event):
""" """
Continuously listen for events. Continuously listen for events.
Triggers a callback on event received. Triggers a callback on event received.
""" """
self.running = True while not stop_event.is_set():
while self.running:
try: try:
event = json.loads(self.base_client.ws.recv()) if response := self.base_client.ws.recv():
except WebSocketTimeoutException as e: event = json.loads(response)
self.logger.exception(f"{type(e).__name__}: {e}")
raise OBSSDKTimeoutError("Timeout while waiting for event") from e
self.logger.debug(f"Event received {event}") self.logger.debug(f"Event received {event}")
type_, data = ( type_, data = (
event["d"].get("eventType"), event["d"].get("eventType"),
event["d"].get("eventData"), event["d"].get("eventData"),
) )
self.callback.trigger(type_, data if data else {}) self.callback.trigger(type_, data if data else {})
time.sleep(self.DELAY) except WebSocketTimeoutException as e:
self.logger.exception(f"{type(e).__name__}: {e}")
raise OBSSDKTimeoutError("Timeout while waiting for event") from e
except (WebSocketConnectionClosedException, OSError) as e:
self.logger.debug(f"{type(e).__name__} terminating the event thread")
stop_event.set()
def disconnect(self):
"""stop listening for events"""
def unsubscribe(self):
"""
stop listening for events
"""
self.running = False
self.base_client.ws.close() self.base_client.ws.close()
self.worker.join()
unsubscribe = disconnect

View File

@ -31,7 +31,7 @@ class ReqClient:
return self return self
def __exit__(self, exc_type, exc_value, exc_traceback): def __exit__(self, exc_type, exc_value, exc_traceback):
self.base_client.ws.close() self.disconnect()
def __repr__(self): def __repr__(self):
return type( return type(
@ -43,6 +43,9 @@ class ReqClient:
def __str__(self): def __str__(self):
return type(self).__name__ return type(self).__name__
def disconnect(self):
self.base_client.ws.close()
def send(self, param, data=None, raw=False): def send(self, param, data=None, raw=False):
try: try:
response = self.base_client.req(param, data) response = self.base_client.req(param, data)

View File

@ -1 +1 @@
version = "1.6.2" version = "1.7.0"