Skip to content

Commit bb148d6

Browse files
author
g
committed
Add comprehensive input management functionality
- Add Input command with full CRUD operations for OBS inputs - Support listing inputs and available input kinds - Include audio controls: volume, mute/unmute/toggle, balance, sync offset - Add monitor type and audio tracks configuration - Support input creation, removal, renaming, and settings management - Add default settings retrieval and special inputs listing - Include comprehensive test coverage for all input commands - Update README with new input management features documentation
1 parent 83510a7 commit bb148d6

File tree

7 files changed

+1025
-4
lines changed

7 files changed

+1025
-4
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
- **Virtual Camera**: Start, stop, toggle virtual camera output
1515
- **Replay Buffer**: Manage replay buffer with save functionality and status tracking
1616
- **Media Inputs**: Full media control with play, pause, stop, restart, and seek capabilities
17+
- **Input Management**: Complete CRUD operations for inputs, settings management, and audio control
18+
- List inputs and available input kinds
19+
- Create, remove, rename, and manage input settings
20+
- Audio controls: volume, mute/unmute/toggle, balance, sync offset, monitor type, tracks
21+
- Get default settings for any input kind
22+
- List special inputs (desktop audio, microphones)
1723
- **Screenshots**: Capture source screenshots with custom dimensions and compression
1824
- **Hotkeys**: Trigger any OBS hotkey by name
1925
- **Projectors**: Open fullscreen and source-specific projectors on multiple monitors

src/cli.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ pub enum Commands {
384384
#[clap(subcommand)]
385385
MediaInput(MediaInput),
386386

387+
#[clap(subcommand)]
388+
Input(Input),
389+
387390
/// Generate shell completion scripts
388391
Completion {
389392
/// Shell type to generate completion for
@@ -427,6 +430,130 @@ pub enum MediaInput {
427430
},
428431
}
429432

433+
#[derive(Subcommand, Clone, Debug, PartialEq)]
434+
pub enum Input {
435+
/// List all inputs, optionally filtered by kind
436+
List {
437+
/// Filter by input kind (e.g., "ffmpeg_source", "image_source")
438+
kind: Option<String>,
439+
},
440+
/// List all available input kinds
441+
ListKinds,
442+
/// Create a new input
443+
Create {
444+
/// Name for the new input
445+
input_name: String,
446+
/// Kind of input to create (e.g., "ffmpeg_source", "image_source")
447+
input_kind: String,
448+
/// Scene to add input to (optional)
449+
#[clap(long)]
450+
scene: Option<String>,
451+
/// Input settings as JSON string (optional)
452+
#[clap(long)]
453+
settings: Option<String>,
454+
},
455+
/// Remove an input
456+
Remove {
457+
/// Name of input to remove
458+
input_name: String,
459+
},
460+
/// Rename an input
461+
Rename {
462+
/// Current name of input
463+
input_name: String,
464+
/// New name for input
465+
new_name: String,
466+
},
467+
/// Get or set input settings
468+
Settings {
469+
/// Name of input
470+
input_name: String,
471+
/// Get current settings
472+
#[clap(long)]
473+
get: bool,
474+
/// Set new settings as JSON string
475+
#[clap(long)]
476+
set: Option<String>,
477+
},
478+
/// Get or set input volume
479+
Volume {
480+
/// Name of input
481+
input_name: String,
482+
/// Get current volume
483+
#[clap(long)]
484+
get: bool,
485+
/// Set volume (0.0 to 1.0)
486+
#[clap(long)]
487+
set: Option<f64>,
488+
},
489+
/// Mute control for input
490+
Mute {
491+
/// Name of input
492+
input_name: String,
493+
#[clap(subcommand)]
494+
action: MuteAction,
495+
},
496+
/// Get or set audio balance
497+
AudioBalance {
498+
/// Name of input
499+
input_name: String,
500+
/// Get current balance
501+
#[clap(long)]
502+
get: bool,
503+
/// Set balance (-1.0 to 1.0)
504+
#[clap(long)]
505+
set: Option<f32>,
506+
},
507+
/// Get or set audio sync offset
508+
AudioSyncOffset {
509+
/// Name of input
510+
input_name: String,
511+
/// Get current sync offset
512+
#[clap(long)]
513+
get: bool,
514+
/// Set sync offset in nanoseconds
515+
#[clap(long)]
516+
set: Option<i64>,
517+
},
518+
/// Get or set audio monitor type
519+
AudioMonitorType {
520+
/// Name of input
521+
input_name: String,
522+
/// Get current monitor type
523+
#[clap(long)]
524+
get: bool,
525+
/// Set monitor type (none, monitorOnly, both)
526+
#[clap(long)]
527+
set: Option<String>,
528+
},
529+
/// Get or set audio tracks
530+
AudioTracks {
531+
/// Name of input
532+
input_name: String,
533+
/// Get current audio tracks
534+
#[clap(long)]
535+
get: bool,
536+
/// Set audio tracks as JSON
537+
#[clap(long)]
538+
set: Option<String>,
539+
},
540+
/// Get default settings for input kind
541+
DefaultSettings {
542+
/// Input kind to get default settings for
543+
input_kind: String,
544+
},
545+
/// Get special inputs
546+
Specials,
547+
}
548+
549+
#[derive(Subcommand, Clone, Debug, PartialEq)]
550+
pub enum MuteAction {
551+
Mute,
552+
Unmute,
553+
Toggle,
554+
Status,
555+
}
556+
430557
/// Parses duration strings in [hh:]mm:ss format.
431558
///
432559
/// This function converts human-readable time strings into Duration objects.

src/error.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ pub enum ObsCmdError {
4848

4949
#[error("Invalid WebSocket URL format: {0}. Expected format: obsws://hostname:port/password")]
5050
WebSocketUrlParseError(String),
51+
52+
#[error("Invalid volume value {volume}. Must be between 0.0 and 1.0")]
53+
InvalidVolume { volume: f64 },
54+
55+
#[error("Invalid audio balance {balance}. Must be between -1.0 and 1.0")]
56+
InvalidAudioBalance { balance: f32 },
57+
58+
#[error(
59+
"Invalid audio monitor type '{monitor_type}'. Valid types are: none, monitorOnly, both"
60+
)]
61+
InvalidAudioMonitorType { monitor_type: String },
5162
}
5263

