Introduce initial implementation of the vmic CLI with PipeWire integration
- Added `Cargo.toml` to define dependencies and project metadata. - Implemented core CLI functionality for managing virtual microphones (`create`, `edit`, `delete`, `list`, `route`, and `wipe` commands) using `clap`. - Integrated `rusqlite` for persistent state storage and `pipewire` to manage PipeWire nodes. - Ensured graceful handling of feedback loops and system defaults during virtual mic creation and deletion. - Added error handling via `thiserror` for cleaner error definitions.
This commit is contained in:
90
src/cli.rs
Normal file
90
src/cli.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use clap_complete::Shell;
|
||||
|
||||
/// vmic - create and manage PipeWire virtual microphones.
|
||||
#[derive(Parser)]
|
||||
#[command(name = "vmic", version, about)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Create a new virtual microphone.
|
||||
#[command(visible_alias = "mk", visible_alias = "make")]
|
||||
Create(CreateArgs),
|
||||
|
||||
/// Move app streams and mix a hardware source into a vmic.
|
||||
Route(RouteArgs),
|
||||
|
||||
/// Change loopback and volume settings on a vmic.
|
||||
Edit(EditArgs),
|
||||
|
||||
/// Delete a virtual microphone.
|
||||
#[command(visible_alias = "rm", visible_alias = "remove")]
|
||||
Delete(DeleteArgs),
|
||||
|
||||
/// List all virtual microphones.
|
||||
#[command(visible_alias = "ls")]
|
||||
List,
|
||||
|
||||
/// Tear down every vmic, tracked or not.
|
||||
#[command(visible_alias = "reset")]
|
||||
Wipe,
|
||||
|
||||
/// Generate a shell completion script.
|
||||
Completions { shell: Shell },
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct CreateArgs {
|
||||
/// Name for the new vmic.
|
||||
pub name: String,
|
||||
|
||||
/// Enable a self-monitor loopback.
|
||||
#[arg(short, long)]
|
||||
pub loopback: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RouteArgs {
|
||||
/// Name of the vmic to route into.
|
||||
pub name: String,
|
||||
|
||||
/// Move matching sink-inputs into this vmic's sink.
|
||||
#[arg(short, long = "input", value_name = "APP[:MEDIA]")]
|
||||
pub inputs: Vec<String>,
|
||||
|
||||
/// Move matching source-outputs off this vmic's source.
|
||||
#[arg(short, long = "output", value_name = "APP[:MEDIA]")]
|
||||
pub outputs: Vec<String>,
|
||||
|
||||
/// Mix a hardware source into the vmic, or "off" to remove it.
|
||||
#[arg(short, long = "source", value_name = "SOURCE|off")]
|
||||
pub source: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct EditArgs {
|
||||
/// Name of the vmic to edit.
|
||||
pub name: String,
|
||||
|
||||
/// Enable or disable the self-monitor loopback.
|
||||
#[arg(short, long)]
|
||||
pub loopback: Option<bool>,
|
||||
|
||||
/// Loopback volume: fraction (0.8) or percent (80).
|
||||
#[arg(short, long)]
|
||||
pub volume: Option<f32>,
|
||||
|
||||
/// Mixed-in source volume: fraction (0.8) or percent (80).
|
||||
#[arg(long = "source-volume", visible_alias = "sv")]
|
||||
pub source_volume: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct DeleteArgs {
|
||||
/// Name of the vmic to delete.
|
||||
pub name: String,
|
||||
}
|
||||
Reference in New Issue
Block a user