Skip to content

Commit

Permalink
⚡ playground improve
Browse files Browse the repository at this point in the history
  • Loading branch information
zhzLuke96 committed Jun 6, 2024
1 parent 124a430 commit f8da40b
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 20 deletions.
21 changes: 21 additions & 0 deletions playground/AudioCreation.page.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { client } from "./client.mjs";
import { html, create, styled } from "./misc.mjs";

import { OpenAI } from "openai";

import { useGlobalStore } from "./global.store.mjs";

const useStore = create((set, get) => ({
// TODO
}));

const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
`;

export const AudioCreation = () => {
return html` <${Container}> TODO 🚧 AudioCreation page <//> `;
};
18 changes: 18 additions & 0 deletions playground/global.store.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { client } from "./client.mjs";
import { create } from "./misc.mjs";

export const useGlobalStore = create((set, get) => ({
speakers: [],
styles: [],
}));

window.addEventListener("load", async () => {
const styles = await client.listStyles();
const speakers = await client.listSpeakers();
console.log("styles:", styles);
console.log("speakers:", speakers);
useGlobalStore.set({
styles: styles.data,
speakers: speakers.data,
});
});
21 changes: 21 additions & 0 deletions playground/google.page.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { client } from "./client.mjs";
import { html, create, styled } from "./misc.mjs";

import { OpenAI } from "openai";

import { useGlobalStore } from "./global.store.mjs";

const useStore = create((set, get) => ({
// TODO
}));

const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
`;

export const GooglePage = () => {
return html` <${Container}> TODO 🚧 Google page <//> `;
};
3 changes: 2 additions & 1 deletion playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"@quik-fe/stand": "https://jsd.onmicrosoft.cn/npm/@quik-fe/stand@1.1.2/+esm",
"goober": "https://jsd.onmicrosoft.cn/npm/goober@2.1.14/+esm",
"@tanstack/react-table": "https://jsd.onmicrosoft.cn/npm/@tanstack/react-table@8.17.3/+esm",
"fast-equals": "https://jsd.onmicrosoft.cn/npm/fast-equals@5.0.1/+esm"
"fast-equals": "https://jsd.onmicrosoft.cn/npm/fast-equals@5.0.1/+esm",
"openai": "https://cdn.jsdelivr.net/npm/openai@4.48.2/+esm"
}
}
</script>
Expand Down
214 changes: 214 additions & 0 deletions playground/openai.page.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { client } from "./client.mjs";
import { html, create, styled } from "./misc.mjs";

import { OpenAI } from "openai";

import { useGlobalStore } from "./global.store.mjs";

const OpenaiPageContainer = styled.div`
display: flex;
width: 100%;
& > * {
flex: 1;
}
textarea {
width: 100%;
height: 10rem;
margin-bottom: 1rem;
min-height: 10rem;
resize: vertical;
}
button {
padding: 0.5rem 1rem;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
fieldset {
margin-top: 1rem;
padding: 1rem;
border: 1px solid #333;
}
legend {
font-weight: bold;
}
label {
display: block;
margin-bottom: 0.5rem;
}
select,
input[type="range"],
input[type="number"] {
width: 100%;
margin-top: 0.25rem;
}
input[type="range"] {
width: calc(100% - 2rem);
}
input[type="number"] {
width: calc(100% - 2rem);
padding: 0.5rem;
}
input[type="text"] {
width: 100%;
padding: 0.5rem;
}
audio {
margin-top: 1rem;
}
textarea,
input,
select {
background-color: #333;
color: white;
border: 1px solid #333;
border-radius: 0.25rem;
padding: 0.5rem;
}
`;

const useStore = create((set, get) => ({
params: {
input: "你好,这是一个测试 [lbreak]",
voice: "female2",
style: "text",
speed: 1,
},
setParams: (params) =>
set({
params: {
...get().params,
...params,
},
}),
result: null,
setResult: (result) => set({ result }),
}));

const base_host =
localStorage.getItem("__chattts_playground_api_base__") ||
`${window.location.origin}`;
const openai = new OpenAI({
apiKey: "sk-xxxx",
baseURL: base_host + (base_host.endsWith("/") ? "" : "/") + "v1",
dangerouslyAllowBrowser: true,
});

