From bcd50b89c860b33bb464a5e35e92ac43ad153721 Mon Sep 17 00:00:00 2001 From: dakai Date: Mon, 14 Oct 2024 03:25:44 +0800 Subject: [PATCH] feat: add voice audio preview button in tts-config option --- app/components/tts-config.tsx | 96 ++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/app/components/tts-config.tsx b/app/components/tts-config.tsx index 39ae85730c2..30c1424d698 100644 --- a/app/components/tts-config.tsx +++ b/app/components/tts-config.tsx @@ -1,19 +1,60 @@ import { TTSConfig, TTSConfigValidator } from "../store"; +import React, { useState } from "react"; import Locale from "../locales"; import { ListItem, Select } from "./ui-lib"; import { + ModelProvider, DEFAULT_TTS_ENGINE, DEFAULT_TTS_ENGINES, DEFAULT_TTS_MODELS, DEFAULT_TTS_VOICES, } from "../constant"; import { InputRange } from "./input-range"; +import { IconButton } from "./button"; +import SpeakIcon from "../icons/speak.svg"; +import SpeakStopIcon from "../icons/speak-stop.svg"; +import { createTTSPlayer } from "../utils/audio"; +import { useAppConfig } from "../store"; +import { ClientApi } from "../client/api"; +const ttsPlayer = createTTSPlayer(); export function TTSConfigList(props: { ttsConfig: TTSConfig; updateConfig: (updater: (config: TTSConfig) => void) => void; }) { + const [speechLoading, setSpeechLoading] = useState(false); + const [speechStatus, setSpeechStatus] = useState(false); + + async function openaiSpeech(text: string) { + if (speechStatus) { + ttsPlayer.stop(); + setSpeechStatus(false); + } else { + var api: ClientApi; + api = new ClientApi(ModelProvider.GPT); + const config = useAppConfig.getState(); + setSpeechLoading(true); + ttsPlayer.init(); + let audioBuffer: ArrayBuffer; + audioBuffer = await api.llm.speech({ + model: config.ttsConfig.model, + input: text, + voice: config.ttsConfig.voice, + speed: config.ttsConfig.speed, + }); + setSpeechStatus(true); + ttsPlayer + .play(audioBuffer, () => { + setSpeechStatus(false); + }) + .catch((e) => { + console.error("[OpenAI Speech]", e); + setSpeechStatus(false); + }) + .finally(() => setSpeechLoading(false)); + } + } return ( <> - +
+ : } + text={ + speechLoading + ? "Loading..." + : speechStatus + ? Locale.Chat.Actions.Stop + : Locale.Chat.Actions.Speech + } + onClick={() => { + speechStatus + ? (ttsPlayer.stop(), setSpeechStatus(false)) + : openaiSpeech( + "NextChat,Unleash your imagination, experience the future of AI conversation.", + ); + }} + /> + + +