save tts audio
This commit is contained in:
@@ -14,6 +14,7 @@ export interface ChatStoreMessage extends Message {
|
|||||||
hide: boolean;
|
hide: boolean;
|
||||||
token: number;
|
token: number;
|
||||||
example: boolean;
|
example: boolean;
|
||||||
|
audio: Blob | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TemplateAPI {
|
export interface TemplateAPI {
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export default function ChatBOX(props: {
|
|||||||
hide: false,
|
hide: false,
|
||||||
token: responseTokenCount,
|
token: responseTokenCount,
|
||||||
example: false,
|
example: false,
|
||||||
|
audio: null,
|
||||||
};
|
};
|
||||||
if (allChunkTool.length > 0) newMsg.tool_calls = allChunkTool;
|
if (allChunkTool.length > 0) newMsg.tool_calls = allChunkTool;
|
||||||
|
|
||||||
@@ -205,6 +206,7 @@ export default function ChatBOX(props: {
|
|||||||
token:
|
token:
|
||||||
data.usage.completion_tokens ?? calculate_token_length(msg.content),
|
data.usage.completion_tokens ?? calculate_token_length(msg.content),
|
||||||
example: false,
|
example: false,
|
||||||
|
audio: null,
|
||||||
});
|
});
|
||||||
setShowGenerating(false);
|
setShowGenerating(false);
|
||||||
};
|
};
|
||||||
@@ -300,6 +302,7 @@ export default function ChatBOX(props: {
|
|||||||
hide: false,
|
hide: false,
|
||||||
token: calculate_token_length(inputMsg.trim()),
|
token: calculate_token_length(inputMsg.trim()),
|
||||||
example: false,
|
example: false,
|
||||||
|
audio: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// manually calculate token length
|
// manually calculate token length
|
||||||
@@ -975,6 +978,7 @@ export default function ChatBOX(props: {
|
|||||||
calculate_token_length(images),
|
calculate_token_length(images),
|
||||||
hide: false,
|
hide: false,
|
||||||
example: false,
|
example: false,
|
||||||
|
audio: null,
|
||||||
});
|
});
|
||||||
update_total_tokens();
|
update_total_tokens();
|
||||||
setInputMsg("");
|
setInputMsg("");
|
||||||
@@ -1068,6 +1072,7 @@ export default function ChatBOX(props: {
|
|||||||
token: calculate_token_length(newToolContent),
|
token: calculate_token_length(newToolContent),
|
||||||
hide: false,
|
hide: false,
|
||||||
example: false,
|
example: false,
|
||||||
|
audio: null,
|
||||||
});
|
});
|
||||||
update_total_tokens();
|
update_total_tokens();
|
||||||
setChatStore({ ...chatStore });
|
setChatStore({ ...chatStore });
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useState, useEffect, StateUpdater } from "preact/hooks";
|
|||||||
import { ChatStore, ChatStoreMessage } from "./app";
|
import { ChatStore, ChatStoreMessage } from "./app";
|
||||||
import { calculate_token_length, getMessageText } from "./chatgpt";
|
import { calculate_token_length, getMessageText } from "./chatgpt";
|
||||||
import Markdown from "preact-markdown";
|
import Markdown from "preact-markdown";
|
||||||
import TTSButton from "./tts";
|
import TTSButton, { TTSPlay } from "./tts";
|
||||||
import { MessageHide } from "./messageHide";
|
import { MessageHide } from "./messageHide";
|
||||||
import { MessageDetail } from "./messageDetail";
|
import { MessageDetail } from "./messageDetail";
|
||||||
import { MessageToolCall } from "./messageToolCall";
|
import { MessageToolCall } from "./messageToolCall";
|
||||||
@@ -130,13 +130,18 @@ export default function Message(props: Props) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<hr className="mt-2" />
|
<hr className="mt-2" />
|
||||||
|
<TTSPlay
|
||||||
|
chat={chat}
|
||||||
|
chatStore={chatStore}
|
||||||
|
setChatStore={setChatStore}
|
||||||
|
/>
|
||||||
<div className="w-full flex justify-between">
|
<div className="w-full flex justify-between">
|
||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
<button onClick={() => setShowEdit(true)}>🖋</button>
|
<button onClick={() => setShowEdit(true)}>🖋</button>
|
||||||
{chatStore.tts_api && chatStore.tts_key && (
|
{chatStore.tts_api && chatStore.tts_key && (
|
||||||
<TTSButton
|
<TTSButton
|
||||||
chatStore={chatStore}
|
chatStore={chatStore}
|
||||||
text={getMessageText(chat)}
|
chat={chat}
|
||||||
setChatStore={setChatStore}
|
setChatStore={setChatStore}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
20
src/tts.tsx
20
src/tts.tsx
@@ -1,10 +1,18 @@
|
|||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { ChatStore, addTotalCost } from "./app";
|
import { ChatStore, ChatStoreMessage, addTotalCost } from "./app";
|
||||||
|
import { Message, getMessageText } from "./chatgpt";
|
||||||
|
|
||||||
interface TTSProps {
|
interface TTSProps {
|
||||||
chatStore: ChatStore;
|
chatStore: ChatStore;
|
||||||
|
chat: ChatStoreMessage;
|
||||||
setChatStore: (cs: ChatStore) => void;
|
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) {
|
export default function TTSButton(props: TTSProps) {
|
||||||
const [generating, setGenerating] = useState(false);
|
const [generating, setGenerating] = useState(false);
|
||||||
@@ -14,7 +22,7 @@ export default function TTSButton(props: TTSProps) {
|
|||||||
const api = props.chatStore.tts_api;
|
const api = props.chatStore.tts_api;
|
||||||
const api_key = props.chatStore.tts_key;
|
const api_key = props.chatStore.tts_key;
|
||||||
const model = "tts-1";
|
const model = "tts-1";
|
||||||
const input = props.text;
|
const input = getMessageText(props.chat);
|
||||||
const voice = props.chatStore.tts_voice;
|
const voice = props.chatStore.tts_voice;
|
||||||
|
|
||||||
const body: Record<string, any> = {
|
const body: Record<string, any> = {
|
||||||
@@ -40,11 +48,15 @@ export default function TTSButton(props: TTSProps) {
|
|||||||
.then((response) => response.blob())
|
.then((response) => response.blob())
|
||||||
.then((blob) => {
|
.then((blob) => {
|
||||||
// update price
|
// update price
|
||||||
const cost = (props.text.length * 0.015) / 1000;
|
const cost = (input.length * 0.015) / 1000;
|
||||||
props.chatStore.cost += cost;
|
props.chatStore.cost += cost;
|
||||||
addTotalCost(cost);
|
addTotalCost(cost);
|
||||||
props.setChatStore({ ...props.chatStore });
|
props.setChatStore({ ...props.chatStore });
|
||||||
|
|
||||||
|
// save blob
|
||||||
|
props.chat.audio = blob;
|
||||||
|
props.setChatStore({ ...props.chatStore });
|
||||||
|
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const audio = new Audio(url);
|
const audio = new Audio(url);
|
||||||
audio.play();
|
audio.play();
|
||||||
|
|||||||
Reference in New Issue
Block a user