@cartesia/cartesia-js 0.0.4-alpha.0 → 1.0.0-alpha.2
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/.turbo/turbo-build.log +63 -45
- package/CHANGELOG.md +12 -0
- package/README.md +123 -16
- package/dist/chunk-36JBKJUN.js +119 -0
- package/dist/chunk-3F5E46FT.js +212 -0
- package/dist/{chunk-XPIMIAAE.js → chunk-3FL2SNIR.js} +1 -1
- package/dist/chunk-JGP5BIUV.js +34 -0
- package/dist/chunk-KWBSQZTY.js +25 -0
- package/dist/chunk-PQ6CIPFW.js +120 -0
- package/dist/chunk-RO7TY474.js +81 -0
- package/dist/chunk-T3RG6WV4.js +22 -0
- package/dist/{chunk-R4P7LWVZ.js → chunk-WIFMLPT5.js} +31 -6
- package/dist/chunk-WVTITUXX.js +58 -0
- package/dist/chunk-XHTDPLFR.js +19 -0
- package/dist/index.cjs +425 -166
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +13 -6
- package/dist/lib/client.cjs +49 -1
- package/dist/lib/client.d.cts +2 -0
- package/dist/lib/client.d.ts +2 -0
- package/dist/lib/client.js +3 -3
- package/dist/lib/constants.cjs +15 -8
- package/dist/lib/constants.d.cts +4 -4
- package/dist/lib/constants.d.ts +4 -4
- package/dist/lib/constants.js +6 -6
- package/dist/lib/index.cjs +310 -171
- package/dist/lib/index.d.cts +6 -2
- package/dist/lib/index.d.ts +6 -2
- package/dist/lib/index.js +9 -6
- package/dist/react/index.cjs +573 -290
- package/dist/react/index.d.cts +20 -14
- package/dist/react/index.d.ts +20 -14
- package/dist/react/index.js +157 -105
- package/dist/react/utils.js +2 -2
- package/dist/tts/index.cjs +496 -0
- package/dist/tts/index.d.cts +17 -0
- package/dist/tts/index.d.ts +17 -0
- package/dist/tts/index.js +12 -0
- package/dist/tts/player.cjs +198 -0
- package/dist/tts/player.d.cts +43 -0
- package/dist/tts/player.d.ts +43 -0
- package/dist/tts/player.js +8 -0
- package/dist/tts/source.cjs +181 -0
- package/dist/tts/source.d.cts +53 -0
- package/dist/tts/source.d.ts +53 -0
- package/dist/tts/source.js +7 -0
- package/dist/{audio → tts}/utils.cjs +25 -60
- package/dist/tts/utils.d.cts +67 -0
- package/dist/tts/utils.d.ts +67 -0
- package/dist/{audio → tts}/utils.js +2 -7
- package/dist/tts/websocket.cjs +479 -0
- package/dist/tts/websocket.d.cts +53 -0
- package/dist/tts/websocket.d.ts +53 -0
- package/dist/tts/websocket.js +11 -0
- package/dist/types/index.d.cts +50 -1
- package/dist/types/index.d.ts +50 -1
- package/dist/voices/index.cjs +157 -0
- package/dist/voices/index.d.cts +12 -0
- package/dist/voices/index.d.ts +12 -0
- package/dist/voices/index.js +9 -0
- package/package.json +2 -1
- package/src/index.ts +1 -0
- package/src/lib/client.ts +15 -1
- package/src/lib/constants.ts +15 -4
- package/src/lib/index.ts +6 -3
- package/src/react/index.ts +176 -110
- package/src/tts/index.ts +17 -0
- package/src/tts/player.ts +110 -0
- package/src/tts/source.ts +115 -0
- package/src/tts/utils.ts +150 -0
- package/src/tts/websocket.ts +214 -0
- package/src/types/index.ts +63 -0
- package/src/voices/index.ts +47 -0
- package/dist/audio/index.cjs +0 -404
- package/dist/audio/index.d.cts +0 -5
- package/dist/audio/index.d.ts +0 -5
- package/dist/audio/index.js +0 -10
- package/dist/audio/utils.d.cts +0 -5
- package/dist/audio/utils.d.ts +0 -5
- package/dist/chunk-4MHF74A7.js +0 -272
- package/dist/chunk-5TSWLYOW.js +0 -113
- package/dist/chunk-MJIFZWHS.js +0 -18
- package/dist/chunk-OVI3W3GG.js +0 -12
- package/dist/chunk-S6A27RQL.js +0 -18
- package/dist/index-C2_3XFxn.d.cts +0 -163
- package/dist/index-DgwnZezj.d.ts +0 -163
- package/src/audio/index.ts +0 -297
- package/src/audio/utils.ts +0 -220
package/dist/lib/index.cjs
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
8
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
9
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
10
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
11
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
-
var __knownSymbol = (name, symbol) => {
|
|
11
|
-
return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
12
|
-
};
|
|
13
12
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
13
|
var __spreadValues = (a, b) => {
|
|
15
14
|
for (var prop in b || (b = {}))
|
|
@@ -22,6 +21,7 @@ var __spreadValues = (a, b) => {
|
|
|
22
21
|
}
|
|
23
22
|
return a;
|
|
24
23
|
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
25
|
var __export = (target, all) => {
|
|
26
26
|
for (var name in all)
|
|
27
27
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -43,6 +43,28 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
43
43
|
mod
|
|
44
44
|
));
|
|
45
45
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
46
|
+
var __accessCheck = (obj, member, msg) => {
|
|
47
|
+
if (!member.has(obj))
|
|
48
|
+
throw TypeError("Cannot " + msg);
|
|
49
|
+
};
|
|
50
|
+
var __privateGet = (obj, member, getter) => {
|
|
51
|
+
__accessCheck(obj, member, "read from private field");
|
|
52
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
53
|
+
};
|
|
54
|
+
var __privateAdd = (obj, member, value) => {
|
|
55
|
+
if (member.has(obj))
|
|
56
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
57
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
58
|
+
};
|
|
59
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
60
|
+
__accessCheck(obj, member, "write to private field");
|
|
61
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
62
|
+
return value;
|
|
63
|
+
};
|
|
64
|
+
var __privateMethod = (obj, member, method) => {
|
|
65
|
+
__accessCheck(obj, member, "access private method");
|
|
66
|
+
return method;
|
|
67
|
+
};
|
|
46
68
|
var __async = (__this, __arguments, generator) => {
|
|
47
69
|
return new Promise((resolve, reject) => {
|
|
48
70
|
var fulfilled = (value) => {
|
|
@@ -63,7 +85,6 @@ var __async = (__this, __arguments, generator) => {
|
|
|
63
85
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
64
86
|
});
|
|
65
87
|
};
|
|
66
|
-
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
67
88
|
|
|
68
89
|
// src/lib/index.ts
|
|
69
90
|
var lib_exports = {};
|
|
@@ -72,16 +93,21 @@ __export(lib_exports, {
|
|
|
72
93
|
});
|
|
73
94
|
module.exports = __toCommonJS(lib_exports);
|
|
74
95
|
|
|
75
|
-
// src/
|
|
76
|
-
var
|
|
77
|
-
var import_human_id = require("human-id");
|
|
78
|
-
var import_partysocket = require("partysocket");
|
|
96
|
+
// src/lib/client.ts
|
|
97
|
+
var import_cross_fetch = __toESM(require("cross-fetch"), 1);
|
|
79
98
|
|
|
80
99
|
// src/lib/constants.ts
|
|
81
|
-
var BASE_URL = "https://api.cartesia.ai/
|
|
82
|
-
var
|
|
83
|
-
var
|
|
84
|
-
|
|
100
|
+
var BASE_URL = "https://api.cartesia.ai/";
|
|
101
|
+
var CARTESIA_VERSION = "2024-06-10";
|
|
102
|
+
var constructApiUrl = (baseUrl, path, protocol) => {
|
|
103
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
104
|
+
if (!protocol) {
|
|
105
|
+
return new URL(`${baseUrl}${normalizedPath}`);
|
|
106
|
+
}
|
|
107
|
+
if (!["http", "ws"].includes(protocol)) {
|
|
108
|
+
throw new Error(`Invalid protocol: ${protocol}`);
|
|
109
|
+
}
|
|
110
|
+
return new URL(`${baseUrl.replace(/^http/, protocol)}${normalizedPath}`);
|
|
85
111
|
};
|
|
86
112
|
|
|
87
113
|
// src/lib/client.ts
|
|
@@ -93,37 +119,154 @@ var Client = class {
|
|
|
93
119
|
this.apiKey = options.apiKey || process.env.CARTESIA_API_KEY;
|
|
94
120
|
this.baseUrl = options.baseUrl || BASE_URL;
|
|
95
121
|
}
|
|
122
|
+
fetch(path, options = {}) {
|
|
123
|
+
const url = constructApiUrl(this.baseUrl, path);
|
|
124
|
+
return (0, import_cross_fetch.default)(url.toString(), __spreadProps(__spreadValues({}, options), {
|
|
125
|
+
headers: __spreadValues({
|
|
126
|
+
"X-API-Key": this.apiKey,
|
|
127
|
+
"Cartesia-Version": CARTESIA_VERSION
|
|
128
|
+
}, options.headers)
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
96
131
|
};
|
|
97
132
|
|
|
98
|
-
// src/
|
|
133
|
+
// src/tts/websocket.ts
|
|
134
|
+
var import_emittery2 = __toESM(require("emittery"), 1);
|
|
135
|
+
var import_human_id = require("human-id");
|
|
136
|
+
var import_partysocket = require("partysocket");
|
|
137
|
+
|
|
138
|
+
// src/tts/source.ts
|
|
139
|
+
var import_emittery = __toESM(require("emittery"), 1);
|
|
140
|
+
var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate;
|
|
141
|
+
var Source = class {
|
|
142
|
+
/**
|
|
143
|
+
* Create a new Source.
|
|
144
|
+
*
|
|
145
|
+
* @param options - Options for the Source.
|
|
146
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
147
|
+
*/
|
|
148
|
+
constructor({ sampleRate }) {
|
|
149
|
+
__privateAdd(this, _emitter, new import_emittery.default());
|
|
150
|
+
__privateAdd(this, _buffer, void 0);
|
|
151
|
+
__privateAdd(this, _readIndex, 0);
|
|
152
|
+
__privateAdd(this, _writeIndex, 0);
|
|
153
|
+
__privateAdd(this, _closed, false);
|
|
154
|
+
__privateAdd(this, _sampleRate, void 0);
|
|
155
|
+
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
156
|
+
this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
|
|
157
|
+
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
158
|
+
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
159
|
+
__privateSet(this, _sampleRate, sampleRate);
|
|
160
|
+
__privateSet(this, _buffer, new Float32Array(1024));
|
|
161
|
+
}
|
|
162
|
+
get sampleRate() {
|
|
163
|
+
return __privateGet(this, _sampleRate);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Append audio to the buffer.
|
|
167
|
+
*
|
|
168
|
+
* @param src The audio to append.
|
|
169
|
+
*/
|
|
170
|
+
enqueue(src) {
|
|
171
|
+
return __async(this, null, function* () {
|
|
172
|
+
const requiredCapacity = __privateGet(this, _writeIndex) + src.length;
|
|
173
|
+
if (requiredCapacity > __privateGet(this, _buffer).length) {
|
|
174
|
+
let newCapacity = __privateGet(this, _buffer).length;
|
|
175
|
+
while (newCapacity < requiredCapacity) {
|
|
176
|
+
newCapacity *= 2;
|
|
177
|
+
}
|
|
178
|
+
const newBuffer = new Float32Array(newCapacity);
|
|
179
|
+
newBuffer.set(__privateGet(this, _buffer));
|
|
180
|
+
__privateSet(this, _buffer, newBuffer);
|
|
181
|
+
}
|
|
182
|
+
__privateGet(this, _buffer).set(src, __privateGet(this, _writeIndex));
|
|
183
|
+
__privateSet(this, _writeIndex, __privateGet(this, _writeIndex) + src.length);
|
|
184
|
+
yield __privateGet(this, _emitter).emit("enqueue");
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Read audio from the buffer.
|
|
189
|
+
*
|
|
190
|
+
* @param dst The buffer to read the audio into.
|
|
191
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
192
|
+
* less than the length of the provided buffer.
|
|
193
|
+
*/
|
|
194
|
+
read(dst) {
|
|
195
|
+
return __async(this, null, function* () {
|
|
196
|
+
const targetReadIndex = __privateGet(this, _readIndex) + dst.length;
|
|
197
|
+
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this, _writeIndex)) {
|
|
198
|
+
yield __privateGet(this, _emitter).emit("wait");
|
|
199
|
+
yield Promise.race([
|
|
200
|
+
__privateGet(this, _emitter).once("enqueue"),
|
|
201
|
+
__privateGet(this, _emitter).once("close")
|
|
202
|
+
]);
|
|
203
|
+
yield __privateGet(this, _emitter).emit("read");
|
|
204
|
+
}
|
|
205
|
+
const read = Math.min(dst.length, __privateGet(this, _writeIndex) - __privateGet(this, _readIndex));
|
|
206
|
+
dst.set(__privateGet(this, _buffer).subarray(__privateGet(this, _readIndex), __privateGet(this, _readIndex) + read));
|
|
207
|
+
__privateSet(this, _readIndex, __privateGet(this, _readIndex) + read);
|
|
208
|
+
return read;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get the number of samples in a given duration.
|
|
213
|
+
*
|
|
214
|
+
* @param durationSecs The duration in seconds.
|
|
215
|
+
* @returns The number of samples.
|
|
216
|
+
*/
|
|
217
|
+
durationToSampleCount(durationSecs) {
|
|
218
|
+
return Math.trunc(durationSecs * __privateGet(this, _sampleRate));
|
|
219
|
+
}
|
|
220
|
+
get buffer() {
|
|
221
|
+
return __privateGet(this, _buffer);
|
|
222
|
+
}
|
|
223
|
+
get readIndex() {
|
|
224
|
+
return __privateGet(this, _readIndex);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
228
|
+
*
|
|
229
|
+
* This will emit a "close" event.
|
|
230
|
+
*
|
|
231
|
+
* @returns A promise that resolves when the source is closed.
|
|
232
|
+
*/
|
|
233
|
+
close() {
|
|
234
|
+
return __async(this, null, function* () {
|
|
235
|
+
__privateSet(this, _closed, true);
|
|
236
|
+
yield __privateGet(this, _emitter).emit("close");
|
|
237
|
+
__privateGet(this, _emitter).clearListeners();
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
_emitter = new WeakMap();
|
|
242
|
+
_buffer = new WeakMap();
|
|
243
|
+
_readIndex = new WeakMap();
|
|
244
|
+
_writeIndex = new WeakMap();
|
|
245
|
+
_closed = new WeakMap();
|
|
246
|
+
_sampleRate = new WeakMap();
|
|
247
|
+
|
|
248
|
+
// src/tts/utils.ts
|
|
99
249
|
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
100
|
-
function getBufferDuration(b64) {
|
|
101
|
-
const floats = base64ToArray(b64);
|
|
102
|
-
return floats.length / SAMPLE_RATE;
|
|
103
|
-
}
|
|
104
250
|
function base64ToArray(b64) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
buffer.getChannelData(0).set(floats);
|
|
119
|
-
source.buffer = buffer;
|
|
120
|
-
source.connect(context.destination);
|
|
121
|
-
source.start(startAt);
|
|
122
|
-
source.onended = onEnded;
|
|
123
|
-
return buffer.duration;
|
|
251
|
+
const byteArrays = filterSentinel(b64).map((b) => import_base64_js.default.toByteArray(b));
|
|
252
|
+
const totalLength = byteArrays.reduce(
|
|
253
|
+
(acc, arr) => acc + arr.length / Float32Array.BYTES_PER_ELEMENT,
|
|
254
|
+
0
|
|
255
|
+
);
|
|
256
|
+
const result = new Float32Array(totalLength);
|
|
257
|
+
let offset = 0;
|
|
258
|
+
for (const arr of byteArrays) {
|
|
259
|
+
const floats = new Float32Array(arr.buffer);
|
|
260
|
+
result.set(floats, offset);
|
|
261
|
+
offset += floats.length;
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
124
264
|
}
|
|
125
265
|
function createMessageHandlerForContextId(contextId, handler) {
|
|
126
266
|
return (event) => {
|
|
267
|
+
if (typeof event.data !== "string") {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
127
270
|
const message = JSON.parse(event.data);
|
|
128
271
|
if (message.context_id !== contextId) {
|
|
129
272
|
return;
|
|
@@ -134,7 +277,7 @@ function createMessageHandlerForContextId(contextId, handler) {
|
|
|
134
277
|
} else {
|
|
135
278
|
chunk = message.data;
|
|
136
279
|
}
|
|
137
|
-
handler({ chunk, message });
|
|
280
|
+
handler({ chunk, message: event.data });
|
|
138
281
|
};
|
|
139
282
|
}
|
|
140
283
|
function getSentinel() {
|
|
@@ -148,9 +291,6 @@ function filterSentinel(collection) {
|
|
|
148
291
|
(x) => !isSentinel(x)
|
|
149
292
|
);
|
|
150
293
|
}
|
|
151
|
-
function isComplete(chunks) {
|
|
152
|
-
return isSentinel(chunks[chunks.length - 1]);
|
|
153
|
-
}
|
|
154
294
|
function getEmitteryCallbacks(emitter) {
|
|
155
295
|
return {
|
|
156
296
|
on: emitter.on.bind(emitter),
|
|
@@ -160,58 +300,75 @@ function getEmitteryCallbacks(emitter) {
|
|
|
160
300
|
};
|
|
161
301
|
}
|
|
162
302
|
|
|
163
|
-
// src/
|
|
164
|
-
var
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
303
|
+
// src/tts/websocket.ts
|
|
304
|
+
var _isConnected, _sampleRate2, _generateId, generateId_fn;
|
|
305
|
+
var WebSocket = class extends Client {
|
|
306
|
+
/**
|
|
307
|
+
* Create a new WebSocket client.
|
|
308
|
+
*
|
|
309
|
+
* @param args - Arguments to pass to the Client constructor.
|
|
310
|
+
*/
|
|
311
|
+
constructor({ sampleRate }, ...args) {
|
|
312
|
+
super(...args);
|
|
313
|
+
/**
|
|
314
|
+
* Generate a unique ID suitable for a streaming context.
|
|
315
|
+
*
|
|
316
|
+
* Not suitable for security purposes or as a primary key, since
|
|
317
|
+
* it lacks the amount of entropy required for those use cases.
|
|
318
|
+
*
|
|
319
|
+
* @returns A unique ID.
|
|
320
|
+
*/
|
|
321
|
+
__privateAdd(this, _generateId);
|
|
322
|
+
__privateAdd(this, _isConnected, false);
|
|
323
|
+
__privateAdd(this, _sampleRate2, void 0);
|
|
324
|
+
__privateSet(this, _sampleRate2, sampleRate);
|
|
168
325
|
}
|
|
169
326
|
/**
|
|
170
|
-
*
|
|
327
|
+
* Send a message over the WebSocket in order to start a stream.
|
|
171
328
|
*
|
|
172
|
-
* @param inputs - Stream options.
|
|
173
|
-
* are model-specific and can be found in the model's documentation.
|
|
329
|
+
* @param inputs - Stream options.
|
|
174
330
|
* @param options - Options for the stream.
|
|
175
331
|
* @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
|
|
176
332
|
* If `0`, the stream will not time out.
|
|
177
|
-
* @returns
|
|
178
|
-
* that plays the audio as it arrives, with `bufferDuration` seconds of audio buffered before
|
|
179
|
-
* starting playback.
|
|
333
|
+
* @returns A Source object that can be passed to a Player to play the audio.
|
|
180
334
|
*/
|
|
181
|
-
|
|
335
|
+
send(inputs, { timeout = 0 } = {}) {
|
|
182
336
|
var _a, _b, _c, _d;
|
|
183
|
-
if (!this
|
|
337
|
+
if (!__privateGet(this, _isConnected)) {
|
|
184
338
|
throw new Error("Not connected to WebSocket. Call .connect() first.");
|
|
185
339
|
}
|
|
186
|
-
const contextId = this.
|
|
340
|
+
const contextId = __privateMethod(this, _generateId, generateId_fn).call(this);
|
|
187
341
|
(_a = this.socket) == null ? void 0 : _a.send(
|
|
188
|
-
JSON.stringify({
|
|
189
|
-
data: inputs,
|
|
342
|
+
JSON.stringify(__spreadProps(__spreadValues({
|
|
190
343
|
context_id: contextId
|
|
191
|
-
})
|
|
344
|
+
}, inputs), {
|
|
345
|
+
output_format: {
|
|
346
|
+
container: "raw",
|
|
347
|
+
encoding: "pcm_f32le",
|
|
348
|
+
sample_rate: __privateGet(this, _sampleRate2)
|
|
349
|
+
}
|
|
350
|
+
}))
|
|
192
351
|
);
|
|
352
|
+
const emitter = new import_emittery2.default();
|
|
353
|
+
const source = new Source({
|
|
354
|
+
sampleRate: __privateGet(this, _sampleRate2)
|
|
355
|
+
});
|
|
193
356
|
const streamCompleteController = new AbortController();
|
|
194
357
|
let timeoutId = null;
|
|
195
358
|
if (timeout > 0) {
|
|
196
359
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
197
360
|
}
|
|
198
|
-
const chunks = [];
|
|
199
|
-
const emitter = new import_emittery.default();
|
|
200
361
|
const handleMessage = createMessageHandlerForContextId(
|
|
201
362
|
contextId,
|
|
202
363
|
(_0) => __async(this, [_0], function* ({ chunk, message }) {
|
|
203
|
-
|
|
204
|
-
yield emitter.emit("chunk", {
|
|
205
|
-
chunk,
|
|
206
|
-
chunks
|
|
207
|
-
});
|
|
208
|
-
yield emitter.emit("message", message);
|
|
364
|
+
emitter.emit("message", message);
|
|
209
365
|
if (isSentinel(chunk)) {
|
|
210
|
-
yield
|
|
211
|
-
chunks
|
|
212
|
-
});
|
|
366
|
+
yield source.close();
|
|
213
367
|
streamCompleteController.abort();
|
|
214
|
-
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
yield source.enqueue(base64ToArray([chunk]));
|
|
371
|
+
if (timeoutId) {
|
|
215
372
|
clearTimeout(timeoutId);
|
|
216
373
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
217
374
|
}
|
|
@@ -239,107 +396,12 @@ var audio_default = class extends Client {
|
|
|
239
396
|
}
|
|
240
397
|
);
|
|
241
398
|
streamCompleteController.signal.addEventListener("abort", () => {
|
|
399
|
+
source.close();
|
|
242
400
|
if (timeoutId) {
|
|
243
401
|
clearTimeout(timeoutId);
|
|
244
402
|
}
|
|
245
|
-
emitter.clearListeners();
|
|
246
|
-
});
|
|
247
|
-
const play = (_0) => __async(this, [_0], function* ({ bufferDuration }) {
|
|
248
|
-
const context = new AudioContext({
|
|
249
|
-
sampleRate: SAMPLE_RATE
|
|
250
|
-
});
|
|
251
|
-
let startNextPlaybackAt = 0;
|
|
252
|
-
const playLatestChunk = (chunk) => {
|
|
253
|
-
if (isSentinel(chunk)) {
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
startNextPlaybackAt = playAudioBuffer([chunk], context, startNextPlaybackAt) + Math.max(context.currentTime, startNextPlaybackAt);
|
|
257
|
-
return false;
|
|
258
|
-
};
|
|
259
|
-
const playChunks = (chunks2) => {
|
|
260
|
-
startNextPlaybackAt += playAudioBuffer(
|
|
261
|
-
chunks2,
|
|
262
|
-
context,
|
|
263
|
-
startNextPlaybackAt
|
|
264
|
-
);
|
|
265
|
-
if (isComplete(chunks2)) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
const tryStart = (chunks2) => __async(this, null, function* () {
|
|
270
|
-
startNextPlaybackAt = context.currentTime;
|
|
271
|
-
if (isComplete(chunks2) || streamCompleteController.signal.aborted) {
|
|
272
|
-
emitter.emit("buffered");
|
|
273
|
-
playChunks(chunks2);
|
|
274
|
-
return true;
|
|
275
|
-
}
|
|
276
|
-
if (getBufferDuration(chunks2) > bufferDuration) {
|
|
277
|
-
emitter.emit("buffered");
|
|
278
|
-
playChunks(chunks2);
|
|
279
|
-
try {
|
|
280
|
-
for (var iter2 = __forAwait(emitter.events("chunk")), more2, temp2, error2; more2 = !(temp2 = yield iter2.next()).done; more2 = false) {
|
|
281
|
-
const { chunk } = temp2.value;
|
|
282
|
-
if (playLatestChunk(chunk)) {
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
} catch (temp2) {
|
|
287
|
-
error2 = [temp2];
|
|
288
|
-
} finally {
|
|
289
|
-
try {
|
|
290
|
-
more2 && (temp2 = iter2.return) && (yield temp2.call(iter2));
|
|
291
|
-
} finally {
|
|
292
|
-
if (error2)
|
|
293
|
-
throw error2[0];
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
298
|
-
emitter.emit("buffering");
|
|
299
|
-
return false;
|
|
300
|
-
});
|
|
301
|
-
if (!(yield tryStart(chunks))) {
|
|
302
|
-
try {
|
|
303
|
-
for (var iter = __forAwait(emitter.events("chunk")), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
|
|
304
|
-
const { chunks: chunks2 } = temp.value;
|
|
305
|
-
if (yield tryStart(chunks2)) {
|
|
306
|
-
const playbackEndsIn = Math.max(0, startNextPlaybackAt - context.currentTime) * 1e3;
|
|
307
|
-
emitter.emit("scheduled", { playbackEndsIn });
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
} catch (temp) {
|
|
312
|
-
error = [temp];
|
|
313
|
-
} finally {
|
|
314
|
-
try {
|
|
315
|
-
more && (temp = iter.return) && (yield temp.call(iter));
|
|
316
|
-
} finally {
|
|
317
|
-
if (error)
|
|
318
|
-
throw error[0];
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
} else {
|
|
322
|
-
const playbackEndsIn = Math.max(0, startNextPlaybackAt - context.currentTime) * 1e3;
|
|
323
|
-
emitter.emit("scheduled", { playbackEndsIn });
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
return __spreadValues({
|
|
327
|
-
play
|
|
328
|
-
}, getEmitteryCallbacks(emitter));
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Generate a unique ID suitable for a streaming context.
|
|
332
|
-
*
|
|
333
|
-
* Not suitable for security purposes or as a primary key, since
|
|
334
|
-
* it lacks the amount of entropy required for those use cases.
|
|
335
|
-
*
|
|
336
|
-
* @returns A unique ID.
|
|
337
|
-
*/
|
|
338
|
-
generateId() {
|
|
339
|
-
return (0, import_human_id.humanId)({
|
|
340
|
-
separator: "-",
|
|
341
|
-
capitalize: false
|
|
342
403
|
});
|
|
404
|
+
return __spreadValues({ source }, getEmitteryCallbacks(emitter));
|
|
343
405
|
}
|
|
344
406
|
/**
|
|
345
407
|
* Authenticate and connect to a Cartesia streaming WebSocket.
|
|
@@ -348,16 +410,20 @@ var audio_default = class extends Client {
|
|
|
348
410
|
* @throws {Error} If the WebSocket fails to connect.
|
|
349
411
|
*/
|
|
350
412
|
connect() {
|
|
351
|
-
const url =
|
|
413
|
+
const url = constructApiUrl(
|
|
414
|
+
this.baseUrl,
|
|
415
|
+
`/tts/websocket?cartesia_version=${CARTESIA_VERSION}`,
|
|
416
|
+
"ws"
|
|
417
|
+
);
|
|
352
418
|
url.searchParams.set("api_key", this.apiKey);
|
|
353
|
-
const emitter = new
|
|
419
|
+
const emitter = new import_emittery2.default();
|
|
354
420
|
this.socket = new import_partysocket.WebSocket(url.toString());
|
|
355
421
|
this.socket.onopen = () => {
|
|
356
|
-
this
|
|
422
|
+
__privateSet(this, _isConnected, true);
|
|
357
423
|
emitter.emit("open");
|
|
358
424
|
};
|
|
359
425
|
this.socket.onclose = () => {
|
|
360
|
-
this
|
|
426
|
+
__privateSet(this, _isConnected, false);
|
|
361
427
|
emitter.emit("close");
|
|
362
428
|
};
|
|
363
429
|
return new Promise(
|
|
@@ -404,12 +470,85 @@ var audio_default = class extends Client {
|
|
|
404
470
|
(_a = this.socket) == null ? void 0 : _a.close();
|
|
405
471
|
}
|
|
406
472
|
};
|
|
473
|
+
_isConnected = new WeakMap();
|
|
474
|
+
_sampleRate2 = new WeakMap();
|
|
475
|
+
_generateId = new WeakSet();
|
|
476
|
+
generateId_fn = function() {
|
|
477
|
+
return (0, import_human_id.humanId)({
|
|
478
|
+
separator: "-",
|
|
479
|
+
capitalize: false
|
|
480
|
+
});
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/tts/index.ts
|
|
484
|
+
var TTS = class extends Client {
|
|
485
|
+
/**
|
|
486
|
+
* Get a WebSocket client for streaming audio from the TTS API.
|
|
487
|
+
*
|
|
488
|
+
* @returns {WebSocket} A Cartesia WebSocket client.
|
|
489
|
+
*/
|
|
490
|
+
websocket(options) {
|
|
491
|
+
return new WebSocket(options, {
|
|
492
|
+
apiKey: this.apiKey,
|
|
493
|
+
baseUrl: this.baseUrl
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
// src/voices/index.ts
|
|
499
|
+
var Voices = class extends Client {
|
|
500
|
+
list() {
|
|
501
|
+
return __async(this, null, function* () {
|
|
502
|
+
const response = yield this.fetch("/voices");
|
|
503
|
+
return response.json();
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
get(voiceId) {
|
|
507
|
+
return __async(this, null, function* () {
|
|
508
|
+
const response = yield this.fetch(`/voices/${voiceId}`);
|
|
509
|
+
return response.json();
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
create(voice) {
|
|
513
|
+
return __async(this, null, function* () {
|
|
514
|
+
const response = yield this.fetch("/voices", {
|
|
515
|
+
method: "POST",
|
|
516
|
+
body: JSON.stringify(voice)
|
|
517
|
+
});
|
|
518
|
+
return response.json();
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
clone(options) {
|
|
522
|
+
return __async(this, null, function* () {
|
|
523
|
+
if (options.mode === "url") {
|
|
524
|
+
const response = yield this.fetch(
|
|
525
|
+
`/voices/clone/url?link=${options.link}`,
|
|
526
|
+
{
|
|
527
|
+
method: "POST"
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
return response.json();
|
|
531
|
+
}
|
|
532
|
+
if (options.mode === "clip") {
|
|
533
|
+
const formData = new FormData();
|
|
534
|
+
formData.append("clip", options.clip);
|
|
535
|
+
const response = yield this.fetch("/voices/clone/clip", {
|
|
536
|
+
method: "POST",
|
|
537
|
+
body: formData
|
|
538
|
+
});
|
|
539
|
+
return response.json();
|
|
540
|
+
}
|
|
541
|
+
throw new Error("Invalid mode for clone()");
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
};
|
|
407
545
|
|
|
408
546
|
// src/lib/index.ts
|
|
409
547
|
var Cartesia = class extends Client {
|
|
410
548
|
constructor(options = {}) {
|
|
411
549
|
super(options);
|
|
412
|
-
this.
|
|
550
|
+
this.tts = new TTS(options);
|
|
551
|
+
this.voices = new Voices(options);
|
|
413
552
|
}
|
|
414
553
|
};
|
|
415
554
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/lib/index.d.cts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TTS from '../tts/index.cjs';
|
|
2
2
|
import { ClientOptions } from '../types/index.cjs';
|
|
3
|
+
import Voices from '../voices/index.cjs';
|
|
3
4
|
import { Client } from './client.cjs';
|
|
5
|
+
import '../tts/websocket.cjs';
|
|
4
6
|
import 'emittery';
|
|
5
7
|
import 'partysocket';
|
|
8
|
+
import '../tts/source.cjs';
|
|
6
9
|
|
|
7
10
|
declare class Cartesia extends Client {
|
|
8
|
-
|
|
11
|
+
tts: TTS;
|
|
12
|
+
voices: Voices;
|
|
9
13
|
constructor(options?: ClientOptions);
|
|
10
14
|
}
|
|
11
15
|
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TTS from '../tts/index.js';
|
|
2
2
|
import { ClientOptions } from '../types/index.js';
|
|
3
|
+
import Voices from '../voices/index.js';
|
|
3
4
|
import { Client } from './client.js';
|
|
5
|
+
import '../tts/websocket.js';
|
|
4
6
|
import 'emittery';
|
|
5
7
|
import 'partysocket';
|
|
8
|
+
import '../tts/source.js';
|
|
6
9
|
|
|
7
10
|
declare class Cartesia extends Client {
|
|
8
|
-
|
|
11
|
+
tts: TTS;
|
|
12
|
+
voices: Voices;
|
|
9
13
|
constructor(options?: ClientOptions);
|
|
10
14
|
}
|
|
11
15
|
|
package/dist/lib/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Cartesia
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-T3RG6WV4.js";
|
|
4
|
+
import "../chunk-WVTITUXX.js";
|
|
5
|
+
import "../chunk-KWBSQZTY.js";
|
|
6
|
+
import "../chunk-3F5E46FT.js";
|
|
7
|
+
import "../chunk-PQ6CIPFW.js";
|
|
8
|
+
import "../chunk-JGP5BIUV.js";
|
|
9
|
+
import "../chunk-XHTDPLFR.js";
|
|
10
|
+
import "../chunk-RO7TY474.js";
|
|
11
|
+
import "../chunk-WIFMLPT5.js";
|
|
9
12
|
export {
|
|
10
13
|
Cartesia
|
|
11
14
|
};
|