diff --git a/package-lock.json b/package-lock.json index aeff80c..44b582c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.12", "@tauri-apps/api": "^2", + "@tauri-apps/plugin-log": "^2.6.0", "@tauri-apps/plugin-opener": "^2", "howler": "^2.2.4", "react": "^19.1.0", @@ -1547,6 +1548,15 @@ "node": ">= 10" } }, + "node_modules/@tauri-apps/plugin-log": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.6.0.tgz", + "integrity": "sha512-gVp3l31akA1Jk2bZsTA0hMFD5/gLe49Nw1btu5lViau0QqgC2XyT79LSwvy7a44ewtQbSexchqIg7oTJKMIbXQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.6.0" + } + }, "node_modules/@tauri-apps/plugin-opener": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.4.0.tgz", diff --git a/package.json b/package.json index c87dd08..299609c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.12", "@tauri-apps/api": "^2", + "@tauri-apps/plugin-log": "^2.6.0", "@tauri-apps/plugin-opener": "^2", "howler": "^2.2.4", "react": "^19.1.0", diff --git a/public/assets/bg-01 (小束袋)_pause.mp3 b/public/assets/bg-01 (小束袋)_pause.mp3 new file mode 100644 index 0000000..c9cd875 Binary files /dev/null and b/public/assets/bg-01 (小束袋)_pause.mp3 differ diff --git a/public/cuelist.json b/public/cuelist.json index 583427c..22fe148 100644 --- a/public/cuelist.json +++ b/public/cuelist.json @@ -5,8 +5,7 @@ "name": "Q1", "type": "bg", "description": "preset bg", - "audioFile": "assets/bg-02.mp3", - "loop": true, + "audioCue": "Q0", "clientCue":"Q1" }, { @@ -14,8 +13,7 @@ "name": "Q2", "type": "announce", "description": "announce", - "audioFile": "assets/bg-01 (小束袋).mp3", - "loop": true, + "audioCue": "Q2", "status":"reset" }, @@ -24,8 +22,7 @@ "name": "Q3", "type": "bg", "description": "during bg", - "loop": true, - "audioFile": "assets/bg-04.mp3", + "audioCue": "Q3", "clientCue":"Q2" }, { @@ -33,16 +30,17 @@ "name": "Q3.1", "type": "light", "description": "fade out light", - "callback": "fade_out_light" + "lightCue": "fade_out_light" }, { "id": 4, "name": "Q4", "type": "bg", "description": "Ending", - "audioFile": "assets/record-05.mp3", + "audioCue": "Q6", "status":"end", - "callback":"fade_in_light" + "lightCue":"fade_in_light", + "clientCue":"Q6" } ] } diff --git a/src-tauri/2 b/src-tauri/2 new file mode 100644 index 0000000..2dc9b3c --- /dev/null +++ b/src-tauri/2 @@ -0,0 +1,7 @@ + +added 1 package, and audited 166 packages in 3s + +23 packages are looking for funding + run `npm fund` for details + +found 0 vulnerabilities diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index edca882..1447aa2 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -47,6 +58,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_logger" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" +dependencies = [ + "android_log-sys", + "env_filter", + "log", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -62,6 +90,12 @@ version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-broadcast" version = "0.7.2" @@ -270,6 +304,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -310,6 +356,29 @@ dependencies = [ "piper", ] +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "brotli" version = "8.0.2" @@ -337,6 +406,39 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "byte-unit" +version = "5.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" +dependencies = [ + "rust_decimal", + "serde", + "utf8-width", +] + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bytemuck" version = "1.23.2" @@ -510,11 +612,13 @@ name = "control-panel" version = "0.1.0" dependencies = [ "dotenv", + "log", "rosc", "serde", "serde_json", "tauri", "tauri-build", + "tauri-plugin-log", "tauri-plugin-opener", "tokio", ] @@ -883,6 +987,16 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -945,6 +1059,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fern" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" +dependencies = [ + "log", +] + [[package]] name = "field-offset" version = "0.3.6" @@ -1007,6 +1130,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futf" version = "0.1.5" @@ -1413,6 +1542,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] [[package]] name = "hashbrown" @@ -1954,6 +2086,9 @@ name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +dependencies = [ + "value-bag", +] [[package]] name = "mac" @@ -2163,6 +2298,15 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -2809,6 +2953,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quick-xml" version = "0.38.1" @@ -2833,6 +2997,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.7.3" @@ -2989,6 +3159,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.23" @@ -3024,6 +3203,35 @@ dependencies = [ "web-sys", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rosc" version = "0.11.4" @@ -3035,6 +3243,22 @@ dependencies = [ "time", ] +[[package]] +name = "rust_decimal" +version = "1.37.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -3141,6 +3365,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "selectors" version = "0.24.0" @@ -3359,6 +3589,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -3601,6 +3837,12 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3739,6 +3981,28 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-log" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a59139183e0907cec1499dddee4e085f5a801dc659efa0848ee224f461371426" +dependencies = [ + "android_logger", + "byte-unit", + "fern", + "log", + "objc2 0.6.2", + "objc2-foundation 0.3.1", + "serde", + "serde_json", + "serde_repr", + "swift-rs", + "tauri", + "tauri-plugin", + "thiserror 2.0.15", + "time", +] + [[package]] name = "tauri-plugin-opener" version = "2.4.0" @@ -3933,7 +4197,9 @@ checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -3966,6 +4232,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.47.1" @@ -4301,6 +4582,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -4319,6 +4606,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "value-bag" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" + [[package]] name = "version-compare" version = "0.2.0" @@ -5032,6 +5325,15 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x11" version = "2.21.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 8936e55..ccbb345 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,3 +25,5 @@ serde_json = "1" rosc = "0.11.4" tokio = { version = "1.45.1", features = ["net"] } dotenv = "0.15.0" +tauri-plugin-log = "2" +log = "0.4.27" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 4cdbf49..bf2c212 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -2,9 +2,12 @@ "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", "description": "Capability for the main window", - "windows": ["main"], + "windows": [ + "main" + ], "permissions": [ "core:default", - "opener:default" + "opener:default", + "log:default" ] -} +} \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 84b211f..55cff7d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,8 +1,15 @@ // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ -use tokio::net::UdpSocket; -use std::{net::SocketAddrV4, str::FromStr}; use rosc::{encoder, OscMessage, OscPacket, OscType}; +use serde::Serialize; +use std::{net::SocketAddrV4, str::FromStr}; +use tauri::{AppHandle, Emitter, Manager}; +use tokio::net::UdpSocket; +#[derive(Serialize, Clone)] +struct OscEvent { + addr: String, + args: Vec, +} #[tauri::command] fn greet(name: &str) -> String { @@ -12,15 +19,25 @@ fn greet(name: &str) -> String { #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_log::Builder::new().build()) .plugin(tauri_plugin_opener::init()) - .invoke_handler(tauri::generate_handler![ - send_osc_message, - ]) + .invoke_handler(tauri::generate_handler![send_osc_message,]) + .setup(|app| { + // if cfg!(debug_assertions) { + // app.handle().plugin( + // tauri_plugin_log::Builder::default() + // .level(log::LevelFilter::Info) + // .build(), + // )?; + // } + + tauri::async_runtime::spawn(setup_osc_server(app.handle().clone())); + Ok(()) + }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } - #[tauri::command] async fn send_osc_message( key: &str, @@ -43,4 +60,53 @@ async fn send_osc_message( sock.send_to(&msg_buf, remote).await.unwrap(); Ok(()) -} \ No newline at end of file +} + +async fn setup_osc_server(app_handle: AppHandle) { + println!("Setting up OSC server..."); + // setup osc sever + let addr = "0.0.0.0:7000"; + let sock = UdpSocket::bind(addr).await.unwrap(); + println!("Listening to {}", addr); + + let mut buf = [0u8; rosc::decoder::MTU]; + + loop { + match sock.recv_from(&mut buf).await { + Ok((size, addr)) => { + println!("Received packet with size {} from: {}", size, addr); + if let Ok((_, packet)) = rosc::decoder::decode_udp(&buf[..size]) { + if let OscPacket::Message(msg) = packet { + println!("OSC message: {:?}", msg); + + app_handle + .emit( + "osc_message", + OscEvent { + addr: msg.addr.clone(), + args: msg + .args + .iter() + .map(|arg| match arg { + OscType::Int(i) => i.to_string(), + OscType::Float(f) => f.to_string(), + OscType::String(s) => s.clone(), + OscType::Bool(b) => b.to_string(), + _ => format!("{:?}", arg), + }) + .collect(), + }, + ) + .unwrap(); + } + } else { + println!("Failed to decode OSC packet"); + } + } + Err(e) => { + println!("Error receiving from socket: {}", e); + break; + } + } + } +} diff --git a/src/App.jsx b/src/App.jsx index 666c45c..e8255bf 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,9 @@ import { useState, useEffect, useRef } from "react"; import {Howl, Howler} from 'howler'; import { invoke } from "@tauri-apps/api/core"; +import { listen } from '@tauri-apps/api/event'; import "./App.css"; +import { OSC_ADDRESS } from "./utils/constant"; const DefaultFadeDuration = 3; // 1 second @@ -20,12 +22,10 @@ const EmojiType={ function App() { const [cuelist, setCuelist] = useState([]); - const refAudioBg= useRef(null); - const refAudioAnnounce= useRef(null); - const refAudio= useRef({}); const [currentCue, setCurrentCue] = useState(null); const [fadeDuration, setFadeDuration] = useState(DefaultFadeDuration); // Default fade duration in seconds const [timestamp, setTimestamp] = useState(); + const [clientStatus, setClientStatus] = useState({}); const refCue = useRef(null); const refNextCue = useRef(null); @@ -41,116 +41,75 @@ function App() { }); } - function onfade(e){ - console.log('onfade', e); - if(refNextCue.current) { - playCue(refNextCue.current); - refNextCue.current = null; - } - if(refAudioBg.current.volume() === 0) { - refAudioBg.current.stop(); - // refAudioBg.current = null; - } + function sendOscToSound(addr, message){ - } - function onAnounceFade(e){ - console.log('onAnounceFade', e); - if(refAudioAnnounce.current.volume() === 0) { - refAudioAnnounce.current.stop(); - } + invoke('send_osc_message', { + key: addr, + message, + host:'0.0.0.0:0', + target:'192.168.234.255:58100', + }); } - function loadAudio(audioFile, loop = false, type) { - if(refAudio.current[audioFile]) { - return refAudio.current[audioFile]; + function onOsc(message){ + + const [id, status, name]= message.args[0]?.split('#'); + if(clientStatus[id]){ + setClientStatus(prev=>({ + ...prev, + [id]:[ + { + status, + name, + timestamp: new Date().toLocaleTimeString(), + }, + ...prev[id], + ] + })); + }else{ + setClientStatus(prev=>({ + ...prev, + [id]:[{ + status, + name, + timestamp: new Date().toLocaleTimeString(), + }] + })); } - const sound = new Howl({ - src: [audioFile], - volume: 1, - loop: loop, - onfade: type==CueType.Bg ? onfade : onAnounceFade, - }); - refAudio.current[audioFile] = sound; - return sound; + + + } - function playAudio(audioFile, loop = false, type) { - switch(type){ - case CueType.Bg: - refAudioBg.current = loadAudio(audioFile, loop, type); - refAudioBg.current.play(); - refAudioBg.current.fade(0, 1, fadeDuration * 1000); - break; - case CueType.Announce: - refAudioAnnounce.current = loadAudio(audioFile, loop, type); - refAudioAnnounce.current.seek(0); - refAudioAnnounce.current.volume(1); - refAudioAnnounce.current.play(); - break; - } - } + + function playCue({id, name, description, type, auto, audioFile, ...props}) { console.log('Playing cue:', {id, name, description, type, auto, audioFile, ...props}); // Handle other cue types and properties here - switch(type) { - case CueType.Bg: - if(refAudioBg.current) { - if(refAudioBg.current.volume() === 0) { - refAudioBg.current.stop(); - playAudio(audioFile, props.loop || false, type); - setCurrentCue({id, name, description, type, auto, audioFile, ...props}); - }else{ - refAudioBg.current.fade(1,0, fadeDuration * 1000); - refNextCue.current = {id, name, description, type, auto, audioFile, ...props}; - } - }else{ - playAudio(audioFile, props.loop || false, type); - setCurrentCue({id, name, description, type, auto, audioFile, ...props}); - } - break; - - case CueType.Announce: - - playAudio(audioFile, props.loop || false, type); - setCurrentCue({id, name, description, type, auto, audioFile, ...props}); - - - break; - - case CueType.Light: - // Handle light cue logic here - console.log('Light cue:', {id, name, description, ...props}); - setCurrentCue({id, name, description, type, auto, audioFile, ...props}); - break; - - default: - console.warn('Unknown cue type:', type); - - } + if(props.audioCue){ + sendOscToSound(OSC_ADDRESS.SCS_GO_CUE, props.audioCue); + } if(props.clientCue){ - sendOsc('/playcue', props.clientCue); + sendOsc(OSC_ADDRESS.PLAYCUE, props.clientCue); } + if(props.lightCue){ + // sendOsc(OSC_ADDRESS.CLIENT_INPUT, props.lightCue); + } } function stop() { - console.log('Stop all audio'); - if(refAudioBg.current) { - refAudioBg.current.fade(1,0, fadeDuration*1000); - } - if(refAudioAnnounce.current) { - refAudioAnnounce.current.fade(1,0, fadeDuration*1000); - } - - sendOsc('/stopcue',''); + console.log('Stop all'); + sendOsc(OSC_ADDRESS.STOPCUE,''); + sendOscToSound(OSC_ADDRESS.SCS_STOP_ALL, ''); } function secondToTime(seconds) { const minutes = Math.floor(seconds / 60); @@ -193,10 +152,13 @@ function App() { console.error('Error fetching cuelist:', error); }); - const intervalId = setInterval(() => { - setTimestamp(getAudioDuration()); - }, 500); - return () => clearInterval(intervalId); + + listen('osc_message', (event) => { + console.log(`Received OSC message: ${event.payload}`); + onOsc(event.payload); + }); + + },[]); @@ -228,12 +190,12 @@ function App() { Description Type Auto - Audio / Due + Due | Light | Audio clientCue - {cuelist?.map(({id, name, description, type, auto, audioFile,...props}, index) => ( + {cuelist?.map(({id, name, description, type, auto,...props}, index) => ( {type==CueType.Announce && } @@ -251,12 +213,40 @@ function App() { {description} {EmojiType[type]} {auto ? '⤵️' : ''} - {audioFile || props.duration} {props.callback && `<${props.callback}>`} + {props.duration} {props.lightCue && `L${props.lightCue}`} {props.audioCue && `S${props.audioCue}`} {props.clientCue || ''} ))} + + + + + + + + + + + + + {Object.entries(clientStatus).map(([id, log])=>( + + + + + + + + ))} + +
idstatuscuetimestampcontrol
{id}{log[0]?.status}{log[0]?.name}{log[0]?.timestamp} + + + + +
); diff --git a/src/utils/constant.js b/src/utils/constant.js new file mode 100644 index 0000000..7adf2fa --- /dev/null +++ b/src/utils/constant.js @@ -0,0 +1,12 @@ +export const OSC_ADDRESS={ + PLAYCUE: '/playcue', + STOPCUE: '/stopcue', + CLIENT_STATUS: '/client', + CLIENT_INPUT: '/client_input', + + + SCS_STOP_ALL:'/ctrl/stop_all', + SCS_FADE_ALL:'/ctrl/fade_all', + SCS_GO_CUE:'/cue/go', + +} \ No newline at end of file diff --git a/src/utils/settings.js b/src/utils/settings.js new file mode 100644 index 0000000..e69de29