Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3dfcf6b

Browse files
✨ feat: Add openai tts
1 parent a115c3b commit 3dfcf6b

File tree

30 files changed

+301
-36
lines changed

30 files changed

+301
-36
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ __test__
2424
# production
2525
dist
2626
es
27-
lib
2827
logs
2928

3029
# misc

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ __snapshots__
3535
# production
3636
dist
3737
es
38-
lib
3938
logs
4039

4140
# umi

api/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import qs from 'query-string';
22

33
import cors from '../lib/cors';
4+
import { fetchMicrosoftSpeech } from '../lib/fetchMicrosoftSpeech';
45
import { SsmlOptions } from '../lib/genSSML';
5-
import { postMicrosoftSpeech } from '../lib/postMicrosoftSpeech';
66

77
export const config = {
88
runtime: 'edge',
@@ -11,7 +11,7 @@ export const config = {
1111
export default async (req: Request) => {
1212
const { text, ...options }: SsmlOptions & { text: string } = qs.parseUrl(req.url).query as any;
1313

14-
const res = await fetch(...postMicrosoftSpeech(text, options));
14+
const res = await fetchMicrosoftSpeech(text, options);
1515

1616
const newResponse = new Response(res.body, res);
1717

lib/postMicrosoftSpeech.ts renamed to lib/fetchMicrosoftSpeech.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { type SsmlOptions, genSSML } from './genSSML';
55
const API =
66
'https://southeastasia.api.speech.microsoft.com/accfreetrial/texttospeech/acc/v3.0-beta1/vcg/speak';
77

8-
export const postMicrosoftSpeech = (text: string, options: SsmlOptions): [any, any] => {
8+
export const fetchMicrosoftSpeech = async (text: string, options: SsmlOptions) => {
99
const data = JSON.stringify({
1010
offsetInPlainText: 0,
1111
properties: {
@@ -15,7 +15,7 @@ export const postMicrosoftSpeech = (text: string, options: SsmlOptions): [any, a
1515
ttsAudioFormat: 'audio-24khz-160kbitrate-mono-mp3',
1616
});
1717

18-
const DEFAULT_HEADERS = {
18+
const DEFAULT_HEADERS = new Headers({
1919
'accept': '*/*',
2020
'accept-language': 'zh-CN,zh;q=0.9',
2121
'authority': 'southeastasia.api.speech.microsoft.com',
@@ -30,15 +30,13 @@ export const postMicrosoftSpeech = (text: string, options: SsmlOptions): [any, a
3030
'sec-fetch-site': 'same-site',
3131
'user-agent':
3232
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
33-
};
33+
});
3434

35-
return [
36-
API,
37-
{
38-
body: data,
39-
headers: DEFAULT_HEADERS,
40-
method: 'POST',
41-
responseType: 'arraybuffer',
42-
},
43-
];
35+
return await fetch(API, {
36+
body: data,
37+
headers: DEFAULT_HEADERS,
38+
method: 'POST',
39+
// @ts-ignore
40+
responseType: 'arraybuffer',
41+
});
4442
};

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"docs:dev": "dumi dev",
2828
"doctor": "father doctor",
2929
"postinstall": "npm run setup",
30-
"lint": "eslint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
30+
"lint": "eslint \"{src,api,lib}/**/*.{js,jsx,ts,tsx}\" --fix",
3131
"lint:md": "remark . --quiet --frail --output",
3232
"prepare": "husky install",
3333
"prepublishOnly": "npm run build",
@@ -65,6 +65,7 @@
6565
"query-string": "^8",
6666
"ssml-document": "^1",
6767
"swr": "^2",
68+
"url-join": "^5.0.0",
6869
"uuid": "^9"
6970
},
7071
"devDependencies": {

src/const/api.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import urlJoin from 'url-join';
2+
3+
export const MICROSOFT_SPEECH_PROXY_URL = process.env.MICROSOFT_SPEECH_PROXY_URL || '';
4+
export const AZURE_SPEECH_KEY = process.env.AZURE_SPEECH_KEY || '';
5+
export const AZURE_SPEECH_REGION = process.env.AZURE_SPEECH_REGION || '';
6+
export const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
7+
export const OPENAI_PROXY_URL = process.env.OPENAI_PROXY_URL || 'https://api.openai.com/v1';
8+
export const OPENAI_TTS_URL = (api?: string) => urlJoin(api || OPENAI_PROXY_URL, 'audio/speech');
9+
export const OPENAI_STT_URL = (api: string) =>
10+
urlJoin(api || OPENAI_PROXY_URL, 'audio/transcriptions');

src/data/openaiVoiceList.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["alloy", "echo", "fable", "onyx", "nova", "shimmer"]

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1+
export { fetchAzureSpeech } from './services/fetchAzureSpeech';
2+
export { fetchEdgeSpeech } from './services/fetchEdgeSpeech';
3+
export { fetchMicrosoftSpeech } from './services/fetchMicrosoftSpeech';
4+
export { fetchOpenaiSTT } from './services/fetchOpenaiSTT';
5+
export { fetchOpenaiTTS } from './services/fetchOpenaiTTS';
16
export { useAzureSpeech } from './useAzureSpeech';
27
export { useEdgeSpeech } from './useEdgeSpeech';
38
export { useMicrosoftSpeech } from './useMicrosoftSpeech';
9+
export { useOpenaiTTS } from './useOpenaiTTS';
410
export { usePersistedSpeechRecognition } from './useSpeechRecognition/usePersistedSpeechRecognition';
511
export { useSpeechRecognition } from './useSpeechRecognition/useSpeechRecognition';
612
export { useSpeechSynthes } from './useSpeechSynthes';
713
export {
814
getAzureVoiceList,
915
getEdgeVoiceList,
16+
getOpenaiVoiceList,
1017
getSpeechSynthesVoiceList,
1118
} from './utils/getVoiceList';

src/services/postAzureSpeech.ts renamed to src/services/fetchAzureSpeech.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
SpeechSynthesizer,
99
} from 'microsoft-cognitiveservices-speech-sdk';
1010

11+
import { AZURE_SPEECH_KEY, AZURE_SPEECH_REGION } from '@/const/api';
12+
1113
import { type SsmlOptions, genSSML } from '../utils/genSSML';
1214

1315
export interface AzureSpeechOptions extends SsmlOptions {
@@ -18,12 +20,12 @@ export interface AzureSpeechOptions extends SsmlOptions {
1820
}
1921

2022
// 纯文本生成语音
21-
export const postAzureSpeech = async (
23+
export const fetchAzureSpeech = async (
2224
text: string,
2325
{ api, ...options }: AzureSpeechOptions,
2426
): Promise<AudioBufferSourceNode> => {
25-
const key = api.key || process.env.AZURE_SPEECH_KEY || '';
26-
const region = api.key || process.env.AZURE_SPEECH_REGION || '';
27+
const key = api.key || AZURE_SPEECH_KEY;
28+
const region = api.key || AZURE_SPEECH_REGION;
2729
const speechConfig = SpeechConfig.fromSubscription(key, region);
2830
speechConfig.setProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, 'true');
2931
speechConfig.speechSynthesisOutputFormat = SpeechSynthesisOutputFormat.Webm24Khz16BitMonoOpus;

src/services/postEdgeSpeech.ts renamed to src/services/fetchEdgeSpeech.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { getHeadersAndData } from '../utils/getHeadersAndData';
88
const API = 'wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1';
99
const TOKEN = '6A5AA1D4EAFF4E9FB37E23D68491D6F4';
1010

11-
export const postEdgeSpeech = async (text: string, options: SsmlOptions) => {
11+
export const fetchEdgeSpeech = async (text: string, options: SsmlOptions) => {
1212
const connectId = uuidv4().replaceAll('-', '');
1313
const date = new Date().toString();
1414
const audioContext = new AudioContext();

0 commit comments

Comments
 (0)