-
Notifications
You must be signed in to change notification settings - Fork 27
/
openai.ts
101 lines (94 loc) · 2.14 KB
/
openai.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { TTSBuilder, TTSProvider, TTSSpeaker } from "../common/type";
import { createStreamHandler } from "../common/stream";
import { fetch } from "node-fetch-native/proxy";
// OpenAI TTS 音色列表:https://platform.openai.com/docs/guides/text-to-speech
const kOpenAISpeakers: TTSSpeaker[] = [
{
name: "Alloy",
gender: "男",
speaker: "alloy",
},
{
name: "Echo",
gender: "男",
speaker: "echo",
},
{
name: "Fable",
gender: "男",
speaker: "fable",
},
{
name: "Onyx",
gender: "男",
speaker: "onyx",
},
{
name: "Nova",
gender: "女",
speaker: "nova",
},
{
name: "Shimmer",
gender: "女",
speaker: "shimmer",
},
];
export const openaiTTS: TTSBuilder = async ({
openai,
text,
speaker,
stream: responseStream,
}) => {
const key = openai?.apiKey;
const model = openai?.model ?? "tts-1";
const baseUrl = openai?.baseUrl ?? "https://api.openai.com/v1";
if (!key) {
console.log("❌ 找不到 OpenAI TTS 环境变量:OPENAI_API_KEY");
return null;
}
const streamHandler = createStreamHandler(responseStream);
fetch(`${baseUrl}/audio/speech`, {
method: "post",
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model,
input: text,
voice: speaker,
}),
})
.catch((error) => error)
.then(async (resp) => {
const stream = resp?.body;
if (!stream) {
streamHandler.error(resp, "OpenAI | Get stream body failed!");
return;
}
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (value) {
streamHandler.push(value);
}
if (done) {
streamHandler.end();
break;
}
}
} catch (err) {
streamHandler.error(resp, "OpenAI | Read stream failed!");
} finally {
reader.releaseLock();
}
});
return streamHandler.result;
};
export const kOpenAI: TTSProvider = {
name: "OpenAI TTS",
tts: openaiTTS,
speakers: kOpenAISpeakers,
};