4 Commits

Author SHA1 Message Date
f389eb53b8 patch bump 2026-03-01 21:59:49 +00:00
341c81fde1 minor bump 2026-03-01 21:16:11 +00:00
e062da51ed add Recorder Command to README 2026-03-01 21:15:51 +00:00
c82a021708 add recorder subcommand group
add validation module
2026-03-01 21:15:42 +00:00
6 changed files with 149 additions and 5 deletions

View File

@@ -117,6 +117,22 @@ vban-cli command restart
see `vban-cli command --help` for more info. see `vban-cli command --help` for more info.
### Recorder Command
Usage: vban-cli recorder COMMAND
examples:
```console
vban-cli recorder play
vban-cli recorder rew
vban-cli recorder replay
```
see `vban-cli recorder --help` for more info.
### Sendtext Command ### Sendtext Command
Usage: vban-cli sendtext TEXT Usage: vban-cli sendtext TEXT

View File

@@ -1,11 +1,11 @@
[project] [project]
name = "vban-cli" name = "vban-cli"
version = "0.6.0" version = "0.7.1"
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 = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.7.1"] dependencies = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.8.1"]
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
"Programming Language :: Python", "Programming Language :: Python",

View File

@@ -5,7 +5,7 @@ import vban_cmd
from cyclopts import App, Argument, Parameter, config from cyclopts import App, Argument, Parameter, config
from . import __version__ as version from . import __version__ as version
from . import bus, command, console, strip from . import bus, command, console, recorder, strip
from .context import Context from .context import Context
app = App( app = App(
@@ -17,6 +17,7 @@ app = App(
app.command(strip.app.meta, name='strip') app.command(strip.app.meta, name='strip')
app.command(bus.app.meta, name='bus') app.command(bus.app.meta, name='bus')
app.command(command.app, name='command') app.command(command.app, name='command')
app.command(recorder.app, name='recorder')
app.register_install_completion_command() app.register_install_completion_command()

118
src/vban_cli/recorder.py Normal file
View File

@@ -0,0 +1,118 @@
from pathlib import Path
from typing import Annotated
from cyclopts import App, Parameter, validators
from . import console, validation
from .context import Context
from .help import BaseHelpFormatter
app = App(name='recorder', help_formatter=BaseHelpFormatter())
@app.command(name='play')
def play(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Start the recorder playback."""
ctx.client.recorder.play()
console.out.print('Recorder playback started.')
@app.command(name='stop')
def stop(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Stop the recorder playback."""
ctx.client.recorder.stop()
console.out.print('Recorder playback stopped.')
@app.command(name='pause')
def pause(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Pause the recorder playback."""
ctx.client.recorder.pause()
console.out.print('Recorder playback paused.')
@app.command(name='replay')
def replay(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Replay the recorder playback."""
ctx.client.recorder.replay()
console.out.print('Recorder playback replay started.')
@app.command(name='record')
def record(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Start recording."""
ctx.client.recorder.record()
console.out.print('Recording started.')
@app.command(name='ff')
def ff(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Fast forward the recorder playback."""
ctx.client.recorder.ff()
console.out.print('Recorder playback fast forwarded.')
@app.command(name='rew')
def rew(
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Rewind the recorder playback."""
ctx.client.recorder.rew()
console.out.print('Recorder playback rewound.')
@app.command(name='load')
def load(
file_path: Annotated[
Path,
Parameter(
help='The path to the recording file to load.',
validator=validators.Path(exists=True),
),
],
/,
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Load a file into the recorder.
note: This command may only work if vban-cli is running on localhost and may not work if vban-cli is running on a remote server."""
ctx.client.recorder.load(file_path)
console.out.print(f'Loaded file: {file_path}')
@app.command(name='goto')
def goto(
time_string: Annotated[
str,
Parameter(
help='The timestamp to go to in the recorder playback (format: HH:MM:SS).',
validator=validation.is_valid_time_string,
),
],
/,
*,
ctx: Annotated[Context, Parameter(show=False)] = None,
):
"""Go to a specific timestamp in the recorder playback."""
ctx.client.recorder.goto(time_string)
console.out.print(f'Went to timestamp {time_string} in recorder playback.')

View File

@@ -0,0 +1,9 @@
import re
def is_valid_time_string(type_, value: str) -> str:
"""Validate if the given string is a valid time format (HH:MM:SS)."""
pattern = r'^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$'
if not re.match(pattern, value):
raise ValueError('Invalid time format. Expected HH:MM:SS.')
return value

4
uv.lock generated
View File

@@ -124,7 +124,7 @@ wheels = [
[[package]] [[package]]
name = "vban-cli" name = "vban-cli"
version = "0.6.0" version = "0.7.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "cyclopts" }, { name = "cyclopts" },
@@ -141,7 +141,7 @@ requires-dist = [
[[package]] [[package]]
name = "vban-cmd" name = "vban-cmd"
version = "2.7.1" version = "2.8.0"
source = { editable = "../vban-cmd-python" } source = { editable = "../vban-cmd-python" }
[package.metadata] [package.metadata]