From 15054eec852609c7ff3f52dfcdab904d73b25610 Mon Sep 17 00:00:00 2001 From: heimoshuiyu Date: Tue, 7 Nov 2023 13:50:49 +0800 Subject: [PATCH] support tts --- src/app.tsx | 34 +++++++++++--- src/message.tsx | 8 ++++ src/settings.tsx | 113 ++++++++++++++++++++++++----------------------- src/tts.tsx | 53 ++++++++++++++++++++++ 4 files changed, 148 insertions(+), 60 deletions(-) create mode 100644 src/tts.tsx diff --git a/src/app.tsx b/src/app.tsx index df7e5a7..c1870f1 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -43,7 +43,11 @@ export interface ChatStore { develop_mode: boolean; whisper_api: string; whisper_key: string; - audioDeviceID: string; + tts_api: string; + tts_key: string; + tts_voice: string; + tts_speed: number; + tts_speed_enabled: boolean; } const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions"; @@ -56,7 +60,11 @@ const newChatStore = ( temperature = 0.7, dev = false, whisper_api = "", - whisper_key = "" + whisper_key = "", + tts_api = "", + tts_key = "", + tts_speed = 1.0, + tts_speed_enabled = false ): ChatStore => { return { chatgpt_api_web_version: CHATGPT_API_WEB_VERSION, @@ -81,7 +89,11 @@ const newChatStore = ( develop_mode: getDefaultParams("dev", dev), whisper_api: getDefaultParams("whisper-api", whisper_api), whisper_key: getDefaultParams("whisper-key", whisper_key), - audioDeviceID: "", + tts_api: getDefaultParams("tts-api", tts_api), + tts_key: getDefaultParams("tts-key", tts_key), + tts_voice: "alloy", + tts_speed: tts_speed, + tts_speed_enabled: tts_speed_enabled, }; }; @@ -215,7 +227,11 @@ export function App() { chatStore.temperature, !!chatStore.develop_mode, chatStore.whisper_api, - chatStore.whisper_key + chatStore.whisper_key, + chatStore.tts_api, + chatStore.tts_key, + chatStore.tts_speed, + chatStore.tts_speed_enabled ) ) ); @@ -296,7 +312,15 @@ export function App() { chatStore.systemMessageContent, chatStore.apiEndpoint, chatStore.streamMode, - chatStore.model + chatStore.model, + chatStore.temperature, + !!chatStore.develop_mode, + chatStore.whisper_api, + chatStore.whisper_key, + chatStore.tts_api, + chatStore.tts_key, + chatStore.tts_speed, + chatStore.tts_speed_enabled ) ); } diff --git a/src/message.tsx b/src/message.tsx index 0baec80..3779cd4 100644 --- a/src/message.tsx +++ b/src/message.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, StateUpdater } from "preact/hooks"; import { ChatStore, ChatStoreMessage } from "./app"; import { calculate_token_length } from "./chatgpt"; import Markdown from "preact-markdown"; +import TTSButton from "./tts"; interface EditMessageProps { chat: ChatStoreMessage; @@ -163,6 +164,13 @@ export default function Message(props: Props) {
+ {chatStore.tts_api && chatStore.tts_key && ( + + )}
diff --git a/src/settings.tsx b/src/settings.tsx index ecd9cb6..b35c6b0 100644 --- a/src/settings.tsx +++ b/src/settings.tsx @@ -6,6 +6,15 @@ import { TemplateChatStore } from "./chatbox"; import { tr, Tr, langCodeContext, LANG_OPTIONS } from "./translate"; import p from "preact-markdown"; +const TTS_VOICES: string[] = [ + "alloy", + "echo", + "fable", + "onyx", + "nova", + "shimmer", +]; + const Help = (props: { children: any; help: string }) => { return (
@@ -71,7 +80,13 @@ const LongInput = (props: { const Input = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; - field: "apiKey" | "apiEndpoint" | "whisper_api" | "whisper_key"; + field: + | "apiKey" + | "apiEndpoint" + | "whisper_api" + | "whisper_key" + | "tts_api" + | "tts_key"; help: string; }) => { const [hideInput, setHideInput] = useState(true); @@ -101,8 +116,10 @@ const Input = (props: { const Slicer = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; - field: "temperature" | "top_p"; + field: "temperature" | "top_p" | "tts_speed"; help: string; + min: number; + max: number; }) => { const enable_filed_name: "temperature_enabled" | "top_p_enabled" = `${props.field}_enabled` as any; @@ -139,8 +156,8 @@ const Slicer = (props: { disabled={!enabled} className="m-2 p-2 border rounded focus w-28" type="range" - min="0" - max="1" + min={props.min} + max={props.max} step="0.01" value={props.chatStore[props.field]} onChange={(event: any) => { @@ -387,8 +404,8 @@ export default (props: { readOnly={true} {...props} /> - - + + - + + -

- - {devices.length === 0 && ( - - )} - {devices.length > 0 && ( - - )} -

+ + + + + + +

diff --git a/src/tts.tsx b/src/tts.tsx new file mode 100644 index 0000000..bbfe79e --- /dev/null +++ b/src/tts.tsx @@ -0,0 +1,53 @@ +import { ChatStore, addTotalCost } from "./app"; + +interface TTSProps { + chatStore: ChatStore; + setChatStore: (cs: ChatStore) => void; + text: string; +} +export default function TTSButton(props: TTSProps) { + return ( + + ); +}