mirror of
https://github.com/onyx-and-iris/obsws-cli.git
synced 2025-08-08 04:31:49 +00:00
Compare commits
No commits in common. "8465944f307af6afcb4f66d9f5ff00276523919c" and "63f2ab9d01693fb4ccac62ec011fd63538701bf0" have entirely different histories.
8465944f30
...
63f2ab9d01
1
.gitignore
vendored
1
.gitignore
vendored
@ -131,7 +131,6 @@ ENV/
|
|||||||
env.bak/
|
env.bak/
|
||||||
venv.bak/
|
venv.bak/
|
||||||
.hatch
|
.hatch
|
||||||
.test.env
|
|
||||||
|
|
||||||
# Spyder project settings
|
# Spyder project settings
|
||||||
.spyderproject
|
.spyderproject
|
||||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,12 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
# [0.9.2] - 2025-04-26
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Initial release.
|
|
11
README.md
11
README.md
@ -3,11 +3,6 @@
|
|||||||
[](https://github.com/pypa/hatch)
|
[](https://github.com/pypa/hatch)
|
||||||
[](https://github.com/astral-sh/ruff)
|
[](https://github.com/astral-sh/ruff)
|
||||||
|
|
||||||
|
|
||||||
A command line interface for OBS Websocket v5
|
|
||||||
|
|
||||||
For an outline of past/future changes refer to: [CHANGELOG](CHANGELOG.md)
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
@ -55,9 +50,9 @@ Store and load environment variables from:
|
|||||||
- `user home directory / .config / obsws-cli / obsws.env`
|
- `user home directory / .config / obsws-cli / obsws.env`
|
||||||
|
|
||||||
```env
|
```env
|
||||||
OBS_HOST=localhost
|
OBSWS_HOST=localhost
|
||||||
OBS_PORT=4455
|
OBSWS_PORT=4455
|
||||||
OBS_PASSWORD=<websocket password>
|
OBSWS_PASSWORD=<websocket password>
|
||||||
```
|
```
|
||||||
|
|
||||||
Flags can be used to override environment variables.
|
Flags can be used to override environment variables.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2025-present onyx-and-iris <code@onyxandiris.online>
|
# SPDX-FileCopyrightText: 2025-present onyx-and-iris <code@onyxandiris.online>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
__version__ = "0.9.2"
|
__version__ = "0.9.1"
|
||||||
|
@ -17,7 +17,6 @@ from . import (
|
|||||||
scene,
|
scene,
|
||||||
scenecollection,
|
scenecollection,
|
||||||
sceneitem,
|
sceneitem,
|
||||||
stream,
|
|
||||||
studiomode,
|
studiomode,
|
||||||
virtualcam,
|
virtualcam,
|
||||||
)
|
)
|
||||||
@ -33,7 +32,7 @@ class Settings(BaseSettings):
|
|||||||
Path.home() / '.config' / 'obsws-cli' / 'obsws.env',
|
Path.home() / '.config' / 'obsws-cli' / 'obsws.env',
|
||||||
),
|
),
|
||||||
env_file_encoding='utf-8',
|
env_file_encoding='utf-8',
|
||||||
env_prefix='OBS_',
|
env_prefix='OBSWS_',
|
||||||
)
|
)
|
||||||
|
|
||||||
HOST: str = 'localhost'
|
HOST: str = 'localhost'
|
||||||
@ -52,7 +51,6 @@ for module in (
|
|||||||
scene,
|
scene,
|
||||||
scenecollection,
|
scenecollection,
|
||||||
sceneitem,
|
sceneitem,
|
||||||
stream,
|
|
||||||
studiomode,
|
studiomode,
|
||||||
virtualcam,
|
virtualcam,
|
||||||
):
|
):
|
||||||
|
18
obsws_cli/errors.py
Normal file
18
obsws_cli/errors.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
"""Exceptions for obsws_cli."""
|
||||||
|
|
||||||
|
|
||||||
|
class ObswsCliError(Exception):
|
||||||
|
"""Base class for all exceptions raised by obsws_cli."""
|
||||||
|
|
||||||
|
def __init__(self, message: str):
|
||||||
|
"""Initialize the exception with a message."""
|
||||||
|
message = (
|
||||||
|
message.split('With message: ')[1]
|
||||||
|
if 'With message: ' in message
|
||||||
|
else message
|
||||||
|
)
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
class ObswsCliBadParameter(ObswsCliError):
|
||||||
|
"""Exception raised when a bad parameter is passed to a command."""
|
@ -44,7 +44,7 @@ def _get_group(group_name: str, resp: DataclassProtocol) -> dict | None:
|
|||||||
return group
|
return group
|
||||||
|
|
||||||
|
|
||||||
@app.command('show | sh')
|
@app.command()
|
||||||
def show(ctx: typer.Context, scene_name: str, group_name: str):
|
def show(ctx: typer.Context, scene_name: str, group_name: str):
|
||||||
"""Show a group in a scene."""
|
"""Show a group in a scene."""
|
||||||
if not validate.scene_in_scenes(ctx, scene_name):
|
if not validate.scene_in_scenes(ctx, scene_name):
|
||||||
@ -71,7 +71,7 @@ def show(ctx: typer.Context, scene_name: str, group_name: str):
|
|||||||
typer.echo(f"Group '{group_name}' is now visible.")
|
typer.echo(f"Group '{group_name}' is now visible.")
|
||||||
|
|
||||||
|
|
||||||
@app.command('hide | h')
|
@app.command()
|
||||||
def hide(ctx: typer.Context, scene_name: str, group_name: str):
|
def hide(ctx: typer.Context, scene_name: str, group_name: str):
|
||||||
"""Hide a group in a scene."""
|
"""Hide a group in a scene."""
|
||||||
if not validate.scene_in_scenes(ctx, scene_name):
|
if not validate.scene_in_scenes(ctx, scene_name):
|
||||||
@ -129,7 +129,7 @@ def toggle(ctx: typer.Context, scene_name: str, group_name: str):
|
|||||||
typer.echo(f"Group '{group_name}' is now hidden.")
|
typer.echo(f"Group '{group_name}' is now hidden.")
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context, scene_name: str, group_name: str):
|
def status(ctx: typer.Context, scene_name: str, group_name: str):
|
||||||
"""Get the status of a group in a scene."""
|
"""Get the status of a group in a scene."""
|
||||||
if not validate.scene_in_scenes(ctx, scene_name):
|
if not validate.scene_in_scenes(ctx, scene_name):
|
||||||
|
@ -42,7 +42,7 @@ def list(
|
|||||||
typer.echo('\n'.join(input_.get('inputName') for input_ in inputs))
|
typer.echo('\n'.join(input_.get('inputName') for input_ in inputs))
|
||||||
|
|
||||||
|
|
||||||
@app.command('mute | m')
|
@app.command()
|
||||||
def mute(ctx: typer.Context, input_name: str):
|
def mute(ctx: typer.Context, input_name: str):
|
||||||
"""Mute an input."""
|
"""Mute an input."""
|
||||||
if not validate.input_in_inputs(ctx, input_name):
|
if not validate.input_in_inputs(ctx, input_name):
|
||||||
@ -60,7 +60,7 @@ def mute(ctx: typer.Context, input_name: str):
|
|||||||
typer.echo(f"Input '{input_name}' muted.")
|
typer.echo(f"Input '{input_name}' muted.")
|
||||||
|
|
||||||
|
|
||||||
@app.command('unmute | um')
|
@app.command()
|
||||||
def unmute(ctx: typer.Context, input_name: str):
|
def unmute(ctx: typer.Context, input_name: str):
|
||||||
"""Unmute an input."""
|
"""Unmute an input."""
|
||||||
if not validate.input_in_inputs(ctx, input_name):
|
if not validate.input_in_inputs(ctx, input_name):
|
||||||
|
@ -21,14 +21,14 @@ def list(ctx: typer.Context):
|
|||||||
typer.echo(profile)
|
typer.echo(profile)
|
||||||
|
|
||||||
|
|
||||||
@app.command('current | get')
|
@app.command()
|
||||||
def current(ctx: typer.Context):
|
def current(ctx: typer.Context):
|
||||||
"""Get the current profile."""
|
"""Get the current profile."""
|
||||||
resp = ctx.obj.get_profile_list()
|
resp = ctx.obj.get_profile_list()
|
||||||
typer.echo(resp.current_profile_name)
|
typer.echo(resp.current_profile_name)
|
||||||
|
|
||||||
|
|
||||||
@app.command('switch | set')
|
@app.command()
|
||||||
def switch(ctx: typer.Context, profile_name: str):
|
def switch(ctx: typer.Context, profile_name: str):
|
||||||
"""Switch to a profile."""
|
"""Switch to a profile."""
|
||||||
if not validate.profile_exists(ctx, profile_name):
|
if not validate.profile_exists(ctx, profile_name):
|
||||||
@ -50,7 +50,7 @@ def switch(ctx: typer.Context, profile_name: str):
|
|||||||
typer.echo(f"Switched to profile '{profile_name}'.")
|
typer.echo(f"Switched to profile '{profile_name}'.")
|
||||||
|
|
||||||
|
|
||||||
@app.command('create | new')
|
@app.command()
|
||||||
def create(ctx: typer.Context, profile_name: str):
|
def create(ctx: typer.Context, profile_name: str):
|
||||||
"""Create a new profile."""
|
"""Create a new profile."""
|
||||||
if validate.profile_exists(ctx, profile_name):
|
if validate.profile_exists(ctx, profile_name):
|
||||||
@ -64,7 +64,7 @@ def create(ctx: typer.Context, profile_name: str):
|
|||||||
typer.echo(f"Created profile '{profile_name}'.")
|
typer.echo(f"Created profile '{profile_name}'.")
|
||||||
|
|
||||||
|
|
||||||
@app.command('remove | rm')
|
@app.command()
|
||||||
def remove(ctx: typer.Context, profile_name: str):
|
def remove(ctx: typer.Context, profile_name: str):
|
||||||
"""Remove a profile."""
|
"""Remove a profile."""
|
||||||
if not validate.profile_exists(ctx, profile_name):
|
if not validate.profile_exists(ctx, profile_name):
|
||||||
|
@ -18,7 +18,7 @@ def _get_recording_status(ctx: typer.Context) -> tuple:
|
|||||||
return resp.output_active, resp.output_paused
|
return resp.output_active, resp.output_paused
|
||||||
|
|
||||||
|
|
||||||
@app.command('start | s')
|
@app.command()
|
||||||
def start(ctx: typer.Context):
|
def start(ctx: typer.Context):
|
||||||
"""Start recording."""
|
"""Start recording."""
|
||||||
active, paused = _get_recording_status(ctx)
|
active, paused = _get_recording_status(ctx)
|
||||||
@ -34,7 +34,7 @@ def start(ctx: typer.Context):
|
|||||||
typer.echo('Recording started successfully.')
|
typer.echo('Recording started successfully.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('stop | st')
|
@app.command()
|
||||||
def stop(ctx: typer.Context):
|
def stop(ctx: typer.Context):
|
||||||
"""Stop recording."""
|
"""Stop recording."""
|
||||||
active, _ = _get_recording_status(ctx)
|
active, _ = _get_recording_status(ctx)
|
||||||
@ -46,7 +46,7 @@ def stop(ctx: typer.Context):
|
|||||||
typer.echo('Recording stopped successfully.')
|
typer.echo('Recording stopped successfully.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context):
|
def status(ctx: typer.Context):
|
||||||
"""Get recording status."""
|
"""Get recording status."""
|
||||||
active, paused = _get_recording_status(ctx)
|
active, paused = _get_recording_status(ctx)
|
||||||
@ -69,7 +69,7 @@ def toggle(ctx: typer.Context):
|
|||||||
ctx.invoke(start, ctx=ctx)
|
ctx.invoke(start, ctx=ctx)
|
||||||
|
|
||||||
|
|
||||||
@app.command('resume | r')
|
@app.command()
|
||||||
def resume(ctx: typer.Context):
|
def resume(ctx: typer.Context):
|
||||||
"""Resume recording."""
|
"""Resume recording."""
|
||||||
active, paused = _get_recording_status(ctx)
|
active, paused = _get_recording_status(ctx)
|
||||||
@ -84,7 +84,7 @@ def resume(ctx: typer.Context):
|
|||||||
typer.echo('Recording resumed successfully.')
|
typer.echo('Recording resumed successfully.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('pause | p')
|
@app.command()
|
||||||
def pause(ctx: typer.Context):
|
def pause(ctx: typer.Context):
|
||||||
"""Pause recording."""
|
"""Pause recording."""
|
||||||
active, paused = _get_recording_status(ctx)
|
active, paused = _get_recording_status(ctx)
|
||||||
|
@ -12,21 +12,21 @@ def main():
|
|||||||
"""Control profiles in OBS."""
|
"""Control profiles in OBS."""
|
||||||
|
|
||||||
|
|
||||||
@app.command('start | s')
|
@app.command()
|
||||||
def start(ctx: typer.Context):
|
def start(ctx: typer.Context):
|
||||||
"""Start the replay buffer."""
|
"""Start the replay buffer."""
|
||||||
ctx.obj.start_replay_buffer()
|
ctx.obj.start_replay_buffer()
|
||||||
typer.echo('Replay buffer started.')
|
typer.echo('Replay buffer started.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('stop | st')
|
@app.command()
|
||||||
def stop(ctx: typer.Context):
|
def stop(ctx: typer.Context):
|
||||||
"""Stop the replay buffer."""
|
"""Stop the replay buffer."""
|
||||||
ctx.obj.stop_replay_buffer()
|
ctx.obj.stop_replay_buffer()
|
||||||
typer.echo('Replay buffer stopped.')
|
typer.echo('Replay buffer stopped.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context):
|
def status(ctx: typer.Context):
|
||||||
"""Get the status of the replay buffer."""
|
"""Get the status of the replay buffer."""
|
||||||
resp = ctx.obj.get_replay_buffer_status()
|
resp = ctx.obj.get_replay_buffer_status()
|
||||||
@ -36,7 +36,7 @@ def status(ctx: typer.Context):
|
|||||||
typer.echo('Replay buffer is not active.')
|
typer.echo('Replay buffer is not active.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('save | sv')
|
@app.command()
|
||||||
def save(ctx: typer.Context):
|
def save(ctx: typer.Context):
|
||||||
"""Save the replay buffer."""
|
"""Save the replay buffer."""
|
||||||
ctx.obj.save_replay_buffer()
|
ctx.obj.save_replay_buffer()
|
||||||
|
@ -77,7 +77,7 @@ def _get_scene_name_and_item_id(
|
|||||||
|
|
||||||
|
|
||||||
@_validate_scene_name_and_item_name
|
@_validate_scene_name_and_item_name
|
||||||
@app.command('show | sh')
|
@app.command()
|
||||||
def show(
|
def show(
|
||||||
ctx: typer.Context,
|
ctx: typer.Context,
|
||||||
scene_name: str,
|
scene_name: str,
|
||||||
@ -99,7 +99,7 @@ def show(
|
|||||||
|
|
||||||
|
|
||||||
@_validate_scene_name_and_item_name
|
@_validate_scene_name_and_item_name
|
||||||
@app.command('hide | h')
|
@app.command()
|
||||||
def hide(
|
def hide(
|
||||||
ctx: typer.Context,
|
ctx: typer.Context,
|
||||||
scene_name: str,
|
scene_name: str,
|
||||||
@ -164,7 +164,7 @@ def toggle(
|
|||||||
|
|
||||||
|
|
||||||
@_validate_scene_name_and_item_name
|
@_validate_scene_name_and_item_name
|
||||||
@app.command('visible | v')
|
@app.command()
|
||||||
def visible(
|
def visible(
|
||||||
ctx: typer.Context,
|
ctx: typer.Context,
|
||||||
scene_name: str,
|
scene_name: str,
|
||||||
@ -206,7 +206,7 @@ def visible(
|
|||||||
|
|
||||||
|
|
||||||
@_validate_scene_name_and_item_name
|
@_validate_scene_name_and_item_name
|
||||||
@app.command('transform | t')
|
@app.command()
|
||||||
def transform(
|
def transform(
|
||||||
ctx: typer.Context,
|
ctx: typer.Context,
|
||||||
scene_name: str,
|
scene_name: str,
|
||||||
|
@ -18,7 +18,7 @@ def _get_streaming_status(ctx: typer.Context) -> tuple:
|
|||||||
return resp.output_active, resp.output_duration
|
return resp.output_active, resp.output_duration
|
||||||
|
|
||||||
|
|
||||||
@app.command('start | s')
|
@app.command()
|
||||||
def start(ctx: typer.Context):
|
def start(ctx: typer.Context):
|
||||||
"""Start streaming."""
|
"""Start streaming."""
|
||||||
active, _ = _get_streaming_status(ctx)
|
active, _ = _get_streaming_status(ctx)
|
||||||
@ -30,7 +30,7 @@ def start(ctx: typer.Context):
|
|||||||
typer.echo('Streaming started successfully.')
|
typer.echo('Streaming started successfully.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('stop | st')
|
@app.command()
|
||||||
def stop(ctx: typer.Context):
|
def stop(ctx: typer.Context):
|
||||||
"""Stop streaming."""
|
"""Stop streaming."""
|
||||||
active, _ = _get_streaming_status(ctx)
|
active, _ = _get_streaming_status(ctx)
|
||||||
@ -42,7 +42,7 @@ def stop(ctx: typer.Context):
|
|||||||
typer.echo('Streaming stopped successfully.')
|
typer.echo('Streaming stopped successfully.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context):
|
def status(ctx: typer.Context):
|
||||||
"""Get streaming status."""
|
"""Get streaming status."""
|
||||||
active, duration = _get_streaming_status(ctx)
|
active, duration = _get_streaming_status(ctx)
|
||||||
|
@ -12,19 +12,19 @@ def main():
|
|||||||
"""Control studio mode in OBS."""
|
"""Control studio mode in OBS."""
|
||||||
|
|
||||||
|
|
||||||
@app.command('enable | on')
|
@app.command()
|
||||||
def enable(ctx: typer.Context):
|
def enable(ctx: typer.Context):
|
||||||
"""Enable studio mode."""
|
"""Enable studio mode."""
|
||||||
ctx.obj.set_studio_mode_enabled(True)
|
ctx.obj.set_studio_mode_enabled(True)
|
||||||
|
|
||||||
|
|
||||||
@app.command('disable | off')
|
@app.command()
|
||||||
def disable(ctx: typer.Context):
|
def disable(ctx: typer.Context):
|
||||||
"""Disable studio mode."""
|
"""Disable studio mode."""
|
||||||
ctx.obj.set_studio_mode_enabled(False)
|
ctx.obj.set_studio_mode_enabled(False)
|
||||||
|
|
||||||
|
|
||||||
@app.command('toggle | tg')
|
@app.command()
|
||||||
def toggle(ctx: typer.Context):
|
def toggle(ctx: typer.Context):
|
||||||
"""Toggle studio mode."""
|
"""Toggle studio mode."""
|
||||||
resp = ctx.obj.get_studio_mode_enabled()
|
resp = ctx.obj.get_studio_mode_enabled()
|
||||||
@ -36,7 +36,7 @@ def toggle(ctx: typer.Context):
|
|||||||
typer.echo('Studio mode is now enabled.')
|
typer.echo('Studio mode is now enabled.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context):
|
def status(ctx: typer.Context):
|
||||||
"""Get the status of studio mode."""
|
"""Get the status of studio mode."""
|
||||||
resp = ctx.obj.get_studio_mode_enabled()
|
resp = ctx.obj.get_studio_mode_enabled()
|
||||||
|
@ -12,28 +12,28 @@ def main():
|
|||||||
"""Control virtual camera in OBS."""
|
"""Control virtual camera in OBS."""
|
||||||
|
|
||||||
|
|
||||||
@app.command('start | s')
|
@app.command()
|
||||||
def start(ctx: typer.Context):
|
def start(ctx: typer.Context):
|
||||||
"""Start the virtual camera."""
|
"""Start the virtual camera."""
|
||||||
ctx.obj.start_virtual_cam()
|
ctx.obj.start_virtual_cam()
|
||||||
typer.echo('Virtual camera started.')
|
typer.echo('Virtual camera started.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('stop | p')
|
@app.command()
|
||||||
def stop(ctx: typer.Context):
|
def stop(ctx: typer.Context):
|
||||||
"""Stop the virtual camera."""
|
"""Stop the virtual camera."""
|
||||||
ctx.obj.stop_virtual_cam()
|
ctx.obj.stop_virtual_cam()
|
||||||
typer.echo('Virtual camera stopped.')
|
typer.echo('Virtual camera stopped.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('toggle | tg')
|
@app.command()
|
||||||
def toggle(ctx: typer.Context):
|
def toggle(ctx: typer.Context):
|
||||||
"""Toggle the virtual camera."""
|
"""Toggle the virtual camera."""
|
||||||
ctx.obj.toggle_virtual_cam()
|
ctx.obj.toggle_virtual_cam()
|
||||||
typer.echo('Virtual camera toggled.')
|
typer.echo('Virtual camera toggled.')
|
||||||
|
|
||||||
|
|
||||||
@app.command('status | ss')
|
@app.command()
|
||||||
def status(ctx: typer.Context):
|
def status(ctx: typer.Context):
|
||||||
"""Get the status of the virtual camera."""
|
"""Get the status of the virtual camera."""
|
||||||
resp = ctx.obj.get_virtual_cam_status()
|
resp = ctx.obj.get_virtual_cam_status()
|
||||||
|
@ -40,9 +40,10 @@ path = "obsws_cli/__about__.py"
|
|||||||
|
|
||||||
[tool.hatch.envs.default.scripts]
|
[tool.hatch.envs.default.scripts]
|
||||||
cli = "obsws-cli {args:}"
|
cli = "obsws-cli {args:}"
|
||||||
|
test = "pytest {args:obsws_cli tests}"
|
||||||
|
|
||||||
[tool.hatch.envs.hatch-test]
|
[tool.hatch.envs.hatch-test]
|
||||||
dependencies = ["pytest>=8.3.5"]
|
dependencies = ["pytest>=8.3.5", "pytest-dotenv"]
|
||||||
|
|
||||||
[tool.hatch.envs.types]
|
[tool.hatch.envs.types]
|
||||||
extra-dependencies = ["mypy>=1.0.0"]
|
extra-dependencies = ["mypy>=1.0.0"]
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import obsws_python as obsws
|
import obsws_python as obsws
|
||||||
from dotenv import find_dotenv, load_dotenv
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
@ -20,9 +19,9 @@ def pytest_sessionstart(session):
|
|||||||
"""
|
"""
|
||||||
# Initialize the OBS WebSocket client
|
# Initialize the OBS WebSocket client
|
||||||
session.obsws = obsws.ReqClient(
|
session.obsws = obsws.ReqClient(
|
||||||
host=os.environ['OBS_HOST'],
|
host=os.environ['OBSWS_HOST'],
|
||||||
port=os.environ['OBS_PORT'],
|
port=os.environ['OBSWS_PORT'],
|
||||||
password=os.environ['OBS_PASSWORD'],
|
password=os.environ['OBSWS_PASSWORD'],
|
||||||
timeout=5,
|
timeout=5,
|
||||||
)
|
)
|
||||||
resp = session.obsws.get_version()
|
resp = session.obsws.get_version()
|
||||||
@ -33,17 +32,6 @@ def pytest_sessionstart(session):
|
|||||||
)
|
)
|
||||||
print(' '.join(out))
|
print(' '.join(out))
|
||||||
|
|
||||||
load_dotenv(find_dotenv('.test.env'))
|
|
||||||
|
|
||||||
session.obsws.set_stream_service_settings(
|
|
||||||
'rtmp_common',
|
|
||||||
{
|
|
||||||
'service': 'Twitch',
|
|
||||||
'server': 'auto',
|
|
||||||
'key': os.environ['OBS_STREAM_KEY'],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
session.obsws.set_current_scene_collection('test-collection')
|
session.obsws.set_current_scene_collection('test-collection')
|
||||||
|
|
||||||
session.obsws.create_scene('pytest')
|
session.obsws.create_scene('pytest')
|
||||||
@ -80,10 +68,6 @@ def pytest_sessionfinish(session, exitstatus):
|
|||||||
"""
|
"""
|
||||||
session.obsws.remove_scene('pytest')
|
session.obsws.remove_scene('pytest')
|
||||||
|
|
||||||
resp = session.obsws.get_stream_status()
|
|
||||||
if resp.output_active:
|
|
||||||
session.obsws.stop_stream()
|
|
||||||
|
|
||||||
# Close the OBS WebSocket client connection
|
# Close the OBS WebSocket client connection
|
||||||
session.obsws.disconnect()
|
session.obsws.disconnect()
|
||||||
|
|
||||||
|
@ -9,35 +9,35 @@ runner = CliRunner()
|
|||||||
|
|
||||||
def test_group_list():
|
def test_group_list():
|
||||||
"""Test the group list command."""
|
"""Test the group list command."""
|
||||||
result = runner.invoke(app, ['group', 'list', 'Scene'])
|
result = runner.invoke(app, ['group', 'list', 'pytest00'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert 'test_group' in result.stdout
|
assert 'test_group' in result.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_group_show():
|
def test_group_show():
|
||||||
"""Test the group show command."""
|
"""Test the group show command."""
|
||||||
result = runner.invoke(app, ['group', 'show', 'Scene', 'test_group'])
|
result = runner.invoke(app, ['group', 'show', 'pytest00', 'test_group'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Group 'test_group' is now visible." in result.stdout
|
assert "Group 'test_group' is now visible." in result.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_group_toggle():
|
def test_group_toggle():
|
||||||
"""Test the group toggle command."""
|
"""Test the group toggle command."""
|
||||||
result = runner.invoke(app, ['group', 'hide', 'Scene', 'test_group'])
|
result = runner.invoke(app, ['group', 'hide', 'pytest00', 'test_group'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Group 'test_group' is now hidden." in result.stdout
|
assert "Group 'test_group' is now hidden." in result.stdout
|
||||||
|
|
||||||
result = runner.invoke(app, ['group', 'toggle', 'Scene', 'test_group'])
|
result = runner.invoke(app, ['group', 'toggle', 'pytest00', 'test_group'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Group 'test_group' is now visible." in result.stdout
|
assert "Group 'test_group' is now visible." in result.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_group_status():
|
def test_group_status():
|
||||||
"""Test the group status command."""
|
"""Test the group status command."""
|
||||||
result = runner.invoke(app, ['group', 'show', 'Scene', 'test_group'])
|
result = runner.invoke(app, ['group', 'show', 'pytest00', 'test_group'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Group 'test_group' is now visible." in result.stdout
|
assert "Group 'test_group' is now visible." in result.stdout
|
||||||
|
|
||||||
result = runner.invoke(app, ['group', 'status', 'Scene', 'test_group'])
|
result = runner.invoke(app, ['group', 'status', 'pytest00', 'test_group'])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Group 'test_group' is now visible." in result.stdout
|
assert "Group 'test_group' is now visible." in result.stdout
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
"""Unit tests for the stream commands in the OBS WebSocket CLI."""
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
from typer.testing import CliRunner
|
|
||||||
|
|
||||||
from obsws_cli.app import app
|
|
||||||
|
|
||||||
runner = CliRunner()
|
|
||||||
|
|
||||||
|
|
||||||
def test_stream_start():
|
|
||||||
"""Test the stream start command."""
|
|
||||||
result = runner.invoke(app, ['stream', 'status'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
active = 'Streaming is in progress' in result.stdout
|
|
||||||
|
|
||||||
result = runner.invoke(app, ['stream', 'start'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
|
|
||||||
time.sleep(1) # Wait for the stream to start
|
|
||||||
|
|
||||||
if active:
|
|
||||||
assert 'Streaming is already in progress, cannot start.' in result.stdout
|
|
||||||
else:
|
|
||||||
assert 'Streaming started successfully.' in result.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_stream_stop():
|
|
||||||
"""Test the stream stop command."""
|
|
||||||
result = runner.invoke(app, ['stream', 'status'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
active = 'Streaming is in progress' in result.stdout
|
|
||||||
|
|
||||||
result = runner.invoke(app, ['stream', 'stop'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
|
|
||||||
time.sleep(1) # Wait for the stream to stop
|
|
||||||
|
|
||||||
if active:
|
|
||||||
assert 'Streaming stopped successfully.' in result.stdout
|
|
||||||
else:
|
|
||||||
assert 'Streaming is not in progress, cannot stop.' in result.stdout
|
|
@ -1,27 +0,0 @@
|
|||||||
"""Unit tests for the studio mode command in the OBS WebSocket CLI."""
|
|
||||||
|
|
||||||
from typer.testing import CliRunner
|
|
||||||
|
|
||||||
from obsws_cli.app import app
|
|
||||||
|
|
||||||
runner = CliRunner()
|
|
||||||
|
|
||||||
|
|
||||||
def test_studio_enable():
|
|
||||||
"""Test the studio enable command."""
|
|
||||||
result = runner.invoke(app, ['studiomode', 'enable'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
|
|
||||||
result = runner.invoke(app, ['studiomode', 'status'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
assert 'Studio mode is enabled.' in result.stdout
|
|
||||||
|
|
||||||
|
|
||||||
def test_studio_disable():
|
|
||||||
"""Test the studio disable command."""
|
|
||||||
result = runner.invoke(app, ['studiomode', 'disable'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
|
|
||||||
result = runner.invoke(app, ['studiomode', 'status'])
|
|
||||||
assert result.exit_code == 0
|
|
||||||
assert 'Studio mode is disabled.' in result.stdout
|
|
Loading…
x
Reference in New Issue
Block a user