@argo-video/cli 0.5.0 → 0.7.0
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 +38 -4
- package/dist/camera.d.ts +30 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +299 -0
- package/dist/camera.js.map +1 -0
- package/dist/chapters.d.ts +7 -0
- package/dist/chapters.d.ts.map +1 -0
- package/dist/chapters.js +22 -0
- package/dist/chapters.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/doctor.d.ts +9 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +119 -0
- package/dist/doctor.js.map +1 -0
- package/dist/export.d.ts +4 -0
- package/dist/export.d.ts.map +1 -1
- package/dist/export.js +51 -5
- package/dist/export.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline.d.ts +4 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +37 -3
- package/dist/pipeline.js.map +1 -1
- package/dist/record.d.ts +1 -0
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +1 -0
- package/dist/record.js.map +1 -1
- package/dist/report.d.ts +16 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +33 -0
- package/dist/report.js.map +1 -0
- package/dist/subtitles.d.ts +4 -0
- package/dist/subtitles.d.ts.map +1 -0
- package/dist/subtitles.js +34 -0
- package/dist/subtitles.js.map +1 -0
- package/dist/tts/cache.d.ts +1 -0
- package/dist/tts/cache.d.ts.map +1 -1
- package/dist/tts/cache.js +2 -2
- package/dist/tts/cache.js.map +1 -1
- package/dist/tts/engine.d.ts +5 -0
- package/dist/tts/engine.d.ts.map +1 -1
- package/dist/tts/engine.js +22 -0
- package/dist/tts/engine.js.map +1 -1
- package/dist/tts/engines/elevenlabs.d.ts +17 -0
- package/dist/tts/engines/elevenlabs.d.ts.map +1 -0
- package/dist/tts/engines/elevenlabs.js +52 -0
- package/dist/tts/engines/elevenlabs.js.map +1 -0
- package/dist/tts/engines/gemini.d.ts +13 -0
- package/dist/tts/engines/gemini.d.ts.map +1 -0
- package/dist/tts/engines/gemini.js +53 -0
- package/dist/tts/engines/gemini.js.map +1 -0
- package/dist/tts/engines/index.d.ts +28 -0
- package/dist/tts/engines/index.d.ts.map +1 -0
- package/dist/tts/engines/index.js +21 -0
- package/dist/tts/engines/index.js.map +1 -0
- package/dist/tts/engines/kokoro.d.ts +27 -0
- package/dist/tts/engines/kokoro.d.ts.map +1 -0
- package/dist/tts/engines/kokoro.js +76 -0
- package/dist/tts/engines/kokoro.js.map +1 -0
- package/dist/tts/engines/mlx-audio.d.ts +14 -0
- package/dist/tts/engines/mlx-audio.d.ts.map +1 -0
- package/dist/tts/engines/mlx-audio.js +40 -0
- package/dist/tts/engines/mlx-audio.js.map +1 -0
- package/dist/tts/engines/openai.d.ts +13 -0
- package/dist/tts/engines/openai.d.ts.map +1 -0
- package/dist/tts/engines/openai.js +50 -0
- package/dist/tts/engines/openai.js.map +1 -0
- package/dist/tts/engines/sarvam.d.ts +13 -0
- package/dist/tts/engines/sarvam.d.ts.map +1 -0
- package/dist/tts/engines/sarvam.js +51 -0
- package/dist/tts/engines/sarvam.js.map +1 -0
- package/dist/tts/generate.d.ts.map +1 -1
- package/dist/tts/generate.js +22 -16
- package/dist/tts/generate.js.map +1 -1
- package/dist/tts/kokoro.d.ts +1 -29
- package/dist/tts/kokoro.d.ts.map +1 -1
- package/dist/tts/kokoro.js +2 -72
- package/dist/tts/kokoro.js.map +1 -1
- package/package.json +1 -1
package/dist/tts/cache.js
CHANGED
|
@@ -41,10 +41,10 @@ export class ClipCache {
|
|
|
41
41
|
fs.writeFileSync(clipPath, wavBuffer);
|
|
42
42
|
}
|
|
43
43
|
computeHash(entry) {
|
|
44
|
-
const { scene, text, voice, speed } = entry;
|
|
44
|
+
const { scene, text, voice, speed, lang } = entry;
|
|
45
45
|
return crypto
|
|
46
46
|
.createHash('sha256')
|
|
47
|
-
.update(JSON.stringify({ scene, text, voice, speed }))
|
|
47
|
+
.update(JSON.stringify({ scene, text, voice, speed, lang }))
|
|
48
48
|
.digest('hex');
|
|
49
49
|
}
|
|
50
50
|
}
|
package/dist/tts/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/tts/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/tts/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,MAAM,OAAO,SAAS;IACH,WAAW,CAAS;IAErC,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,QAAgB,EAAE,KAAoB;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,QAAgB,EAAE,KAAoB;QAC7C,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,QAAgB,EAAE,KAAoB;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,QAAgB,EAAE,KAAoB,EAAE,SAAiB;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAEO,WAAW,CAAC,KAAoB;QACtC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QAClD,OAAO,MAAM;aACV,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;aAC3D,MAAM,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;CACF"}
|
package/dist/tts/engine.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ export interface WavHeader {
|
|
|
28
28
|
* assuming a fixed offset.
|
|
29
29
|
*/
|
|
30
30
|
export declare function parseWavHeader(wav: Buffer): WavHeader;
|
|
31
|
+
/**
|
|
32
|
+
* Convert arbitrary audio (MP3, OGG, PCM, etc.) to Argo's WAV format
|
|
33
|
+
* (mono, Float32, 24kHz) using ffmpeg.
|
|
34
|
+
*/
|
|
35
|
+
export declare function convertToWav(audioBuffer: Buffer): Buffer;
|
|
31
36
|
/**
|
|
32
37
|
* Creates a mock TTS engine that produces silent WAV buffers of the given
|
|
33
38
|
* duration and records all calls for test assertions.
|
package/dist/tts/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/tts/engine.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/tts/engine.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,SAAQ,GAAG,MAAM,CAoCjF;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA6DrD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAWxD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,SAAM,GACf,SAAS,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAA;CAAE,CAa3E"}
|
package/dist/tts/engine.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TTS Engine interface and WAV utilities for Argo.
|
|
3
3
|
*/
|
|
4
|
+
import * as childProcess from 'node:child_process';
|
|
4
5
|
/**
|
|
5
6
|
* Creates a valid WAV file buffer from Float32Array samples.
|
|
6
7
|
* Format: mono, 32-bit IEEE float, given sample rate.
|
|
@@ -75,6 +76,11 @@ export function parseWavHeader(wav) {
|
|
|
75
76
|
if (dataOffset === 0) {
|
|
76
77
|
throw new Error('No data chunk found in WAV file');
|
|
77
78
|
}
|
|
79
|
+
// When ffmpeg pipes WAV to stdout, it can't seek back to write the final
|
|
80
|
+
// data size, so it writes 0xFFFFFFFF. Use actual buffer length instead.
|
|
81
|
+
if (dataSize === 0xFFFFFFFF || dataSize > wav.length - dataOffset) {
|
|
82
|
+
dataSize = wav.length - dataOffset;
|
|
83
|
+
}
|
|
78
84
|
const bytesPerSample = bitsPerSample / 8;
|
|
79
85
|
const totalSamples = dataSize / (bytesPerSample * numChannels);
|
|
80
86
|
const durationMs = (totalSamples / sampleRate) * 1000;
|
|
@@ -88,6 +94,22 @@ export function parseWavHeader(wav) {
|
|
|
88
94
|
durationMs,
|
|
89
95
|
};
|
|
90
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Convert arbitrary audio (MP3, OGG, PCM, etc.) to Argo's WAV format
|
|
99
|
+
* (mono, Float32, 24kHz) using ffmpeg.
|
|
100
|
+
*/
|
|
101
|
+
export function convertToWav(audioBuffer) {
|
|
102
|
+
const { execFileSync } = childProcess;
|
|
103
|
+
const result = execFileSync('ffmpeg', [
|
|
104
|
+
'-i', 'pipe:0',
|
|
105
|
+
'-f', 'wav',
|
|
106
|
+
'-acodec', 'pcm_f32le',
|
|
107
|
+
'-ac', '1',
|
|
108
|
+
'-ar', '24000',
|
|
109
|
+
'pipe:1',
|
|
110
|
+
], { input: audioBuffer, stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: 50 * 1024 * 1024 });
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
91
113
|
/**
|
|
92
114
|
* Creates a mock TTS engine that produces silent WAV buffers of the given
|
|
93
115
|
* duration and records all calls for test assertions.
|
package/dist/tts/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/tts/engine.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/tts/engine.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAYnD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE,UAAU,GAAG,KAAK;IACvE,MAAM,WAAW,GAAG,CAAC,CAAC;IACtB,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,MAAM,cAAc,GAAG,aAAa,GAAG,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,WAAW,GAAG,cAAc,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,cAAc,CAAC;IACjD,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC;IAEhD,cAAc;IACd,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9B,GAAG,CAAC,aAAa,CAAC,UAAU,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAE9B,YAAY;IACZ,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAU,iBAAiB;IACrD,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAW,+BAA+B;IACnE,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClC,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChC,GAAG,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClC,GAAG,CAAC,aAAa,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAErC,aAAa;IACb,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEhC,cAAc;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,qDAAqD;IACrD,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAE3C,0BAA0B;IAC1B,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,eAAe;IAChC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE/C,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACvB,QAAQ,GAAG,SAAS,CAAC;YACrB,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC;YACxB,MAAM;QACR,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QAClE,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC;IACrC,CAAC;IAED,MAAM,cAAc,GAAG,aAAa,GAAG,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,QAAQ,GAAG,CAAC,cAAc,GAAG,WAAW,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IAEtD,OAAO;QACL,UAAU;QACV,WAAW;QACX,aAAa;QACb,WAAW;QACX,QAAQ;QACR,UAAU;QACV,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC;IACtC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE;QACpC,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,WAAW;QACtB,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,OAAO;QACd,QAAQ;KACT,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IACzF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAU,GAAG,GAAG;IAEhB,MAAM,KAAK,GAAuD,EAAE,CAAC;IAErE,OAAO;QACL,KAAK;QACL,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAyB;YACpD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9B,MAAM,UAAU,GAAG,KAAK,CAAC;YACzB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB;YAChE,OAAO,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface ElevenLabsEngineOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
stability?: number;
|
|
6
|
+
similarityBoost?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ElevenLabsEngine implements TTSEngine {
|
|
9
|
+
private apiKey;
|
|
10
|
+
private model;
|
|
11
|
+
private stability;
|
|
12
|
+
private similarityBoost;
|
|
13
|
+
constructor(options?: ElevenLabsEngineOptions);
|
|
14
|
+
private resolveApiKey;
|
|
15
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=elevenlabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevenlabs.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/elevenlabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,CAAC,EAAE,uBAAuB;IAO7C,OAAO,CAAC,aAAa;IAWf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAqCzE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export class ElevenLabsEngine {
|
|
2
|
+
apiKey;
|
|
3
|
+
model;
|
|
4
|
+
stability;
|
|
5
|
+
similarityBoost;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.apiKey = options?.apiKey ?? '';
|
|
8
|
+
this.model = options?.model ?? 'eleven_monolingual_v1';
|
|
9
|
+
this.stability = options?.stability ?? 0.5;
|
|
10
|
+
this.similarityBoost = options?.similarityBoost ?? 0.75;
|
|
11
|
+
}
|
|
12
|
+
resolveApiKey() {
|
|
13
|
+
const key = this.apiKey || process.env.ELEVENLABS_API_KEY || '';
|
|
14
|
+
if (!key) {
|
|
15
|
+
throw new Error('ElevenLabs TTS engine requires an API key. ' +
|
|
16
|
+
'Set ELEVENLABS_API_KEY environment variable or pass apiKey option.');
|
|
17
|
+
}
|
|
18
|
+
return key;
|
|
19
|
+
}
|
|
20
|
+
async generate(text, options) {
|
|
21
|
+
if (!text?.trim())
|
|
22
|
+
throw new Error('TTS text must not be empty');
|
|
23
|
+
let ElevenLabsClient;
|
|
24
|
+
try {
|
|
25
|
+
// @ts-ignore — elevenlabs is an optional dependency
|
|
26
|
+
({ ElevenLabsClient } = await import('elevenlabs'));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error("ElevenLabs TTS engine requires the 'elevenlabs' package. Install it with: npm i elevenlabs");
|
|
30
|
+
}
|
|
31
|
+
const client = new ElevenLabsClient({ apiKey: this.resolveApiKey() });
|
|
32
|
+
const audioStream = await client.textToSpeech.convert(options.voice ?? '21m00Tcm4TlvDq8ikWAM', // Rachel default
|
|
33
|
+
{
|
|
34
|
+
text,
|
|
35
|
+
model_id: this.model,
|
|
36
|
+
voice_settings: {
|
|
37
|
+
stability: this.stability,
|
|
38
|
+
similarity_boost: this.similarityBoost,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// Collect stream into buffer
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for await (const chunk of audioStream) {
|
|
44
|
+
chunks.push(Buffer.from(chunk));
|
|
45
|
+
}
|
|
46
|
+
const mp3Buffer = Buffer.concat(chunks);
|
|
47
|
+
// Convert MP3 to Argo WAV format
|
|
48
|
+
const { convertToWav } = await import('../engine.js');
|
|
49
|
+
return convertToWav(mp3Buffer);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=elevenlabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevenlabs.js","sourceRoot":"","sources":["../../../src/tts/engines/elevenlabs.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,eAAe,CAAS;IAEhC,YAAY,OAAiC;QAC3C,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,uBAAuB,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,IAAI,CAAC;IAC1D,CAAC;IAEO,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC;QAChE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,6CAA6C;gBAC7C,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAyB;QACpD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,IAAI,gBAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,oDAAoD;YACpD,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,CACnD,OAAO,CAAC,KAAK,IAAI,sBAAsB,EAAE,iBAAiB;QAC1D;YACE,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,KAAK;YACpB,cAAc,EAAE;gBACd,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,gBAAgB,EAAE,IAAI,CAAC,eAAe;aACvC;SACF,CACF,CAAC;QAEF,6BAA6B;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAExC,iCAAiC;QACjC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACtD,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface GeminiEngineOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class GeminiEngine implements TTSEngine {
|
|
7
|
+
private apiKey;
|
|
8
|
+
private model;
|
|
9
|
+
constructor(options?: GeminiEngineOptions);
|
|
10
|
+
private resolveApiKey;
|
|
11
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,CAAC,EAAE,mBAAmB;IAKzC,OAAO,CAAC,aAAa;IAWf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CA4CzE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export class GeminiEngine {
|
|
2
|
+
apiKey;
|
|
3
|
+
model;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.apiKey = options?.apiKey ?? '';
|
|
6
|
+
this.model = options?.model ?? 'gemini-2.5-flash';
|
|
7
|
+
}
|
|
8
|
+
resolveApiKey() {
|
|
9
|
+
const key = this.apiKey || process.env.GEMINI_API_KEY || '';
|
|
10
|
+
if (!key) {
|
|
11
|
+
throw new Error('Gemini TTS engine requires an API key. ' +
|
|
12
|
+
'Set GEMINI_API_KEY environment variable or pass apiKey option.');
|
|
13
|
+
}
|
|
14
|
+
return key;
|
|
15
|
+
}
|
|
16
|
+
async generate(text, options) {
|
|
17
|
+
if (!text?.trim())
|
|
18
|
+
throw new Error('TTS text must not be empty');
|
|
19
|
+
let GoogleGenAI;
|
|
20
|
+
try {
|
|
21
|
+
// @ts-ignore — @google/genai is an optional dependency
|
|
22
|
+
({ GoogleGenAI } = await import('@google/genai'));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error("Gemini TTS engine requires the '@google/genai' package. Install it with: npm i @google/genai");
|
|
26
|
+
}
|
|
27
|
+
const ai = new GoogleGenAI({ apiKey: this.resolveApiKey() });
|
|
28
|
+
const response = await ai.models.generateContent({
|
|
29
|
+
model: this.model,
|
|
30
|
+
contents: [{ role: 'user', parts: [{ text: `Please read the following text aloud: ${text}` }] }],
|
|
31
|
+
config: {
|
|
32
|
+
responseModalities: ['AUDIO'],
|
|
33
|
+
speechConfig: {
|
|
34
|
+
voiceConfig: {
|
|
35
|
+
prebuiltVoiceConfig: {
|
|
36
|
+
voiceName: options.voice ?? 'Kore',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
// Gemini returns inline audio data as base64
|
|
43
|
+
const audioPart = response.candidates?.[0]?.content?.parts?.find((p) => p.inlineData?.mimeType?.startsWith('audio/'));
|
|
44
|
+
if (!audioPart?.inlineData?.data) {
|
|
45
|
+
throw new Error('Gemini did not return audio data. Check model and voice configuration.');
|
|
46
|
+
}
|
|
47
|
+
const audioBuffer = Buffer.from(audioPart.inlineData.data, 'base64');
|
|
48
|
+
// Convert to Argo WAV format
|
|
49
|
+
const { convertToWav } = await import('../engine.js');
|
|
50
|
+
return convertToWav(audioBuffer);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/tts/engines/gemini.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,YAAY;IACf,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,OAA6B;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,kBAAkB,CAAC;IACpD,CAAC;IAEO,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;QAC5D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,yCAAyC;gBACzC,gEAAgE,CACjE,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAyB;QACpD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,IAAI,WAAgB,CAAC;QACrB,IAAI,CAAC;YACH,uDAAuD;YACvD,CAAC,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,yCAAyC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;YAChG,MAAM,EAAE;gBACN,kBAAkB,EAAE,CAAC,OAAO,CAAC;gBAC7B,YAAY,EAAE;oBACZ,WAAW,EAAE;wBACX,mBAAmB,EAAE;4BACnB,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;yBACnC;qBACF;iBACF;aACF;SACF,CAAC,CAAC;QAEH,6CAA6C;QAC7C,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAC9D,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CACzD,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAErE,6BAA6B;QAC7B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACtD,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TTSEngine } from '../engine.js';
|
|
2
|
+
import { type KokoroEngineOptions } from './kokoro.js';
|
|
3
|
+
import { type OpenAIEngineOptions } from './openai.js';
|
|
4
|
+
import { type ElevenLabsEngineOptions } from './elevenlabs.js';
|
|
5
|
+
import { type GeminiEngineOptions } from './gemini.js';
|
|
6
|
+
import { type SarvamEngineOptions } from './sarvam.js';
|
|
7
|
+
import { type MlxAudioEngineOptions } from './mlx-audio.js';
|
|
8
|
+
export declare const engines: {
|
|
9
|
+
kokoro: (opts?: KokoroEngineOptions) => TTSEngine;
|
|
10
|
+
openai: (opts?: OpenAIEngineOptions) => TTSEngine;
|
|
11
|
+
elevenlabs: (opts?: ElevenLabsEngineOptions) => TTSEngine;
|
|
12
|
+
gemini: (opts?: GeminiEngineOptions) => TTSEngine;
|
|
13
|
+
sarvam: (opts?: SarvamEngineOptions) => TTSEngine;
|
|
14
|
+
mlxAudio: (opts?: MlxAudioEngineOptions) => TTSEngine;
|
|
15
|
+
};
|
|
16
|
+
export type { KokoroEngineOptions } from './kokoro.js';
|
|
17
|
+
export type { OpenAIEngineOptions } from './openai.js';
|
|
18
|
+
export type { ElevenLabsEngineOptions } from './elevenlabs.js';
|
|
19
|
+
export type { GeminiEngineOptions } from './gemini.js';
|
|
20
|
+
export type { SarvamEngineOptions } from './sarvam.js';
|
|
21
|
+
export type { MlxAudioEngineOptions } from './mlx-audio.js';
|
|
22
|
+
export { KokoroEngine } from './kokoro.js';
|
|
23
|
+
export { OpenAIEngine } from './openai.js';
|
|
24
|
+
export { ElevenLabsEngine } from './elevenlabs.js';
|
|
25
|
+
export { GeminiEngine } from './gemini.js';
|
|
26
|
+
export { SarvamEngine } from './sarvam.js';
|
|
27
|
+
export { MlxAudioEngine } from './mlx-audio.js';
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,eAAO,MAAM,OAAO;oBACF,mBAAmB,KAAG,SAAS;oBAC/B,mBAAmB,KAAG,SAAS;wBAC3B,uBAAuB,KAAG,SAAS;oBACvC,mBAAmB,KAAG,SAAS;oBAC/B,mBAAmB,KAAG,SAAS;sBAC7B,qBAAqB,KAAG,SAAS;CACpD,CAAC;AAEF,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { KokoroEngine } from './kokoro.js';
|
|
2
|
+
import { OpenAIEngine } from './openai.js';
|
|
3
|
+
import { ElevenLabsEngine } from './elevenlabs.js';
|
|
4
|
+
import { GeminiEngine } from './gemini.js';
|
|
5
|
+
import { SarvamEngine } from './sarvam.js';
|
|
6
|
+
import { MlxAudioEngine } from './mlx-audio.js';
|
|
7
|
+
export const engines = {
|
|
8
|
+
kokoro: (opts) => new KokoroEngine(opts),
|
|
9
|
+
openai: (opts) => new OpenAIEngine(opts),
|
|
10
|
+
elevenlabs: (opts) => new ElevenLabsEngine(opts),
|
|
11
|
+
gemini: (opts) => new GeminiEngine(opts),
|
|
12
|
+
sarvam: (opts) => new SarvamEngine(opts),
|
|
13
|
+
mlxAudio: (opts) => new MlxAudioEngine(opts),
|
|
14
|
+
};
|
|
15
|
+
export { KokoroEngine } from './kokoro.js';
|
|
16
|
+
export { OpenAIEngine } from './openai.js';
|
|
17
|
+
export { ElevenLabsEngine } from './elevenlabs.js';
|
|
18
|
+
export { GeminiEngine } from './gemini.js';
|
|
19
|
+
export { SarvamEngine } from './sarvam.js';
|
|
20
|
+
export { MlxAudioEngine } from './mlx-audio.js';
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tts/engines/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAgC,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAC;AAE5E,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,MAAM,EAAE,CAAC,IAA0B,EAAa,EAAE,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;IACzE,MAAM,EAAE,CAAC,IAA0B,EAAa,EAAE,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;IACzE,UAAU,EAAE,CAAC,IAA8B,EAAa,EAAE,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC;IACrF,MAAM,EAAE,CAAC,IAA0B,EAAa,EAAE,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;IACzE,MAAM,EAAE,CAAC,IAA0B,EAAa,EAAE,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;IACzE,QAAQ,EAAE,CAAC,IAA4B,EAAa,EAAE,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC;CAChF,CAAC;AASF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface KokoroEngineOptions {
|
|
3
|
+
modelId?: string;
|
|
4
|
+
dtype?: 'fp32' | 'fp16' | 'q8' | 'q4' | 'q4f16';
|
|
5
|
+
device?: 'wasm' | 'webgpu' | 'cpu' | null;
|
|
6
|
+
onProgress?: (progress: {
|
|
7
|
+
status: string;
|
|
8
|
+
progress?: number;
|
|
9
|
+
file?: string;
|
|
10
|
+
}) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare class KokoroEngine implements TTSEngine {
|
|
13
|
+
private tts;
|
|
14
|
+
private initPromise;
|
|
15
|
+
private modelId;
|
|
16
|
+
private dtype;
|
|
17
|
+
private device;
|
|
18
|
+
private onProgress?;
|
|
19
|
+
constructor(options?: KokoroEngineOptions);
|
|
20
|
+
private getTTS;
|
|
21
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
22
|
+
stream(text: string, options: TTSEngineOptions): AsyncGenerator<{
|
|
23
|
+
text: string;
|
|
24
|
+
audio: Buffer;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=kokoro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kokoro.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/kokoro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACvF;AAED,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,UAAU,CAAC,CAAoC;gBAE3C,OAAO,CAAC,EAAE,mBAAmB;YAO3B,MAAM;IAyBd,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBjE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,cAAc,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAaxG"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export class KokoroEngine {
|
|
2
|
+
tts = null;
|
|
3
|
+
initPromise = null;
|
|
4
|
+
modelId;
|
|
5
|
+
dtype;
|
|
6
|
+
device;
|
|
7
|
+
onProgress;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.modelId = options?.modelId ?? 'onnx-community/Kokoro-82M-v1.0-ONNX';
|
|
10
|
+
this.dtype = options?.dtype ?? 'q8';
|
|
11
|
+
this.device = options?.device ?? null;
|
|
12
|
+
this.onProgress = options?.onProgress;
|
|
13
|
+
}
|
|
14
|
+
async getTTS() {
|
|
15
|
+
if (this.tts)
|
|
16
|
+
return this.tts;
|
|
17
|
+
if (!this.initPromise) {
|
|
18
|
+
this.initPromise = (async () => {
|
|
19
|
+
try {
|
|
20
|
+
const { KokoroTTS } = await import('kokoro-js');
|
|
21
|
+
this.tts = await KokoroTTS.from_pretrained(this.modelId, {
|
|
22
|
+
dtype: this.dtype,
|
|
23
|
+
device: this.device,
|
|
24
|
+
progress_callback: this.onProgress ?? undefined,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
this.initPromise = null;
|
|
29
|
+
throw new Error(`Failed to initialize Kokoro TTS (model: ${this.modelId}, dtype: ${this.dtype}). ` +
|
|
30
|
+
`This may require an internet connection for first-time model download. ` +
|
|
31
|
+
`Original error: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
return this.tts;
|
|
34
|
+
})();
|
|
35
|
+
}
|
|
36
|
+
return this.initPromise;
|
|
37
|
+
}
|
|
38
|
+
async generate(text, options) {
|
|
39
|
+
if (!text?.trim())
|
|
40
|
+
throw new Error('TTS text must not be empty');
|
|
41
|
+
const tts = await this.getTTS();
|
|
42
|
+
let audio;
|
|
43
|
+
try {
|
|
44
|
+
audio = await tts.generate(text, {
|
|
45
|
+
voice: options.voice ?? 'af_heart',
|
|
46
|
+
speed: options.speed ?? 1.0,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
throw new Error(`Kokoro TTS failed to generate audio for text "${text.substring(0, 80)}..." ` +
|
|
51
|
+
`(voice: ${options.voice ?? 'af_heart'}). Original error: ${err.message}`);
|
|
52
|
+
}
|
|
53
|
+
const samples = audio.data ?? audio.audio;
|
|
54
|
+
if (!samples || !(samples instanceof Float32Array)) {
|
|
55
|
+
throw new Error('kokoro-js returned unexpected audio format. Check kokoro-js version.');
|
|
56
|
+
}
|
|
57
|
+
const sampleRate = audio.sampling_rate;
|
|
58
|
+
const { createWavBuffer } = await import('../engine.js');
|
|
59
|
+
return createWavBuffer(samples, sampleRate);
|
|
60
|
+
}
|
|
61
|
+
async *stream(text, options) {
|
|
62
|
+
if (!text?.trim())
|
|
63
|
+
throw new Error('TTS text must not be empty');
|
|
64
|
+
const tts = await this.getTTS();
|
|
65
|
+
const { createWavBuffer } = await import('../engine.js');
|
|
66
|
+
for await (const chunk of tts.stream(text, {
|
|
67
|
+
voice: options.voice ?? 'af_heart',
|
|
68
|
+
speed: options.speed ?? 1.0,
|
|
69
|
+
})) {
|
|
70
|
+
const samples = chunk.audio.data ?? chunk.audio.audio;
|
|
71
|
+
const sampleRate = chunk.audio.sampling_rate;
|
|
72
|
+
yield { text: chunk.text, audio: createWavBuffer(samples, sampleRate) };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=kokoro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kokoro.js","sourceRoot":"","sources":["../../../src/tts/engines/kokoro.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface MlxAudioEngineOptions {
|
|
3
|
+
/** mlx-audio server URL. Default: http://localhost:8000 */
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
/** Model ID passed to the server. Default: mlx-community/Spark-TTS-0.5B-bf16 */
|
|
6
|
+
model?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class MlxAudioEngine implements TTSEngine {
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private model;
|
|
11
|
+
constructor(options?: MlxAudioEngineOptions);
|
|
12
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=mlx-audio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mlx-audio.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/mlx-audio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,CAAC,EAAE,qBAAqB;IAKrC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoCzE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class MlxAudioEngine {
|
|
2
|
+
baseUrl;
|
|
3
|
+
model;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.baseUrl = options?.baseUrl ?? 'http://localhost:8000';
|
|
6
|
+
this.model = options?.model ?? 'mlx-community/Spark-TTS-0.5B-bf16';
|
|
7
|
+
}
|
|
8
|
+
async generate(text, options) {
|
|
9
|
+
if (!text?.trim())
|
|
10
|
+
throw new Error('TTS text must not be empty');
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timeout = setTimeout(() => controller.abort(), 180_000);
|
|
13
|
+
let response;
|
|
14
|
+
try {
|
|
15
|
+
response = await fetch(`${this.baseUrl}/v1/audio/speech`, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
headers: { 'Content-Type': 'application/json' },
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
model: this.model,
|
|
20
|
+
input: text,
|
|
21
|
+
voice: options.voice ?? 'af_heart',
|
|
22
|
+
}),
|
|
23
|
+
signal: controller.signal,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
clearTimeout(timeout);
|
|
28
|
+
}
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
const body = await response.text();
|
|
31
|
+
throw new Error(`mlx-audio server error ${response.status}: ${body}. ` +
|
|
32
|
+
`Ensure the server is running: python3 -m mlx_audio.server --model ${this.model}`);
|
|
33
|
+
}
|
|
34
|
+
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
35
|
+
// Convert to Argo WAV format (mono Float32 24kHz)
|
|
36
|
+
const { convertToWav } = await import('../engine.js');
|
|
37
|
+
return convertToWav(audioBuffer);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=mlx-audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mlx-audio.js","sourceRoot":"","sources":["../../../src/tts/engines/mlx-audio.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,cAAc;IACjB,OAAO,CAAS;IAChB,KAAK,CAAS;IAEtB,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,uBAAuB,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,mCAAmC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAyB;QACpD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAE9D,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,UAAU;iBACnC,CAAC;gBACF,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,CAAC,MAAM,KAAK,IAAI,IAAI;gBACtD,qEAAqE,IAAI,CAAC,KAAK,EAAE,CAClF,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QAE9D,kDAAkD;QAClD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACtD,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface OpenAIEngineOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: 'tts-1' | 'tts-1-hd';
|
|
5
|
+
}
|
|
6
|
+
export declare class OpenAIEngine implements TTSEngine {
|
|
7
|
+
private apiKey;
|
|
8
|
+
private model;
|
|
9
|
+
constructor(options?: OpenAIEngineOptions);
|
|
10
|
+
private resolveApiKey;
|
|
11
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC9B;AAED,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,CAAC,EAAE,mBAAmB;IAKzC,OAAO,CAAC,aAAa;IAWf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAuCzE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export class OpenAIEngine {
|
|
2
|
+
apiKey;
|
|
3
|
+
model;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.apiKey = options?.apiKey ?? '';
|
|
6
|
+
this.model = options?.model ?? 'tts-1';
|
|
7
|
+
}
|
|
8
|
+
resolveApiKey() {
|
|
9
|
+
const key = this.apiKey || process.env.OPENAI_API_KEY || '';
|
|
10
|
+
if (!key) {
|
|
11
|
+
throw new Error('OpenAI TTS engine requires an API key. ' +
|
|
12
|
+
'Set OPENAI_API_KEY environment variable or pass apiKey option.');
|
|
13
|
+
}
|
|
14
|
+
return key;
|
|
15
|
+
}
|
|
16
|
+
async generate(text, options) {
|
|
17
|
+
if (!text?.trim())
|
|
18
|
+
throw new Error('TTS text must not be empty');
|
|
19
|
+
let OpenAI;
|
|
20
|
+
try {
|
|
21
|
+
// @ts-ignore — openai is an optional dependency
|
|
22
|
+
({ OpenAI } = await import('openai'));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error("OpenAI TTS engine requires the 'openai' package. Install it with: npm i openai");
|
|
26
|
+
}
|
|
27
|
+
const client = new OpenAI({ apiKey: this.resolveApiKey() });
|
|
28
|
+
// Request raw PCM so we can build an exact WAV without ffmpeg pipe artifacts
|
|
29
|
+
const response = await client.audio.speech.create({
|
|
30
|
+
model: this.model,
|
|
31
|
+
voice: options.voice ?? 'alloy',
|
|
32
|
+
input: text,
|
|
33
|
+
speed: options.speed ?? 1.0,
|
|
34
|
+
response_format: 'pcm',
|
|
35
|
+
});
|
|
36
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
37
|
+
const pcmBuffer = Buffer.from(arrayBuffer);
|
|
38
|
+
// OpenAI PCM format: 24kHz, 16-bit signed LE, mono
|
|
39
|
+
// Convert 16-bit PCM samples to Float32 and build WAV directly
|
|
40
|
+
const sampleRate = 24000;
|
|
41
|
+
const sampleCount = pcmBuffer.length / 2;
|
|
42
|
+
const samples = new Float32Array(sampleCount);
|
|
43
|
+
for (let i = 0; i < sampleCount; i++) {
|
|
44
|
+
samples[i] = pcmBuffer.readInt16LE(i * 2) / 32768;
|
|
45
|
+
}
|
|
46
|
+
const { createWavBuffer } = await import('../engine.js');
|
|
47
|
+
return createWavBuffer(samples, sampleRate);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/tts/engines/openai.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,YAAY;IACf,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,OAA6B;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC;IACzC,CAAC;IAEO,aAAa;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;QAC5D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,yCAAyC;gBACzC,gEAAgE,CACjE,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,OAAyB;QACpD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAEjE,IAAI,MAAW,CAAC;QAChB,IAAI,CAAC;YACH,gDAAgD;YAChD,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAE5D,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;YAChD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO;YAC/B,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG;YAC3B,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE3C,mDAAmD;QACnD,+DAA+D;QAC/D,MAAM,UAAU,GAAG,KAAK,CAAC;QACzB,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QACpD,CAAC;QAED,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACzD,OAAO,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TTSEngine, TTSEngineOptions } from '../engine.js';
|
|
2
|
+
export interface SarvamEngineOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class SarvamEngine implements TTSEngine {
|
|
7
|
+
private apiKey;
|
|
8
|
+
private model;
|
|
9
|
+
constructor(options?: SarvamEngineOptions);
|
|
10
|
+
private resolveApiKey;
|
|
11
|
+
generate(text: string, options: TTSEngineOptions): Promise<Buffer>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=sarvam.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarvam.d.ts","sourceRoot":"","sources":["../../../src/tts/engines/sarvam.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,CAAC,EAAE,mBAAmB;IAKzC,OAAO,CAAC,aAAa;IAWf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAsCzE"}
|