From 8bbb8342359fd856b045f5cd3546897e752d7065 Mon Sep 17 00:00:00 2001 From: reng Date: Thu, 9 Oct 2025 19:20:51 +0800 Subject: [PATCH] WIP --- vite/public/cuelist_1009.json | 3 ++- vite/src/pages/flow_free.jsx | 37 ++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/vite/public/cuelist_1009.json b/vite/public/cuelist_1009.json index ab3eec8..1a54454 100644 --- a/vite/public/cuelist_1009.json +++ b/vite/public/cuelist_1009.json @@ -81,7 +81,8 @@ "auto": true, "nextcue": 4.3, "duration": 90, - "status":"go" + "status":"go", + "chatInterval":20 }, { "id": 4.3, diff --git a/vite/src/pages/flow_free.jsx b/vite/src/pages/flow_free.jsx index ddb7686..1f9645e 100644 --- a/vite/src/pages/flow_free.jsx +++ b/vite/src/pages/flow_free.jsx @@ -88,6 +88,8 @@ export function FreeFlow(){ const refFadeOutInterval=useRef(); const refVolDownInterval=useRef(); + const refChatTimer=useRef(); + const [lastOsc, setLastOsc]=useState(); const { history, status, reset, sendMessage, setStatus, audioOutput, setAudioOutput, stop:stopChat, @@ -486,7 +488,7 @@ export function FreeFlow(){ resetData(); } } - if(cue.type=='chat' || cue.type=='user_input') { + if(cue.type=='user_input') { sendOsc(OSC_ADDRESS.COUNTDOWN, cue.duration || '0'); // Send OSC countdown message }else{ sendOsc(OSC_ADDRESS.COUNTDOWN, '0'); // Reset countdown for non-chat cues @@ -581,6 +583,27 @@ export function FreeFlow(){ writeSheet(); } + function startChatTimer(){ + sendOsc(OSC_ADDRESS.COUNTDOWN, refCurrentCue.current?.chatInterval || '0'); // Send OSC countdown message + if(refChatTimer.current) clearInterval(refChatTimer.current); + + let timeleft=refCurrentCue.current?.chatInterval || 0; + const start_time=Date.now(); + refChatTimer.current=setInterval(()=>{ + + let delta_time=(Date.now()-start_time)/1000.0; + timeleft-=delta_time; + + if(timeleft<=0){ + console.log('~~~ chat timer ended, process speech'); + clearInterval(refChatTimer.current); + // send message + if(chatStatus==ChatStatus.User) processSpeech(); + } + }, 1000); + + } + useEffect(()=>{ if(!lastOsc) return; @@ -669,8 +692,15 @@ export function FreeFlow(){ } function processSpeech(){ - if(currentCue?.type!='chat') return; // Only process if current cue is user input - + + if(refPauseTimer.current) clearTimeout(refPauseTimer.current); + if(refChatTimer.current) clearInterval(refChatTimer.current); + sendOsc(OSC_ADDRESS.COUNTDOWN, '0'); // Reset countdown + + + if(currentCue?.type!='chat') return; // Only process if current cue is user input + + console.log('processSpeech:', finalTranscript); if(refChatCueEnd.current) { @@ -806,6 +836,7 @@ export function FreeFlow(){ break; case ChatStatus.User: text = '換你說了'; + startChatTimer(); break; case ChatStatus.Processing: text = '記憶讀取中';