js-tts-wrapper
Version:
A JavaScript/TypeScript library that provides a unified API for working with multiple cloud-based Text-to-Speech (TTS) services
212 lines (211 loc) • 6.8 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpliftAITTSClient = void 0;
const abstract_tts_1 = require("../core/abstract-tts");
const SpeechMarkdown = __importStar(require("../markdown/converter"));
const SSMLUtils = __importStar(require("../core/ssml-utils"));
const fetch_utils_1 = require("../utils/fetch-utils");
// Static voice list as provider doesn't expose voice query API
const UPLIFTAI_VOICES = [
{
id: "v_8eelc901",
name: "Info/Education",
gender: "Unknown",
provider: "upliftai",
languageCodes: [
{
bcp47: "ur-PK",
iso639_3: "urd",
display: "Urdu (Pakistan)",
},
],
},
{
id: "v_30s70t3a",
name: "Nostalgic News",
gender: "Unknown",
provider: "upliftai",
languageCodes: [
{
bcp47: "ur-PK",
iso639_3: "urd",
display: "Urdu (Pakistan)",
},
],
},
{
id: "v_yypgzenx",
name: "Dada Jee",
gender: "Unknown",
provider: "upliftai",
languageCodes: [
{
bcp47: "ur-PK",
iso639_3: "urd",
display: "Urdu (Pakistan)",
},
],
},
{
id: "v_kwmp7zxt",
name: "Gen Z (beta)",
gender: "Unknown",
provider: "upliftai",
languageCodes: [
{
bcp47: "ur-PK",
iso639_3: "urd",
display: "Urdu (Pakistan)",
},
],
},
];
/**
* UpliftAI TTS Client
*/
class UpliftAITTSClient extends abstract_tts_1.AbstractTTSClient {
/**
* Create a new UpliftAI TTS client
* @param credentials Credentials including API key
*/
constructor(credentials = {}) {
super(credentials);
Object.defineProperty(this, "apiKey", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "baseUrl", {
enumerable: true,
configurable: true,
writable: true,
value: "https://api.upliftai.org/v1/synthesis"
});
Object.defineProperty(this, "outputFormat", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "sampleRate", {
enumerable: true,
configurable: true,
writable: true,
value: 22050
});
this.apiKey = credentials.apiKey || process.env.UPLIFTAI_API_KEY || "";
this.outputFormat = "MP3_22050_128"; // Default format
}
/**
* Check if credentials are valid
*/
async checkCredentials() {
if (!this.apiKey) {
console.error("UpliftAI API key is required");
return false;
}
return true;
}
/**
* Get required credential field names
*/
getRequiredCredentials() {
return ["apiKey"];
}
/**
* Get available voices (static list)
*/
async _getVoices() {
return UPLIFTAI_VOICES;
}
/**
* Synthesize text to audio bytes
*/
async synthToBytes(text, options = {}) {
const { audioStream } = await this.synthToBytestream(text, options);
const reader = audioStream.getReader();
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done)
break;
chunks.push(value);
}
const totalLength = chunks.reduce((acc, cur) => acc + cur.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const chunk of chunks) {
result.set(chunk, offset);
offset += chunk.length;
}
return result;
}
/**
* Synthesize text to a byte stream
*/
async synthToBytestream(text, options = {}) {
let processedText = text;
if (options.useSpeechMarkdown && SpeechMarkdown.isSpeechMarkdown(processedText)) {
const ssml = await SpeechMarkdown.toSSML(processedText);
processedText = SSMLUtils.stripSSML(ssml);
}
if (SSMLUtils.isSSML(processedText)) {
processedText = SSMLUtils.stripSSML(processedText);
}
const voiceId = options.voice || this.voiceId || UPLIFTAI_VOICES[0].id;
this.voiceId = voiceId;
const response = await (0, fetch_utils_1.getFetch)()(`${this.baseUrl}/text-to-speech/stream`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`,
},
body: JSON.stringify({
voiceId,
text: processedText,
outputFormat: options.outputFormat || this.outputFormat,
}),
});
if (!response.ok || !response.body) {
throw new Error(`Failed to synthesize speech: ${response.status} ${response.statusText}`);
}
options.onEnd?.();
return { audioStream: response.body, wordBoundaries: [] };
}
}
exports.UpliftAITTSClient = UpliftAITTSClient;
exports.default = UpliftAITTSClient;
;