mirror of
https://github.com/onyx-and-iris/vban-cli.git
synced 2026-04-16 02:23:30 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c535ae5571 | |||
| 7b5d2150c7 | |||
| 28ec67839a | |||
| dd0d150202 | |||
| 78952aa3ff | |||
| c4d67527f5 | |||
| b3cfc6bc4a | |||
| c642bbc1f2 |
58
README.md
58
README.md
@@ -51,7 +51,7 @@ export VBAN_CLI_STREAMNAME=Command1
|
|||||||
|
|
||||||
### Strip Command
|
### Strip Command
|
||||||
|
|
||||||
Usage: vban-cli strip <index> COMMAND [ARGS]
|
Usage: vban-cli strip \<index> COMMAND [ARGS]
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
|
|
||||||
@@ -65,22 +65,66 @@ vban-cli strip 2 gain -18.7
|
|||||||
|
|
||||||
see `vban-cli strip --help` for more info.
|
see `vban-cli strip --help` for more info.
|
||||||
|
|
||||||
### Bus Command
|
#### Strip EQ
|
||||||
|
|
||||||
Usage: vban-cli bus <index> COMMAND [ARGS]
|
Usage: vban-cli strip \<index> eq COMMAND [OPTIONS]
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
vban-cli bus mode normal
|
vban-cli strip 0 eq on true
|
||||||
|
```
|
||||||
|
|
||||||
vban-cli bus mute true
|
see `vban-cli strip eq --help` for more info.
|
||||||
|
|
||||||
|
#### Strip EQ Cell Command
|
||||||
|
|
||||||
|
Usage: vban-cli strip \<index> eq cell \<band> COMMAND [ARGS]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli strip 0 eq cell 0 on false
|
||||||
|
```
|
||||||
|
|
||||||
|
see `vban-cli strip eq cell --help` for more info.
|
||||||
|
|
||||||
|
### Bus Command
|
||||||
|
|
||||||
|
Usage: vban-cli bus \<index> COMMAND [ARGS]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli bus 0 mode tvmix
|
||||||
|
|
||||||
|
vban-cli bus 1 mute true
|
||||||
```
|
```
|
||||||
|
|
||||||
see `vban-cli bus --help` for more info.
|
see `vban-cli bus --help` for more info.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Sendtext Command
|
||||||
|
|
||||||
|
Usage: vban-cli sendtext TEXT
|
||||||
|
|
||||||
|
*To Voicemeeter*
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli sendtext 'Strip[0].Mute=1;Bus[0].Mono=2'
|
||||||
|
```
|
||||||
|
|
||||||
|
*To Matrix*
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli sendtext 'Command.Version = ?'
|
||||||
|
|
||||||
|
vban-cli sendtext 'Point(ASIO128.IN[1..4],ASIO128.OUT[1]).dBGain = -3.0'
|
||||||
|
```
|
||||||
|
|
||||||
## Implementation Notes
|
## Implementation Notes
|
||||||
|
|
||||||
1. The VBAN TEXT subprotocol defines two packet structures [ident:0][ident-0] and [ident:1][ident-1]. Neither of them contain the data for Bus EQ parameters.
|
1. The VBAN TEXT subprotocol defines two packet structures [ident:0][ident-0] and [ident:1][ident-1]. Neither of them contain the data for Bus EQ parameters.
|
||||||
@@ -93,9 +137,7 @@ see `vban-cli bus --help` for more info.
|
|||||||
|
|
||||||
I've made the effort to set up the basic skeletal structure of the CLI as well as demonstrate how to combine subcommand groups with subcommand groups so more can be implemented, it just needs doing. There may be restrictions on some things however, for example, retrieving values is only possible for parameters [defined in the protocol](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/3be2c1c36563afbd6df3da8436406c77d2cc1f10/VoicemeeterRemote.h#L787). Setting parameters can be done for anything possible by a string request.
|
I've made the effort to set up the basic skeletal structure of the CLI as well as demonstrate how to combine subcommand groups with subcommand groups so more can be implemented, it just needs doing. There may be restrictions on some things however, for example, retrieving values is only possible for parameters [defined in the protocol](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/3be2c1c36563afbd6df3da8436406c77d2cc1f10/VoicemeeterRemote.h#L787). Setting parameters can be done for anything possible by a string request.
|
||||||
|
|
||||||
Shell completion scripts are available (for zsh, bash and fish) but I haven't tested them
|
Shell completion scripts are available (for zsh, bash and fish) but they haven't been thoroughly tested.
|
||||||
|
|
||||||
Some of the help output needs improving for commands that branch off positional arguments.
|
|
||||||
|
|
||||||
If there's something missing that you would like to see added the best bet is to submit a PR. You may raise an issue and if it's quick and simple to do I may (or may not) do it.
|
If there's something missing that you would like to see added the best bet is to submit a PR. You may raise an issue and if it's quick and simple to do I may (or may not) do it.
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "vban-cli"
|
name = "vban-cli"
|
||||||
version = "0.4.2"
|
version = "0.5.0"
|
||||||
description = "A command-line interface for Voicemeeter leveraging VBAN."
|
description = "A command-line interface for Voicemeeter leveraging VBAN."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { text = "LICENSE" }
|
license = { text = "LICENSE" }
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.7.1"]
|
||||||
"cyclopts>=4.6.0",
|
|
||||||
"loguru>=0.7.3",
|
|
||||||
"vban-cmd>=2.6.0",
|
|
||||||
]
|
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 3 - Alpha",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
@@ -28,4 +24,4 @@ vban-cli = "vban_cli.app:run"
|
|||||||
package = true
|
package = true
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
vban-cmd = { path = "../vban-cmd-python" }
|
vban-cmd = { path = "../vban-cmd-python", editable = true }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from dataclasses import dataclass
|
|||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
import vban_cmd
|
import vban_cmd
|
||||||
from cyclopts import App, Parameter, config
|
from cyclopts import App, Argument, Parameter, config
|
||||||
|
|
||||||
from . import __version__ as version
|
from . import __version__ as version
|
||||||
from . import bus, console, strip
|
from . import bus, console, strip
|
||||||
@@ -37,15 +37,32 @@ def launcher(
|
|||||||
if tokens[0] == '--install-completion':
|
if tokens[0] == '--install-completion':
|
||||||
return command(*bound.args, **bound.kwargs)
|
return command(*bound.args, **bound.kwargs)
|
||||||
|
|
||||||
|
disable_rt_listeners = False
|
||||||
|
if command.__name__ == 'sendtext':
|
||||||
|
disable_rt_listeners = True
|
||||||
|
|
||||||
with vban_cmd.api(
|
with vban_cmd.api(
|
||||||
vban_config.kind,
|
vban_config.kind,
|
||||||
ip=vban_config.host,
|
ip=vban_config.host,
|
||||||
port=vban_config.port,
|
port=vban_config.port,
|
||||||
streamname=vban_config.streamname,
|
streamname=vban_config.streamname,
|
||||||
|
disable_rt_listeners=disable_rt_listeners,
|
||||||
) as client:
|
) as client:
|
||||||
return command(*bound.args, **bound.kwargs, ctx=Context(client=client))
|
return command(*bound.args, **bound.kwargs, ctx=Context(client=client))
|
||||||
|
|
||||||
|
|
||||||
|
@app.command(name='sendtext')
|
||||||
|
def sendtext(
|
||||||
|
text: Annotated[str, Argument()],
|
||||||
|
/,
|
||||||
|
*,
|
||||||
|
ctx: Annotated[Context, Parameter(show=False)] = None,
|
||||||
|
):
|
||||||
|
"""Send a text command to the current Voicemeeter/Matrix instance."""
|
||||||
|
if resp := ctx.client.sendtext(text):
|
||||||
|
console.out.print(resp)
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
try:
|
try:
|
||||||
app.meta()
|
app.meta()
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ def launcher(
|
|||||||
|
|
||||||
@app.command(name='mono')
|
@app.command(name='mono')
|
||||||
def mono(
|
def mono(
|
||||||
new_value: Annotated[Optional[bool], Argument()] = None,
|
new_value: Annotated[
|
||||||
|
Optional[Literal['off', 'mono', 'stereoreverse']], Argument()
|
||||||
|
] = None,
|
||||||
*,
|
*,
|
||||||
index: Annotated[int, Parameter(show=False)] = None,
|
index: Annotated[int, Parameter(show=False)] = None,
|
||||||
ctx: Annotated[Context, Parameter(show=False)] = None,
|
ctx: Annotated[Context, Parameter(show=False)] = None,
|
||||||
@@ -41,13 +43,13 @@ def mono(
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
new_value : bool, optional
|
new_value : {'off', 'mono', 'stereoreverse'}, optional
|
||||||
If provided, sets the mono state to this value. If not provided, the current mono state is printed.
|
If provided, sets the mono state to this value. If not provided, the current mono state is printed.
|
||||||
"""
|
"""
|
||||||
if new_value is None:
|
if new_value is None:
|
||||||
console.out.print(ctx.client.bus[index].mono)
|
console.out.print(['off', 'mono', 'stereoreverse'][ctx.client.bus[index].mono])
|
||||||
return
|
return
|
||||||
ctx.client.bus[index].mono = new_value
|
ctx.client.bus[index].mono = ['off', 'mono', 'stereoreverse'].index(new_value)
|
||||||
|
|
||||||
|
|
||||||
@app.command(name='mute')
|
@app.command(name='mute')
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import StripSubcommandHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='comp', help_formatter=StripSubcommandHelpFormatter())
|
app = App(name='comp', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import StripSubcommandHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='denoiser', help_formatter=StripSubcommandHelpFormatter())
|
app = App(name='denoiser', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import StripSubcommandHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='gate', help_formatter=StripSubcommandHelpFormatter())
|
app = App(name='gate', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -61,18 +61,6 @@ class StripHelpFormatter(BaseHelpFormatter):
|
|||||||
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
||||||
|
|
||||||
|
|
||||||
class StripSubcommandHelpFormatter(BaseHelpFormatter):
|
|
||||||
"""Help formatter for strip subcommands that injects <index> after 'strip'."""
|
|
||||||
|
|
||||||
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
|
||||||
"""Render the usage line with index argument injected after 'strip'."""
|
|
||||||
if usage:
|
|
||||||
modified_usage = re.sub(
|
|
||||||
r'(\S+\s+strip)\s+(\w+)\s+(COMMAND)', r'\1 <index> \2 \3', str(usage)
|
|
||||||
)
|
|
||||||
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
|
||||||
|
|
||||||
|
|
||||||
class BusHelpFormatter(BaseHelpFormatter):
|
class BusHelpFormatter(BaseHelpFormatter):
|
||||||
"""Help formatter for bus commands that injects <index> after 'bus'."""
|
"""Help formatter for bus commands that injects <index> after 'bus'."""
|
||||||
|
|
||||||
|
|||||||
8
uv.lock
generated
8
uv.lock
generated
@@ -124,7 +124,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vban-cli"
|
name = "vban-cli"
|
||||||
version = "0.4.2"
|
version = "0.5.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "cyclopts" },
|
{ name = "cyclopts" },
|
||||||
@@ -136,13 +136,13 @@ dependencies = [
|
|||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "cyclopts", specifier = ">=4.6.0" },
|
{ name = "cyclopts", specifier = ">=4.6.0" },
|
||||||
{ name = "loguru", specifier = ">=0.7.3" },
|
{ name = "loguru", specifier = ">=0.7.3" },
|
||||||
{ name = "vban-cmd", directory = "../vban-cmd-python" },
|
{ name = "vban-cmd", editable = "../vban-cmd-python" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vban-cmd"
|
name = "vban-cmd"
|
||||||
version = "2.6.0"
|
version = "2.7.1"
|
||||||
source = { directory = "../vban-cmd-python" }
|
source = { editable = "../vban-cmd-python" }
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [{ name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0.1,<3.0" }]
|
requires-dist = [{ name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0.1,<3.0" }]
|
||||||
|
|||||||
Reference in New Issue
Block a user