5364
/// Result type alias for obs-cmd operations.

src/handler.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::error::Result;
44
use crate::handlers::{
55
audio::AudioHandler, config::ProfileHandler, config::RecordDirectoryHandler,
66
config::StreamServiceHandler, config::VideoSettingsHandler, filters::FilterHandler,
7-
general::HotkeyHandler, general::InfoHandler, media::MediaInputHandler,
8-
recording::RecordingHandler, replay_buffer::ReplayBufferHandler,
7+
general::HotkeyHandler, general::InfoHandler, inputs::InputCmdHandler,
8+
media::MediaInputHandler, recording::RecordingHandler, replay_buffer::ReplayBufferHandler,
99
scene_collections::SceneCollectionHandler, scene_items::SceneItemHandler, scenes::SceneHandler,
1010
sources::SourceHandler, streaming::StreamingHandler, ui::FullscreenProjectorHandler,
1111
ui::SourceProjectorHandler, virtual_camera::VirtualCameraHandler, CommandHandler,
@@ -29,6 +29,11 @@ pub async fn handle_commands(client: &Client, commands: &Commands) -> Result<()>
2929
Commands::MediaInput(media_input) => Box::new(MediaInputHandler {
3030
action: media_input.clone(),
3131
}),
32+
33+
Commands::Input(action) => Box::new(InputCmdHandler {
34+
action: action.clone(),
35+
}),
36+
3237
Commands::Scene(action) => Box::new(SceneHandler {
3338
action: action.clone(),
3439
}),

0 commit comments

Comments
 (0)