obsws_connection_active: bool = False
record_output_active: bool = False
record_output_paused: bool = False
- record_output_bytes: float = 0.0
+ record_output_bytes: int = 0
"""Total bytes to disk."""
record_output_duration: float = 0.0
+ """Elapsed time in MS"""
stream_output_active: bool = False
- stream_output_skipped_frames: float = 0.0
- stream_output_total_frames: float = 0.0
- stats_render_skipped_frames: float = 0.0
- stats_render_total_frames: float = 0.0
- stats_output_skipped_frames: float = 0.0
- stats_output_total_frames: float = 0.0
+ stream_output_skipped_frames: int = 0
+ stream_output_total_frames: int = 0
+ stats_render_skipped_frames: int = 0
+ stats_render_total_frames: int = 0
+ stats_output_skipped_frames: int = 0
+ stats_output_total_frames: int = 0
cpu_usage_percent: float = 0.0
memory_usage_mb: float = 0.0
active_fps: float = 0.0
available_disk_space: float = 0.0
+ """Available space in MB"""
record_directory: str = ""
@property
(self.available_disk_space * MB_TO_BYTES) /
(self.record_output_bytes / self.record_output_duration)
) * MS_TO_HOURS
- except:
+ except ZeroDivisionError:
output = "N/A"
return output
"""The API is a widget for access to textual's message pump.
It stores no states. It reads, writes, and outputs states.
-
- Messages: StreamStateUpdated, RecordStateUpdated, Report"""
+ # Public Methods
+ |signature|description|
+ |---|---|
+ |start_stream() -> None||
+ |stop_stream() -> None||
+ |start_record() -> None||
+ |stop_record() -> None||
+ |start_pause() -> None||
+ |stop_pause() -> None||
+ |set_record_path(path: str) -> None||
+ |get_obs_stats() -> OBSStats||
+ |connect(host:str=None, port:int=None, password:str=None, timeout:str=None) -> None|Attempts to connect to the given OBS WebSocket. Parameters default to API's variables.|
+ |disconnect() -> None||
+ # Enums
+ ## OutputStates(StrEnum)
+ Named output states from OBS WebSocket
+ |name |value |note |
+ |---|---|---|
+ |UNKNOWN|OBS_WEBSOCKET_OUTPUT_UNKNOWN||
+ |STARTED|OBS_WEBSOCKET_OUTPUT_STARTED||
+ |STARTING|OBS_WEBSOCKET_OUTPUT_STARTING||
+ |PAUSED|OBS_WEBSOCKET_OUTPUT_PAUSED||
+ |RESUMED|OBS_WEBSOCKET_OUTPUT_RESUMED||
+ |STOPPED|OBS_WEBSOCKET_OUTPUT_STOPPED||
+ |STOPPING|OBS_WEBSOCKET_OUTPUT_STOPPING||
+ |RECONNECTING|OBS_WEBSOCKET_OUTPUT_RECONNECTING||
+ |RECONNECTED|OBS_WEBSOCKET_OUTPUT_RECONNECTED||
+ ## KnownReqErrs(IntEnum)
+ Known obs websocket request statuses/error codes
+ |name |value |note |
+ |---|---|---|
+ |NOT_READY|207|Try again after a delay|
+ |OUTPUT_RUNNING|500||
+ |OUTPUT_NOT_RUNNING|501||
+ |OUTPUT_PAUSED|502||
+ |OUTPUT_NOT_PAUSED|503||
+
+ # Reactives
+ |name |type |description|
+ |--- |--- |--- |
+ |interval|float|Refresh interval, in seconds|
+ |ws_host|str|OBS WebSocket hostname|
+ |ws_port|str|OBS WebSocket port|
+ |ws_password|str|OBS WebSocket password (insecure!)|
+ |ws_timeout|float, int, None|Timeout in seconds for OBS WebSocket connection|
+
+ # Messages
+ |name |description|members|member description |
+ |--- |--- |--- |--- |
+ |StreamStateUpdated |WebSocket event received|state |A state from OutputStates|
+ |RecordStateUpdated |WebSocket event received|state |A state from OutputStates|
+ |Report |Posted every interval seconds, a report on the state of the WebSocket.|data |An OBSStats object|
+ """
+
event_client: obs.EventClient = None
request_client: obs.ReqClient = None
is_connected: reactive[bool] = False
RECONNECTING = "OBS_WEBSOCKET_OUTPUT_RECONNECTING"
RECONNECTED = "OBS_WEBSOCKET_OUTPUT_RECONNECTED"
- class KnownReqErr(IntEnum):
+ class KnownReqErrs(IntEnum):
"""Known obs websocket request statuses/error codes"""
NOT_READY = 207
"""This usually occurs during OBS scene collection change or exit.
"""Posted when OBS WebSocket reports a change to the Record state.
state should be something from API.OutputStates."""
- pass
class Report(MSGBase):
"""Posted ever self.interval second. data is an OBSStats object."""
ws_port: int = 4455,
ws_password: str = "",
ws_timeout: int | float | None = None,
- *,
- content = "",
- expand = False,
- shrink = False,
- markup = True,
- name = None,
- id = None,
- classes = None,
- disabled = False
+ *args,
+ **kwargs,
):
+ """Initialize the API.
+
+ interval is the refresh rate.
+ ws_host, _port, _password, and _timeout are all passed to obs_ws.*Client,
+ and stored locally as members of this instance."""
logger.debug(f"Initializing obs.API widget: {self}")
- super().__init__(content, expand=expand, shrink=shrink, markup=markup, name=name, id=id, classes=classes, disabled=disabled)
+ super().__init__(*args, **kwargs)
self.set_reactive(API.interval, interval)
self.set_reactive(API.ws_host, ws_host)
self.set_reactive(API.ws_port, ws_port)
output = request()
handled = True
except obs_error.OBSSDKRequestError as err:
- if err.code == API.KnownReqErr.NOT_READY:
+ if err.code == API.KnownReqErrs.NOT_READY:
logger.info(f"OBS WebSocket not ready; trying again in 3 seconds.")
logger.debug(f"At most {_sentry} more tries.")
time.sleep(TRY_AGAIN)
continue
- elif err.code in API.KnownReqErr:
- logger.debug(f"Error handled: {API.KnownReqErr(err.code)}")
+ elif err.code in API.KnownReqErrs:
+ logger.debug(f"Error handled: {API.KnownReqErrs(err.code)}")
handled = True
else: