use std::{ net::{Ipv4Addr, SocketAddrV4}, str::FromStr, sync::Arc, time::Duration, }; use atem_connection_rs::{ atem::Atem, atem_lib::atem_socket::{AtemSocket, AtemSocketMessage}, commands::mix_effects::program_input::ProgramInput, }; use clap::Parser; use color_eyre::Report; use tokio::{select, time::sleep}; use tokio_util::sync::CancellationToken; /// ATEM Rust Library Test App #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// IP of the ATEM to connect to #[arg(short, long)] ip: String, } #[tokio::main] async fn main() { let args = Args::parse(); setup_logging().unwrap(); let (socket_message_tx, socket_message_rx) = tokio::sync::mpsc::channel::(10); let (atem_event_tx, atem_event_rx) = tokio::sync::mpsc::unbounded_channel(); let cancel = CancellationToken::new(); let mut atem_socket = AtemSocket::new(socket_message_rx, atem_event_tx); let atem = Arc::new(Atem::new(atem_socket, socket_message_tx)); let atem_thread = atem.clone(); let atem_run = atem_thread.run(atem_event_rx, cancel); let switch_loop = tokio::spawn(async move { let address = Ipv4Addr::from_str(&args.ip).unwrap(); let socket = SocketAddrV4::new(address, 9910); atem.connect(socket.into()).await; loop { sleep(Duration::from_millis(5000)).await; log::info!("Switch to source 1"); atem.send_commands(vec![Box::new(ProgramInput::new(0, 1))]) .await; log::info!("Switched to source 1"); sleep(Duration::from_millis(5000)).await; log::info!("Switch to source 2"); atem.send_commands(vec![Box::new(ProgramInput::new(0, 2))]) .await; log::info!("Switched to source 2"); } }); select! { _ = atem_run => {}, _ = switch_loop => {} } } fn setup_logging() -> Result<(), Report> { if std::env::var("RUST_LIB_BACKTRACE").is_err() { std::env::set_var("RUST_LIB_BACKTRACE", "1"); } color_eyre::install()?; if std::env::var("RUST_LOG").is_err() { std::env::set_var("RUST_LOG", "debug"); } env_logger::init(); Ok(()) }