Compare commits

...

9 Commits

Author SHA1 Message Date
ca0f01ef79 fix index column alignment 2025-05-26 22:14:30 +01:00
c4f3f1713f add open scene/group examples to projector section 2025-05-26 22:07:30 +01:00
47b6ef49ed add output to projector open
patch bump
2025-05-26 21:59:46 +01:00
2c7302cfde project open source_name arg now optional.
defaults to current scene

patch bump
2025-05-26 21:37:32 +01:00
a7385e58c6 minor bump 2025-05-26 20:55:30 +01:00
ac4dbb69ec add 0.13.0 to CHANGELOG
add projector section to README
2025-05-26 20:54:47 +01:00
2739fa28f0 add projector subtyper 2025-05-26 20:54:22 +01:00
b5364bfedc return 0 and write to stdout if empty list 2025-05-26 20:54:06 +01:00
9fa61351d0 return 0 for empty lists and write to stdout 2025-05-26 20:45:36 +01:00
8 changed files with 117 additions and 7 deletions

View File

@ -5,6 +5,16 @@ 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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# [0.13.0] - 2025-05-26
### Added
- projector commands, see [projector](https://github.com/onyx-and-iris/obsws-cli?tab=readme-ov-file#projector)
### Changed
- list commands that result in empty lists now return exit code 0 and write to stdout.
# [0.12.0] - 2025-05-23 # [0.12.0] - 2025-05-23
### Added ### Added

View File

@ -534,6 +534,34 @@ obsws-cli filter toggle "Mic/Aux" "Gain"
obsws-cli filter status "Mic/Aux" "Gain" obsws-cli filter status "Mic/Aux" "Gain"
``` ```
#### Projector
- list-monitors: List available monitors.
```console
obsws-cli projector list-monitors
```
- open: Open a fullscreen projector for a source on a specific monitor.
- flags:
*optional*
- --monitor-index: Index of the monitor to open the projector on.
- defaults to 0
*optional*
- args: <source_name>
- defaults to current scene
```console
obsws-cli project open
obsws-cli projector open --monitor-index=1 "test_scene"
obsws-cli projector open --monitor-index=1 "test_group"
```
## License ## License
`obsws-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. `obsws-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.

View File

@ -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.12.10" __version__ = "0.13.3"

View File

@ -12,6 +12,7 @@ from . import (
hotkey, hotkey,
input, input,
profile, profile,
projector,
record, record,
replaybuffer, replaybuffer,
scene, scene,
@ -30,6 +31,7 @@ for module in (
group, group,
hotkey, hotkey,
input, input,
projector,
profile, profile,
record, record,
replaybuffer, replaybuffer,

View File

@ -41,8 +41,8 @@ def list(
] ]
if not groups: if not groups:
err_console.print(f"No groups found in scene '{scene_name}'.") out_console.print(f"No groups found in scene '{scene_name}'.")
raise typer.Exit(1) return
table = Table(title=f'Groups in Scene: {scene_name}', padding=(0, 2)) table = Table(title=f'Groups in Scene: {scene_name}', padding=(0, 2))

View File

@ -48,8 +48,8 @@ def list(
] ]
if not inputs: if not inputs:
err_console.print('No inputs found.') out_console.print('No inputs found.')
raise typer.Exit(1) return
table = Table(title='Inputs', padding=(0, 2)) table = Table(title='Inputs', padding=(0, 2))
for column in ('Input Name', 'Kind'): for column in ('Input Name', 'Kind'):

70
obsws_cli/projector.py Normal file
View File

@ -0,0 +1,70 @@
"""module containing commands for manipulating projectors in OBS."""
from typing import Annotated
import typer
from rich.console import Console
from rich.table import Table
from .alias import AliasGroup
app = typer.Typer(cls=AliasGroup)
out_console = Console()
err_console = Console(stderr=True)
@app.callback()
def main():
"""Control projectors in OBS."""
@app.command('list-monitors | ls-m')
def list_monitors(ctx: typer.Context):
"""List available monitors."""
resp = ctx.obj.get_monitor_list()
if not resp.monitors:
out_console.print('No monitors found.')
return
monitors = sorted(
((m['monitorIndex'], m['monitorName']) for m in resp.monitors),
key=lambda m: m[0],
)
table = Table(title='Available Monitors', padding=(0, 2))
table.add_column('Index', justify='center', style='cyan')
table.add_column('Name', style='cyan')
for index, monitor in monitors:
table.add_row(str(index), monitor)
out_console.print(table)
@app.command('open | o')
def open(
ctx: typer.Context,
monitor_index: Annotated[
int,
typer.Option(help='Index of the monitor to open the projector on.'),
] = 0,
source_name: Annotated[
str,
typer.Argument(
help='Name of the source to project. (optional, defaults to current scene)'
),
] = '',
):
"""Open a fullscreen projector for a source on a specific monitor."""
if not source_name:
source_name = ctx.obj.get_current_program_scene().scene_name
ctx.obj.open_source_projector(
source_name=source_name,
monitor_index=monitor_index,
)
out_console.print(
f'Opened projector for source [bold]{source_name}[/] on monitor [bold]{monitor_index}[/].'
)

View File

@ -39,8 +39,8 @@ def list(
items = [item.get('sourceName') for item in resp.scene_items] items = [item.get('sourceName') for item in resp.scene_items]
if not items: if not items:
err_console.print(f"No items found in scene '{scene_name}'.") out_console.print(f"No items found in scene '{scene_name}'.")
raise typer.Exit(1) return
table = Table(title=f'Items in Scene: {scene_name}', padding=(0, 2)) table = Table(title=f'Items in Scene: {scene_name}', padding=(0, 2))
table.add_column('Item Name', justify='left', style='cyan') table.add_column('Item Name', justify='left', style='cyan')