export const OpenaiPage = () => {
// 可以传 input voice style 参数
const { params, setParams, result, setResult } = useStore();
const { input, voice, style, speed } = params;

const { speakers, styles } = useGlobalStore();

const handleInput = (e) => {
setParams({ input: e.target.value });
};

const handleVoice = (e) => {
if (e.target.value.startsWith("*")) {
setParams({ voice: "" });
return;
}
setParams({ voice: e.target.value });
};

const handleStyle = (e) => {
if (e.target.value.startsWith("*")) {
setParams({ style: "" });
return;
}
setParams({ style: e.target.value });
};

const handleSpeed = (e) => {
setParams({ speed: Number(e.target.value) });
};

const handleSubmit = async () => {
const response = await openai.audio.speech.create({
...params,
response_format: "mp3",
});
const blob = await response.blob();
console.log(response);
const url = URL.createObjectURL(blob);
setResult(url);
};

return html`
<${OpenaiPageContainer}>
<div>
<textarea value=${input} onInput=${handleInput}></textarea>
</div>
<fieldset>
<legend>Payload</legend>
<label>
Speaker:
<select value=${voice} onChange=${handleVoice}>
<option value="-1">*random</option>
${speakers.map(
(spk) => html`
<option key=${spk.index} value=${spk.name}>${spk.name}</option>
`
)}
</select>
</label>
<label>
Style:
<select value=${style} onChange=${handleStyle}>
<option value="">*auto</option>
${styles.map(
(style) => html`
<option key=${style.id} value=${style.name}>
${style.name}
</option>
`
)}
</select>
</label>
<label>
速度
<input
type="range"
min="0.5"
max="1.5"
step="0.1"
value=${speed}
onInput=${handleSpeed}
/>
<output>${speed}</output>
</label>
<button onClick=${handleSubmit}>提交</button>
</fieldset>
<fieldset>
<legend>Result</legend>
${result && html`<audio controls src=${result}></audio>`}
</fieldset>
<//>
`;
};
6 changes: 6 additions & 0 deletions playground/pages.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { TTSPage } from "./tts.page.mjs";
import { SSMLPage } from "./ssml.page.mjs";
import { SpeakerPage } from "./speakers.page.mjs";
import { OpenaiPage } from "./openai.page.mjs";
import { GooglePage } from "./google.page.mjs";
import { AudioCreation } from "./AudioCreation.page.mjs";

export const pages = {
tts: TTSPage,
ssml: SSMLPage,
speakers: SpeakerPage,
openai: OpenaiPage,
google: GooglePage,
AudioCreation: AudioCreation,
};
23 changes: 4 additions & 19 deletions playground/tts.page.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { client } from "./client.mjs";
import { html, create, styled } from "./misc.mjs";

import { useGlobalStore } from "./global.store.mjs";

const sample_texts = [
{
text: "大🍌,一条大🍌,嘿,你的感觉真的很奇妙 [lbreak]",
Expand Down Expand Up @@ -77,8 +79,6 @@ const useStore = create((set, get) => ({
prompt2: "",
prefix: "",
},
styles: [],
speakers: [],

ui: {
loading: false,
Expand Down Expand Up @@ -107,12 +107,6 @@ const useStore = create((set, get) => ({
},
});
},
setStyles(styles) {
set({ styles });
},
setSpeakers(speakers) {
set({ speakers });
},
setTTS(tts) {
set({
tts: {
Expand All @@ -131,15 +125,6 @@ const useStore = create((set, get) => ({
},
}));

window.addEventListener("load", async () => {
const styles = await client.listStyles();
const speakers = await client.listSpeakers();
console.log("styles:", styles);
console.log("speakers:", speakers);
useStore.get().setStyles(styles.data);
useStore.get().setSpeakers(speakers.data);
});

const TTSPageContainer = styled.div`
h1 {
margin-bottom: 1rem;
Expand Down Expand Up @@ -329,8 +314,8 @@ const TTSPageContainer = styled.div`
`;

export const TTSPage = () => {
const { tts, setTTS, synthesizeTTS, ui, setUI, speakers, styles } =
useStore();
const { tts, setTTS, synthesizeTTS, ui, setUI } = useStore();
const { speakers, styles } = useGlobalStore();

const request = async () => {
if (ui.loading) {
Expand Down

0 comments on commit f8da40b

Please sign in to comment.