main
reng 3 months ago
parent 023e3aeb52
commit 815720cebc
  1. 10
      package-lock.json
  2. 1
      package.json
  3. BIN
      public/assets/bg-01 (小束袋)_pause.mp3
  4. 16
      public/cuelist.json
  5. 7
      src-tauri/2
  6. 302
      src-tauri/Cargo.lock
  7. 2
      src-tauri/Cargo.toml
  8. 9
      src-tauri/capabilities/default.json
  9. 80
      src-tauri/src/lib.rs
  10. 188
      src/App.jsx
  11. 12
      src/utils/constant.js
  12. 0
      src/utils/settings.js

10
package-lock.json generated

@ -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",

@ -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",

@ -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"
}
]
}

@ -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

302
src-tauri/Cargo.lock generated

@ -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"

@ -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"

@ -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"
]
}
}

@ -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<String>,
}
#[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(())
}
}
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;
}
}
}
}

@ -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() {
<th>Description</th>
<th>Type</th>
<th>Auto</th>
<th>Audio / Due</th>
<th>Due | Light | Audio</th>
<th>clientCue</th>
</tr>
</thead>
<tbody>
{cuelist?.map(({id, name, description, type, auto, audioFile,...props}, index) => (
{cuelist?.map(({id, name, description, type, auto,...props}, index) => (
<tr key={id} className={currentCue?.id === id ? 'bg-green-200' : ''}>
<td className="flex flex-row gap-2">
<button
@ -242,8 +204,8 @@ function App() {
}}>go</button>
{type==CueType.Announce && <button
onClick={()=>{
if(refAudioAnnounce.current) {
refAudioAnnounce.current.fade(1,0, fadeDuration * 1000);
if(props.audioCue){
sendOscToSound(OSC_ADDRESS.SCS_STOP_ALL, '');
}
}}>stop</button>}
</td>
@ -251,12 +213,40 @@ function App() {
<td>{description}</td>
<td>{EmojiType[type]}</td>
<td>{auto ? '⤵' : ''}</td>
<td>{audioFile || props.duration} {props.callback && `<${props.callback}>`}</td>
<td>{props.duration} {props.lightCue && `L${props.lightCue}`} {props.audioCue && `S${props.audioCue}`}</td>
<td className={`${props.clientCue&& 'bg-green-300 rounded-full text-center font-[900]'}`}>{props.clientCue || ''}</td>
</tr>
))}
</tbody>
</table>
<table>
<thead className="bg-blue-500">
<tr className="text-left lowercase font-[900]">
<th>id</th>
<th>status</th>
<th>cue</th>
<th>timestamp</th>
<th>control</th>
</tr>
</thead>
<tbody>
{Object.entries(clientStatus).map(([id, log])=>(
<tr key={id} className="text-left lowercase font-[900]">
<td className="font-[900]">{id}</td>
<td>{log[0]?.status}</td>
<td>{log[0]?.name}</td>
<td>{log[0]?.timestamp}</td>
<td>
<button>stop</button>
<button>Q1</button>
<button>Q2</button>
<button>Q6</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</main>
);

@ -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',
}
Loading…
Cancel
Save