@neosapience/typecast-js 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -57
- package/lib/index.d.cts +2 -16
- package/lib/index.d.ts +2 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
The official Node.js library for the [Typecast API](https://typecast.ai). Convert text to lifelike speech using AI-powered voices.
|
|
9
9
|
|
|
10
|
-
Works with both JavaScript and TypeScript. TypeScript types included.
|
|
10
|
+
Works with both JavaScript and TypeScript. Full TypeScript types included.
|
|
11
|
+
|
|
12
|
+
ESM & CommonJS supported. This SDK targets Node.js environments only (browser usage is not supported).
|
|
11
13
|
|
|
12
14
|
## Installation
|
|
13
15
|
|
|
@@ -23,21 +25,18 @@ npm install @neosapience/typecast-js
|
|
|
23
25
|
import { TypecastClient } from '@neosapience/typecast-js';
|
|
24
26
|
import fs from 'fs';
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
const client = new TypecastClient({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
28
|
+
async function main() {
|
|
29
|
+
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
|
|
30
|
+
const audio = await client.textToSpeech({
|
|
31
|
+
text: "Hello there! I'm your friendly text-to-speech agent.",
|
|
32
|
+
model: "ssfm-v21",
|
|
33
|
+
voice_id: "tc_62a8975e695ad26f7fb514d1"
|
|
34
|
+
});
|
|
35
|
+
await fs.promises.writeFile(`output.${audio.format}`, Buffer.from(audio.audioData));
|
|
36
|
+
console.log(`Audio saved! Duration: ${audio.duration}s, Format: ${audio.format}`);
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
await fs.promises.writeFile('output.wav', Buffer.from(audio.audioData));
|
|
40
|
-
console.log(`Audio saved! Duration: ${audio.duration}s, Format: ${audio.format}`);
|
|
39
|
+
main();
|
|
41
40
|
```
|
|
42
41
|
|
|
43
42
|
### JavaScript (CommonJS)
|
|
@@ -47,17 +46,13 @@ const { TypecastClient } = require('@neosapience/typecast-js');
|
|
|
47
46
|
const fs = require('fs');
|
|
48
47
|
|
|
49
48
|
async function main() {
|
|
50
|
-
const client = new TypecastClient({
|
|
51
|
-
apiKey: 'YOUR_API_KEY'
|
|
52
|
-
});
|
|
53
|
-
|
|
49
|
+
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
|
|
54
50
|
const audio = await client.textToSpeech({
|
|
55
51
|
text: "Hello there! I'm your friendly text-to-speech agent.",
|
|
56
52
|
model: "ssfm-v21",
|
|
57
53
|
voice_id: "tc_62a8975e695ad26f7fb514d1"
|
|
58
54
|
});
|
|
59
|
-
|
|
60
|
-
await fs.promises.writeFile('output.wav', Buffer.from(audio.audioData));
|
|
55
|
+
await fs.promises.writeFile(`output.${audio.format}`, Buffer.from(audio.audioData));
|
|
61
56
|
console.log(`Audio saved! Duration: ${audio.duration}s, Format: ${audio.format}`);
|
|
62
57
|
}
|
|
63
58
|
|
|
@@ -70,14 +65,14 @@ The client can be configured using environment variables or constructor options:
|
|
|
70
65
|
|
|
71
66
|
```typescript
|
|
72
67
|
// Using environment variables
|
|
73
|
-
// TYPECAST_API_KEY=your_api_key
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
// export TYPECAST_API_KEY=your_api_key
|
|
69
|
+
const client = new TypecastClient({
|
|
70
|
+
apiKey: process.env.TYPECAST_API_KEY!
|
|
71
|
+
});
|
|
76
72
|
|
|
77
|
-
//
|
|
73
|
+
// Or pass API key directly
|
|
78
74
|
const client = new TypecastClient({
|
|
79
|
-
apiKey: 'your_api_key'
|
|
80
|
-
baseHost: 'https://api.typecast.ai' // optional
|
|
75
|
+
apiKey: 'your_api_key'
|
|
81
76
|
});
|
|
82
77
|
```
|
|
83
78
|
|
|
@@ -114,10 +109,8 @@ const response = await client.textToSpeech({
|
|
|
114
109
|
- **model** (required): Voice model (`ssfm-v21`)
|
|
115
110
|
- **language** (optional): Language code (see supported languages below)
|
|
116
111
|
- **prompt** (optional): Emotion and style settings
|
|
117
|
-
- `emotion_preset`: `'happy' | 'sad' | 'normal' | 'angry'` (default: `'normal'`)
|
|
112
|
+
- `emotion_preset`: Emotion type for the voice. Available options include `'happy' | 'sad' | 'normal' | 'angry' | 'tonemid' | 'toneup'` (default: `'normal'`). Note: Each voice supports different emotions - check the voice's `emotions` array using `getVoices()` to see which emotions are supported.
|
|
118
113
|
- `emotion_intensity`: 0.0 - 2.0 (default: 1.0)
|
|
119
|
-
- `speed`: 0.5 - 2.0 (default: 1.0)
|
|
120
|
-
- `intonation`: -2 - 2 (default: 0)
|
|
121
114
|
- **output** (optional): Audio output settings
|
|
122
115
|
- `audio_format`: `'wav' | 'mp3'` (default: `'wav'`)
|
|
123
116
|
- `volume`: 0 - 200 (default: 100)
|
|
@@ -129,6 +122,8 @@ const response = await client.textToSpeech({
|
|
|
129
122
|
|
|
130
123
|
List all available voices, optionally filtered by model.
|
|
131
124
|
|
|
125
|
+
**Signature:** `getVoices(model?: string): Promise<Voice[]>`
|
|
126
|
+
|
|
132
127
|
```typescript
|
|
133
128
|
// Get all voices
|
|
134
129
|
const voices = await client.getVoices();
|
|
@@ -142,15 +137,27 @@ voices.forEach(voice => {
|
|
|
142
137
|
});
|
|
143
138
|
```
|
|
144
139
|
|
|
140
|
+
For detailed Voice object fields, see the [API Reference](https://typecast.ai/docs/api-reference).
|
|
141
|
+
|
|
145
142
|
### Get Voice by ID
|
|
146
143
|
|
|
147
144
|
Get information about a specific voice.
|
|
148
145
|
|
|
146
|
+
**Signature:** `getVoiceById(voiceId: string, model?: string): Promise<Voice[]>`
|
|
147
|
+
|
|
149
148
|
```typescript
|
|
150
149
|
const voiceInfo = await client.getVoiceById("tc_62a8975e695ad26f7fb514d1");
|
|
151
|
-
console.log(voiceInfo);
|
|
150
|
+
console.log(`Voice: ${voiceInfo[0].voice_name}`);
|
|
151
|
+
console.log(`Model: ${voiceInfo[0].model}`);
|
|
152
|
+
console.log(`Supported emotions: ${voiceInfo[0].emotions.join(', ')}`);
|
|
152
153
|
```
|
|
153
154
|
|
|
155
|
+
**Voice Object Fields:**
|
|
156
|
+
- `voice_id`: Unique identifier (format: `tc_*` or `uc_*`)
|
|
157
|
+
- `voice_name`: Human-readable name of the voice
|
|
158
|
+
- `model`: Voice model type (`ssfm-v21`)
|
|
159
|
+
- `emotions`: Array of supported emotion presets for this voice
|
|
160
|
+
|
|
154
161
|
## Supported Languages
|
|
155
162
|
|
|
156
163
|
The SDK supports 27 languages with automatic language detection:
|
|
@@ -171,6 +178,33 @@ If not specified, the language will be automatically detected from the input tex
|
|
|
171
178
|
|
|
172
179
|
## Advanced Examples
|
|
173
180
|
|
|
181
|
+
### Working with Voice Emotions
|
|
182
|
+
|
|
183
|
+
Each voice supports different emotion presets. Check which emotions a voice supports before using them:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Get voice information
|
|
187
|
+
const voices = await client.getVoices("ssfm-v21");
|
|
188
|
+
const myVoice = voices.find(v => v.voice_id === "tc_62a8975e695ad26f7fb514d1");
|
|
189
|
+
|
|
190
|
+
console.log(`${myVoice.voice_name} supports: ${myVoice.emotions.join(', ')}`);
|
|
191
|
+
// Example output: "Olivia supports: tonemid, toneup, normal, happy, sad, angry"
|
|
192
|
+
|
|
193
|
+
// Use a supported emotion
|
|
194
|
+
if (myVoice.emotions.includes('happy')) {
|
|
195
|
+
const audio = await client.textToSpeech({
|
|
196
|
+
text: "This voice supports the happy emotion!",
|
|
197
|
+
voice_id: myVoice.voice_id,
|
|
198
|
+
model: "ssfm-v21",
|
|
199
|
+
prompt: {
|
|
200
|
+
emotion_preset: "happy",
|
|
201
|
+
emotion_intensity: 1.5
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// Save: await fs.promises.writeFile(`happy.${audio.format}`, Buffer.from(audio.audioData));
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
174
208
|
### Emotion Control
|
|
175
209
|
|
|
176
210
|
```typescript
|
|
@@ -181,10 +215,13 @@ const happyAudio = await client.textToSpeech({
|
|
|
181
215
|
model: "ssfm-v21",
|
|
182
216
|
prompt: {
|
|
183
217
|
emotion_preset: "happy",
|
|
184
|
-
emotion_intensity: 1.8
|
|
185
|
-
|
|
218
|
+
emotion_intensity: 1.8
|
|
219
|
+
},
|
|
220
|
+
output: {
|
|
221
|
+
audio_tempo: 1.2
|
|
186
222
|
}
|
|
187
223
|
});
|
|
224
|
+
// Save: await fs.promises.writeFile(`happy.${happyAudio.format}`, Buffer.from(happyAudio.audioData));
|
|
188
225
|
|
|
189
226
|
// Calm and professional voice
|
|
190
227
|
const calmAudio = await client.textToSpeech({
|
|
@@ -193,10 +230,13 @@ const calmAudio = await client.textToSpeech({
|
|
|
193
230
|
model: "ssfm-v21",
|
|
194
231
|
prompt: {
|
|
195
232
|
emotion_preset: "normal",
|
|
196
|
-
emotion_intensity: 0.8
|
|
197
|
-
|
|
233
|
+
emotion_intensity: 0.8
|
|
234
|
+
},
|
|
235
|
+
output: {
|
|
236
|
+
audio_tempo: 0.9
|
|
198
237
|
}
|
|
199
238
|
});
|
|
239
|
+
// Save: await fs.promises.writeFile(`calm.${calmAudio.format}`, Buffer.from(calmAudio.audioData));
|
|
200
240
|
```
|
|
201
241
|
|
|
202
242
|
### Audio Customization
|
|
@@ -214,6 +254,7 @@ const customAudio = await client.textToSpeech({
|
|
|
214
254
|
audio_format: "mp3"
|
|
215
255
|
}
|
|
216
256
|
});
|
|
257
|
+
// Save: await fs.promises.writeFile(`custom.${customAudio.format}`, Buffer.from(customAudio.audioData));
|
|
217
258
|
```
|
|
218
259
|
|
|
219
260
|
### Multilingual Content
|
|
@@ -226,6 +267,7 @@ const koreanAudio = await client.textToSpeech({
|
|
|
226
267
|
model: "ssfm-v21",
|
|
227
268
|
language: "kor"
|
|
228
269
|
});
|
|
270
|
+
// Save: await fs.promises.writeFile(`korean.${koreanAudio.format}`, Buffer.from(koreanAudio.audioData));
|
|
229
271
|
|
|
230
272
|
// Japanese text
|
|
231
273
|
const japaneseAudio = await client.textToSpeech({
|
|
@@ -234,6 +276,7 @@ const japaneseAudio = await client.textToSpeech({
|
|
|
234
276
|
model: "ssfm-v21",
|
|
235
277
|
language: "jpn"
|
|
236
278
|
});
|
|
279
|
+
// Save: await fs.promises.writeFile(`japanese.${japaneseAudio.format}`, Buffer.from(japaneseAudio.audioData));
|
|
237
280
|
```
|
|
238
281
|
|
|
239
282
|
### Error Handling
|
|
@@ -241,31 +284,38 @@ const japaneseAudio = await client.textToSpeech({
|
|
|
241
284
|
```typescript
|
|
242
285
|
import { TypecastClient, TypecastAPIError } from '@neosapience/typecast-js';
|
|
243
286
|
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
287
|
+
async function main() {
|
|
288
|
+
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
const audio = await client.textToSpeech({
|
|
292
|
+
text: "Hello world",
|
|
293
|
+
voice_id: "tc_62a8975e695ad26f7fb514d1",
|
|
294
|
+
model: "ssfm-v21"
|
|
295
|
+
});
|
|
296
|
+
} catch (error) {
|
|
297
|
+
if (error instanceof TypecastAPIError) {
|
|
298
|
+
// TypecastAPIError exposes: statusCode (number), message (string), response (unknown)
|
|
299
|
+
switch (error.statusCode) {
|
|
300
|
+
case 401:
|
|
301
|
+
console.error('Invalid API key');
|
|
302
|
+
break;
|
|
303
|
+
case 402:
|
|
304
|
+
console.error('Insufficient credits');
|
|
305
|
+
break;
|
|
306
|
+
case 422:
|
|
307
|
+
console.error('Validation error:', error.response);
|
|
308
|
+
break;
|
|
309
|
+
default:
|
|
310
|
+
console.error(`API error (${error.statusCode}):`, error.message);
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
console.error('Unexpected error:', error);
|
|
264
314
|
}
|
|
265
|
-
} else {
|
|
266
|
-
console.error('Unexpected error:', error);
|
|
267
315
|
}
|
|
268
316
|
}
|
|
317
|
+
|
|
318
|
+
main();
|
|
269
319
|
```
|
|
270
320
|
|
|
271
321
|
## TypeScript Support
|
package/lib/index.d.cts
CHANGED
|
@@ -36,7 +36,7 @@ type LanguageCode = 'eng' | 'kor' | 'jpn' | 'spa' | 'deu' | 'fra' | 'ita' | 'pol
|
|
|
36
36
|
*/
|
|
37
37
|
interface Prompt {
|
|
38
38
|
/** Emotion preset for the voice (default: 'normal') */
|
|
39
|
-
emotion_preset?: 'happy' | 'sad' | 'normal' | 'angry';
|
|
39
|
+
emotion_preset?: 'happy' | 'sad' | 'normal' | 'angry' | 'tonemid' | 'toneup';
|
|
40
40
|
/**
|
|
41
41
|
* Emotion intensity
|
|
42
42
|
* @min 0.0
|
|
@@ -44,20 +44,6 @@ interface Prompt {
|
|
|
44
44
|
* @default 1.0
|
|
45
45
|
*/
|
|
46
46
|
emotion_intensity?: number;
|
|
47
|
-
/**
|
|
48
|
-
* Speech speed
|
|
49
|
-
* @min 0.5
|
|
50
|
-
* @max 2.0
|
|
51
|
-
* @default 1.0
|
|
52
|
-
*/
|
|
53
|
-
speed?: number;
|
|
54
|
-
/**
|
|
55
|
-
* Intonation adjustment
|
|
56
|
-
* @min -2
|
|
57
|
-
* @max 2
|
|
58
|
-
* @default 0
|
|
59
|
-
*/
|
|
60
|
-
intonation?: number;
|
|
61
47
|
}
|
|
62
48
|
/**
|
|
63
49
|
* Audio output settings for controlling the final audio characteristics
|
|
@@ -127,7 +113,7 @@ interface TTSResponse {
|
|
|
127
113
|
interface VoicesResponse {
|
|
128
114
|
voice_id: string;
|
|
129
115
|
voice_name: string;
|
|
130
|
-
model:
|
|
116
|
+
model: TTSModel;
|
|
131
117
|
emotions: string[];
|
|
132
118
|
}
|
|
133
119
|
|
package/lib/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ type LanguageCode = 'eng' | 'kor' | 'jpn' | 'spa' | 'deu' | 'fra' | 'ita' | 'pol
|
|
|
36
36
|
*/
|
|
37
37
|
interface Prompt {
|
|
38
38
|
/** Emotion preset for the voice (default: 'normal') */
|
|
39
|
-
emotion_preset?: 'happy' | 'sad' | 'normal' | 'angry';
|
|
39
|
+
emotion_preset?: 'happy' | 'sad' | 'normal' | 'angry' | 'tonemid' | 'toneup';
|
|
40
40
|
/**
|
|
41
41
|
* Emotion intensity
|
|
42
42
|
* @min 0.0
|
|
@@ -44,20 +44,6 @@ interface Prompt {
|
|
|
44
44
|
* @default 1.0
|
|
45
45
|
*/
|
|
46
46
|
emotion_intensity?: number;
|
|
47
|
-
/**
|
|
48
|
-
* Speech speed
|
|
49
|
-
* @min 0.5
|
|
50
|
-
* @max 2.0
|
|
51
|
-
* @default 1.0
|
|
52
|
-
*/
|
|
53
|
-
speed?: number;
|
|
54
|
-
/**
|
|
55
|
-
* Intonation adjustment
|
|
56
|
-
* @min -2
|
|
57
|
-
* @max 2
|
|
58
|
-
* @default 0
|
|
59
|
-
*/
|
|
60
|
-
intonation?: number;
|
|
61
47
|
}
|
|
62
48
|
/**
|
|
63
49
|
* Audio output settings for controlling the final audio characteristics
|
|
@@ -127,7 +113,7 @@ interface TTSResponse {
|
|
|
127
113
|
interface VoicesResponse {
|
|
128
114
|
voice_id: string;
|
|
129
115
|
voice_name: string;
|
|
130
|
-
model:
|
|
116
|
+
model: TTSModel;
|
|
131
117
|
emotions: string[];
|
|
132
118
|
}
|
|
133
119
|
|