Skip to content

Commit

Permalink
Reorganize and make things more typed, as well as improve the CLI (#14)
Browse files Browse the repository at this point in the history
* Reorganize and make things more typed, as well as improve the CLI

Signed-off-by: Dallas Strouse <[email protected]>

* Slightly update the README to add websocket details

Signed-off-by: Dallas Strouse <[email protected]>

* Format and clippy fixes

Signed-off-by: Dallas Strouse <[email protected]>

* Bring back a default websocket argument

Signed-off-by: Dallas Strouse <[email protected]>

---------

Signed-off-by: Dallas Strouse <[email protected]>
  • Loading branch information
orowith2os committed Nov 21, 2023
1 parent af35b01 commit 62998f5
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 104 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ name = "obs-cmd"
tokio = { version = "1.28.1", features = ["rt-multi-thread", "macros"] }
obws = "0.11.0"
clap = { version = "4.4.8", features = ["derive"] }
url = "2.4.1"


6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ obs-cmd virtualcam start
obs-cmd replay toggle
obs-cmd replay save
obs-cmd info
obs-cmd --obsws obsws://localhost:4455/secret info # You can override the default `obsws` url
obs-cmd --websocket obsws://localhost:4455/secret info # You can override the default `obsws` url
```

You can override the websocket URL, which can be found in OBS -> Tools -> WebSocket Server Settings. `localhost` for the hostname will work for most, instead of the full IP address.

### Installation


Expand Down Expand Up @@ -105,4 +107,4 @@ Donations are welcome and will go towards further development of this project
monero:88LyqYXn4LdCVDtPWKuton9hJwbo8ZduNEGuARHGdeSJ79BBYWGpMQR8VGWxGDKtTLLM6E9MJm8RvW9VMUgCcSXu19L9FSv
bitcoin:bc1q6mh77hfv8x8pa0clzskw6ndysujmr78j6se025
lightning:[email protected]
```
```
124 changes: 124 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use clap::{Parser, Subcommand};
use std::str::FromStr;
use url::Url;

#[derive(Clone, Debug)]
pub struct ObsWebsocket {
pub hostname: String,
pub port: u16,
pub password: Option<String>,
}

impl FromStr for ObsWebsocket {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match Url::parse(s) {
Ok(unvalidated_websocket) => {
if unvalidated_websocket.scheme() != "obsws" {
return Err(
"Invalid URL format, use the format obsws://hostname:port/password",
);
}

let hostname = unvalidated_websocket.host().unwrap().to_string();

let port =
match unvalidated_websocket.port() {
Some(port) => port,
None => return Err(
"Please specify a port in the format obsws://hostname:port/password",
),
};

let password = match unvalidated_websocket.path() {
"" => None,
_ => {
let mut pass = unvalidated_websocket.path().to_string();
// Otherwise the `/` part of the password in the URL is included.
let _ = pass.remove(0);
Some(pass)
}
};

Ok(ObsWebsocket {
hostname,
port,
password,
})
}
Err(_) => Err("Invalid URL format, use the format obsws://hostname:port/password"),
}
}
}

#[derive(Subcommand, Clone, Debug)]
pub enum Replay {
Start,
Stop,
Toggle,
Save,
}

#[derive(Subcommand, Clone, Debug)]
pub enum VirtualCamera {
Start,
Stop,
Toggle,
}

#[derive(Subcommand, Clone, Debug)]
pub enum Streaming {
Start,
Stop,
Toggle,
}

#[derive(Subcommand, Clone, Debug)]
pub enum Recording {
Start,
Stop,
Toggle,
}

#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
pub struct Cli {
#[clap(short, long)]
/// The default websocket URL is `obsws://localhost:4455/secret`
/// if this argument is not provided
pub websocket: Option<ObsWebsocket>,
#[clap(subcommand)]
pub command: Commands,
}

#[derive(Subcommand)]
pub enum Commands {
Info,
Scene {
switch_placeholder: String, // NOTE: just for args positioning
scene_name: String,
},

#[clap(subcommand)]
Replay(Replay),

#[clap(subcommand)]
VirtualCamera(VirtualCamera),

#[clap(subcommand)]
Streaming(Streaming),

#[clap(subcommand)]
Recording(Recording),

ToggleMute {
device: String,
},

Filter {
command: String,
source: String,
filter: String,
},
}
Loading

0 comments on commit 62998f5

Please sign in to comment.