@cartesia/cartesia-js 0.0.3 → 1.0.0-alpha.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 +68 -38
- package/CHANGELOG.md +12 -0
- package/README.md +123 -16
- package/dist/chunk-3FL2SNIR.js +17 -0
- package/dist/chunk-3GBZUGUD.js +17 -0
- package/dist/chunk-4RMSIQLG.js +25 -0
- package/dist/chunk-BCQ63627.js +32 -0
- package/dist/chunk-JOHSCOLW.js +106 -0
- package/dist/chunk-LYPTISWL.js +75 -0
- package/dist/chunk-NDNN326Q.js +207 -0
- package/dist/chunk-WBK6LLXX.js +58 -0
- package/dist/chunk-WE63M7PJ.js +119 -0
- package/dist/{chunk-HNLIBHEN.mjs → chunk-WIFMLPT5.js} +31 -16
- package/dist/chunk-X7SJMF2R.js +22 -0
- package/dist/index.cjs +652 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +20 -0
- package/dist/lib/client.cjs +89 -0
- package/dist/lib/client.d.cts +11 -0
- package/dist/lib/client.d.ts +2 -0
- package/dist/lib/client.js +7 -42
- package/dist/lib/constants.cjs +42 -0
- package/dist/lib/constants.d.cts +4 -0
- package/dist/lib/constants.d.ts +2 -3
- package/dist/lib/constants.js +8 -37
- package/dist/lib/index.cjs +531 -0
- package/dist/lib/index.d.cts +16 -0
- package/dist/lib/index.d.ts +6 -2
- package/dist/lib/index.js +13 -409
- package/dist/react/index.cjs +846 -0
- package/dist/react/index.d.cts +33 -0
- package/dist/react/index.d.ts +20 -13
- package/dist/react/index.js +161 -501
- package/dist/react/utils.cjs +57 -0
- package/dist/react/utils.d.cts +7 -0
- package/dist/react/utils.d.ts +7 -0
- package/dist/react/utils.js +7 -0
- package/dist/tts/index.cjs +470 -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 +167 -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/utils.js → tts/utils.cjs} +13 -54
- package/dist/tts/utils.d.cts +67 -0
- package/dist/tts/utils.d.ts +67 -0
- package/dist/{audio/utils.mjs → tts/utils.js} +2 -6
- package/dist/tts/websocket.cjs +453 -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.cjs +18 -0
- package/dist/types/index.d.cts +55 -0
- package/dist/types/index.d.ts +50 -1
- package/dist/types/index.js +1 -18
- package/dist/voices/index.cjs +155 -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 +11 -7
- package/src/index.ts +4 -0
- package/src/lib/client.ts +14 -1
- package/src/lib/constants.ts +13 -3
- package/src/lib/index.ts +6 -3
- package/src/react/index.ts +167 -75
- package/src/react/utils.ts +11 -0
- package/src/tts/index.ts +17 -0
- package/src/tts/player.ts +109 -0
- package/src/tts/source.ts +98 -0
- package/src/{audio → tts}/utils.ts +19 -97
- package/src/tts/websocket.ts +210 -0
- package/src/types/index.ts +63 -0
- package/src/voices/index.ts +47 -0
- package/dist/audio/index.d.mts +0 -5
- package/dist/audio/index.d.ts +0 -5
- package/dist/audio/index.js +0 -396
- package/dist/audio/index.mjs +0 -9
- package/dist/audio/utils.d.mts +0 -5
- package/dist/audio/utils.d.ts +0 -5
- package/dist/chunk-3CYTAFLF.mjs +0 -262
- package/dist/chunk-FRIBQZPN.mjs +0 -113
- package/dist/chunk-XSFPHPPG.mjs +0 -18
- package/dist/index-DSBmfK9-.d.mts +0 -158
- package/dist/index-qwAyxV5I.d.ts +0 -158
- package/dist/lib/client.d.mts +0 -9
- package/dist/lib/client.mjs +0 -7
- package/dist/lib/constants.d.mts +0 -5
- package/dist/lib/constants.mjs +0 -10
- package/dist/lib/index.d.mts +0 -12
- package/dist/lib/index.mjs +0 -19
- package/dist/react/index.d.mts +0 -26
- package/dist/react/index.mjs +0 -130
- package/dist/types/index.d.mts +0 -6
- package/index.ts +0 -3
- package/src/audio/index.ts +0 -282
- /package/dist/{types/index.mjs → chunk-FXPGR372.js} +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,45 +1,75 @@
|
|
|
1
1
|
$ tsup src/ --format cjs,esm --dts
|
|
2
|
-
[34mCLI[39m Building entry: src/
|
|
2
|
+
[34mCLI[39m Building entry: src/index.ts, src/lib/client.ts, src/lib/constants.ts, src/lib/index.ts, src/react/index.ts, src/react/utils.ts, src/tts/index.ts, src/tts/player.ts, src/tts/source.ts, src/tts/utils.ts, src/tts/websocket.ts, src/types/index.ts, src/voices/index.ts
|
|
3
3
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
4
4
|
[34mCLI[39m tsup v8.0.2
|
|
5
5
|
[34mCLI[39m Target: es6
|
|
6
6
|
[34mCJS[39m Build start
|
|
7
7
|
[34mESM[39m Build start
|
|
8
|
-
[32mESM[39m [1mdist/
|
|
9
|
-
[32mESM[39m [1mdist/chunk-
|
|
10
|
-
[32mESM[39m [1mdist/
|
|
11
|
-
[32mESM[39m [1mdist/
|
|
12
|
-
[32mESM[39m [1mdist/
|
|
13
|
-
[32mESM[39m [1mdist/
|
|
14
|
-
[32mESM[39m [1mdist/lib/
|
|
15
|
-
[32mESM[39m [1mdist/
|
|
16
|
-
[32mESM[39m [1mdist/
|
|
17
|
-
[32mESM[39m [1mdist/
|
|
18
|
-
[32mESM[39m [1mdist/
|
|
19
|
-
[32mESM[39m
|
|
20
|
-
[
|
|
21
|
-
[
|
|
22
|
-
[
|
|
23
|
-
[
|
|
24
|
-
[
|
|
25
|
-
[
|
|
26
|
-
[
|
|
27
|
-
[
|
|
8
|
+
[32mESM[39m [1mdist/index.js [22m[32m437.00 B[39m
|
|
9
|
+
[32mESM[39m [1mdist/chunk-FXPGR372.js [22m[32m0 B[39m
|
|
10
|
+
[32mESM[39m [1mdist/lib/client.js [22m[32m132.00 B[39m
|
|
11
|
+
[32mESM[39m [1mdist/react/index.js [22m[32m6.00 KB[39m
|
|
12
|
+
[32mESM[39m [1mdist/tts/index.js [22m[32m261.00 B[39m
|
|
13
|
+
[32mESM[39m [1mdist/lib/constants.js [22m[32m143.00 B[39m
|
|
14
|
+
[32mESM[39m [1mdist/lib/index.js [22m[32m322.00 B[39m
|
|
15
|
+
[32mESM[39m [1mdist/chunk-X7SJMF2R.js [22m[32m353.00 B[39m
|
|
16
|
+
[32mESM[39m [1mdist/chunk-WBK6LLXX.js [22m[32m1.35 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/react/utils.js [22m[32m109.00 B[39m
|
|
18
|
+
[32mESM[39m [1mdist/chunk-3FL2SNIR.js [22m[32m337.00 B[39m
|
|
19
|
+
[32mESM[39m [1mdist/chunk-4RMSIQLG.js [22m[32m439.00 B[39m
|
|
20
|
+
[32mESM[39m [1mdist/chunk-NDNN326Q.js [22m[32m5.73 KB[39m
|
|
21
|
+
[32mESM[39m [1mdist/chunk-JOHSCOLW.js [22m[32m3.39 KB[39m
|
|
22
|
+
[32mESM[39m [1mdist/chunk-BCQ63627.js [22m[32m775.00 B[39m
|
|
23
|
+
[32mESM[39m [1mdist/chunk-3GBZUGUD.js [22m[32m487.00 B[39m
|
|
24
|
+
[32mESM[39m [1mdist/tts/player.js [22m[32m143.00 B[39m
|
|
25
|
+
[32mESM[39m [1mdist/chunk-WE63M7PJ.js [22m[32m3.52 KB[39m
|
|
26
|
+
[32mESM[39m [1mdist/chunk-LYPTISWL.js [22m[32m1.81 KB[39m
|
|
27
|
+
[32mESM[39m [1mdist/chunk-WIFMLPT5.js [22m[32m2.27 KB[39m
|
|
28
|
+
[32mESM[39m [1mdist/types/index.js [22m[32m31.00 B[39m
|
|
29
|
+
[32mESM[39m [1mdist/voices/index.js [22m[32m174.00 B[39m
|
|
30
|
+
[32mESM[39m [1mdist/tts/source.js [22m[32m112.00 B[39m
|
|
31
|
+
[32mESM[39m [1mdist/tts/utils.js [22m[32m395.00 B[39m
|
|
32
|
+
[32mESM[39m [1mdist/tts/websocket.js [22m[32m242.00 B[39m
|
|
33
|
+
[32mESM[39m ⚡️ Build success in 115ms
|
|
34
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m20.24 KB[39m
|
|
35
|
+
[32mCJS[39m [1mdist/lib/client.cjs [22m[32m3.43 KB[39m
|
|
36
|
+
[32mCJS[39m [1mdist/lib/constants.cjs [22m[32m1.51 KB[39m
|
|
37
|
+
[32mCJS[39m [1mdist/lib/index.cjs [22m[32m16.42 KB[39m
|
|
38
|
+
[32mCJS[39m [1mdist/react/index.cjs [22m[32m26.25 KB[39m
|
|
39
|
+
[32mCJS[39m [1mdist/react/utils.cjs [22m[32m1.80 KB[39m
|
|
40
|
+
[32mCJS[39m [1mdist/tts/index.cjs [22m[32m14.89 KB[39m
|
|
41
|
+
[32mCJS[39m [1mdist/tts/player.cjs [22m[32m6.66 KB[39m
|
|
42
|
+
[32mCJS[39m [1mdist/tts/source.cjs [22m[32m5.99 KB[39m
|
|
43
|
+
[32mCJS[39m [1mdist/tts/utils.cjs [22m[32m3.73 KB[39m
|
|
44
|
+
[32mCJS[39m [1mdist/tts/websocket.cjs [22m[32m14.58 KB[39m
|
|
45
|
+
[32mCJS[39m [1mdist/types/index.cjs [22m[32m764.00 B[39m
|
|
46
|
+
[32mCJS[39m [1mdist/voices/index.cjs [22m[32m5.13 KB[39m
|
|
47
|
+
[32mCJS[39m ⚡️ Build success in 117ms
|
|
28
48
|
[34mDTS[39m Build start
|
|
29
|
-
[32mDTS[39m ⚡️ Build success in
|
|
30
|
-
[32mDTS[39m [1mdist/
|
|
31
|
-
[32mDTS[39m [1mdist/lib/
|
|
32
|
-
[32mDTS[39m [1mdist/
|
|
33
|
-
[32mDTS[39m [1mdist/
|
|
34
|
-
[32mDTS[39m [1mdist/
|
|
35
|
-
[32mDTS[39m [1mdist/
|
|
36
|
-
[32mDTS[39m [1mdist/
|
|
37
|
-
[32mDTS[39m [1mdist/
|
|
38
|
-
[32mDTS[39m [1mdist/
|
|
39
|
-
[32mDTS[39m [1mdist/
|
|
40
|
-
[32mDTS[39m [1mdist/
|
|
41
|
-
[32mDTS[39m [1mdist/lib/client.d.
|
|
42
|
-
[32mDTS[39m [1mdist/types/index.d.
|
|
43
|
-
[32mDTS[39m [1mdist/
|
|
44
|
-
[32mDTS[39m [1mdist/
|
|
45
|
-
[32mDTS[39m [1mdist/index
|
|
49
|
+
[32mDTS[39m ⚡️ Build success in 8423ms
|
|
50
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m509.00 B[39m
|
|
51
|
+
[32mDTS[39m [1mdist/lib/constants.d.cts [22m[32m184.00 B[39m
|
|
52
|
+
[32mDTS[39m [1mdist/lib/index.d.cts [22m[32m410.00 B[39m
|
|
53
|
+
[32mDTS[39m [1mdist/react/index.d.cts [22m[32m1018.00 B[39m
|
|
54
|
+
[32mDTS[39m [1mdist/react/utils.d.cts [22m[32m240.00 B[39m
|
|
55
|
+
[32mDTS[39m [1mdist/tts/index.d.cts [22m[32m471.00 B[39m
|
|
56
|
+
[32mDTS[39m [1mdist/tts/player.d.cts [22m[32m1.06 KB[39m
|
|
57
|
+
[32mDTS[39m [1mdist/tts/utils.d.cts [22m[32m2.56 KB[39m
|
|
58
|
+
[32mDTS[39m [1mdist/tts/websocket.d.cts [22m[32m2.39 KB[39m
|
|
59
|
+
[32mDTS[39m [1mdist/tts/source.d.cts [22m[32m2.17 KB[39m
|
|
60
|
+
[32mDTS[39m [1mdist/voices/index.d.cts [22m[32m399.00 B[39m
|
|
61
|
+
[32mDTS[39m [1mdist/lib/client.d.cts [22m[32m267.00 B[39m
|
|
62
|
+
[32mDTS[39m [1mdist/types/index.d.cts [22m[32m1.28 KB[39m
|
|
63
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m501.00 B[39m
|
|
64
|
+
[32mDTS[39m [1mdist/lib/constants.d.ts [22m[32m184.00 B[39m
|
|
65
|
+
[32mDTS[39m [1mdist/lib/index.d.ts [22m[32m404.00 B[39m
|
|
66
|
+
[32mDTS[39m [1mdist/react/index.d.ts [22m[32m1016.00 B[39m
|
|
67
|
+
[32mDTS[39m [1mdist/react/utils.d.ts [22m[32m240.00 B[39m
|
|
68
|
+
[32mDTS[39m [1mdist/tts/index.d.ts [22m[32m467.00 B[39m
|
|
69
|
+
[32mDTS[39m [1mdist/tts/player.d.ts [22m[32m1.06 KB[39m
|
|
70
|
+
[32mDTS[39m [1mdist/tts/utils.d.ts [22m[32m2.55 KB[39m
|
|
71
|
+
[32mDTS[39m [1mdist/tts/websocket.d.ts [22m[32m2.39 KB[39m
|
|
72
|
+
[32mDTS[39m [1mdist/tts/source.d.ts [22m[32m2.16 KB[39m
|
|
73
|
+
[32mDTS[39m [1mdist/voices/index.d.ts [22m[32m397.00 B[39m
|
|
74
|
+
[32mDTS[39m [1mdist/lib/client.d.ts [22m[32m266.00 B[39m
|
|
75
|
+
[32mDTS[39m [1mdist/types/index.d.ts [22m[32m1.28 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @cartesia/cartesia-js
|
|
2
2
|
|
|
3
|
+
## 1.0.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 3ee5bfc: Initial release of Cartesia client with voices and WebSocket support
|
|
8
|
+
|
|
9
|
+
## 0.0.4-alpha.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 8ecf940: Add provisional Node.js support
|
|
14
|
+
|
|
3
15
|
## 0.0.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -15,39 +15,146 @@ bun add @cartesia/cartesia-js
|
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
### CRUD on Voices
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import Cartesia from "@cartesia/cartesia-js";
|
|
22
|
+
|
|
23
|
+
const cartesia = new Cartesia({
|
|
24
|
+
apiKey: "your-api-key",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// List all voices.
|
|
28
|
+
const voices = await cartesia.voices.list();
|
|
29
|
+
console.log(voices);
|
|
30
|
+
|
|
31
|
+
// Get a voice.
|
|
32
|
+
const voice = await cartesia.voices.get("<voice-id>");
|
|
33
|
+
console.log(voice);
|
|
34
|
+
|
|
35
|
+
// Create a voice.
|
|
36
|
+
const newVoice = await cartesia.voices.create({
|
|
37
|
+
name: "Tim",
|
|
38
|
+
description: "A deep, resonant voice.",
|
|
39
|
+
embedding: Array(192).fill(1.0),
|
|
40
|
+
});
|
|
41
|
+
console.log(newVoice);
|
|
42
|
+
|
|
43
|
+
// Clone a voice from a URL.
|
|
44
|
+
const clonedVoice = await cartesia.voices.clone({
|
|
45
|
+
mode: "url",
|
|
46
|
+
url: "https://youtu.be/AdtLxlttrHg?si=07OLmDPg__0IN14f&t=6",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Clone a voice from a file.
|
|
50
|
+
const clonedVoice = await cartesia.voices.clone({
|
|
51
|
+
mode: "clip",
|
|
52
|
+
clip: myFile, // Pass a File object or a Blob.
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### TTS over WebSocket
|
|
57
|
+
|
|
58
|
+
```js
|
|
19
59
|
import Cartesia from "@cartesia/cartesia-js";
|
|
20
60
|
|
|
21
|
-
const cartesia = new Cartesia(
|
|
61
|
+
const cartesia = new Cartesia({
|
|
62
|
+
apiKey: "your-api-key",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Initialize the WebSocket. Make sure the sample rate you specify is supported.
|
|
66
|
+
const websocket = cartesia.tts.websocket({ sampleRate: 44100 });
|
|
22
67
|
|
|
23
68
|
try {
|
|
24
|
-
await
|
|
69
|
+
await websocket.connect();
|
|
25
70
|
} catch (error) {
|
|
26
71
|
console.error(`Failed to connect to Cartesia: ${error}`);
|
|
27
72
|
}
|
|
28
73
|
|
|
29
|
-
|
|
74
|
+
// Create a stream.
|
|
75
|
+
const response = await websocket.send({
|
|
30
76
|
model: "upbeat-moon",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
77
|
+
voice: {
|
|
78
|
+
mode: "embedding",
|
|
79
|
+
embedding: Array(192).fill(1.0),
|
|
34
80
|
},
|
|
81
|
+
transcript: "Hello, world!"
|
|
82
|
+
// The WebSocket sets output_format on your behalf.
|
|
83
|
+
// The container is "raw" and the encoding is "pcm_f32le".
|
|
35
84
|
});
|
|
36
85
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
console.log("Received
|
|
41
|
-
console.log("All chunks:", chunks);
|
|
86
|
+
// Access the raw messages from the WebSocket.
|
|
87
|
+
response.on("message", (message) => {
|
|
88
|
+
// Raw message.
|
|
89
|
+
console.log("Received message:", message);
|
|
42
90
|
});
|
|
43
91
|
|
|
44
|
-
|
|
92
|
+
// You can also access messages using a for-await-of loop.
|
|
93
|
+
for await (const message of response.events('message')) {
|
|
45
94
|
// Raw message.
|
|
46
95
|
console.log("Received message:", message);
|
|
47
|
-
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Playing audio in the browser
|
|
100
|
+
|
|
101
|
+
(We currently only support playing audio in the browser. Support for other JS environments is coming soon.)
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
// If you're using the client in the browser, you can play the audio like this:
|
|
105
|
+
import { WebPlayer } from "@cartesia/cartesia-js";
|
|
48
106
|
|
|
49
|
-
// If you're using the client in the browser, you can play the stream like this:
|
|
50
107
|
console.log("Playing stream...");
|
|
51
|
-
|
|
108
|
+
|
|
109
|
+
// Create a Player object.
|
|
110
|
+
const player = new WebPlayer();
|
|
111
|
+
|
|
112
|
+
// Play the audio. (`response` includes a custom Source object that the Player can play.)
|
|
113
|
+
// The call resolves when the audio finishes playing.
|
|
114
|
+
await player.play(response.source);
|
|
115
|
+
|
|
52
116
|
console.log("Done playing.");
|
|
53
117
|
```
|
|
118
|
+
|
|
119
|
+
## React
|
|
120
|
+
|
|
121
|
+
We export a React hook that simplifies the process of using the TTS API. The hook manages the WebSocket connection and provides a simple interface for buffering and playing audio.
|
|
122
|
+
|
|
123
|
+
```jsx
|
|
124
|
+
import { useTTS } from '@cartesia/cartesia-js/react';
|
|
125
|
+
|
|
126
|
+
function TextToSpeech() {
|
|
127
|
+
const tts = useTTS({
|
|
128
|
+
apiKey: "your-api-key",
|
|
129
|
+
samplingRate: 44100,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const [text, setText] = useState("");
|
|
133
|
+
|
|
134
|
+
const handlePlay = async () => {
|
|
135
|
+
// Begin buffering the audio.
|
|
136
|
+
const response = await tts.buffer({
|
|
137
|
+
model: "upbeat-moon",
|
|
138
|
+
voice: {
|
|
139
|
+
mode: "embedding",
|
|
140
|
+
embedding: Array(192).fill(1.0),
|
|
141
|
+
},
|
|
142
|
+
transcript: text,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Immediately play the audio. (You can also buffer in advance and play later.)
|
|
146
|
+
await tts.play();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<div>
|
|
151
|
+
<input type="text" value={text} onChange={(event) => setText(event.target.value)} />
|
|
152
|
+
<button onClick={handlePlay}>Play</button>
|
|
153
|
+
|
|
154
|
+
<div>
|
|
155
|
+
{tts.playbackStatus} | {tts.bufferStatus} | {tts.isWaiting}
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async
|
|
3
|
+
} from "./chunk-WIFMLPT5.js";
|
|
4
|
+
|
|
5
|
+
// src/react/utils.ts
|
|
6
|
+
function pingServer(url) {
|
|
7
|
+
return __async(this, null, function* () {
|
|
8
|
+
const start = (/* @__PURE__ */ new Date()).getTime();
|
|
9
|
+
yield fetch(url);
|
|
10
|
+
const end = (/* @__PURE__ */ new Date()).getTime();
|
|
11
|
+
return end - start;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
pingServer
|
|
17
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/lib/constants.ts
|
|
2
|
+
var BASE_URL = "https://api.cartesia.ai/v0";
|
|
3
|
+
var constructApiUrl = (baseUrl, path, protocol) => {
|
|
4
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
5
|
+
if (!protocol) {
|
|
6
|
+
return new URL(`${baseUrl}${normalizedPath}`);
|
|
7
|
+
}
|
|
8
|
+
if (!["http", "ws"].includes(protocol)) {
|
|
9
|
+
throw new Error(`Invalid protocol: ${protocol}`);
|
|
10
|
+
}
|
|
11
|
+
return new URL(`${baseUrl.replace(/^http/, protocol)}${normalizedPath}`);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
BASE_URL,
|
|
16
|
+
constructApiUrl
|
|
17
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WebSocket
|
|
3
|
+
} from "./chunk-NDNN326Q.js";
|
|
4
|
+
import {
|
|
5
|
+
Client
|
|
6
|
+
} from "./chunk-BCQ63627.js";
|
|
7
|
+
|
|
8
|
+
// src/tts/index.ts
|
|
9
|
+
var TTS = class extends Client {
|
|
10
|
+
/**
|
|
11
|
+
* Get a WebSocket client for streaming audio from the TTS API.
|
|
12
|
+
*
|
|
13
|
+
* @returns {WebSocket} A Cartesia WebSocket client.
|
|
14
|
+
*/
|
|
15
|
+
websocket(options) {
|
|
16
|
+
return new WebSocket(options, {
|
|
17
|
+
apiKey: this.apiKey,
|
|
18
|
+
baseUrl: this.baseUrl
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
TTS
|
|
25
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASE_URL,
|
|
3
|
+
constructApiUrl
|
|
4
|
+
} from "./chunk-3GBZUGUD.js";
|
|
5
|
+
import {
|
|
6
|
+
__spreadProps,
|
|
7
|
+
__spreadValues
|
|
8
|
+
} from "./chunk-WIFMLPT5.js";
|
|
9
|
+
|
|
10
|
+
// src/lib/client.ts
|
|
11
|
+
import fetch from "cross-fetch";
|
|
12
|
+
var Client = class {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
if (!(options.apiKey || process.env.CARTESIA_API_KEY)) {
|
|
15
|
+
throw new Error("Missing Cartesia API key.");
|
|
16
|
+
}
|
|
17
|
+
this.apiKey = options.apiKey || process.env.CARTESIA_API_KEY;
|
|
18
|
+
this.baseUrl = options.baseUrl || BASE_URL;
|
|
19
|
+
}
|
|
20
|
+
fetch(path, options = {}) {
|
|
21
|
+
const url = constructApiUrl(this.baseUrl, path);
|
|
22
|
+
return fetch(url.toString(), __spreadProps(__spreadValues({}, options), {
|
|
23
|
+
headers: __spreadValues({
|
|
24
|
+
"X-API-KEY": this.apiKey
|
|
25
|
+
}, options.headers)
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
Client
|
|
32
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async,
|
|
3
|
+
__privateAdd,
|
|
4
|
+
__privateGet,
|
|
5
|
+
__privateSet
|
|
6
|
+
} from "./chunk-WIFMLPT5.js";
|
|
7
|
+
|
|
8
|
+
// src/tts/source.ts
|
|
9
|
+
import Emittery from "emittery";
|
|
10
|
+
var _emitter, _buffer, _readIndex, _closed, _sampleRate;
|
|
11
|
+
var Source = class {
|
|
12
|
+
/**
|
|
13
|
+
* Create a new Source.
|
|
14
|
+
*
|
|
15
|
+
* @param options - Options for the Source.
|
|
16
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
17
|
+
*/
|
|
18
|
+
constructor({ sampleRate }) {
|
|
19
|
+
__privateAdd(this, _emitter, new Emittery());
|
|
20
|
+
__privateAdd(this, _buffer, new Float32Array());
|
|
21
|
+
__privateAdd(this, _readIndex, 0);
|
|
22
|
+
__privateAdd(this, _closed, false);
|
|
23
|
+
__privateAdd(this, _sampleRate, void 0);
|
|
24
|
+
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
25
|
+
this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
|
|
26
|
+
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
27
|
+
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
28
|
+
__privateSet(this, _sampleRate, sampleRate);
|
|
29
|
+
}
|
|
30
|
+
get sampleRate() {
|
|
31
|
+
return __privateGet(this, _sampleRate);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Append audio to the buffer.
|
|
35
|
+
*
|
|
36
|
+
* @param src The audio to append.
|
|
37
|
+
*/
|
|
38
|
+
enqueue(src) {
|
|
39
|
+
return __async(this, null, function* () {
|
|
40
|
+
__privateSet(this, _buffer, new Float32Array([...__privateGet(this, _buffer), ...src]));
|
|
41
|
+
yield __privateGet(this, _emitter).emit("enqueue");
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read audio from the buffer.
|
|
46
|
+
*
|
|
47
|
+
* @param dst The buffer to read the audio into.
|
|
48
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
49
|
+
* less than the length of the provided buffer.
|
|
50
|
+
*/
|
|
51
|
+
read(dst) {
|
|
52
|
+
return __async(this, null, function* () {
|
|
53
|
+
const targetReadIndex = __privateGet(this, _readIndex) + dst.length;
|
|
54
|
+
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this, _buffer).length) {
|
|
55
|
+
yield __privateGet(this, _emitter).emit("wait");
|
|
56
|
+
yield Promise.race([
|
|
57
|
+
__privateGet(this, _emitter).once("enqueue"),
|
|
58
|
+
__privateGet(this, _emitter).once("close")
|
|
59
|
+
]);
|
|
60
|
+
yield __privateGet(this, _emitter).emit("read");
|
|
61
|
+
}
|
|
62
|
+
const read = Math.min(dst.length, __privateGet(this, _buffer).length - __privateGet(this, _readIndex));
|
|
63
|
+
dst.set(__privateGet(this, _buffer).slice(__privateGet(this, _readIndex), __privateGet(this, _readIndex) + read));
|
|
64
|
+
__privateSet(this, _readIndex, __privateGet(this, _readIndex) + read);
|
|
65
|
+
return read;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the number of samples in a given duration.
|
|
70
|
+
*
|
|
71
|
+
* @param durationSecs The duration in seconds.
|
|
72
|
+
* @returns The number of samples.
|
|
73
|
+
*/
|
|
74
|
+
durationToSampleCount(durationSecs) {
|
|
75
|
+
return Math.trunc(durationSecs * __privateGet(this, _sampleRate));
|
|
76
|
+
}
|
|
77
|
+
get buffer() {
|
|
78
|
+
return __privateGet(this, _buffer);
|
|
79
|
+
}
|
|
80
|
+
get readIndex() {
|
|
81
|
+
return __privateGet(this, _readIndex);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
85
|
+
*
|
|
86
|
+
* This will emit a "close" event.
|
|
87
|
+
*
|
|
88
|
+
* @returns A promise that resolves when the source is closed.
|
|
89
|
+
*/
|
|
90
|
+
close() {
|
|
91
|
+
return __async(this, null, function* () {
|
|
92
|
+
__privateSet(this, _closed, true);
|
|
93
|
+
yield __privateGet(this, _emitter).emit("close");
|
|
94
|
+
__privateGet(this, _emitter).clearListeners();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
_emitter = new WeakMap();
|
|
99
|
+
_buffer = new WeakMap();
|
|
100
|
+
_readIndex = new WeakMap();
|
|
101
|
+
_closed = new WeakMap();
|
|
102
|
+
_sampleRate = new WeakMap();
|
|
103
|
+
|
|
104
|
+
export {
|
|
105
|
+
Source
|
|
106
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// src/tts/utils.ts
|
|
2
|
+
import base64 from "base64-js";
|
|
3
|
+
function base64ToArray(b64) {
|
|
4
|
+
return filterSentinel(b64).reduce((acc, b) => {
|
|
5
|
+
const floats = new Float32Array(base64.toByteArray(b).buffer);
|
|
6
|
+
const newAcc = new Float32Array(acc.length + floats.length);
|
|
7
|
+
newAcc.set(acc, 0);
|
|
8
|
+
newAcc.set(floats, acc.length);
|
|
9
|
+
return newAcc;
|
|
10
|
+
}, new Float32Array(0));
|
|
11
|
+
}
|
|
12
|
+
function playAudioBuffer(floats, context, startAt, sampleRate) {
|
|
13
|
+
const source = context.createBufferSource();
|
|
14
|
+
const buffer = context.createBuffer(1, floats.length, sampleRate);
|
|
15
|
+
buffer.getChannelData(0).set(floats);
|
|
16
|
+
source.buffer = buffer;
|
|
17
|
+
source.connect(context.destination);
|
|
18
|
+
source.start(startAt);
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
source.onended = () => {
|
|
21
|
+
resolve();
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function createMessageHandlerForContextId(contextId, handler) {
|
|
26
|
+
return (event) => {
|
|
27
|
+
if (typeof event.data !== "string") {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const message = JSON.parse(event.data);
|
|
31
|
+
if (message.context_id !== contextId) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let chunk;
|
|
35
|
+
if (message.done) {
|
|
36
|
+
chunk = getSentinel();
|
|
37
|
+
} else {
|
|
38
|
+
chunk = message.data;
|
|
39
|
+
}
|
|
40
|
+
handler({ chunk, message: event.data });
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function getSentinel() {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function isSentinel(x) {
|
|
47
|
+
return x === getSentinel();
|
|
48
|
+
}
|
|
49
|
+
function filterSentinel(collection) {
|
|
50
|
+
return collection.filter(
|
|
51
|
+
(x) => !isSentinel(x)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function isComplete(chunks) {
|
|
55
|
+
return isSentinel(chunks[chunks.length - 1]);
|
|
56
|
+
}
|
|
57
|
+
function getEmitteryCallbacks(emitter) {
|
|
58
|
+
return {
|
|
59
|
+
on: emitter.on.bind(emitter),
|
|
60
|
+
off: emitter.off.bind(emitter),
|
|
61
|
+
once: emitter.once.bind(emitter),
|
|
62
|
+
events: emitter.events.bind(emitter)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
base64ToArray,
|
|
68
|
+
playAudioBuffer,
|
|
69
|
+
createMessageHandlerForContextId,
|
|
70
|
+
getSentinel,
|
|
71
|
+
isSentinel,
|
|
72
|
+
filterSentinel,
|
|
73
|
+
isComplete,
|
|
74
|
+
getEmitteryCallbacks
|
|
75
|
+
};
|