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()}")
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):
"""The current program scene has changed."""
print(f"Switched to scene {data.scene_name}")
@ -31,13 +37,11 @@ class Observer:
def on_exit_started(self, _):
"""OBS has begun the shutdown process."""
print(f"OBS closing!")
self._client.unsubscribe()
print("OBS closing!")
self.running = False
if __name__ == "__main__":
observer = Observer()
with Observer() as observer:
while observer.running:
time.sleep(0.1)

View File

@ -1,6 +1,7 @@
import inspect
import keyboard
import obsws_python as obs
@ -10,6 +11,12 @@ class Observer:
self._client.callback.register(self.on_current_program_scene_changed)
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
def event_identifier(self):
return inspect.stack()[1].function
@ -31,9 +38,8 @@ def set_scene(scene, *args):
if __name__ == "__main__":
req_client = obs.ReqClient()
observer = Observer()
with obs.ReqClient() as req_client:
with Observer() as observer:
keyboard.add_hotkey("0", version)
keyboard.add_hotkey("1", set_scene, args=("START",))
keyboard.add_hotkey("2", set_scene, args=("BRB",))

View File

@ -9,6 +9,8 @@ LEVELTYPE = IntEnum(
start=0,
)
DEVICE = "Desktop Audio"
def on_input_mute_state_changed(data):
"""An input's mute state has changed."""
@ -32,15 +34,14 @@ def on_input_volume_meters(data):
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])
while cmd := input("<Enter> to exit>\n"):
if not cmd:
break
while _ := input("Press <Enter> to exit\n"):
pass
if __name__ == "__main__":
DEVICE = "Desktop Audio"
main()

View File

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

View File

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

View File

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