yaejunyang/packages/tts/supertonic.ts
2026-05-21 14:48:16 +00:00

62 lines
2.1 KiB
TypeScript

import { join } from "path";
import fetch from "../utils/fetch";
import TTSModelBase from ".";
export class TTSSupertonicModel extends TTSModelBase<TTSSupertonicModel.RequestId> {
protected override cachedVoice: Map<String, Promise<Buffer>>
constructor() {
super()
this.cachedVoice = new Map();
}
override ttsify(input: string): string {
return super.ttsify(input);
}
private async getSupertonicResponse(voiceId: TTSSupertonicModel.RequestId) {
const payload = {
text: voiceId.text,
lang: "ko",
style_id: voiceId.styleId
};
if (!process.env.SUPERTONIC_API_URL) {
throw Error("process.env.SUPERTONIC_API_URL not set");
}
return await fetch(process.env.SUPERTONIC_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
}
async getVoiceBuffer(voiceId: TTSSupertonicModel.RequestId): Promise<ArrayBuffer> {
let response: Response | undefined;
response = await this.getSupertonicResponse(voiceId) as Response;
if (response.ok)
return await response.arrayBuffer();
throw new Error(`invalid supertonic response ${await response.text()}`);
}
public getVoicePath(id: TTSSupertonicModel.RequestId): string {
const audioFileName = TTSModelBase.hashAudioFile(id.text + id.styleId);
const audioPath = join(
TTSSupertonicModel.SupertonicAudioCachePath,
audioFileName
);
return audioPath;
}
public createRequestId(text: string, styleId?: string): TTSSupertonicModel.RequestId {
return {
text,
styleId: styleId ?? "F1"
};
}
}
export namespace TTSSupertonicModel {
export const instance = new TTSSupertonicModel();
export type RequestId = { text: string, styleId: string };
export const SupertonicAudioCachePath = join(TTSModelBase.AudioCachePath, "supertonic");
}
export default TTSSupertonicModel;