@cartesia/cartesia-js 1.0.0 → 1.0.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 +50 -50
- package/CHANGELOG.md +12 -0
- package/LICENSE.md +21 -0
- package/README.md +92 -19
- package/dist/{chunk-PQ6CIPFW.js → chunk-6YQ6KDIQ.js} +44 -5
- package/dist/{chunk-RO7TY474.js → chunk-BHY7MNGT.js} +11 -6
- package/dist/{chunk-F4QWVJY3.js → chunk-EDAAHENY.js} +2 -2
- package/dist/{chunk-WIFMLPT5.js → chunk-GHY2WEOK.js} +13 -0
- package/dist/{chunk-FN7BK4PS.js → chunk-IZBPLCGW.js} +97 -75
- package/dist/{chunk-JYLAM6VU.js → chunk-LZO6K34D.js} +2 -2
- package/dist/{chunk-3FL2SNIR.js → chunk-NQVZNVOU.js} +1 -1
- package/dist/{chunk-IEN4NCER.js → chunk-NVOCUUOF.js} +3 -3
- package/dist/chunk-PISCPZK4.js +40 -0
- package/dist/{chunk-SGXUEFII.js → chunk-UCYL2SOX.js} +18 -15
- package/dist/index.cjs +186 -103
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +15 -9
- package/dist/lib/client.cjs +35 -10
- package/dist/lib/client.d.cts +2 -2
- package/dist/lib/client.d.ts +2 -2
- package/dist/lib/client.js +2 -2
- package/dist/lib/constants.js +1 -1
- package/dist/lib/index.cjs +181 -102
- package/dist/lib/index.js +8 -8
- package/dist/react/index.cjs +286 -158
- package/dist/react/index.d.cts +5 -4
- package/dist/react/index.d.ts +5 -4
- package/dist/react/index.js +115 -66
- package/dist/react/utils.js +2 -2
- package/dist/tts/index.cjs +165 -89
- package/dist/tts/index.js +6 -6
- package/dist/tts/player.cjs +5 -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 +165 -89
- package/dist/tts/websocket.d.cts +12 -8
- package/dist/tts/websocket.d.ts +12 -8
- package/dist/tts/websocket.js +5 -5
- package/dist/types/index.d.cts +65 -5
- package/dist/types/index.d.ts +65 -5
- package/dist/voices/index.cjs +31 -23
- package/dist/voices/index.d.cts +2 -1
- package/dist/voices/index.d.ts +2 -1
- package/dist/voices/index.js +3 -3
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/lib/client.ts +10 -10
- package/src/react/index.ts +115 -64
- package/src/tts/source.ts +53 -7
- package/src/tts/utils.ts +26 -12
- package/src/tts/websocket.ts +42 -23
- package/src/types/index.ts +89 -4
- package/src/voices/index.ts +22 -15
- package/dist/chunk-PQ5EVEEH.js +0 -34
package/src/tts/source.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import Emittery from "emittery";
|
|
2
|
-
import type { SourceEventData } from "../types";
|
|
2
|
+
import type { Encoding, SourceEventData, TypedArray } from "../types";
|
|
3
|
+
|
|
4
|
+
type EncodingInfo = {
|
|
5
|
+
arrayType:
|
|
6
|
+
| Float32ArrayConstructor
|
|
7
|
+
| Int16ArrayConstructor
|
|
8
|
+
| Uint8ArrayConstructor;
|
|
9
|
+
bytesPerElement: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const ENCODING_MAP: Record<Encoding, EncodingInfo> = {
|
|
13
|
+
pcm_f32le: { arrayType: Float32Array, bytesPerElement: 4 },
|
|
14
|
+
pcm_s16le: { arrayType: Int16Array, bytesPerElement: 2 },
|
|
15
|
+
pcm_alaw: { arrayType: Uint8Array, bytesPerElement: 1 },
|
|
16
|
+
pcm_mulaw: { arrayType: Uint8Array, bytesPerElement: 1 },
|
|
17
|
+
};
|
|
3
18
|
|
|
4
19
|
export default class Source {
|
|
5
20
|
#emitter = new Emittery<SourceEventData>();
|
|
6
|
-
#buffer:
|
|
21
|
+
#buffer: TypedArray;
|
|
7
22
|
#readIndex = 0;
|
|
8
23
|
#writeIndex = 0;
|
|
9
24
|
#closed = false;
|
|
10
25
|
#sampleRate: number;
|
|
26
|
+
#encoding: Encoding;
|
|
27
|
+
#container: string;
|
|
11
28
|
|
|
12
29
|
on = this.#emitter.on.bind(this.#emitter);
|
|
13
30
|
once = this.#emitter.once.bind(this.#emitter);
|
|
@@ -20,21 +37,46 @@ export default class Source {
|
|
|
20
37
|
* @param options - Options for the Source.
|
|
21
38
|
* @param options.sampleRate - The sample rate of the audio.
|
|
22
39
|
*/
|
|
23
|
-
constructor({
|
|
40
|
+
constructor({
|
|
41
|
+
sampleRate,
|
|
42
|
+
encoding,
|
|
43
|
+
container,
|
|
44
|
+
}: { sampleRate: number; encoding: string; container: string }) {
|
|
24
45
|
this.#sampleRate = sampleRate;
|
|
25
|
-
this.#
|
|
46
|
+
this.#encoding = encoding as Encoding;
|
|
47
|
+
this.#container = container;
|
|
48
|
+
this.#buffer = this.#createBuffer(1024); // Initial size, can be adjusted
|
|
26
49
|
}
|
|
27
50
|
|
|
28
51
|
get sampleRate() {
|
|
29
52
|
return this.#sampleRate;
|
|
30
53
|
}
|
|
31
54
|
|
|
55
|
+
get encoding() {
|
|
56
|
+
return this.#encoding;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get container() {
|
|
60
|
+
return this.#container;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Create a new buffer for the source.
|
|
65
|
+
*
|
|
66
|
+
* @param size - The size of the buffer to create.
|
|
67
|
+
* @returns The new buffer as a TypedArray based on the encoding.
|
|
68
|
+
*/
|
|
69
|
+
#createBuffer(size: number): TypedArray {
|
|
70
|
+
const { arrayType: ArrayType } = ENCODING_MAP[this.#encoding];
|
|
71
|
+
return new ArrayType(size);
|
|
72
|
+
}
|
|
73
|
+
|
|
32
74
|
/**
|
|
33
75
|
* Append audio to the buffer.
|
|
34
76
|
*
|
|
35
77
|
* @param src The audio to append.
|
|
36
78
|
*/
|
|
37
|
-
async enqueue(src:
|
|
79
|
+
async enqueue(src: TypedArray) {
|
|
38
80
|
const requiredCapacity = this.#writeIndex + src.length;
|
|
39
81
|
|
|
40
82
|
// Resize buffer if necessary
|
|
@@ -44,7 +86,7 @@ export default class Source {
|
|
|
44
86
|
newCapacity *= 2; // Double the buffer size
|
|
45
87
|
}
|
|
46
88
|
|
|
47
|
-
const newBuffer =
|
|
89
|
+
const newBuffer = this.#createBuffer(newCapacity);
|
|
48
90
|
newBuffer.set(this.#buffer);
|
|
49
91
|
this.#buffer = newBuffer;
|
|
50
92
|
}
|
|
@@ -62,7 +104,7 @@ export default class Source {
|
|
|
62
104
|
* @returns The number of samples read. If the source is closed, this will be
|
|
63
105
|
* less than the length of the provided buffer.
|
|
64
106
|
*/
|
|
65
|
-
async read(dst:
|
|
107
|
+
async read(dst: TypedArray): Promise<number> {
|
|
66
108
|
// Read the buffer into the provided buffer.
|
|
67
109
|
const targetReadIndex = this.#readIndex + dst.length;
|
|
68
110
|
|
|
@@ -100,6 +142,10 @@ export default class Source {
|
|
|
100
142
|
return this.#readIndex;
|
|
101
143
|
}
|
|
102
144
|
|
|
145
|
+
get writeIndex() {
|
|
146
|
+
return this.#writeIndex;
|
|
147
|
+
}
|
|
148
|
+
|
|
103
149
|
/**
|
|
104
150
|
* Close the source. This signals that no more audio will be enqueued.
|
|
105
151
|
*
|
package/src/tts/utils.ts
CHANGED
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
import base64 from "base64-js";
|
|
2
2
|
import type Emittery from "emittery";
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
Chunk,
|
|
5
|
+
EmitteryCallbacks,
|
|
6
|
+
Encoding,
|
|
7
|
+
Sentinel,
|
|
8
|
+
TypedArray,
|
|
9
|
+
WebSocketResponse,
|
|
10
|
+
} from "../types";
|
|
11
|
+
import { ENCODING_MAP } from "./source";
|
|
4
12
|
|
|
5
13
|
/**
|
|
6
|
-
* Convert base64-encoded audio buffer(s) to a
|
|
14
|
+
* Convert base64-encoded audio buffer(s) to a TypedArray.
|
|
7
15
|
*
|
|
8
16
|
* @param b64 The base64-encoded audio buffer, or an array of base64-encoded
|
|
9
17
|
* audio buffers.
|
|
10
|
-
* @
|
|
18
|
+
* @param encoding The encoding of the audio buffer(s).
|
|
19
|
+
* @returns The audio buffer(s) as a TypedArray.
|
|
11
20
|
*/
|
|
12
|
-
export function base64ToArray(b64: Chunk[]):
|
|
21
|
+
export function base64ToArray(b64: Chunk[], encoding: string): TypedArray {
|
|
13
22
|
const byteArrays = filterSentinel(b64).map((b) => base64.toByteArray(b));
|
|
23
|
+
|
|
24
|
+
const { arrayType: ArrayType, bytesPerElement } =
|
|
25
|
+
ENCODING_MAP[encoding as Encoding];
|
|
26
|
+
|
|
14
27
|
const totalLength = byteArrays.reduce(
|
|
15
|
-
(acc, arr) => acc + arr.length /
|
|
28
|
+
(acc, arr) => acc + arr.length / bytesPerElement,
|
|
16
29
|
0,
|
|
17
30
|
);
|
|
18
|
-
const result = new
|
|
31
|
+
const result = new ArrayType(totalLength);
|
|
19
32
|
|
|
20
33
|
let offset = 0;
|
|
21
34
|
for (const arr of byteArrays) {
|
|
22
|
-
const floats = new
|
|
35
|
+
const floats = new ArrayType(arr.buffer);
|
|
23
36
|
result.set(floats, offset);
|
|
24
37
|
offset += floats.length;
|
|
25
38
|
}
|
|
@@ -70,26 +83,27 @@ export function createMessageHandlerForContextId(
|
|
|
70
83
|
chunk,
|
|
71
84
|
message,
|
|
72
85
|
}: {
|
|
73
|
-
chunk
|
|
86
|
+
chunk?: Chunk;
|
|
74
87
|
message: string;
|
|
88
|
+
data: WebSocketResponse;
|
|
75
89
|
}) => void,
|
|
76
90
|
) {
|
|
77
91
|
return (event: MessageEvent) => {
|
|
78
92
|
if (typeof event.data !== "string") {
|
|
79
93
|
return; // Ignore non-string messages.
|
|
80
94
|
}
|
|
81
|
-
const message = JSON.parse(event.data);
|
|
95
|
+
const message: WebSocketResponse = JSON.parse(event.data);
|
|
82
96
|
if (message.context_id !== contextId) {
|
|
83
97
|
return; // Ignore messages for other contexts.
|
|
84
98
|
}
|
|
85
|
-
let chunk: Chunk;
|
|
99
|
+
let chunk: Chunk | undefined;
|
|
86
100
|
if (message.done) {
|
|
87
101
|
// Convert the done message to a sentinel value.
|
|
88
102
|
chunk = getSentinel();
|
|
89
|
-
} else {
|
|
103
|
+
} else if (message.type === "chunk") {
|
|
90
104
|
chunk = message.data;
|
|
91
105
|
}
|
|
92
|
-
handler({ chunk, message: event.data });
|
|
106
|
+
handler({ chunk, message: event.data, data: message });
|
|
93
107
|
};
|
|
94
108
|
}
|
|
95
109
|
|
package/src/tts/websocket.ts
CHANGED
|
@@ -6,8 +6,10 @@ import { CARTESIA_VERSION, constructApiUrl } from "../lib/constants";
|
|
|
6
6
|
import type {
|
|
7
7
|
ConnectionEventData,
|
|
8
8
|
EmitteryCallbacks,
|
|
9
|
+
StreamOptions,
|
|
9
10
|
StreamRequest,
|
|
10
11
|
WebSocketOptions,
|
|
12
|
+
WordTimestamps,
|
|
11
13
|
} from "../types";
|
|
12
14
|
import Source from "./source";
|
|
13
15
|
import {
|
|
@@ -21,6 +23,8 @@ export default class WebSocket extends Client {
|
|
|
21
23
|
socket?: PartySocketWebSocket;
|
|
22
24
|
#isConnected = false;
|
|
23
25
|
#sampleRate: number;
|
|
26
|
+
#container: string;
|
|
27
|
+
#encoding: string;
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
30
|
* Create a new WebSocket client.
|
|
@@ -28,18 +32,20 @@ export default class WebSocket extends Client {
|
|
|
28
32
|
* @param args - Arguments to pass to the Client constructor.
|
|
29
33
|
*/
|
|
30
34
|
constructor(
|
|
31
|
-
{ sampleRate }: WebSocketOptions,
|
|
35
|
+
{ sampleRate, container, encoding }: WebSocketOptions,
|
|
32
36
|
...args: ConstructorParameters<typeof Client>
|
|
33
37
|
) {
|
|
34
38
|
super(...args);
|
|
35
39
|
|
|
36
40
|
this.#sampleRate = sampleRate;
|
|
41
|
+
this.#container = container ?? "raw"; // Default to raw audio for backwards compatibility.
|
|
42
|
+
this.#encoding = encoding ?? "pcm_f32le"; // Default to 32-bit floating point PCM for backwards compatibility.
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
46
|
* Send a message over the WebSocket to start a stream.
|
|
41
47
|
*
|
|
42
|
-
* @param inputs - Stream options.
|
|
48
|
+
* @param inputs - Stream options. Defined in the StreamRequest type.
|
|
43
49
|
* @param options - Options for the stream.
|
|
44
50
|
* @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
|
|
45
51
|
* If set to `0`, the stream will not time out.
|
|
@@ -47,33 +53,37 @@ export default class WebSocket extends Client {
|
|
|
47
53
|
* @returns An Emittery instance that emits messages from the WebSocket.
|
|
48
54
|
* @returns An abort function that can be called to cancel the stream.
|
|
49
55
|
*/
|
|
50
|
-
send(
|
|
51
|
-
inputs: StreamRequest["inputs"],
|
|
52
|
-
{ timeout = 0 }: StreamRequest["options"] = {},
|
|
53
|
-
) {
|
|
56
|
+
send({ ...inputs }: StreamRequest, { timeout = 0 }: StreamOptions = {}) {
|
|
54
57
|
if (!this.#isConnected) {
|
|
55
58
|
throw new Error("Not connected to WebSocket. Call .connect() first.");
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
if (!inputs.context_id) {
|
|
62
|
+
inputs.context_id = this.#generateId();
|
|
63
|
+
}
|
|
64
|
+
if (!inputs.output_format) {
|
|
65
|
+
inputs.output_format = {
|
|
66
|
+
container: this.#container,
|
|
67
|
+
encoding: this.#encoding,
|
|
68
|
+
sample_rate: this.#sampleRate,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
// Send audio request.
|
|
59
|
-
const contextId = this.#generateId();
|
|
60
73
|
this.socket?.send(
|
|
61
74
|
JSON.stringify({
|
|
62
|
-
context_id: contextId,
|
|
63
75
|
...inputs,
|
|
64
|
-
output_format: {
|
|
65
|
-
container: "raw",
|
|
66
|
-
encoding: "pcm_f32le",
|
|
67
|
-
sample_rate: this.#sampleRate,
|
|
68
|
-
},
|
|
69
76
|
}),
|
|
70
77
|
);
|
|
71
78
|
|
|
72
79
|
const emitter = new Emittery<{
|
|
73
80
|
message: string;
|
|
81
|
+
timestamps: WordTimestamps;
|
|
74
82
|
}>();
|
|
75
83
|
const source = new Source({
|
|
76
84
|
sampleRate: this.#sampleRate,
|
|
85
|
+
encoding: this.#encoding,
|
|
86
|
+
container: this.#container,
|
|
77
87
|
});
|
|
78
88
|
// Used to signal that the stream is complete, either because the
|
|
79
89
|
// WebSocket has closed, or because the stream has finished.
|
|
@@ -84,19 +94,26 @@ export default class WebSocket extends Client {
|
|
|
84
94
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
85
95
|
}
|
|
86
96
|
const handleMessage = createMessageHandlerForContextId(
|
|
87
|
-
|
|
88
|
-
async ({ chunk, message }) => {
|
|
97
|
+
inputs.context_id,
|
|
98
|
+
async ({ chunk, message, data }) => {
|
|
89
99
|
emitter.emit("message", message);
|
|
100
|
+
if (data.type === "timestamps") {
|
|
101
|
+
emitter.emit("timestamps", data.word_timestamps);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
90
104
|
if (isSentinel(chunk)) {
|
|
91
105
|
await source.close();
|
|
92
106
|
streamCompleteController.abort();
|
|
93
107
|
return;
|
|
94
108
|
}
|
|
95
|
-
await source.enqueue(base64ToArray([chunk]));
|
|
96
109
|
if (timeoutId) {
|
|
97
110
|
clearTimeout(timeoutId);
|
|
98
111
|
timeoutId = setTimeout(streamCompleteController.abort, timeout);
|
|
99
112
|
}
|
|
113
|
+
if (!chunk) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
await source.enqueue(base64ToArray([chunk], this.#encoding));
|
|
100
117
|
},
|
|
101
118
|
);
|
|
102
119
|
this.socket?.addEventListener("message", handleMessage, {
|
|
@@ -155,14 +172,16 @@ export default class WebSocket extends Client {
|
|
|
155
172
|
* @returns A promise that resolves when the WebSocket is connected.
|
|
156
173
|
* @throws {Error} If the WebSocket fails to connect.
|
|
157
174
|
*/
|
|
158
|
-
connect() {
|
|
159
|
-
const url = constructApiUrl(this.baseUrl, "/tts/websocket", {
|
|
160
|
-
websocket: true,
|
|
161
|
-
});
|
|
162
|
-
url.searchParams.set("api_key", this.apiKey);
|
|
163
|
-
url.searchParams.set("cartesia_version", CARTESIA_VERSION);
|
|
175
|
+
async connect() {
|
|
164
176
|
const emitter = new Emittery<ConnectionEventData>();
|
|
165
|
-
this.socket = new PartySocketWebSocket(
|
|
177
|
+
this.socket = new PartySocketWebSocket(async () => {
|
|
178
|
+
const url = constructApiUrl(this.baseUrl, "/tts/websocket", {
|
|
179
|
+
websocket: true,
|
|
180
|
+
});
|
|
181
|
+
url.searchParams.set("api_key", await this.apiKey());
|
|
182
|
+
url.searchParams.set("cartesia_version", CARTESIA_VERSION);
|
|
183
|
+
return url.toString();
|
|
184
|
+
});
|
|
166
185
|
this.socket.onopen = () => {
|
|
167
186
|
this.#isConnected = true;
|
|
168
187
|
emitter.emit("open");
|
package/src/types/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type Emittery from "emittery";
|
|
2
2
|
|
|
3
3
|
export interface ClientOptions {
|
|
4
|
-
apiKey?: string;
|
|
4
|
+
apiKey?: string | (() => Promise<string>);
|
|
5
5
|
baseUrl?: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -14,13 +14,85 @@ export type ConnectionEventData = {
|
|
|
14
14
|
close: never;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
export type VoiceSpecifier =
|
|
18
|
+
| {
|
|
19
|
+
mode: "id";
|
|
20
|
+
id: string;
|
|
21
|
+
}
|
|
22
|
+
| {
|
|
23
|
+
mode: "embedding";
|
|
24
|
+
embedding: number[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type Emotion =
|
|
28
|
+
| "anger"
|
|
29
|
+
| "sadness"
|
|
30
|
+
| "positivity"
|
|
31
|
+
| "curiosity"
|
|
32
|
+
| "surprise";
|
|
33
|
+
export type Intensity = "lowest" | "low" | "high" | "highest";
|
|
34
|
+
export type EmotionControl = Emotion | `${Emotion}:${Intensity}`;
|
|
35
|
+
|
|
36
|
+
export type VoiceOptions = VoiceSpecifier & {
|
|
37
|
+
__experimental_controls?: {
|
|
38
|
+
speed?: "slowest" | "slow" | "normal" | "fast" | "fastest";
|
|
39
|
+
emotion?: EmotionControl[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
17
43
|
export type StreamRequest = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
44
|
+
model_id: string;
|
|
45
|
+
transcript: string;
|
|
46
|
+
voice: VoiceOptions;
|
|
47
|
+
output_format?: {
|
|
48
|
+
container: string;
|
|
49
|
+
encoding: string;
|
|
50
|
+
sample_rate: number;
|
|
21
51
|
};
|
|
52
|
+
context_id?: string;
|
|
53
|
+
continue?: boolean;
|
|
54
|
+
duration?: number;
|
|
55
|
+
language?: string;
|
|
56
|
+
add_timestamps?: boolean;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type StreamOptions = {
|
|
60
|
+
timeout?: number;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type WebSocketBaseResponse = {
|
|
64
|
+
context_id: string;
|
|
65
|
+
status_code: number;
|
|
66
|
+
done: boolean;
|
|
22
67
|
};
|
|
23
68
|
|
|
69
|
+
export type WordTimestamps = {
|
|
70
|
+
words: string[];
|
|
71
|
+
start: number[];
|
|
72
|
+
end: number[];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type WebSocketTimestampsResponse = WebSocketBaseResponse & {
|
|
76
|
+
type: "timestamps";
|
|
77
|
+
word_timestamps: WordTimestamps;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export type WebSocketChunkResponse = WebSocketBaseResponse & {
|
|
81
|
+
type: "chunk";
|
|
82
|
+
data: string;
|
|
83
|
+
step_time: number;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type WebSocketErrorResponse = WebSocketBaseResponse & {
|
|
87
|
+
type: "error";
|
|
88
|
+
error: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type WebSocketResponse =
|
|
92
|
+
| WebSocketTimestampsResponse
|
|
93
|
+
| WebSocketChunkResponse
|
|
94
|
+
| WebSocketErrorResponse;
|
|
95
|
+
|
|
24
96
|
export type EmitteryCallbacks<T> = {
|
|
25
97
|
on: Emittery<T>["on"];
|
|
26
98
|
off: Emittery<T>["off"];
|
|
@@ -32,10 +104,12 @@ export type CloneOptions =
|
|
|
32
104
|
| {
|
|
33
105
|
mode: "url";
|
|
34
106
|
link: string;
|
|
107
|
+
enhance?: boolean;
|
|
35
108
|
}
|
|
36
109
|
| {
|
|
37
110
|
mode: "clip";
|
|
38
111
|
clip: Blob;
|
|
112
|
+
enhance?: boolean;
|
|
39
113
|
};
|
|
40
114
|
|
|
41
115
|
export type Voice = {
|
|
@@ -46,16 +120,23 @@ export type Voice = {
|
|
|
46
120
|
is_public: boolean;
|
|
47
121
|
user_id: string;
|
|
48
122
|
created_at: string;
|
|
123
|
+
language: string;
|
|
49
124
|
};
|
|
50
125
|
|
|
51
126
|
export type CreateVoice = Pick<Voice, "name" | "description" | "embedding"> &
|
|
52
127
|
Partial<Omit<Voice, "name" | "description" | "embedding">>;
|
|
53
128
|
|
|
129
|
+
export type UpdateVoice = Partial<
|
|
130
|
+
Pick<Voice, "name" | "description" | "embedding">
|
|
131
|
+
>;
|
|
132
|
+
|
|
54
133
|
export type CloneResponse = {
|
|
55
134
|
embedding: number[];
|
|
56
135
|
};
|
|
57
136
|
|
|
58
137
|
export type WebSocketOptions = {
|
|
138
|
+
container?: string;
|
|
139
|
+
encoding?: string;
|
|
59
140
|
sampleRate: number;
|
|
60
141
|
};
|
|
61
142
|
|
|
@@ -65,3 +146,7 @@ export type SourceEventData = {
|
|
|
65
146
|
wait: never;
|
|
66
147
|
read: never;
|
|
67
148
|
};
|
|
149
|
+
|
|
150
|
+
export type TypedArray = Float32Array | Int16Array | Uint8Array;
|
|
151
|
+
|
|
152
|
+
export type Encoding = "pcm_f32le" | "pcm_s16le" | "pcm_alaw" | "pcm_mulaw";
|
package/src/voices/index.ts
CHANGED
|
@@ -1,41 +1,48 @@
|
|
|
1
1
|
import { Client } from "../lib/client";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CloneOptions,
|
|
4
|
+
CloneResponse,
|
|
5
|
+
CreateVoice,
|
|
6
|
+
UpdateVoice,
|
|
7
|
+
Voice,
|
|
8
|
+
} from "../types";
|
|
3
9
|
|
|
4
10
|
export default class Voices extends Client {
|
|
5
11
|
async list(): Promise<Voice[]> {
|
|
6
|
-
const response = await this.
|
|
12
|
+
const response = await this._fetch("/voices");
|
|
7
13
|
return response.json();
|
|
8
14
|
}
|
|
9
15
|
|
|
10
16
|
async get(voiceId: string): Promise<Voice> {
|
|
11
|
-
const response = await this.
|
|
17
|
+
const response = await this._fetch(`/voices/${voiceId}`);
|
|
12
18
|
return response.json();
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
async create(voice: CreateVoice): Promise<Voice> {
|
|
16
|
-
const response = await this.
|
|
22
|
+
const response = await this._fetch("/voices", {
|
|
17
23
|
method: "POST",
|
|
18
24
|
body: JSON.stringify(voice),
|
|
19
25
|
});
|
|
20
26
|
return response.json() as Promise<Voice>;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
|
-
async
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
31
|
-
return response.json();
|
|
32
|
-
}
|
|
29
|
+
async update(id: string, voice: UpdateVoice): Promise<Voice> {
|
|
30
|
+
const response = await this._fetch(`/voices/${id}`, {
|
|
31
|
+
method: "PATCH",
|
|
32
|
+
body: JSON.stringify(voice),
|
|
33
|
+
});
|
|
34
|
+
return response.json() as Promise<Voice>;
|
|
35
|
+
}
|
|
33
36
|
|
|
37
|
+
async clone(options: CloneOptions): Promise<CloneResponse> {
|
|
34
38
|
if (options.mode === "clip") {
|
|
35
39
|
const formData = new FormData();
|
|
36
40
|
formData.append("clip", options.clip);
|
|
41
|
+
if (options.enhance !== undefined) {
|
|
42
|
+
formData.append("enhance", options.enhance.toString());
|
|
43
|
+
}
|
|
37
44
|
|
|
38
|
-
const response = await this.
|
|
45
|
+
const response = await this._fetch("/voices/clone/clip", {
|
|
39
46
|
method: "POST",
|
|
40
47
|
body: formData,
|
|
41
48
|
});
|
package/dist/chunk-PQ5EVEEH.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BASE_URL,
|
|
3
|
-
CARTESIA_VERSION,
|
|
4
|
-
constructApiUrl
|
|
5
|
-
} from "./chunk-2BFEKY3F.js";
|
|
6
|
-
import {
|
|
7
|
-
__spreadProps,
|
|
8
|
-
__spreadValues
|
|
9
|
-
} from "./chunk-WIFMLPT5.js";
|
|
10
|
-
|
|
11
|
-
// src/lib/client.ts
|
|
12
|
-
import fetch from "cross-fetch";
|
|
13
|
-
var Client = class {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
if (!(options.apiKey || process.env.CARTESIA_API_KEY)) {
|
|
16
|
-
throw new Error("Missing Cartesia API key.");
|
|
17
|
-
}
|
|
18
|
-
this.apiKey = options.apiKey || process.env.CARTESIA_API_KEY;
|
|
19
|
-
this.baseUrl = options.baseUrl || BASE_URL;
|
|
20
|
-
}
|
|
21
|
-
fetch(path, options = {}) {
|
|
22
|
-
const url = constructApiUrl(this.baseUrl, path);
|
|
23
|
-
return fetch(url.toString(), __spreadProps(__spreadValues({}, options), {
|
|
24
|
-
headers: __spreadValues({
|
|
25
|
-
"X-API-Key": this.apiKey,
|
|
26
|
-
"Cartesia-Version": CARTESIA_VERSION
|
|
27
|
-
}, options.headers)
|
|
28
|
-
}));
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export {
|
|
33
|
-
Client
|
|
34
|
-
};
|