From 9f8fd1edfe3386a77a2a42bfeace08d92242d915 Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Wed, 3 Jul 2024 11:40:21 -0500 Subject: [PATCH 1/7] feat: add SpeakLiveClient and LiveTTSEvents --- src/lib/enums/LiveTTSEvents.ts | 31 ++++++++ src/lib/enums/index.ts | 1 + src/packages/SpeakLiveClient.ts | 130 ++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 src/lib/enums/LiveTTSEvents.ts create mode 100644 src/packages/SpeakLiveClient.ts diff --git a/src/lib/enums/LiveTTSEvents.ts b/src/lib/enums/LiveTTSEvents.ts new file mode 100644 index 0000000..b7e9a7e --- /dev/null +++ b/src/lib/enums/LiveTTSEvents.ts @@ -0,0 +1,31 @@ +/** + * Enumeration of events related to live text-to-speech synthesis. + * + * - `Open`: Built-in socket event for when the connection is opened. + * - `Close`: Built-in socket event for when the connection is closed. + * - `Error`: Built-in socket event for when an error occurs. + * - `Metadata`: Event for when metadata is received. + * - `Flushed`: Event for when the server has flushed the buffer. + * - `Warning`: Event for when a warning is received. + * - `Unhandled`: Catch-all event for any other message event. + */ +export enum LiveTTSEvents { + /** + * Built in socket events. + */ + Open = "Open", + Close = "Close", + Error = "Error", + + /** + * Message { type: string } + */ + Metadata = "Metadata", + Flushed = "Flushed", + Warning = "Warning", + + /** + * Catch all for any other message event + */ + Unhandled = "Unhandled", +} diff --git a/src/lib/enums/index.ts b/src/lib/enums/index.ts index 42226c9..d85c2cd 100644 --- a/src/lib/enums/index.ts +++ b/src/lib/enums/index.ts @@ -1,2 +1,3 @@ export * from "./LiveConnectionState"; export * from "./LiveTranscriptionEvents"; +export * from "./LiveTTSEvents"; diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts new file mode 100644 index 0000000..0cc7051 --- /dev/null +++ b/src/packages/SpeakLiveClient.ts @@ -0,0 +1,130 @@ +import { AbstractLiveClient } from "./AbstractLiveClient"; +import { LiveTTSEvents } from "../lib/enums"; +import type { SpeakSchema, DeepgramClientOptions } from "../lib/types"; + +/** + * The `SpeakLiveClient` class extends the `AbstractLiveClient` class and provides functionality for setting up and managing a WebSocket connection for live text-to-speech synthesis. + * + * The constructor takes in `DeepgramClientOptions` and an optional `SpeakSchema` object, as well as an optional `endpoint` string. It then calls the `connect` method of the parent `AbstractLiveClient` class to establish the WebSocket connection. + * + * The `setupConnection` method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving messages. It sets up event handlers for these events and emits the appropriate events based on the message type. + * + * The `configure` method allows you to send additional configuration options to the connected session. + * + * + * The `requestClose` method requests the server to close the connection. + * + */ +export class SpeakLiveClient extends AbstractLiveClient { + public namespace: string = "speak"; + + /** + * Constructs a new `SpeakLiveClient` instance with the provided options. + * + * @param options - The `DeepgramClientOptions` to use for the client connection. + * @param speakOptions - An optional `SpeakSchema` object containing additional configuration options for the text-to-speech. + * @param endpoint - An optional string representing the WebSocket endpoint to connect to. Defaults to `:version/speak`. + */ + constructor( + options: DeepgramClientOptions, + speakOptions: SpeakSchema = {}, + endpoint: string = ":version/speak" + ) { + super(options); + + this.connect(speakOptions, endpoint); + } + + /** + * Sets up the connection event handlers. + * This method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving data. + * - When the connection is opened, it emits the `LiveTTSEvents.Open` event. + * - When the connection is closed, it emits the `LiveTTSEvents.Close` event. + * - When an error occurs on the connection, it emits the `LiveTTSEvents.Error` event. + * - When a message is received, it parses the message and emits the appropriate event based on the message type, such as `LiveTTSEvents.Metadata`, `LiveTTSEvents.Flushed`, and `LiveTTSEvents.Warning`. + */ + public setupConnection(): void { + if (this.conn) { + this.conn.onopen = () => { + this.emit(LiveTTSEvents.Open, this); + }; + + this.conn.onclose = (event: any) => { + this.emit(LiveTTSEvents.Close, event); + }; + + this.conn.onerror = (event: ErrorEvent) => { + this.emit(LiveTTSEvents.Error, event); + }; + + this.conn.onmessage = (event: MessageEvent) => { + try { + const data: any = JSON.parse(event.data.toString()); + + if (data.type === LiveTTSEvents.Metadata) { + this.emit(LiveTTSEvents.Metadata, data); + } else if (data.type === LiveTTSEvents.Flushed) { + this.emit(LiveTTSEvents.Flushed, data); + } else if (data.type === "Warning") { + this.emit(LiveTTSEvents.Warning, data); + } else { + this.emit(LiveTTSEvents.Unhandled, data); + } + } catch (error) { + this.emit(LiveTTSEvents.Error, { + event, + message: "Unable to parse `data` as JSON.", + error, + }); + } + }; + } + } + + /** + * Sends a text input message to the server. + * + * @param text - The text to convert to speech. + */ + public sendText(text: string): void { + this.send( + JSON.stringify({ + type: "Speak", + text, + }) + ); + } + + /** + * Requests the server flush the current buffer and return generated audio. + */ + public flush(): void { + this.send( + JSON.stringify({ + type: "Flush", + }) + ); + } + /** + * Requests the server reset the current buffer. + */ + public reset(): void { + this.send( + JSON.stringify({ + type: "Reset", + }) + ); + } + /** + * Requests the server close the connection. + */ + public requestClose(): void { + this.send( + JSON.stringify({ + type: "Close", + }) + ); + } +} + +export { SpeakLiveClient as Liveclient }; From 54036a3a07afc3dd5a5014779113d23ce5f52b3c Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Wed, 3 Jul 2024 12:04:39 -0500 Subject: [PATCH 2/7] feat: update AbstractLiveClient to handle binary data --- src/lib/enums/LiveTTSEvents.ts | 5 ++++ src/packages/AbstractLiveClient.ts | 43 +++++++++++++++++++++++++++++ src/packages/SpeakLiveClient.ts | 44 +++++++++++++++++------------- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/lib/enums/LiveTTSEvents.ts b/src/lib/enums/LiveTTSEvents.ts index b7e9a7e..6c39a47 100644 --- a/src/lib/enums/LiveTTSEvents.ts +++ b/src/lib/enums/LiveTTSEvents.ts @@ -24,6 +24,11 @@ export enum LiveTTSEvents { Flushed = "Flushed", Warning = "Warning", + /** + * Audio data event. + */ + Audio = "Audio", + /** * Catch all for any other message event */ diff --git a/src/packages/AbstractLiveClient.ts b/src/packages/AbstractLiveClient.ts index b0cf78c..088fffc 100644 --- a/src/packages/AbstractLiveClient.ts +++ b/src/packages/AbstractLiveClient.ts @@ -2,6 +2,7 @@ import { AbstractClient, noop } from "./AbstractClient"; import { CONNECTION_STATE, SOCKET_STATES } from "../lib/constants"; import type { DeepgramClientOptions, LiveSchema } from "../lib/types"; import type { WebSocket as WSWebSocket } from "ws"; +import { LiveTTSEvents } from "../lib/enums"; /** * Represents a constructor for a WebSocket-like object that can be used in the application. @@ -258,6 +259,48 @@ export abstract class AbstractLiveClient extends AbstractClient { * @abstract Requires subclasses to set up context aware event handlers. */ abstract setupConnection(): void; + + /** + * Handles incoming messages from the WebSocket connection. + * @param event - The MessageEvent object representing the received message. + */ + protected handleMessage(event: MessageEvent): void { + if (typeof event.data === "string") { + try { + const data = JSON.parse(event.data); + this.handleTextMessage(data); + } catch (error) { + this.emit(LiveTTSEvents.Error, { + event, + message: "Unable to parse `data` as JSON.", + error, + }); + } + } else if (event.data instanceof ArrayBuffer) { + this.handleBinaryMessage(event.data); + } else { + this.emit(LiveTTSEvents.Error, { + event, + message: "Received unknown data type.", + }); + } + } + + /** + * Handles text messages received from the WebSocket connection. + * @param data - The parsed JSON data. + */ + protected handleTextMessage(data: any): void { + // To be implemented by subclasses + } + + /** + * Handles binary messages received from the WebSocket connection. + * @param data - The binary data. + */ + protected handleBinaryMessage(data: ArrayBuffer): void { + // To be implemented by subclasses + } } class WSWebSocketDummy { diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts index 0cc7051..a3c12ef 100644 --- a/src/packages/SpeakLiveClient.ts +++ b/src/packages/SpeakLiveClient.ts @@ -58,29 +58,35 @@ export class SpeakLiveClient extends AbstractLiveClient { }; this.conn.onmessage = (event: MessageEvent) => { - try { - const data: any = JSON.parse(event.data.toString()); - - if (data.type === LiveTTSEvents.Metadata) { - this.emit(LiveTTSEvents.Metadata, data); - } else if (data.type === LiveTTSEvents.Flushed) { - this.emit(LiveTTSEvents.Flushed, data); - } else if (data.type === "Warning") { - this.emit(LiveTTSEvents.Warning, data); - } else { - this.emit(LiveTTSEvents.Unhandled, data); - } - } catch (error) { - this.emit(LiveTTSEvents.Error, { - event, - message: "Unable to parse `data` as JSON.", - error, - }); - } + this.handleMessage(event); }; } } + /** + * Handles text messages received from the WebSocket connection. + * @param data - The parsed JSON data. + */ + protected handleTextMessage(data: any): void { + if (data.type === LiveTTSEvents.Metadata) { + this.emit(LiveTTSEvents.Metadata, data); + } else if (data.type === LiveTTSEvents.Flushed) { + this.emit(LiveTTSEvents.Flushed, data); + } else if (data.type === LiveTTSEvents.Warning) { + this.emit(LiveTTSEvents.Warning, data); + } else { + this.emit(LiveTTSEvents.Unhandled, data); + } + } + + /** + * Handles binary messages received from the WebSocket connection. + * @param data - The binary data. + */ + protected handleBinaryMessage(data: ArrayBuffer): void { + this.emit(LiveTTSEvents.Audio, data); + } + /** * Sends a text input message to the server. * From 9134fb098f29f9a9a0141209914b1370d4eae485 Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Wed, 3 Jul 2024 16:18:38 -0500 Subject: [PATCH 3/7] feat: add SpeakClient and example --- examples/node-speak-live/index.js | 44 +++++++++++++++++++++++++++++++ src/packages/SpeakClient.ts | 32 ++++++++++++++++++++++ src/packages/SpeakLiveClient.ts | 6 ++--- src/packages/SpeakRestClient.ts | 2 -- src/packages/index.ts | 2 +- 5 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 examples/node-speak-live/index.js create mode 100644 src/packages/SpeakClient.ts diff --git a/examples/node-speak-live/index.js b/examples/node-speak-live/index.js new file mode 100644 index 0000000..d544111 --- /dev/null +++ b/examples/node-speak-live/index.js @@ -0,0 +1,44 @@ +const { createClient, LiveTTSEvents } = require("../../dist/main/index"); +const fetch = require("cross-fetch"); + +const live = async () => { + const text = "Hello, how can I help you today?"; + + const deepgram = createClient(process.env.DEEPGRAM_API_KEY, { + global: { fetch: { options: { url: "https://api.beta.deepgram.com" } } }, + }); + + const connection = deepgram.speak.live({ text }, { model: "aura-asteria-en" }); + + connection.on(LiveTTSEvents.Open, () => { + connection.on(LiveTTSEvents.Close, () => { + console.log("Connection closed."); + }); + + connection.on(LiveTTSEvents.Metadata, (data) => { + console.log(`Deepgram Metadata: ${data}`); + }); + + connection.on(LiveTTSEvents.Audio, (data) => { + console.log(`Deepgram Audio: ${data}`); + }); + + connection.on(LiveTTSEvents.Flushed, (data) => { + console.log("Deepgram Flushed"); + }); + + connection.on(LiveTTSEvents.Error, (err) => { + console.error(err); + }); + + fetch(url) + .then((r) => r.body) + .then((res) => { + res.on("readable", () => { + connection.send(res.read()); + }); + }); + }); +}; + +live(); diff --git a/src/packages/SpeakClient.ts b/src/packages/SpeakClient.ts new file mode 100644 index 0000000..ab4b2d8 --- /dev/null +++ b/src/packages/SpeakClient.ts @@ -0,0 +1,32 @@ +import { AbstractClient } from "./AbstractClient"; +import { SpeakLiveClient } from "./SpeakLiveClient"; +import { SpeakRestClient } from "./SpeakRestClient"; +import { SpeakSchema } from "../lib/types"; + +/** + * The `SpeakClient` class extends the `AbstractClient` class and provides access to the "speak" namespace. + * It exposes two methods: + * + * 1. `request()`: Returns a `SpeakRestClient` instance for interacting with the rest speak API. + * 2. `live(ttsOptions: SpeakSchema = {}, endpoint = ":version/speak")`: Returns a `SpeakLiveClient` instance for interacting with the live speak API, with the provided TTS options and endpoint. + */ +export class SpeakClient extends AbstractClient { + public namespace: string = "speak"; + + /** + * Returns a `SpeakRestClient` instance for interacting with the rest speak API. + */ + get request() { + return new SpeakRestClient(this.options); + } + + /** + * Returns a `SpeakLiveClient` instance for interacting with the live speak API, with the provided TTS options and endpoint. + * @param {SpeakSchema} [ttsOptions={}] - The TTS options to use for the live speak API. + * @param {string} [endpoint=":version/speak"] - The endpoint to use for the live speak API. + * @returns {SpeakLiveClient} - A `SpeakLiveClient` instance for interacting with the live speak API. + */ + public live(ttsOptions: SpeakSchema = {}, endpoint: string = ":version/speak"): SpeakLiveClient { + return new SpeakLiveClient(this.options, ttsOptions, endpoint); + } +} diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts index a3c12ef..075dd29 100644 --- a/src/packages/SpeakLiveClient.ts +++ b/src/packages/SpeakLiveClient.ts @@ -90,7 +90,7 @@ export class SpeakLiveClient extends AbstractLiveClient { /** * Sends a text input message to the server. * - * @param text - The text to convert to speech. + * @param {string} text - The text to convert to speech. */ public sendText(text: string): void { this.send( @@ -111,6 +111,7 @@ export class SpeakLiveClient extends AbstractLiveClient { }) ); } + /** * Requests the server reset the current buffer. */ @@ -121,6 +122,7 @@ export class SpeakLiveClient extends AbstractLiveClient { }) ); } + /** * Requests the server close the connection. */ @@ -132,5 +134,3 @@ export class SpeakLiveClient extends AbstractLiveClient { ); } } - -export { SpeakLiveClient as Liveclient }; diff --git a/src/packages/SpeakRestClient.ts b/src/packages/SpeakRestClient.ts index 0695e96..30db0a9 100644 --- a/src/packages/SpeakRestClient.ts +++ b/src/packages/SpeakRestClient.ts @@ -75,5 +75,3 @@ export class SpeakRestClient extends AbstractRestClient { return this.result.headers; } } - -export { SpeakRestClient as SpeakClient }; diff --git a/src/packages/index.ts b/src/packages/index.ts index 92d7bdf..8d6512b 100644 --- a/src/packages/index.ts +++ b/src/packages/index.ts @@ -7,4 +7,4 @@ export * from "./ListenRestClient"; export * from "./ManageRestClient"; export * from "./ReadRestClient"; export * from "./SelfHostedRestClient"; -export * from "./SpeakRestClient"; +export * from "./SpeakClient"; From 23e8fe1cf67d9f12e2f99134e4846dc4de52c443 Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Mon, 8 Jul 2024 13:03:21 -0500 Subject: [PATCH 4/7] feat: finishing touches TTS live client --- examples/node-speak-live/index.js | 50 ++++++++++++++++++++---------- src/packages/AbstractLiveClient.ts | 43 ------------------------- src/packages/SpeakClient.ts | 7 +++-- src/packages/SpeakLiveClient.ts | 31 ++++++++++++++++-- src/packages/index.ts | 2 ++ 5 files changed, 70 insertions(+), 63 deletions(-) diff --git a/examples/node-speak-live/index.js b/examples/node-speak-live/index.js index d544111..95910cb 100644 --- a/examples/node-speak-live/index.js +++ b/examples/node-speak-live/index.js @@ -1,44 +1,62 @@ +const fs = require("fs"); const { createClient, LiveTTSEvents } = require("../../dist/main/index"); -const fetch = require("cross-fetch"); const live = async () => { const text = "Hello, how can I help you today?"; - const deepgram = createClient(process.env.DEEPGRAM_API_KEY, { - global: { fetch: { options: { url: "https://api.beta.deepgram.com" } } }, - }); + const deepgram = createClient(process.env.DEEPGRAM_API_KEY); + + const connection = deepgram.speak.live({ model: "aura-asteria-en" }); - const connection = deepgram.speak.live({ text }, { model: "aura-asteria-en" }); + let audioBuffer = Buffer.alloc(0); connection.on(LiveTTSEvents.Open, () => { + console.log("Connection opened"); + + // Send text data for TTS synthesis + connection.sendText(text); + + // Send Flush message to the server after sending the text + connection.flush(); + connection.on(LiveTTSEvents.Close, () => { - console.log("Connection closed."); + console.log("Connection closed"); }); connection.on(LiveTTSEvents.Metadata, (data) => { - console.log(`Deepgram Metadata: ${data}`); + console.dir(data, { depth: null }); }); connection.on(LiveTTSEvents.Audio, (data) => { - console.log(`Deepgram Audio: ${data}`); + console.log("Deepgram audio data received"); + // Concatenate the audio chunks into a single buffer + const buffer = Buffer.from(data); + audioBuffer = Buffer.concat([audioBuffer, buffer]); }); - connection.on(LiveTTSEvents.Flushed, (data) => { + connection.on(LiveTTSEvents.Flushed, () => { console.log("Deepgram Flushed"); + // Write the buffered audio data to a file when the flush event is received + writeFile(); }); connection.on(LiveTTSEvents.Error, (err) => { console.error(err); }); + }); - fetch(url) - .then((r) => r.body) - .then((res) => { - res.on("readable", () => { - connection.send(res.read()); - }); + const writeFile = () => { + if (audioBuffer.length > 0) { + fs.writeFile("output.mp3", audioBuffer, (err) => { + if (err) { + console.error("Error writing audio file:", err); + } else { + console.log("Audio file saved as output.mp3"); + } }); - }); + audioBuffer = Buffer.alloc(0); // Reset buffer after writing + } + }; }; live(); diff --git a/src/packages/AbstractLiveClient.ts b/src/packages/AbstractLiveClient.ts index 088fffc..b0cf78c 100644 --- a/src/packages/AbstractLiveClient.ts +++ b/src/packages/AbstractLiveClient.ts @@ -2,7 +2,6 @@ import { AbstractClient, noop } from "./AbstractClient"; import { CONNECTION_STATE, SOCKET_STATES } from "../lib/constants"; import type { DeepgramClientOptions, LiveSchema } from "../lib/types"; import type { WebSocket as WSWebSocket } from "ws"; -import { LiveTTSEvents } from "../lib/enums"; /** * Represents a constructor for a WebSocket-like object that can be used in the application. @@ -259,48 +258,6 @@ export abstract class AbstractLiveClient extends AbstractClient { * @abstract Requires subclasses to set up context aware event handlers. */ abstract setupConnection(): void; - - /** - * Handles incoming messages from the WebSocket connection. - * @param event - The MessageEvent object representing the received message. - */ - protected handleMessage(event: MessageEvent): void { - if (typeof event.data === "string") { - try { - const data = JSON.parse(event.data); - this.handleTextMessage(data); - } catch (error) { - this.emit(LiveTTSEvents.Error, { - event, - message: "Unable to parse `data` as JSON.", - error, - }); - } - } else if (event.data instanceof ArrayBuffer) { - this.handleBinaryMessage(event.data); - } else { - this.emit(LiveTTSEvents.Error, { - event, - message: "Received unknown data type.", - }); - } - } - - /** - * Handles text messages received from the WebSocket connection. - * @param data - The parsed JSON data. - */ - protected handleTextMessage(data: any): void { - // To be implemented by subclasses - } - - /** - * Handles binary messages received from the WebSocket connection. - * @param data - The binary data. - */ - protected handleBinaryMessage(data: ArrayBuffer): void { - // To be implemented by subclasses - } } class WSWebSocketDummy { diff --git a/src/packages/SpeakClient.ts b/src/packages/SpeakClient.ts index ab4b2d8..097e070 100644 --- a/src/packages/SpeakClient.ts +++ b/src/packages/SpeakClient.ts @@ -2,6 +2,7 @@ import { AbstractClient } from "./AbstractClient"; import { SpeakLiveClient } from "./SpeakLiveClient"; import { SpeakRestClient } from "./SpeakRestClient"; import { SpeakSchema } from "../lib/types"; +import { TextSource } from "../lib/types"; /** * The `SpeakClient` class extends the `AbstractClient` class and provides access to the "speak" namespace. @@ -16,8 +17,10 @@ export class SpeakClient extends AbstractClient { /** * Returns a `SpeakRestClient` instance for interacting with the rest speak API. */ - get request() { - return new SpeakRestClient(this.options); + public request(source: TextSource, options?: SpeakSchema, endpoint = ":version/speak") { + const client = new SpeakRestClient(this.options); + + return client.request(source, options, endpoint); } /** diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts index 075dd29..47b3b2f 100644 --- a/src/packages/SpeakLiveClient.ts +++ b/src/packages/SpeakLiveClient.ts @@ -11,9 +11,7 @@ import type { SpeakSchema, DeepgramClientOptions } from "../lib/types"; * * The `configure` method allows you to send additional configuration options to the connected session. * - * * The `requestClose` method requests the server to close the connection. - * */ export class SpeakLiveClient extends AbstractLiveClient { public namespace: string = "speak"; @@ -133,4 +131,33 @@ export class SpeakLiveClient extends AbstractLiveClient { }) ); } + + /** + * Handles incoming messages from the WebSocket connection. + * @param event - The MessageEvent object representing the received message. + */ + protected handleMessage(event: MessageEvent): void { + if (typeof event.data === "string") { + try { + const data = JSON.parse(event.data); + this.handleTextMessage(data); + } catch (error) { + this.emit(LiveTTSEvents.Error, { + event, + message: "Unable to parse `data` as JSON.", + error, + }); + } + } else if (event.data instanceof ArrayBuffer) { + this.handleBinaryMessage(event.data); + } else if (Buffer.isBuffer(event.data)) { + this.handleBinaryMessage(event.data.buffer); + } else { + console.log("Received unknown data type", event.data); + this.emit(LiveTTSEvents.Error, { + event, + message: "Received unknown data type.", + }); + } + } } diff --git a/src/packages/index.ts b/src/packages/index.ts index 8d6512b..ce580f8 100644 --- a/src/packages/index.ts +++ b/src/packages/index.ts @@ -8,3 +8,5 @@ export * from "./ManageRestClient"; export * from "./ReadRestClient"; export * from "./SelfHostedRestClient"; export * from "./SpeakClient"; +export * from "./SpeakLiveClient"; +export * from "./SpeakRestClient"; From d290ec93c1f0e50d6c72bf6a64c677f0c933585e Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Mon, 8 Jul 2024 13:06:12 -0500 Subject: [PATCH 5/7] chore: update readme for TTS websocket --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 62792e2..7faf07c 100644 --- a/README.md +++ b/README.md @@ -382,10 +382,18 @@ const vttOutput = webvtt(result); # Text to Speech +## Rest + ```js const { result } = await deepgram.speak.request({ text }, { model: "aura-asteria-en" }); ``` +## Websocket + +```js +const connection = deepgram.speak.live({ model: "aura-asteria-en" }); +``` + [See our API reference for more info](https://developers.deepgram.com/reference/text-to-speech-api). # Text Intelligence From 66bbf804f116fee993512de2751e8a5c776bf27e Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 4 Jul 2024 13:24:20 +0200 Subject: [PATCH 6/7] fix: correct spelling of LiveClient --- src/packages/ListenLiveClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ListenLiveClient.ts b/src/packages/ListenLiveClient.ts index ca8076b..4fc6af7 100644 --- a/src/packages/ListenLiveClient.ts +++ b/src/packages/ListenLiveClient.ts @@ -130,4 +130,4 @@ export class ListenLiveClient extends AbstractLiveClient { } } -export { ListenLiveClient as Liveclient }; +export { ListenLiveClient as LiveClient }; From a43d766db75e32a4827e6524beb4a0fab2e55c93 Mon Sep 17 00:00:00 2001 From: Sandra Rodgers Date: Mon, 8 Jul 2024 14:40:53 -0500 Subject: [PATCH 7/7] chore: update example and readme to be consistent with live STT --- README.md | 16 +++++++++++++++- examples/node-speak-live/index.js | 18 +++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7faf07c..2359967 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,21 @@ const { result } = await deepgram.speak.request({ text }, { model: "aura-asteria ## Websocket ```js -const connection = deepgram.speak.live({ model: "aura-asteria-en" }); +const dgConnection = deepgram.speak.live({ model: "aura-asteria-en" }); + +dgConnection.on(LiveTTSEvents.Open, () => { + console.log("Connection opened"); + + // Send text data for TTS synthesis + dgConnection.sendText(text); + + // Send Flush message to the server after sending the text + dgConnection.flush(); + + dgConnection.on(LiveTTSEvents.Close, () => { + console.log("Connection closed"); + }); +}); ``` [See our API reference for more info](https://developers.deepgram.com/reference/text-to-speech-api). diff --git a/examples/node-speak-live/index.js b/examples/node-speak-live/index.js index 95910cb..4cc1ceb 100644 --- a/examples/node-speak-live/index.js +++ b/examples/node-speak-live/index.js @@ -6,41 +6,41 @@ const live = async () => { const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const connection = deepgram.speak.live({ model: "aura-asteria-en" }); + const dgConnection = deepgram.speak.live({ model: "aura-asteria-en" }); let audioBuffer = Buffer.alloc(0); - connection.on(LiveTTSEvents.Open, () => { + dgConnection.on(LiveTTSEvents.Open, () => { console.log("Connection opened"); // Send text data for TTS synthesis - connection.sendText(text); + dgConnection.sendText(text); // Send Flush message to the server after sending the text - connection.flush(); + dgConnection.flush(); - connection.on(LiveTTSEvents.Close, () => { + dgConnection.on(LiveTTSEvents.Close, () => { console.log("Connection closed"); }); - connection.on(LiveTTSEvents.Metadata, (data) => { + dgConnection.on(LiveTTSEvents.Metadata, (data) => { console.dir(data, { depth: null }); }); - connection.on(LiveTTSEvents.Audio, (data) => { + dgConnection.on(LiveTTSEvents.Audio, (data) => { console.log("Deepgram audio data received"); // Concatenate the audio chunks into a single buffer const buffer = Buffer.from(data); audioBuffer = Buffer.concat([audioBuffer, buffer]); }); - connection.on(LiveTTSEvents.Flushed, () => { + dgConnection.on(LiveTTSEvents.Flushed, () => { console.log("Deepgram Flushed"); // Write the buffered audio data to a file when the flush event is received writeFile(); }); - connection.on(LiveTTSEvents.Error, (err) => { + dgConnection.on(LiveTTSEvents.Error, (err) => { console.error(err); }); });