diff --git a/vite/public/assets/combine/Q1_0919.mp3 b/vite/public/assets/combine/Q1_0919.mp3 new file mode 100644 index 0000000..89b924a Binary files /dev/null and b/vite/public/assets/combine/Q1_0919.mp3 differ diff --git a/vite/public/assets/combine/Q1_announce_0919.mp3 b/vite/public/assets/combine/Q1_announce_0919.mp3 new file mode 100644 index 0000000..3e18081 Binary files /dev/null and b/vite/public/assets/combine/Q1_announce_0919.mp3 differ diff --git a/vite/public/assets/combine/Q2-1.mp3 b/vite/public/assets/combine/Q2-1.mp3 new file mode 100644 index 0000000..09769f5 Binary files /dev/null and b/vite/public/assets/combine/Q2-1.mp3 differ diff --git a/vite/public/assets/combine/Q2-1_0919_v3.mp3 b/vite/public/assets/combine/Q2-1_0919_v3.mp3 new file mode 100644 index 0000000..e96c9bc Binary files /dev/null and b/vite/public/assets/combine/Q2-1_0919_v3.mp3 differ diff --git a/vite/public/assets/combine/Q2-2.mp3 b/vite/public/assets/combine/Q2-2.mp3 new file mode 100644 index 0000000..7ab7728 Binary files /dev/null and b/vite/public/assets/combine/Q2-2.mp3 differ diff --git a/vite/public/assets/combine/Q4-0-1.mp3 b/vite/public/assets/combine/Q4-0-1.mp3 new file mode 100644 index 0000000..ffd0756 Binary files /dev/null and b/vite/public/assets/combine/Q4-0-1.mp3 differ diff --git a/vite/public/assets/combine/Q4-1-1.mp3 b/vite/public/assets/combine/Q4-1-1.mp3 new file mode 100644 index 0000000..f3f82df Binary files /dev/null and b/vite/public/assets/combine/Q4-1-1.mp3 differ diff --git a/vite/public/assets/combine/Q4-1.mp3 b/vite/public/assets/combine/Q4-1.mp3 new file mode 100644 index 0000000..232b0ae Binary files /dev/null and b/vite/public/assets/combine/Q4-1.mp3 differ diff --git a/vite/public/assets/combine/Q4-1_撥打音效.mp3 b/vite/public/assets/combine/Q4-1_撥打音效.mp3 new file mode 100644 index 0000000..b9c1807 Binary files /dev/null and b/vite/public/assets/combine/Q4-1_撥打音效.mp3 differ diff --git a/vite/public/assets/combine/Q4-3.mp3 b/vite/public/assets/combine/Q4-3.mp3 new file mode 100644 index 0000000..1368342 Binary files /dev/null and b/vite/public/assets/combine/Q4-3.mp3 differ diff --git a/vite/public/assets/combine/Q4.mp3 b/vite/public/assets/combine/Q4.mp3 new file mode 100644 index 0000000..f581d75 Binary files /dev/null and b/vite/public/assets/combine/Q4.mp3 differ diff --git a/vite/public/assets/combine/Q5-2.mp3 b/vite/public/assets/combine/Q5-2.mp3 new file mode 100644 index 0000000..49dea2d Binary files /dev/null and b/vite/public/assets/combine/Q5-2.mp3 differ diff --git a/vite/public/assets/combine/Q5-4.mp3 b/vite/public/assets/combine/Q5-4.mp3 new file mode 100644 index 0000000..28467ee Binary files /dev/null and b/vite/public/assets/combine/Q5-4.mp3 differ diff --git a/vite/public/assets/combine/Q5-5.mp3 b/vite/public/assets/combine/Q5-5.mp3 new file mode 100644 index 0000000..2e06d93 Binary files /dev/null and b/vite/public/assets/combine/Q5-5.mp3 differ diff --git a/vite/public/assets/combine/Q5-6.mp3 b/vite/public/assets/combine/Q5-6.mp3 new file mode 100644 index 0000000..5d5730c Binary files /dev/null and b/vite/public/assets/combine/Q5-6.mp3 differ diff --git a/vite/public/assets/combine/Q6_管家announce_0919.mp3 b/vite/public/assets/combine/Q6_管家announce_0919.mp3 new file mode 100644 index 0000000..9cc3ee3 Binary files /dev/null and b/vite/public/assets/combine/Q6_管家announce_0919.mp3 differ diff --git a/vite/public/assets/combine/Q7_0919.mp3 b/vite/public/assets/combine/Q7_0919.mp3 new file mode 100644 index 0000000..5a73c7f Binary files /dev/null and b/vite/public/assets/combine/Q7_0919.mp3 differ diff --git a/vite/public/cuelist_0923.json b/vite/public/cuelist_0923.json new file mode 100644 index 0000000..bb2529e --- /dev/null +++ b/vite/public/cuelist_0923.json @@ -0,0 +1,192 @@ +{ + "cuelist": [ + { + "id": 1, + "name": "Q1", + "type": "space", + "description": "preset bg", + "audioFile": "assets/combine/Q1_0919.mp3", + "loop": true, + "status":"reset" + }, + { + "id": 1.1, + "name": "Q1.1", + "type": "announce", + "description": "Annonce", + "audioFile": "assets/combine/Q1_announce_0919.mp3", + "layer":"announce", + "loop": true, + "status":"reset", + "fadeout": true + }, + { + "id": 2, + "name": "Q2", + "type": "headphone", + "description": "Guide for drink", + "auto": true, + "audioFile": "assets/combine/Q2-1_0919_v3.mp3", + "nextcue": 4, + "status":"reset" + }, + { + "id": 4, + "name": "Q4", + "type": "phone", + "description": "引導撥號", + "auto": true, + "audioFile": "assets/combine/Q4.mp3", + "nextcue": 4.01 + }, + { + "id": 4.01, + "name": "Q4.01", + "type": "phone", + "description": "撥號", + "auto": false, + "audioFile": "assets/combine/Q4-0-1.mp3", + "nextcue": 4.1, + "callback":"numpad", + "numpad_type":"userid" + }, + { + "id": 4.1, + "name": "Q4.1", + "type": "phone", + "description": "輸入完成,請描述腦中的記憶畫面", + "auto": false, + "audioFile": "assets/combine/Q4-1_撥打音效.mp3", + "loop": true, + "nextcue": 4.11 + }, + { + "id": 4.11, + "name": "Q4.11", + "type": "phone", + "description": "裝置啟動音效", + "auto": true, + "audioFile": "assets/combine/Q4-1-1.mp3", + "nextcue": 4.2, + "status":"intro", + "status_delay": 3000 + }, + { + "id": 4.2, + "name": "Q4.2", + "type": "chat", + "description": "chat", + "auto": true, + "nextcue": 4.3, + "duration": 90, + "status":"go" + }, + { + "id": 4.3, + "name": "Q4.3", + "type": "phone", + "description": "記憶提取完成", + "auto": true, + "audioFile": "assets/combine/Q4-3.mp3", + "nextcue": 5.1 + }, + { + "id": 5.1, + "name": "Q5.1", + "type": "user_input", + "description": "call", + "duration": 30, + "auto": true, + "nextcue": 5.11 + }, + { + "id":5.11, + "name":"Q5.11", + "type":"summary", + "auto":true, + "description":"summary", + "nextcue":5.2 + }, + { + "id": 5.2, + "name": "Q5.2", + "type": "phone", + "description": "保留刪除操作說明", + "audioFile": "assets/combine/Q5-2.mp3", + "callback":"numpad", + "numpad_type":"choice", + "auto": false, + "branch":{ + "1": { + "nextcue": 5.4, + "description": "save" + }, + "9": { + "nextcue": 5.5, + "description": "discard" + } + }, + "hint":"保留,請按1\n刪除,請按9\n確定,請按#", + "hint_time": 21800, + "nextcue":5.4 + }, + { + "id": 5.4, + "name": "Q5.4", + "type": "phone", + "description": "保留", + "auto": false, + "nextcue": 5.6, + "audioFile": "assets/combine/Q5-4.mp3", + "callback":"numpad", + "numpad_type":"password", + "hint":"請輸入四位數密碼\n確定輸入後,請按#", + "hint_time": 7800, + "default_password":"0000" + }, + { + "id": 5.5, + "name": "Q5.5", + "type": "phone", + "description": "刪除", + "auto": false, + "nextcue": 5.6, + "audioFile": "assets/combine/Q5-5.mp3", + "callback":"numpad", + "numpad_type":"password", + "hint":"請輸入四位數密碼\n確定輸入後,請按#", + "hint_time": 7900, + "default_password":"0000" + }, + { + "id":5.6, + "name":"Q5.6", + "type":"phone", + "description":"play music", + "auto": false, + "nextcue": 5.7, + "audioFile": "assets/combine/Q5-6.mp3", + "callback":"exportFile" + }, + { + "id":6, + "name":"Q6", + "type":"announce", + "description":"end", + "auto": false, + "audioFile": "assets/combine/Q6_管家announce_0919.mp3", + "layer":"announce", + "fadeout": true, + "callback":"exportFile" + }, + { + "id": 7, + "name": "Q7", + "type": "space", + "description": "Ending", + "status":"end", + "callback":"fadeout" + } + ] +} + \ No newline at end of file diff --git a/vite/src/pages/flow_free.jsx b/vite/src/pages/flow_free.jsx index 4604a7f..c88389f 100644 --- a/vite/src/pages/flow_free.jsx +++ b/vite/src/pages/flow_free.jsx @@ -16,7 +16,7 @@ import { DebugControl, TEST_PROMPT } from "../comps/debug"; import { useUser } from "../util/useUser"; -const CUELIST_FILE = 'cuelist_demo3.json'; +const CUELIST_FILE = 'cuelist_0923.json'; const AUDIO_FADE_TIME=3000; // in ms const EmojiType={ @@ -26,6 +26,7 @@ const EmojiType={ chat: '🤖', chat_end: '🤖', user_input: '💬', + announce: '📢', } const ChatStatus={ @@ -65,6 +66,8 @@ export function FreeFlow(){ const refAudio=useRef(); const refAudioPrompt=useRef(); + const refAudioAnnounce=useRef(); + const refInput=useRef(); // const refLight=useRef(); @@ -79,6 +82,8 @@ export function FreeFlow(){ const refHintTimeout=useRef(); + const refFadeOutInterval=useRef(); + const { history, status, reset, sendMessage, setStatus, audioOutput, setAudioOutput, stop:stopChat, audioUrl }=useChat(); @@ -169,6 +174,24 @@ export function FreeFlow(){ console.log('Playing audio:', url); + if(refCurrentCue.current?.layer=='announce'){ + if(refAudioAnnounce.current) { + refAudioAnnounce.current.pause(); // Stop any currently playing announce audio + } + refAudioAnnounce.current = new Audio(url); + refAudioAnnounce.current.loop=refCurrentCue.current?.loop || false; // Set loop if defined in cue + refAudioAnnounce.current.play().catch(error => { + console.error("Audio announce playback error:", error); + }); + return; + } + + + if(refAudioAnnounce.current) { + refAudioAnnounce.current.pause(); // Stop any currently playing announce audio + refAudioAnnounce.current = null; + } + if(refAudio.current) { refAudio.current.pause(); // Stop any currently playing audio } @@ -246,20 +269,41 @@ export function FreeFlow(){ } function fadeOutAudio(callback){ - if(refAudio.current) { + if(refAudio.current || refAudioAnnounce.current){ console.log('Fading out audio'); let audio = refAudio.current; + let announce = refAudioAnnounce.current; + + if(refFadeOutInterval.current){ + clearInterval(refFadeOutInterval.current); + refFadeOutInterval.current=null; + } + let fadeOutInterval = setInterval(() => { - if (audio.volume > 0) { - audio.volume =Math.max(0, audio.volume - 1.0/(AUDIO_FADE_TIME/100)); // Decrease volume gradually + if(audio){ + if (audio.volume > 0) { + audio.volume =Math.max(0, audio.volume - 1.0/(AUDIO_FADE_TIME/100)); // Decrease volume gradually + } else { + clearInterval(fadeOutInterval); + audio.pause(); + audio.volume = 0; // Reset volume for next play + if(callback) callback(); + } + } + + if(!announce) return; + if (announce.volume > 0) { + announce.volume = Math.max(0, announce.volume - 1.0/(AUDIO_FADE_TIME/100)); // Decrease volume gradually } else { clearInterval(fadeOutInterval); - audio.pause(); - audio.volume = 0; // Reset volume for next play - if(callback) callback(); + announce.pause(); + announce.volume = 0; // Reset volume for next play } - }, 100); // Decrease volume every 100ms + }, 100); // Decrease volume every 100ms + + refFadeOutInterval.current=fadeOutInterval; + }else{ if(callback) callback(); } @@ -271,7 +315,7 @@ export function FreeFlow(){ console.log('Playing cue:', cue); // stop audio - if(refAudio.current) refAudio.current.pause(); + // if(refAudio.current) refAudio.current.pause(); @@ -371,8 +415,13 @@ export function FreeFlow(){ }); } - if(cue.callback=='exportFile'){ - exportFile(); + switch(cue.callback){ + case 'exportFile': + exportFile(); + break; + // case 'fadeout': + // fadeOutAudio(); + // break; } @@ -460,6 +509,10 @@ export function FreeFlow(){ refAudio.current.pause(); refAudio.current = null; } + if(refAudioAnnounce.current) { + refAudioAnnounce.current.pause(); + refAudioAnnounce.current = null; + } setCurrentCue(null); refCurrentCue.current = null; // Clear the current cue reference @@ -718,7 +771,7 @@ export function FreeFlow(){ console.log('Next cue:', nextCue); const next=cuelist.find(c => c.name === nextCue); - if(false && currentCue?.fadeout){ + if(currentCue?.fadeout){ // fade out audio fadeOutAudio(()=>{ console.log('fade out then play next cue:', next); @@ -823,7 +876,8 @@ export function FreeFlow(){