@cartesia/cartesia-js 1.0.0-alpha.4 → 1.0.1
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 +49 -49
- package/CHANGELOG.md +23 -0
- package/LICENSE.md +21 -0
- package/README.md +102 -21
- package/dist/{chunk-VK7LBMVI.js → chunk-2NA5SEML.js} +2 -2
- package/dist/{chunk-PQ5EVEEH.js → chunk-5M33ZF3Y.js} +1 -1
- package/dist/{chunk-PQ6CIPFW.js → chunk-6YQ6KDIQ.js} +44 -5
- package/dist/{chunk-IQAXBRHU.js → chunk-ASZKHN7Q.js} +53 -29
- package/dist/{chunk-RO7TY474.js → chunk-BHY7MNGT.js} +11 -6
- package/dist/{chunk-WIFMLPT5.js → chunk-GHY2WEOK.js} +13 -0
- package/dist/{chunk-SGXUEFII.js → chunk-KUSVZXDT.js} +2 -2
- package/dist/{chunk-36JBKJUN.js → chunk-LZO6K34D.js} +20 -7
- package/dist/{chunk-3FL2SNIR.js → chunk-NQVZNVOU.js} +1 -1
- package/dist/{chunk-ISRU7PLL.js → chunk-OFH3ML4L.js} +3 -3
- package/dist/index.cjs +129 -39
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +15 -9
- package/dist/lib/client.js +2 -2
- package/dist/lib/constants.js +1 -1
- package/dist/lib/index.cjs +106 -33
- package/dist/lib/index.js +8 -8
- package/dist/react/index.cjs +231 -92
- package/dist/react/index.d.cts +4 -3
- package/dist/react/index.d.ts +4 -3
- package/dist/react/index.js +117 -64
- package/dist/react/utils.js +2 -2
- package/dist/tts/index.cjs +106 -33
- package/dist/tts/index.js +6 -6
- package/dist/tts/player.cjs +23 -5
- package/dist/tts/player.d.cts +6 -0
- package/dist/tts/player.d.ts +6 -0
- package/dist/tts/player.js +4 -3
- package/dist/tts/source.cjs +50 -4
- package/dist/tts/source.d.cts +16 -6
- package/dist/tts/source.d.ts +16 -6
- package/dist/tts/source.js +4 -2
- package/dist/tts/utils.cjs +18 -6
- package/dist/tts/utils.d.cts +7 -5
- package/dist/tts/utils.d.ts +7 -5
- package/dist/tts/utils.js +3 -2
- package/dist/tts/websocket.cjs +106 -33
- package/dist/tts/websocket.d.cts +20 -10
- package/dist/tts/websocket.d.ts +20 -10
- package/dist/tts/websocket.js +5 -5
- package/dist/types/index.d.cts +60 -4
- package/dist/types/index.d.ts +60 -4
- package/dist/voices/index.js +3 -3
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/react/index.ts +117 -62
- package/src/tts/player.ts +15 -8
- package/src/tts/source.ts +53 -7
- package/src/tts/utils.ts +26 -12
- package/src/tts/websocket.ts +42 -19
- package/src/types/index.ts +81 -3
package/dist/react/index.cjs
CHANGED
|
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
|
|
|
22
22
|
return a;
|
|
23
23
|
};
|
|
24
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __objRest = (source, exclude) => {
|
|
26
|
+
var target = {};
|
|
27
|
+
for (var prop in source)
|
|
28
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
if (source != null && __getOwnPropSymbols)
|
|
31
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
+
target[prop] = source[prop];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
};
|
|
25
37
|
var __export = (target, all) => {
|
|
26
38
|
for (var name in all)
|
|
27
39
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -135,7 +147,13 @@ var import_partysocket = require("partysocket");
|
|
|
135
147
|
|
|
136
148
|
// src/tts/source.ts
|
|
137
149
|
var import_emittery = __toESM(require("emittery"), 1);
|
|
138
|
-
var
|
|
150
|
+
var ENCODING_MAP = {
|
|
151
|
+
pcm_f32le: { arrayType: Float32Array, bytesPerElement: 4 },
|
|
152
|
+
pcm_s16le: { arrayType: Int16Array, bytesPerElement: 2 },
|
|
153
|
+
pcm_alaw: { arrayType: Uint8Array, bytesPerElement: 1 },
|
|
154
|
+
pcm_mulaw: { arrayType: Uint8Array, bytesPerElement: 1 }
|
|
155
|
+
};
|
|
156
|
+
var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate, _encoding, _container, _createBuffer, createBuffer_fn;
|
|
139
157
|
var Source = class {
|
|
140
158
|
/**
|
|
141
159
|
* Create a new Source.
|
|
@@ -143,23 +161,44 @@ var Source = class {
|
|
|
143
161
|
* @param options - Options for the Source.
|
|
144
162
|
* @param options.sampleRate - The sample rate of the audio.
|
|
145
163
|
*/
|
|
146
|
-
constructor({
|
|
164
|
+
constructor({
|
|
165
|
+
sampleRate,
|
|
166
|
+
encoding,
|
|
167
|
+
container
|
|
168
|
+
}) {
|
|
169
|
+
/**
|
|
170
|
+
* Create a new buffer for the source.
|
|
171
|
+
*
|
|
172
|
+
* @param size - The size of the buffer to create.
|
|
173
|
+
* @returns The new buffer as a TypedArray based on the encoding.
|
|
174
|
+
*/
|
|
175
|
+
__privateAdd(this, _createBuffer);
|
|
147
176
|
__privateAdd(this, _emitter, new import_emittery.default());
|
|
148
177
|
__privateAdd(this, _buffer, void 0);
|
|
149
178
|
__privateAdd(this, _readIndex, 0);
|
|
150
179
|
__privateAdd(this, _writeIndex, 0);
|
|
151
180
|
__privateAdd(this, _closed, false);
|
|
152
181
|
__privateAdd(this, _sampleRate, void 0);
|
|
182
|
+
__privateAdd(this, _encoding, void 0);
|
|
183
|
+
__privateAdd(this, _container, void 0);
|
|
153
184
|
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
154
185
|
this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
|
|
155
186
|
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
156
187
|
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
157
188
|
__privateSet(this, _sampleRate, sampleRate);
|
|
158
|
-
__privateSet(this,
|
|
189
|
+
__privateSet(this, _encoding, encoding);
|
|
190
|
+
__privateSet(this, _container, container);
|
|
191
|
+
__privateSet(this, _buffer, __privateMethod(this, _createBuffer, createBuffer_fn).call(this, 1024));
|
|
159
192
|
}
|
|
160
193
|
get sampleRate() {
|
|
161
194
|
return __privateGet(this, _sampleRate);
|
|
162
195
|
}
|
|
196
|
+
get encoding() {
|
|
197
|
+
return __privateGet(this, _encoding);
|
|
198
|
+
}
|
|
199
|
+
get container() {
|
|
200
|
+
return __privateGet(this, _container);
|
|
201
|
+
}
|
|
163
202
|
/**
|
|
164
203
|
* Append audio to the buffer.
|
|
165
204
|
*
|
|
@@ -173,7 +212,7 @@ var Source = class {
|
|
|
173
212
|
while (newCapacity < requiredCapacity) {
|
|
174
213
|
newCapacity *= 2;
|
|
175
214
|
}
|
|
176
|
-
const newBuffer =
|
|
215
|
+
const newBuffer = __privateMethod(this, _createBuffer, createBuffer_fn).call(this, newCapacity);
|
|
177
216
|
newBuffer.set(__privateGet(this, _buffer));
|
|
178
217
|
__privateSet(this, _buffer, newBuffer);
|
|
179
218
|
}
|
|
@@ -221,6 +260,9 @@ var Source = class {
|
|
|
221
260
|
get readIndex() {
|
|
222
261
|
return __privateGet(this, _readIndex);
|
|
223
262
|
}
|
|
263
|
+
get writeIndex() {
|
|
264
|
+
return __privateGet(this, _writeIndex);
|
|
265
|
+
}
|
|
224
266
|
/**
|
|
225
267
|
* Close the source. This signals that no more audio will be enqueued.
|
|
226
268
|
*
|
|
@@ -242,19 +284,27 @@ _readIndex = new WeakMap();
|
|
|
242
284
|
_writeIndex = new WeakMap();
|
|
243
285
|
_closed = new WeakMap();
|
|
244
286
|
_sampleRate = new WeakMap();
|
|
287
|
+
_encoding = new WeakMap();
|
|
288
|
+
_container = new WeakMap();
|
|
289
|
+
_createBuffer = new WeakSet();
|
|
290
|
+
createBuffer_fn = function(size) {
|
|
291
|
+
const { arrayType: ArrayType } = ENCODING_MAP[__privateGet(this, _encoding)];
|
|
292
|
+
return new ArrayType(size);
|
|
293
|
+
};
|
|
245
294
|
|
|
246
295
|
// src/tts/utils.ts
|
|
247
296
|
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
248
|
-
function base64ToArray(b64) {
|
|
297
|
+
function base64ToArray(b64, encoding) {
|
|
249
298
|
const byteArrays = filterSentinel(b64).map((b) => import_base64_js.default.toByteArray(b));
|
|
299
|
+
const { arrayType: ArrayType, bytesPerElement } = ENCODING_MAP[encoding];
|
|
250
300
|
const totalLength = byteArrays.reduce(
|
|
251
|
-
(acc, arr) => acc + arr.length /
|
|
301
|
+
(acc, arr) => acc + arr.length / bytesPerElement,
|
|
252
302
|
0
|
|
253
303
|
);
|
|
254
|
-
const result = new
|
|
304
|
+
const result = new ArrayType(totalLength);
|
|
255
305
|
let offset = 0;
|
|
256
306
|
for (const arr of byteArrays) {
|
|
257
|
-
const floats = new
|
|
307
|
+
const floats = new ArrayType(arr.buffer);
|
|
258
308
|
result.set(floats, offset);
|
|
259
309
|
offset += floats.length;
|
|
260
310
|
}
|
|
@@ -285,10 +335,10 @@ function createMessageHandlerForContextId(contextId, handler) {
|
|
|
285
335
|
let chunk;
|
|
286
336
|
if (message.done) {
|
|
287
337
|
chunk = getSentinel();
|
|
288
|
-
} else {
|
|
338
|
+
} else if (message.type === "chunk") {
|
|
289
339
|
chunk = message.data;
|
|
290
340
|
}
|
|
291
|
-
handler({ chunk, message: event.data });
|
|
341
|
+
handler({ chunk, message: event.data, data: message });
|
|
292
342
|
};
|
|
293
343
|
}
|
|
294
344
|
function getSentinel() {
|
|
@@ -312,14 +362,14 @@ function getEmitteryCallbacks(emitter) {
|
|
|
312
362
|
}
|
|
313
363
|
|
|
314
364
|
// src/tts/websocket.ts
|
|
315
|
-
var _isConnected, _sampleRate2, _generateId, generateId_fn;
|
|
365
|
+
var _isConnected, _sampleRate2, _container2, _encoding2, _generateId, generateId_fn;
|
|
316
366
|
var WebSocket = class extends Client {
|
|
317
367
|
/**
|
|
318
368
|
* Create a new WebSocket client.
|
|
319
369
|
*
|
|
320
370
|
* @param args - Arguments to pass to the Client constructor.
|
|
321
371
|
*/
|
|
322
|
-
constructor({ sampleRate }, ...args) {
|
|
372
|
+
constructor({ sampleRate, container, encoding }, ...args) {
|
|
323
373
|
super(...args);
|
|
324
374
|
/**
|
|
325
375
|
* Generate a unique ID suitable for a streaming context.
|
|
@@ -332,37 +382,47 @@ var WebSocket = class extends Client {
|
|
|
332
382
|
__privateAdd(this, _generateId);
|
|
333
383
|
__privateAdd(this, _isConnected, false);
|
|
334
384
|
__privateAdd(this, _sampleRate2, void 0);
|
|
385
|
+
__privateAdd(this, _container2, void 0);
|
|
386
|
+
__privateAdd(this, _encoding2, void 0);
|
|
335
387
|
__privateSet(this, _sampleRate2, sampleRate);
|
|
388
|
+
__privateSet(this, _container2, container != null ? container : "raw");
|
|
389
|
+
__privateSet(this, _encoding2, encoding != null ? encoding : "pcm_f32le");
|
|
336
390
|
}
|
|
337
391
|
/**
|
|
338
|
-
* Send a message over the WebSocket
|
|
392
|
+
* Send a message over the WebSocket to start a stream.
|
|
339
393
|
*
|
|
340
|
-
* @param inputs - Stream options.
|
|
394
|
+
* @param inputs - Stream options. Defined in the StreamRequest type.
|
|
341
395
|
* @param options - Options for the stream.
|
|
342
396
|
* @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
|
|
343
|
-
*
|
|
397
|
+
* If set to `0`, the stream will not time out.
|
|
344
398
|
* @returns A Source object that can be passed to a Player to play the audio.
|
|
399
|
+
* @returns An Emittery instance that emits messages from the WebSocket.
|
|
400
|
+
* @returns An abort function that can be called to cancel the stream.
|
|
345
401
|
*/
|
|
346
|
-
send(
|
|
347
|
-
var
|
|
402
|
+
send(_a, { timeout = 0 } = {}) {
|
|
403
|
+
var inputs = __objRest(_a, []);
|
|
404
|
+
var _a2, _b, _c, _d;
|
|
348
405
|
if (!__privateGet(this, _isConnected)) {
|
|
349
406
|
throw new Error("Not connected to WebSocket. Call .connect() first.");
|
|
350
407
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
408
|
+
if (!inputs.context_id) {
|
|
409
|
+
inputs.context_id = __privateMethod(this, _generateId, generateId_fn).call(this);
|
|
410
|
+
}
|
|
411
|
+
if (!inputs.output_format) {
|
|
412
|
+
inputs.output_format = {
|
|
413
|
+
container: __privateGet(this, _container2),
|
|
414
|
+
encoding: __privateGet(this, _encoding2),
|
|
415
|
+
sample_rate: __privateGet(this, _sampleRate2)
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
(_a2 = this.socket) == null ? void 0 : _a2.send(
|
|
419
|
+
JSON.stringify(__spreadValues({}, inputs))
|
|
362
420
|
);
|
|
363
421
|
const emitter = new import_emittery2.default();
|
|
364
422
|
const source = new Source({
|
|
365
|
-
sampleRate: __privateGet(this, _sampleRate2)
|
|
423
|
+
sampleRate: __privateGet(this, _sampleRate2),
|
|
424
|
+
encoding: __privateGet(this, _encoding2),
|
|
425
|
+
container: __privateGet(this, _container2)
|
|
366
426
|
});
|
|
367
427
|
const streamCompleteController = new AbortController();
|
|
368
428
|
let timeoutId = null;
|
|
@@ -370,19 +430,26 @@ var WebSocket = class extends Client {
|
|
|
370
430
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
371
431
|
}
|
|
372
432
|
const handleMessage = createMessageHandlerForContextId(
|
|
373
|
-
|
|
374
|
-
(_0) => __async(this, [_0], function* ({ chunk, message }) {
|
|
433
|
+
inputs.context_id,
|
|
434
|
+
(_0) => __async(this, [_0], function* ({ chunk, message, data }) {
|
|
375
435
|
emitter.emit("message", message);
|
|
436
|
+
if (data.type === "timestamps") {
|
|
437
|
+
emitter.emit("timestamps", data.word_timestamps);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
376
440
|
if (isSentinel(chunk)) {
|
|
377
441
|
yield source.close();
|
|
378
442
|
streamCompleteController.abort();
|
|
379
443
|
return;
|
|
380
444
|
}
|
|
381
|
-
yield source.enqueue(base64ToArray([chunk]));
|
|
382
445
|
if (timeoutId) {
|
|
383
446
|
clearTimeout(timeoutId);
|
|
384
447
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
385
448
|
}
|
|
449
|
+
if (!chunk) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
yield source.enqueue(base64ToArray([chunk], __privateGet(this, _encoding2)));
|
|
386
453
|
})
|
|
387
454
|
);
|
|
388
455
|
(_b = this.socket) == null ? void 0 : _b.addEventListener("message", handleMessage, {
|
|
@@ -412,7 +479,11 @@ var WebSocket = class extends Client {
|
|
|
412
479
|
clearTimeout(timeoutId);
|
|
413
480
|
}
|
|
414
481
|
});
|
|
415
|
-
return __spreadValues({
|
|
482
|
+
return __spreadProps(__spreadValues({
|
|
483
|
+
source
|
|
484
|
+
}, getEmitteryCallbacks(emitter)), {
|
|
485
|
+
stop: streamCompleteController.abort.bind(streamCompleteController)
|
|
486
|
+
});
|
|
416
487
|
}
|
|
417
488
|
/**
|
|
418
489
|
* Authenticate and connect to a Cartesia streaming WebSocket.
|
|
@@ -482,6 +553,8 @@ var WebSocket = class extends Client {
|
|
|
482
553
|
};
|
|
483
554
|
_isConnected = new WeakMap();
|
|
484
555
|
_sampleRate2 = new WeakMap();
|
|
556
|
+
_container2 = new WeakMap();
|
|
557
|
+
_encoding2 = new WeakMap();
|
|
485
558
|
_generateId = new WeakSet();
|
|
486
559
|
generateId_fn = function() {
|
|
487
560
|
return (0, import_human_id.humanId)({
|
|
@@ -563,8 +636,7 @@ var Cartesia = class extends Client {
|
|
|
563
636
|
};
|
|
564
637
|
|
|
565
638
|
// src/tts/player.ts
|
|
566
|
-
var
|
|
567
|
-
var _context, _startNextPlaybackAt, _bufferDuration, _emitter2, _playBuffer, playBuffer_fn;
|
|
639
|
+
var _context, _startNextPlaybackAt, _bufferDuration, _playBuffer, playBuffer_fn;
|
|
568
640
|
var Player = class {
|
|
569
641
|
/**
|
|
570
642
|
* Create a new Player.
|
|
@@ -577,7 +649,6 @@ var Player = class {
|
|
|
577
649
|
__privateAdd(this, _context, null);
|
|
578
650
|
__privateAdd(this, _startNextPlaybackAt, 0);
|
|
579
651
|
__privateAdd(this, _bufferDuration, void 0);
|
|
580
|
-
__privateAdd(this, _emitter2, new import_emittery3.default());
|
|
581
652
|
__privateSet(this, _bufferDuration, bufferDuration);
|
|
582
653
|
}
|
|
583
654
|
/**
|
|
@@ -599,7 +670,6 @@ var Player = class {
|
|
|
599
670
|
const playableAudio = buffer.subarray(0, read);
|
|
600
671
|
plays.push(__privateMethod(this, _playBuffer, playBuffer_fn).call(this, playableAudio, source.sampleRate));
|
|
601
672
|
if (read < buffer.length) {
|
|
602
|
-
yield __privateGet(this, _emitter2).emit("finish");
|
|
603
673
|
break;
|
|
604
674
|
}
|
|
605
675
|
}
|
|
@@ -649,17 +719,33 @@ var Player = class {
|
|
|
649
719
|
}
|
|
650
720
|
});
|
|
651
721
|
}
|
|
722
|
+
/**
|
|
723
|
+
* Stop the audio.
|
|
724
|
+
*
|
|
725
|
+
* @returns A promise that resolves when the audio has been stopped.
|
|
726
|
+
*/
|
|
727
|
+
stop() {
|
|
728
|
+
return __async(this, null, function* () {
|
|
729
|
+
var _a;
|
|
730
|
+
if (!__privateGet(this, _context)) {
|
|
731
|
+
throw new Error("AudioContext not initialized.");
|
|
732
|
+
}
|
|
733
|
+
yield (_a = __privateGet(this, _context)) == null ? void 0 : _a.close();
|
|
734
|
+
});
|
|
735
|
+
}
|
|
652
736
|
};
|
|
653
737
|
_context = new WeakMap();
|
|
654
738
|
_startNextPlaybackAt = new WeakMap();
|
|
655
739
|
_bufferDuration = new WeakMap();
|
|
656
|
-
_emitter2 = new WeakMap();
|
|
657
740
|
_playBuffer = new WeakSet();
|
|
658
741
|
playBuffer_fn = function(buf, sampleRate) {
|
|
659
742
|
return __async(this, null, function* () {
|
|
660
743
|
if (!__privateGet(this, _context)) {
|
|
661
744
|
throw new Error("AudioContext not initialized.");
|
|
662
745
|
}
|
|
746
|
+
if (buf.length === 0) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
663
749
|
const startAt = __privateGet(this, _startNextPlaybackAt);
|
|
664
750
|
const duration = buf.length / sampleRate;
|
|
665
751
|
__privateSet(this, _startNextPlaybackAt, duration + Math.max(__privateGet(this, _context).currentTime, __privateGet(this, _startNextPlaybackAt)));
|
|
@@ -683,7 +769,8 @@ var DEFAULT_BUFFER_DURATION = 0.01;
|
|
|
683
769
|
function useTTS({
|
|
684
770
|
apiKey,
|
|
685
771
|
baseUrl,
|
|
686
|
-
sampleRate
|
|
772
|
+
sampleRate,
|
|
773
|
+
onError
|
|
687
774
|
}) {
|
|
688
775
|
var _a, _b;
|
|
689
776
|
if (typeof window === "undefined") {
|
|
@@ -714,7 +801,11 @@ function useTTS({
|
|
|
714
801
|
}
|
|
715
802
|
const cartesia = new Cartesia({ apiKey, baseUrl });
|
|
716
803
|
baseUrl = baseUrl != null ? baseUrl : cartesia.baseUrl;
|
|
717
|
-
return cartesia.tts.websocket({
|
|
804
|
+
return cartesia.tts.websocket({
|
|
805
|
+
container: "raw",
|
|
806
|
+
encoding: "pcm_f32le",
|
|
807
|
+
sampleRate
|
|
808
|
+
});
|
|
718
809
|
}, [apiKey, baseUrl, sampleRate]);
|
|
719
810
|
const websocketReturn = (0, import_react.useRef)(null);
|
|
720
811
|
const player = (0, import_react.useRef)(null);
|
|
@@ -726,21 +817,34 @@ function useTTS({
|
|
|
726
817
|
const [messages, setMessages] = (0, import_react.useState)([]);
|
|
727
818
|
const buffer = (0, import_react.useCallback)(
|
|
728
819
|
(options) => __async(this, null, function* () {
|
|
729
|
-
var _a2;
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
820
|
+
var _a2, _b2;
|
|
821
|
+
(_a2 = websocketReturn.current) == null ? void 0 : _a2.stop();
|
|
822
|
+
try {
|
|
823
|
+
setMessages([]);
|
|
824
|
+
setBufferStatus("buffering");
|
|
825
|
+
websocketReturn.current = (_b2 = websocket == null ? void 0 : websocket.send(options)) != null ? _b2 : null;
|
|
826
|
+
if (!websocketReturn.current) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
const unsubscribe = websocketReturn.current.on("message", (message) => {
|
|
830
|
+
const parsedMessage = JSON.parse(message);
|
|
831
|
+
setMessages((messages2) => [...messages2, parsedMessage]);
|
|
832
|
+
if (parsedMessage.error) {
|
|
833
|
+
onError == null ? void 0 : onError(new Error(parsedMessage.error));
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
yield websocketReturn.current.source.once("close");
|
|
837
|
+
setBufferStatus("buffered");
|
|
838
|
+
unsubscribe();
|
|
839
|
+
} catch (error) {
|
|
840
|
+
if (error instanceof Error) {
|
|
841
|
+
onError == null ? void 0 : onError(error);
|
|
842
|
+
} else {
|
|
843
|
+
console.error(error);
|
|
844
|
+
}
|
|
735
845
|
}
|
|
736
|
-
const unsubscribe = websocketReturn.current.on("message", (message) => {
|
|
737
|
-
setMessages((messages2) => [...messages2, JSON.parse(message)]);
|
|
738
|
-
});
|
|
739
|
-
yield websocketReturn.current.source.once("close");
|
|
740
|
-
setBufferStatus("buffered");
|
|
741
|
-
unsubscribe();
|
|
742
846
|
}),
|
|
743
|
-
[websocket]
|
|
847
|
+
[websocket, onError]
|
|
744
848
|
);
|
|
745
849
|
const metrics = (0, import_react.useMemo)(() => {
|
|
746
850
|
var _a2;
|
|
@@ -809,53 +913,88 @@ function useTTS({
|
|
|
809
913
|
return () => cleanup == null ? void 0 : cleanup();
|
|
810
914
|
}, [websocket, baseUrl]);
|
|
811
915
|
const play = (0, import_react.useCallback)(() => __async(this, null, function* () {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
916
|
+
try {
|
|
917
|
+
if (playbackStatus === "playing" || !websocketReturn.current) {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
if (player.current) {
|
|
921
|
+
yield player.current.stop();
|
|
922
|
+
}
|
|
923
|
+
setPlaybackStatus("playing");
|
|
924
|
+
const unsubscribes = [];
|
|
925
|
+
unsubscribes.push(
|
|
926
|
+
websocketReturn.current.source.on("wait", () => {
|
|
927
|
+
setIsWaiting(true);
|
|
928
|
+
})
|
|
929
|
+
);
|
|
930
|
+
unsubscribes.push(
|
|
931
|
+
websocketReturn.current.source.on("read", () => {
|
|
932
|
+
setIsWaiting(false);
|
|
933
|
+
})
|
|
934
|
+
);
|
|
935
|
+
player.current = new Player({
|
|
936
|
+
bufferDuration: bufferDuration != null ? bufferDuration : DEFAULT_BUFFER_DURATION
|
|
937
|
+
});
|
|
938
|
+
yield player.current.play(websocketReturn.current.source);
|
|
939
|
+
for (const unsubscribe of unsubscribes) {
|
|
940
|
+
unsubscribe();
|
|
941
|
+
}
|
|
942
|
+
setPlaybackStatus("finished");
|
|
943
|
+
} catch (error) {
|
|
944
|
+
if (error instanceof Error) {
|
|
945
|
+
onError == null ? void 0 : onError(error);
|
|
946
|
+
} else {
|
|
947
|
+
console.error(error);
|
|
948
|
+
}
|
|
833
949
|
}
|
|
834
|
-
|
|
835
|
-
}), [playbackStatus, bufferDuration]);
|
|
950
|
+
}), [playbackStatus, bufferDuration, onError]);
|
|
836
951
|
const pause = (0, import_react.useCallback)(() => __async(this, null, function* () {
|
|
837
952
|
var _a2;
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
953
|
+
try {
|
|
954
|
+
yield (_a2 = player.current) == null ? void 0 : _a2.pause();
|
|
955
|
+
setPlaybackStatus("paused");
|
|
956
|
+
} catch (error) {
|
|
957
|
+
if (error instanceof Error) {
|
|
958
|
+
onError == null ? void 0 : onError(error);
|
|
959
|
+
} else {
|
|
960
|
+
console.error(error);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}), [onError]);
|
|
841
964
|
const resume = (0, import_react.useCallback)(() => __async(this, null, function* () {
|
|
842
965
|
var _a2;
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
966
|
+
try {
|
|
967
|
+
yield (_a2 = player.current) == null ? void 0 : _a2.resume();
|
|
968
|
+
setPlaybackStatus("playing");
|
|
969
|
+
} catch (error) {
|
|
970
|
+
if (error instanceof Error) {
|
|
971
|
+
onError == null ? void 0 : onError(error);
|
|
972
|
+
} else {
|
|
973
|
+
console.error(error);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}), [onError]);
|
|
846
977
|
const toggle = (0, import_react.useCallback)(() => __async(this, null, function* () {
|
|
847
978
|
var _a2;
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
979
|
+
try {
|
|
980
|
+
yield (_a2 = player.current) == null ? void 0 : _a2.toggle();
|
|
981
|
+
setPlaybackStatus((status) => {
|
|
982
|
+
if (status === "playing") {
|
|
983
|
+
return "paused";
|
|
984
|
+
}
|
|
985
|
+
if (status === "paused") {
|
|
986
|
+
return "playing";
|
|
987
|
+
}
|
|
988
|
+
return status;
|
|
989
|
+
});
|
|
990
|
+
} catch (error) {
|
|
991
|
+
if (error instanceof Error) {
|
|
992
|
+
onError == null ? void 0 : onError(error);
|
|
993
|
+
} else {
|
|
994
|
+
console.error(error);
|
|
855
995
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
}), []);
|
|
996
|
+
}
|
|
997
|
+
}), [onError]);
|
|
859
998
|
return {
|
|
860
999
|
buffer,
|
|
861
1000
|
play,
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import Source from '../tts/source.cjs';
|
|
2
|
+
import { StreamRequest } from '../types/index.cjs';
|
|
2
3
|
import 'emittery';
|
|
3
|
-
import '../types/index.cjs';
|
|
4
4
|
|
|
5
5
|
type UseTTSOptions = {
|
|
6
6
|
apiKey: string | null;
|
|
7
7
|
baseUrl?: string;
|
|
8
8
|
sampleRate: number;
|
|
9
|
+
onError?: (error: Error) => void;
|
|
9
10
|
};
|
|
10
11
|
type PlaybackStatus = "inactive" | "playing" | "paused" | "finished";
|
|
11
12
|
type BufferStatus = "inactive" | "buffering" | "buffered";
|
|
@@ -13,7 +14,7 @@ type Metrics = {
|
|
|
13
14
|
modelLatency: number | null;
|
|
14
15
|
};
|
|
15
16
|
interface UseTTSReturn {
|
|
16
|
-
buffer: (options:
|
|
17
|
+
buffer: (options: StreamRequest) => Promise<void>;
|
|
17
18
|
play: (bufferDuration?: number) => Promise<void>;
|
|
18
19
|
pause: () => Promise<void>;
|
|
19
20
|
resume: () => Promise<void>;
|
|
@@ -28,6 +29,6 @@ interface UseTTSReturn {
|
|
|
28
29
|
/**
|
|
29
30
|
* React hook to use the Cartesia audio API.
|
|
30
31
|
*/
|
|
31
|
-
declare function useTTS({ apiKey, baseUrl, sampleRate, }: UseTTSOptions): UseTTSReturn;
|
|
32
|
+
declare function useTTS({ apiKey, baseUrl, sampleRate, onError, }: UseTTSOptions): UseTTSReturn;
|
|
32
33
|
|
|
33
34
|
export { type BufferStatus, type Metrics, type PlaybackStatus, type UseTTSOptions, type UseTTSReturn, useTTS };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import Source from '../tts/source.js';
|
|
2
|
+
import { StreamRequest } from '../types/index.js';
|
|
2
3
|
import 'emittery';
|
|
3
|
-
import '../types/index.js';
|
|
4
4
|
|
|
5
5
|
type UseTTSOptions = {
|
|
6
6
|
apiKey: string | null;
|
|
7
7
|
baseUrl?: string;
|
|
8
8
|
sampleRate: number;
|
|
9
|
+
onError?: (error: Error) => void;
|
|
9
10
|
};
|
|
10
11
|
type PlaybackStatus = "inactive" | "playing" | "paused" | "finished";
|
|
11
12
|
type BufferStatus = "inactive" | "buffering" | "buffered";
|
|
@@ -13,7 +14,7 @@ type Metrics = {
|
|
|
13
14
|
modelLatency: number | null;
|
|
14
15
|
};
|
|
15
16
|
interface UseTTSReturn {
|
|
16
|
-
buffer: (options:
|
|
17
|
+
buffer: (options: StreamRequest) => Promise<void>;
|
|
17
18
|
play: (bufferDuration?: number) => Promise<void>;
|
|
18
19
|
pause: () => Promise<void>;
|
|
19
20
|
resume: () => Promise<void>;
|
|
@@ -28,6 +29,6 @@ interface UseTTSReturn {
|
|
|
28
29
|
/**
|
|
29
30
|
* React hook to use the Cartesia audio API.
|
|
30
31
|
*/
|
|
31
|
-
declare function useTTS({ apiKey, baseUrl, sampleRate, }: UseTTSOptions): UseTTSReturn;
|
|
32
|
+
declare function useTTS({ apiKey, baseUrl, sampleRate, onError, }: UseTTSOptions): UseTTSReturn;
|
|
32
33
|
|
|
33
34
|
export { type BufferStatus, type Metrics, type PlaybackStatus, type UseTTSOptions, type UseTTSReturn, useTTS };
|