From c6c3ed5d421051d7bbd96e71a2c1c489785b4140 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Mon, 30 Oct 2023 06:34:12 -0500 Subject: [PATCH] adding a basic setup for connecting OBS --- Cargo.lock | 288 +++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/rust/lib.rs | 1 + src/rust/obs.rs | 38 +++++ src/rust/service_item_model.rs | 6 + 5 files changed, 324 insertions(+), 10 deletions(-) create mode 100644 src/rust/obs.rs diff --git a/Cargo.lock b/Cargo.lock index f3ff646..6c7f097 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ashpd" version = "0.6.7" @@ -351,6 +366,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets", +] + [[package]] name = "clang-format" version = "0.1.3" @@ -400,6 +428,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "cpufeatures" version = "0.2.9" @@ -578,6 +612,47 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.28", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + [[package]] name = "der" version = "0.7.8" @@ -594,6 +669,9 @@ name = "deranged" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +dependencies = [ + "serde", +] [[package]] name = "derivative" @@ -813,6 +891,12 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -960,6 +1044,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.0" @@ -976,7 +1066,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown", + "hashbrown 0.14.0", ] [[package]] @@ -1027,6 +1117,52 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.4.0" @@ -1037,6 +1173,17 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.0.0" @@ -1044,7 +1191,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.0", + "serde", ] [[package]] @@ -1152,6 +1300,7 @@ dependencies = [ "diesel_migrations", "dirs", "fastrand 2.0.0", + "obws", "qt-build-utils", "quote", "rfd", @@ -1453,6 +1602,29 @@ dependencies = [ "memchr", ] +[[package]] +name = "obws" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a1f9a0b90718cf798dd72018d1a59ef01c339b67fb7d56e63503b98d68f74e" +dependencies = [ + "base64", + "bitflags 2.4.0", + "futures-util", + "rgb", + "semver", + "serde", + "serde_json", + "serde_repr", + "serde_with", + "sha2", + "thiserror", + "time", + "tokio", + "tokio-tungstenite", + "tracing", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -1790,6 +1962,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" + [[package]] name = "rsa" version = "0.9.2" @@ -1863,6 +2041,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + [[package]] name = "serde" version = "1.0.188" @@ -1885,9 +2072,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1914,6 +2101,35 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "sha1" version = "0.10.6" @@ -2080,7 +2296,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap", + "indexmap 2.0.0", "log", "memchr", "once_cell", @@ -2256,6 +2472,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.5.0" @@ -2319,18 +2541,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -2433,6 +2655,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "toml" version = "0.7.6" @@ -2460,7 +2694,7 @@ version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -2531,6 +2765,25 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -2604,6 +2857,12 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "valuable" version = "0.1.0" @@ -2776,6 +3035,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6041b3f84485c21b57acdc0fee4f4f0c93f426053dc05fa5d6fc262537bbff" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 8f66b41..0c99ab2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ tokio = { version = "1.32.0", features = ["full"] } tracing-subscriber = { version = "0.3.17", features = ["fmt", "std", "time", "local-time", "env-filter"] } tracing = "0.1.37" time = { version = "0.3.29", features = ["formatting", "macros"] } +obws = "0.11.5" # ffmpeg-next = "6.0.0" # cxx-qt-build generates C++ code from the `#[cxx_qt::bridge]` module diff --git a/src/rust/lib.rs b/src/rust/lib.rs index 23e5aa0..34328d7 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -14,4 +14,5 @@ pub mod songs; pub mod video_model; pub mod ytdl; pub mod utils; +pub mod obs; // mod video_thumbnail; diff --git a/src/rust/obs.rs b/src/rust/obs.rs new file mode 100644 index 0000000..15d0f58 --- /dev/null +++ b/src/rust/obs.rs @@ -0,0 +1,38 @@ +use std::error::Error; + +use obws::Client; +use obws::responses::scenes::Scenes; +use tracing::debug; +pub struct Obs { + scenes: Scenes, + client: Client, +} + +impl Obs { + pub async fn setup(mut self) -> Result<(), Box> { + let client = Client::connect("localhost", 4455, Some("")).await?; + let scene_list = client.scenes().list().await?; + debug!(?scene_list); + self.scenes = scene_list; + self.client = client; + Ok(()) + } + + pub fn get_list(self) -> Result, String> { + let scenes = self.scenes.scenes.iter().map(|x| x.name).collect::>(); + if scenes.len() > 0 { + Ok(scenes) + } else { + Err(format!("Scenes found: {}", scenes.len())) + } + } + + pub fn set_scene(self, scene: String) -> Result<(), String> { + if let Some(scene) = self.scenes.scenes.iter().filter(|x| x.name == scene).next() { + self.client.scenes().set_current_program_scene(scene.name.as_str()); + Ok(()) + } else { + Err("Couldn't set the scene".to_string()) + } + } +} diff --git a/src/rust/service_item_model.rs b/src/rust/service_item_model.rs index 1f6f8fe..508222c 100644 --- a/src/rust/service_item_model.rs +++ b/src/rust/service_item_model.rs @@ -56,6 +56,8 @@ mod service_item_model { video_start_time: f32, #[qproperty] video_end_time: f32, + #[qproperty] + obs_scene: QString, } impl Default for ServiceItm { @@ -75,6 +77,7 @@ mod service_item_model { looping: false, video_start_time: 0.0, video_end_time: 0.0, + obs_scene: QString::default(), } } } @@ -147,6 +150,8 @@ mod service_item_model { use tar::{Archive, Builder}; use tracing::{debug, debug_span, error, info, instrument}; use zstd::{Decoder, Encoder}; + + use crate::obs::Obs; impl qobject::ServiceItemMod { #[qinvokable] pub fn clear(mut self: Pin<&mut Self>) { @@ -602,6 +607,7 @@ mod service_item_model { // We use this signal generated by our signals enum to tell QML that // the active service_item has changed which is used to reposition views. self.as_mut().emit_active_changed(); + Obs::set_scene(service_item.obs_scene.to_string()); true } else { false