From db060d732abeab3724f61eeae9ed6f5b4c93c9be Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Thu, 7 Nov 2024 11:45:38 +0800 Subject: [PATCH] upload save record wav file --- .../realtime-chat/realtime-chat.tsx | 39 +++++++++++++------ app/lib/audio.ts | 18 +++++++++ app/utils/chat.ts | 2 +- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/components/realtime-chat/realtime-chat.tsx b/app/components/realtime-chat/realtime-chat.tsx index 30181c0fac9..815dcce8532 100644 --- a/app/components/realtime-chat/realtime-chat.tsx +++ b/app/components/realtime-chat/realtime-chat.tsx @@ -127,7 +127,6 @@ export function RealtimeChat({ const handleResponse = async (response: RTResponse) => { for await (const item of response) { - console.log("handleResponse", item); if (item.type === "message" && item.role === "assistant") { const botMessage = createMessage({ role: item.role, @@ -156,12 +155,16 @@ export function RealtimeChat({ }; await Promise.all([textTask(), audioTask()]); } + // update message.content + chatStore.updateTargetSession((session) => { + session.messages = session.messages.concat(); + }); } // upload audio get audio_url const blob = audioHandlerRef.current?.savePlayFile(); uploadImage(blob).then((audio_url) => { botMessage.audio_url = audio_url; - botMessage.date = new Date().toLocaleString(); + // botMessage.date = new Date().toLocaleString(); // update text and audio_url chatStore.updateTargetSession((session) => { session.messages = session.messages.concat(); @@ -174,16 +177,28 @@ export function RealtimeChat({ const handleInputAudio = async (item: RTInputAudioItem) => { audioHandlerRef.current?.stopStreamingPlayback(); await item.waitForCompletion(); - const { audioStartMillis, audioEndMillis } = item; - // TODO, save input audio_url, and update session - console.log("handleInputAudio", item, audioStartMillis, audioEndMillis); - const userMessage = createMessage({ - role: "user", - content: item.transcription, - }); - chatStore.updateTargetSession(session, (session) => { - session.messages = session.messages.concat([userMessage]); - }); + if (item.transcription) { + const userMessage = createMessage({ + role: "user", + content: item.transcription, + }); + chatStore.updateTargetSession(session, (session) => { + session.messages = session.messages.concat([userMessage]); + }); + // save input audio_url, and update session + const { audioStartMillis, audioEndMillis } = item; + // upload audio get audio_url + const blob = audioHandlerRef.current?.saveRecordFile( + audioStartMillis, + audioEndMillis, + ); + uploadImage(blob).then((audio_url) => { + userMessage.audio_url = audio_url; + chatStore.updateTargetSession((session) => { + session.messages = session.messages.concat(); + }); + }); + } }; const toggleRecording = async () => { diff --git a/app/lib/audio.ts b/app/lib/audio.ts index d62f4e86da0..46a75f7ad83 100644 --- a/app/lib/audio.ts +++ b/app/lib/audio.ts @@ -3,6 +3,7 @@ export class AudioHandler { private workletNode: AudioWorkletNode | null = null; private stream: MediaStream | null = null; private source: MediaStreamAudioSourceNode | null = null; + private recordBuffer: Int16Array[] = []; private readonly sampleRate = 24000; private nextPlayTime: number = 0; @@ -52,6 +53,8 @@ export class AudioHandler { const uint8Data = new Uint8Array(int16Data.buffer); onChunk(uint8Data); + // save recordBuffer + this.recordBuffer.push.apply(this.recordBuffer, int16Data); } }; @@ -154,7 +157,22 @@ export class AudioHandler { savePlayFile() { return this._saveData(new Int16Array(this.playBuffer)); } + saveRecordFile( + audioStartMillis: number | undefined, + audioEndMillis: number | undefined, + ) { + const startIndex = audioStartMillis + ? Math.floor((audioStartMillis * this.sampleRate) / 1000) + : 0; + const endIndex = audioEndMillis + ? Math.floor((audioEndMillis * this.sampleRate) / 1000) + : this.recordBuffer.length; + return this._saveData( + new Int16Array(this.recordBuffer.slice(startIndex, endIndex)), + ); + } async close() { + this.recordBuffer = []; this.workletNode?.disconnect(); this.source?.disconnect(); this.stream?.getTracks().forEach((track) => track.stop()); diff --git a/app/utils/chat.ts b/app/utils/chat.ts index 9209b5da540..abace88e854 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -138,7 +138,7 @@ export function uploadImage(file: Blob): Promise { }) .then((res) => res.json()) .then((res) => { - console.log("res", res); + // console.log("res", res); if (res?.code == 0 && res?.data) { return res?.data; }