diff --git a/public/cuelist - 複製.json b/public/cuelist - 複製.json deleted file mode 100644 index 1ebd6e0..0000000 --- a/public/cuelist - 複製.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "cuelist": [ - { - "id": 1, - "name": "Q1", - "type": "bg", - "description": "preset bg", - "audioCue": "Q0", - "clientCue":"Q1" - }, - { - "id": 2, - "name": "Q2", - "type": "announce", - "description": "announce", - "audioCue": "Q2" - }, - { - "id": 3, - "name": "Q3", - "type": "bg", - "description": "(START) CQ2-CQ4.1", - "audioCue": "Q3", - "clientCue":"Q2", - "duration":495, - "auto": true - }, - { - "id": 4, - "name": "Q4", - "type": "light", - "description": "(AI) CQ4.11-CQ5.6", - "lightCue":"fade_out_light", - "duration":298, - "clientCue":"Q4.11", - "auto": true - }, - { - "id": 5, - "name": "Q5", - "type": "bg", - "description": "(END)", - "audioCue": "Q6", - "status":"end", - "lightCue":"fade_in_light", - "clientCue":"Q6" - } - ] -} - \ No newline at end of file diff --git a/public/cuelist_1009.json b/public/cuelist_1009.json new file mode 100644 index 0000000..be70d5a --- /dev/null +++ b/public/cuelist_1009.json @@ -0,0 +1,109 @@ +{ + "cuelist": [ + { + "id": 1, + "name": "Q1", + "type": "bg", + "description": "[外場+電話亭] preset 音樂", + "audioCue": "Q0", + "clientCue":"Q1", + "reset":true + }, + { + "id": 2, + "name": "Q2", + "type": "announce", + "description": "[外場 + 電話亭] announce", + "audioCue": "Q1", + "clientCue":"Q1.1" + }, + { + "id": 3, + "name": "Q3", + "type": "bg", + "description": "[電話亭] 開始流程 CQ2-CQ4.1", + "audioCue": "Q3", + "clientCue":"Q2", + "duration":110, + "auto": true, + "reset":true + }, + { + "id": 3.1, + "name": "Q3.1", + "type": "light", + "description": "關燈", + "duration":62, + "auto": true, + "lightCue":"fade_out_light", + "lightDuration":8, + "syncUnityLight":true + }, + { + "id": 3.2, + "name": "Q3.2", + "type": "light", + "description": "開燈", + "duration":126, + "auto": true, + "lightCue":"fade_in_light", + "lightDuration":4, + "syncUnityLight":true + }, + { + "id": 4, + "name": "Q4", + "type": "light", + "description": "[電話亭] 記憶裝置啟動 (AI) CQ4.11-CQ5.6", + "audioCue": "Q4", + "lightCue":"fade_out_light", + "duration":250, + "clientCue":"Q4.11", + "auto": true + }, + { + "id": 5, + "name": "Q5", + "type": "bg", + "description": "[電話亭] 結尾announce", + "duration":25, + "status":"end", + "lightCue":"fade_in_light", + "clientCue":"Q6", + "audioCue": "Q5", + "auto":true + }, + { + "id": 6, + "name": "Q6", + "type": "bg", + "description": "[外場] 結尾音樂", + "audioCue": "Q6", + "clientCue":"Q7" + }, + { + "id": 7, + "name": "Q7", + "type": "bg", + "description": "[外場] fadeout", + "audioCue": "Q7" + }, + { + "id": 0.1, + "name": "CQ101", + "type": "debug", + "description": "debug-key", + "clientCue":"Q101", + "debug":true + },{ + "id": 0.2, + "name": "CQ103", + "type": "debug", + "description": "debug-speech", + "lightCue":"fade_out_light", + "clientCue":"Q103", + "debug":true + } + ] +} + \ No newline at end of file diff --git a/src/App.css b/src/App.css index 45f4ab9..d167feb 100644 --- a/src/App.css +++ b/src/App.css @@ -11,7 +11,7 @@ tr{ @apply border-b border-gray-400; } td{ - @apply p-1; + @apply px-1; } input[type='range'] { overflow: hidden; diff --git a/src/App.jsx b/src/App.jsx index 0fd52af..70ce987 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -9,7 +9,10 @@ import { Light } from "./utils/light"; const DefaultFadeDuration = 3; // 1 second const CLIENT_COUNT = 13; -const CUE_FILE = 'cuelist_0924.json'; +const CUE_FILE = 'cuelist_1009.json'; +// const OSC_BROADCAST_IP='192.168.51.255:8000'; +const OSC_BROADCAST_IP = '192.168.234.255:8000'; +const UNITY_BROADCAST_IP = '192.168.234.255:9000'; const CueType = { @@ -44,7 +47,7 @@ function App() { key: addr, message: `${id}#${message}`, host: '0.0.0.0:0', - target: '192.168.51.255:8000', + target: OSC_BROADCAST_IP, }); } @@ -134,14 +137,16 @@ function App() { if (props.lightCue) { // sendOsc(OSC_ADDRESS.CLIENT_INPUT, props.lightCue); - if (props.lightCue == 'fade_in_light') refLight.current.fadeIn(); // Fade in light for conversation start - if (props.lightCue == 'fade_out_light') refLight.current.fadeOut(); // Fade out light for conversation end + if (props.lightCue == 'fade_in_light'){ + refLight.current.fadeIn(props.lightDuration, props.syncUnityLight?UNITY_BROADCAST_IP:null); // Fade in light for conversation start + } + if (props.lightCue == 'fade_out_light'){ + refLight.current.fadeOut(props.lightDuration, props.syncUnityLight?UNITY_BROADCAST_IP:null); // Fade out light for conversation end + } } if (props.reset) { - //sendOsc(OSC_ADDRESS.RESETCUE,'','all'); - refLight.current.set(1); - + resetLight(); } if (refTimer.current) { @@ -172,7 +177,11 @@ function App() { refTimer.current = null; if (auto) { - const next = cuelist.find(c => c.id === id + 1); + // const next = cuelist.find(c => c.id === id + 1); + const index = cuelist.findIndex(c => c.id === id); + const next = cuelist[index + 1]; + if (!next) return; + console.log('Auto play next cue:', next); playCue(next); } @@ -209,7 +218,16 @@ function App() { sendOsc(OSC_ADDRESS.RESETCUE, '', 'all'); sendOscToSound(OSC_ADDRESS.SCS_STOP_ALL, ''); + resetLight(); + } + function resetLight(){ refLight.current.set(1); + invoke('send_osc_message', { + key: '/amplitude', + message: 1.0.toString(), + host:`0.0.0.0:0`, + target: UNITY_BROADCAST_IP, + }); } function secondToTime(seconds) { @@ -267,7 +285,7 @@ function App() {
-
+
{currentCue ? `${currentCue.name}` : 'None'}
@@ -284,7 +302,7 @@ function App() { {fadeDuration}s
- +
{/* */} diff --git a/src/utils/light.jsx b/src/utils/light.jsx index 6e52959..33bffd1 100644 --- a/src/utils/light.jsx +++ b/src/utils/light.jsx @@ -11,13 +11,14 @@ export const Light=forwardRef((props, ref)=>{ const refContainer=useRef(); const refGsap=useRef(); - function fade(from, to){ - - const time= parseFloat(refInput.current.value) || FADE_TIME; + function fade(from, to, duration=null, unity_ip=null){ + + const time= duration || parseFloat(refInput.current.value) || FADE_TIME; + console.log(`fade light from ${from} to ${to} in ${time}s`, unity_ip); gsap.killTweensOf(refVal.current); // Kill all tweens of refVal - gsap.current=gsap.fromTo(refVal.current,{val: from}, { + refGsap.current=gsap.fromTo(refVal.current,{val: from}, { val: to, duration: time, onUpdate: () => { @@ -32,6 +33,14 @@ export const Light=forwardRef((props, ref)=>{ // console.error('Error sending DMX message:', error); // }); + if(unity_ip){ + invoke('send_osc_message', { + key: '/amplitude', + message: refVal.current.val.toString(), + host:`0.0.0.0:0`, + target: unity_ip, + }); + } invoke('send_osc_message', { key: '/light', message: refVal.current.val.toString(), @@ -45,13 +54,13 @@ export const Light=forwardRef((props, ref)=>{ }); } useImperativeHandle(ref, () => ({ - fadeIn: ()=>{ + fadeIn: (duration, sync_unity)=>{ console.log('fadeIn'); - fade(0, 1); + fade(0, 1, duration, sync_unity); }, - fadeOut: ()=>{ + fadeOut: (duration, sync_unity)=>{ console.log('fadeOut'); - fade(1, 0); + fade(1, 0, duration, sync_unity); }, reset:()=>{ console.log('reset'); @@ -70,8 +79,11 @@ export const Light=forwardRef((props, ref)=>{ }, set: (value)=>{ console.log('set', value); + + gsap.killTweensOf(refVal.current); refVal.current.val=value; refContainer.current.style.background= `rgba(0, 255, 0, ${value})`; // Update background color based on value + invoke('send_osc_message', { key: '/light', message: value.toString(),
ID