save tts audio

This commit is contained in:
2023-11-30 11:47:29 +08:00
parent 647098ef83
commit 97a75ce35f
4 changed files with 29 additions and 6 deletions

View File

@@ -14,6 +14,7 @@ export interface ChatStoreMessage extends Message {
hide: boolean;
token: number;
example: boolean;
audio: Blob | null;
}
export interface TemplateAPI {

View File

@@ -151,6 +151,7 @@ export default function ChatBOX(props: {
hide: false,
token: responseTokenCount,
example: false,
audio: null,
};
if (allChunkTool.length > 0) newMsg.tool_calls = allChunkTool;
@@ -205,6 +206,7 @@ export default function ChatBOX(props: {
token:
data.usage.completion_tokens ?? calculate_token_length(msg.content),
example: false,
audio: null,
});
setShowGenerating(false);
};
@@ -300,6 +302,7 @@ export default function ChatBOX(props: {
hide: false,
token: calculate_token_length(inputMsg.trim()),
example: false,
audio: null,
});
// manually calculate token length
@@ -975,6 +978,7 @@ export default function ChatBOX(props: {
calculate_token_length(images),
hide: false,
example: false,
audio: null,
});
update_total_tokens();
setInputMsg("");
@@ -1068,6 +1072,7 @@ export default function ChatBOX(props: {
token: calculate_token_length(newToolContent),
hide: false,
example: false,
audio: null,
});
update_total_tokens();
setChatStore({ ...chatStore });

View File

@@ -3,7 +3,7 @@ import { useState, useEffect, StateUpdater } from "preact/hooks";
import { ChatStore, ChatStoreMessage } from "./app";
import { calculate_token_length, getMessageText } from "./chatgpt";
import Markdown from "preact-markdown";
import TTSButton from "./tts";
import TTSButton, { TTSPlay } from "./tts";
import { MessageHide } from "./messageHide";
import { MessageDetail } from "./messageDetail";
import { MessageToolCall } from "./messageToolCall";
@@ -130,13 +130,18 @@ export default function Message(props: Props) {
</div>
)}
<hr className="mt-2" />
<TTSPlay
chat={chat}
chatStore={chatStore}
setChatStore={setChatStore}
/>
<div className="w-full flex justify-between">
<DeleteIcon />
<button onClick={() => setShowEdit(true)}>🖋</button>
{chatStore.tts_api && chatStore.tts_key && (
<TTSButton
chatStore={chatStore}
text={getMessageText(chat)}
chat={chat}
setChatStore={setChatStore}
/>
)}

View File

@@ -1,10 +1,18 @@
import { useState } from "preact/hooks";
import { ChatStore, addTotalCost } from "./app";
import { ChatStore, ChatStoreMessage, addTotalCost } from "./app";
import { Message, getMessageText } from "./chatgpt";
interface TTSProps {
chatStore: ChatStore;
chat: ChatStoreMessage;
setChatStore: (cs: ChatStore) => void;
text: string;
}
export function TTSPlay(props: TTSProps) {
if (props.chat.audio instanceof Blob) {
const url = URL.createObjectURL(props.chat.audio);
return <audio src={url} controls />;
}
return <></>;
}
export default function TTSButton(props: TTSProps) {
const [generating, setGenerating] = useState(false);
@@ -14,7 +22,7 @@ export default function TTSButton(props: TTSProps) {
const api = props.chatStore.tts_api;
const api_key = props.chatStore.tts_key;
const model = "tts-1";
const input = props.text;
const input = getMessageText(props.chat);
const voice = props.chatStore.tts_voice;
const body: Record<string, any> = {
@@ -40,11 +48,15 @@ export default function TTSButton(props: TTSProps) {
.then((response) => response.blob())
.then((blob) => {
// update price
const cost = (props.text.length * 0.015) / 1000;
const cost = (input.length * 0.015) / 1000;
props.chatStore.cost += cost;
addTotalCost(cost);
props.setChatStore({ ...props.chatStore });
// save blob
props.chat.audio = blob;
props.setChatStore({ ...props.chatStore });
const url = URL.createObjectURL(blob);
const audio = new Audio(url);
audio.play();