### Initialize and Start Project Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Commands to clone submodules, install dependencies, and launch the backend and frontend servers. ```bash # Initialize (clone submodules + install deps) make init # Set up environment test -f .env || cp sample.env .env # then set DEEPGRAM_API_KEY # Start both servers make start # Backend: http://localhost:8081 # Frontend: http://localhost:8080 ``` -------------------------------- ### Initialize and Start Project Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/README.md Use this command to initialize the project dependencies, copy the environment file, and start the local development server. Ensure your DEEPGRAM_API_KEY is set in the .env file. ```bash make init cp sample.env .env # Add your DEEPGRAM_API_KEY make start ``` -------------------------------- ### Install Dependencies Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Commands to install backend and frontend dependencies. ```bash cargo build Frontend: cd frontend && corepack pnpm install ``` -------------------------------- ### Initialize Project with Make Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Clones submodules and installs project dependencies to set up the development environment. ```bash # Initialize project (clone submodules + install dependencies) make init ``` -------------------------------- ### Start Development Servers with Make Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Launches both the backend and frontend development servers simultaneously. ```bash # Start both backend and frontend servers make start # Backend runs at: http://localhost:8081 # Frontend runs at: http://localhost:8080 ``` -------------------------------- ### Start and Stop Commands Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Utility commands for managing the lifecycle of the development servers. ```bash make start ``` ```bash # Terminal 1 — Backend cargo run # Terminal 2 — Frontend cd frontend && corepack pnpm run dev -- --port 8080 --no-open ``` ```bash lsof -ti:8080,8081 | xargs kill -9 2>/dev/null ``` ```bash rm -rf target frontend/node_modules frontend/.vite make init ``` -------------------------------- ### Environment Variables Setup - Bash Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Configure the application using environment variables. Copy `sample.env` to `.env` and set required values. ```bash # sample.env - Copy to .env and configure # Required: Your Deepgram API key DEEPGRAM_API_KEY=your_deepgram_api_key_here # Optional: Backend server port (default: 8081) PORT=8081 # Optional: Server bind address (default: 0.0.0.0) HOST=0.0.0.0 # Optional: JWT signing secret (auto-generated if not set) # Set this in production for consistent token validation across restarts SESSION_SECRET=your_secret_key_here ``` -------------------------------- ### Check Prerequisites with Make Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Ensures that necessary development tools like git, cargo, and pnpm are installed on the system. ```bash # Check prerequisites (git, cargo, pnpm) make check-prereqs ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Standardized commit message formats for project contributions. ```text feat(rust-live-text-to-speech): add diarization support fix(rust-live-text-to-speech): resolve WebSocket close handling refactor(rust-live-text-to-speech): simplify session endpoint chore(deps): update frontend submodule ``` -------------------------------- ### Start Frontend Server Separately Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Runs only the frontend development server, allowing for frontend-specific debugging. Can be invoked directly with `pnpm` commands. ```bash # Terminal 2 - Start frontend only make start-frontend # Or directly: cd frontend && corepack pnpm run dev -- --port 8080 --no-open ``` -------------------------------- ### Start Backend Server Separately Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Runs only the backend server, useful for debugging specific backend issues. Can be run directly with `cargo run`. ```bash # Terminal 1 - Start backend only make start-backend # Or directly: cargo run ``` -------------------------------- ### GET /api/metadata Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Endpoint to retrieve application metadata. ```APIDOC ## GET /api/metadata ### Description This endpoint returns metadata about the application, including its use case, framework, and programming language. ### Method GET ### Endpoint `/api/metadata` ### Parameters None ### Response #### Success Response (200) - **useCase** (string) - The primary use case of the application. - **framework** (string) - The backend framework used (e.g., Axum). - **language** (string) - The programming language used (e.g., Rust). ``` -------------------------------- ### GET /api/session Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Endpoint to issue JWT session tokens for authentication. ```APIDOC ## GET /api/session ### Description This endpoint issues a JSON Web Token (JWT) session token. This token can be used for authenticating WebSocket connections. ### Method GET ### Endpoint `/api/session` ### Parameters None ### Response #### Success Response (200) - **token** (string) - The issued JWT session token. ``` -------------------------------- ### GET /api/metadata - Project Metadata Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Retrieves project metadata, such as title, description, author, and tags, from the `deepgram.toml` configuration file. ```APIDOC ## GET /api/metadata ### Description Returns project metadata from the `deepgram.toml` configuration file, including use case, framework, and language information. ### Method GET ### Endpoint /api/metadata ### Parameters None ### Request Example ```bash curl -s http://localhost:8081/api/metadata | python3 -m json.tool ``` ### Response #### Success Response (200) - **title** (string) - The title of the project. - **description** (string) - A brief description of the project. - **author** (string) - The author(s) of the project. - **repository** (string) - URL to the project's repository. - **useCase** (string) - The primary use case of the application. - **language** (string) - The programming language used. - **framework** (string) - The web framework used. - **sdk** (string) - The SDK used (if any). - **tags** (array of strings) - Keywords associated with the project. #### Response Example ```json { "title": "Rust Live Text-to-Speech Starter", "description": "Get started using Deepgram's Live Text-to-Speech with this Rust demo app", "author": "Deepgram DX Team (https://developers.deepgram.com)", "repository": "https://github.com/deepgram-starters/rust-live-text-to-speech", "useCase": "live-text-to-speech", "language": "Rust", "framework": "Axum", "sdk": "N/A", "tags": ["live-text-to-speech", "live-tts", "streaming-tts", "real-time-tts", "streaming-text-to-speech", "rust", "axum"] } ``` ``` -------------------------------- ### GET /health - Health Check Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt A simple health check endpoint to verify if the server is running and responsive. ```APIDOC ## GET /health ### Description Simple health check endpoint that returns the server status. ### Method GET ### Endpoint /health ### Parameters None ### Request Example ```bash curl -s http://localhost:8081/health ``` ### Response #### Success Response (200) - **status** (string) - The status of the server, typically "ok". #### Response Example ```json {"status":"ok"} ``` ``` -------------------------------- ### GET /api/session - Issue JWT Session Token Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt This endpoint issues a signed JWT token required for authenticating WebSocket connections to the Deepgram Live Text-to-Speech API. The token is valid for 1 hour. ```APIDOC ## GET /api/session ### Description Issues a signed JWT token for authenticating WebSocket connections. The token is valid for 1 hour and is required for connecting to the live text-to-speech WebSocket endpoint. ### Method GET ### Endpoint /api/session ### Parameters None ### Request Example ```bash curl -s http://localhost:8081/api/session ``` ### Response #### Success Response (200) - **token** (string) - The JWT session token. #### Response Example ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ### Usage Notes Use the obtained token to authenticate WebSocket connections via the `Sec-WebSocket-Protocol` header with the format: `access_token.`. ``` -------------------------------- ### Build Frontend for Production Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Compiles the frontend application for deployment. ```bash # Build frontend for production make build ``` -------------------------------- ### Set Up Environment Variables Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Copies the sample environment file and prompts the user to edit it with their Deepgram API key. ```bash # Set up environment cp sample.env .env # Edit .env and add your DEEPGRAM_API_KEY ``` -------------------------------- ### Clean Rebuild from Scratch Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Removes all build artifacts, node modules, and Vite cache, then re-initializes the project. ```bash # Clean rebuild from scratch rm -rf target frontend/node_modules frontend/.vite make init ``` -------------------------------- ### Configuration Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Details on how to configure the Rust Live Text-to-Speech application using environment variables and Rust structs. ```APIDOC ## Configuration ### Environment Variables Setup Configure the application using environment variables. Copy `sample.env` to `.env` and set required values. ```bash # sample.env - Copy to .env and configure # Required: Your Deepgram API key DEEPGRAM_API_KEY=your_deepgram_api_key_here # Optional: Backend server port (default: 8081) PORT=8081 # Optional: Server bind address (default: 0.0.0.0) HOST=0.0.0.0 # Optional: JWT signing secret (auto-generated if not set) # Set this in production for consistent token validation across restarts SESSION_SECRET=your_secret_key_here ``` ### Config Struct in Rust The application configuration is loaded from environment variables with sensible defaults. ```rust /// Application configuration loaded from environment variables. #[derive(Clone)] struct Config { deepgram_api_key: String, deepgram_tts_url: String, port: u16, host: String, session_secret: String, } /// Loads configuration from environment variables with sensible defaults. fn load_config() -> Config { // Load .env file (optional, won't error if missing) let _ = dotenvy::dotenv(); let deepgram_api_key = env::var("DEEPGRAM_API_KEY").unwrap_or_else(|_| { eprintln!("ERROR: DEEPGRAM_API_KEY environment variable is required"); std::process::exit(1); }); let port = env::var("PORT") .unwrap_or_else(|_| "8081".to_string()) .parse::() .expect("PORT must be a valid number"); let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string()); // Auto-generate session secret if not provided let session_secret = env::var("SESSION_SECRET").unwrap_or_else(|_| { use rand::Rng; let mut rng = rand::thread_rng(); let bytes: Vec = (0..32).map(|_| rng.r#gen()).collect(); hex::encode(bytes) }); Config { deepgram_api_key, deepgram_tts_url: "wss://api.deepgram.com/v1/speak".to_string(), port, host, session_secret, } } ``` ``` -------------------------------- ### Fetch Project Metadata via cURL Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Retrieves project configuration details from the backend. ```bash # Fetch project metadata curl -s http://localhost:8081/api/metadata | python3 -m json.tool # Response: # { # "title": "Rust Live Text-to-Speech Starter", # "description": "Get started using Deepgram's Live Text-to-Speech with this Rust demo app", # "author": "Deepgram DX Team (https://developers.deepgram.com)", # "repository": "https://github.com/deepgram-starters/rust-live-text-to-speech", # "useCase": "live-text-to-speech", # "language": "Rust", # "framework": "Axum", # "sdk": "N/A", # "tags": ["live-text-to-speech", "live-tts", "streaming-tts", "real-time-tts", "streaming-text-to-speech", "rust", "axum"] # } ``` -------------------------------- ### Specify Audio Container - Bash Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Specifies the audio container format. Default is `none` for raw audio. ```bash # Container options: none, wav, ogg ws://localhost:8081/api/live-text-to-speech?container=none ``` -------------------------------- ### Testing and Endpoint Verification Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Commands to execute conformance tests and verify API metadata and session endpoints. ```bash # Run conformance tests (requires app to be running) make test # Manual endpoint check curl -sf http://localhost:8081/api/metadata | python3 -m json.tool curl -sf http://localhost:8081/api/session | python3 -m json.tool ``` -------------------------------- ### Run Conformance Tests Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Executes contract conformance tests, which requires the application to be running. ```bash # Run conformance tests (requires app to be running) make test ``` -------------------------------- ### Clean Build Artifacts with Make Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Removes generated build files and dependencies to ensure a clean state. ```bash # Clean all build artifacts make clean ``` -------------------------------- ### Config Struct in Rust Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt The application configuration is loaded from environment variables with sensible defaults. ```rust /// Application configuration loaded from environment variables. #[derive(Clone)] struct Config { deepgram_api_key: String, deepgram_tts_url: String, port: u16, host: String, session_secret: String, } /// Loads configuration from environment variables with sensible defaults. fn load_config() -> Config { // Load .env file (optional, won't error if missing) let _ = dotenvy::dotenv(); let deepgram_api_key = env::var("DEEPGRAM_API_KEY").unwrap_or_else(|_| { eprintln!("ERROR: DEEPGRAM_API_KEY environment variable is required"); std::process::exit(1); }); let port = env::var("PORT") .unwrap_or_else(|_| "8081".to_string()) .parse::() .expect("PORT must be a valid number"); let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string()); // Auto-generate session secret if not provided let session_secret = env::var("SESSION_SECRET").unwrap_or_else(|_| { use rand::Rng; let mut rng = rand::thread_rng(); let bytes: Vec = (0..32).map(|_| rng.r#gen()).collect(); hex::encode(bytes) }); Config { deepgram_api_key, deepgram_tts_url: "wss://api.deepgram.com/v1/speak".to_string(), port, host, session_secret, } } ``` -------------------------------- ### Specify Audio Encoding - Bash Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Specifies the audio encoding format. Default is `linear16`. ```bash # Encoding options: linear16, mp3, opus, mulaw, alaw ws://localhost:8081/api/live-text-to-speech?encoding=linear16 # For raw PCM playback, use linear16 with container=none # For compressed formats, consider mp3 or opus ``` -------------------------------- ### Specify Sample Rate - Bash Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Specifies the audio sample rate in Hz. Default is `24000`. Range is `8000` to `48000`. ```bash # Common sample rates: 8000, 16000, 22050, 24000, 44100, 48000 ws://localhost:8081/api/live-text-to-speech?sample_rate=48000 ``` -------------------------------- ### API Endpoints Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Overview of the available API endpoints for the Rust Axum backend. ```APIDOC ## API Endpoints | Endpoint | Method | Auth | Purpose | |----------|--------|------|---------| | `/api/session` | GET | None | Issue JWT session token | | `/api/metadata` | GET | None | Return app metadata (useCase, framework, language) | | `/api/live-text-to-speech` | WS | JWT | Streams text to Deepgram for real-time audio generation. | ``` -------------------------------- ### Specify Voice Model - Bash Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Specifies the voice model for text-to-speech synthesis. Default is `aura-asteria-en`. ```bash # Available models include various aura-* voices # Example: aura-asteria-en, aura-luna-en, aura-stella-en, etc. ws://localhost:8081/api/live-text-to-speech?model=aura-luna-en ``` -------------------------------- ### Connect to Live TTS WebSocket Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Establishes a secure WebSocket connection using a JWT token and streams text for synthesis. ```javascript // JavaScript client example with authentication // Step 1: Get session token const tokenResponse = await fetch('http://localhost:8081/api/session'); const { token } = await tokenResponse.json(); // Step 2: Connect WebSocket with authentication and TTS parameters const wsUrl = new URL('ws://localhost:8081/api/live-text-to-speech'); wsUrl.searchParams.set('model', 'aura-asteria-en'); // Voice model wsUrl.searchParams.set('encoding', 'linear16'); // Audio encoding wsUrl.searchParams.set('sample_rate', '24000'); // Sample rate in Hz wsUrl.searchParams.set('container', 'none'); // Container format const ws = new WebSocket(wsUrl.toString(), [`access_token.${token}`]); // Step 3: Handle connection and audio streaming ws.onopen = () => { console.log('Connected to TTS WebSocket'); // Send text to synthesize ws.send(JSON.stringify({ type: 'Speak', text: 'Hello, world! This is a test.' })); // Flush the buffer to signal end of text ws.send(JSON.stringify({ type: 'Flush' })); }; ws.onmessage = (event) => { if (event.data instanceof Blob) { // Binary audio data (raw PCM when container=none) event.data.arrayBuffer().then(buffer => { // Process audio buffer for playback const int16Array = new Int16Array(buffer); // Convert Int16 to Float32 for Web Audio API const float32Array = new Float32Array(int16Array.length); for (let i = 0; i < int16Array.length; i++) { float32Array[i] = int16Array[i] / 32768.0; } // Queue for AudioContext playback... }); } else { // JSON metadata/status messages from Deepgram console.log('Received:', event.data); } }; ws.onerror = (error) => console.error('WebSocket error:', error); ws.onclose = (event) => console.log('WebSocket closed:', event.code, event.reason); ``` -------------------------------- ### Queue Text for Synthesis - JavaScript Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Sends text to Deepgram for synthesis. Multiple Speak messages can be queued sequentially. ```javascript // Queue text for synthesis ws.send(JSON.stringify({ type: 'Speak', text: 'Welcome to the Deepgram Text-to-Speech demo.' })); // Queue additional text ws.send(JSON.stringify({ type: 'Speak', text: 'This sentence will be spoken after the first one.' })); ``` -------------------------------- ### WebSocket Endpoint: /api/live-text-to-speech Source: https://github.com/deepgram-starters/rust-live-text-to-speech/blob/main/AGENTS.md Details on the WebSocket endpoint for live text-to-speech streaming. ```APIDOC ## WS /api/live-text-to-speech ### Description This endpoint establishes a WebSocket connection to stream text to Deepgram for real-time audio generation. It uses JWT for authentication via the `access_token.` subprotocol. ### Method WS (WebSocket) ### Endpoint `/api/live-text-to-speech` ### Authentication JWT session tokens via WebSocket subprotocol: `access_token.` ### WebSocket Message Protocol **Client to Server:** - `{ "type": "Speak", "text": "Hello world" }` - Queue text for synthesis. - `{ "type": "Flush" }` - Signal end of text, flush audio buffer. - `{ "type": "Clear" }` - Cancel pending audio. - `{ "type": "Close" }` - Graceful disconnect. **Server to Client:** - Streams binary audio chunks (raw PCM when container=none). ### Customization Guide Modify the Deepgram URL parameters in the backend to change voice, encoding, sample rate, and container. **Default Parameters:** - `model`: `aura-asteria-en` (Voice selection) - `encoding`: `linear16` (Audio encoding) - `sample_rate`: `48000` (Audio sample rate) - `container`: `none` (Audio container) **Important:** Frontend audio playback is configured for Linear16 at 48kHz. Changes to `encoding` or `sample_rate` require corresponding updates in the frontend's `frontend/main.js`. ``` -------------------------------- ### Generate JWT Token - Rust Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Creates a signed JWT for session authentication with a 1-hour expiry. ```rust const JWT_EXPIRY_SECS: u64 = 3600; // 1 hour /// Creates a signed JWT for session authentication. fn generate_token(secret: &str) -> Result { let now = chrono::Utc::now(); let claims = serde_json::json!({ "iat": now.timestamp(), "exp": now.timestamp() + JWT_EXPIRY_SECS as i64, }); jsonwebtoken::encode( &jsonwebtoken::Header::default(), &claims, &jsonwebtoken::EncodingKey::from_secret(secret.as_bytes()), ) } ``` -------------------------------- ### JWT Authentication Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Details on generating JWT tokens for session authentication. ```APIDOC ## JWT Authentication ### Generate JWT Token Creates a signed JWT for session authentication with a 1-hour expiry. ```rust const JWT_EXPIRY_SECS: u64 = 3600; // 1 hour /// Creates a signed JWT for session authentication. fn generate_token(secret: &str) -> Result { let now = chrono::Utc::now(); let claims = serde_json::json!({ "iat": now.timestamp(), "exp": now.timestamp() + JWT_EXPIRY_SECS as i64, }); jsonwebtoken::encode( &jsonwebtoken::Header::default(), &claims, &jsonwebtoken::EncodingKey::from_secret(secret.as_bytes()), ) } ``` ``` -------------------------------- ### Check Server Health via cURL Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Verifies the operational status of the backend server. ```bash # Check server health curl -s http://localhost:8081/health # Response: # {"status":"ok"} ``` -------------------------------- ### TTS Query Parameters Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt These query parameters can be appended to the WebSocket URL to configure the text-to-speech synthesis. ```APIDOC ## TTS Query Parameters ### Model Parameter Specifies the voice model for text-to-speech synthesis. Default is `aura-asteria-en`. ```bash # Available models include various aura-* voices # Example: aura-asteria-en, aura-luna-en, aura-stella-en, etc. ws://localhost:8081/api/live-text-to-speech?model=aura-luna-en ``` ### Encoding Parameter Specifies the audio encoding format. Default is `linear16`. ```bash # Encoding options: linear16, mp3, opus, mulaw, alaw ws://localhost:8081/api/live-text-to-speech?encoding=linear16 # For raw PCM playback, use linear16 with container=none # For compressed formats, consider mp3 or opus ``` ### Sample Rate Parameter Specifies the audio sample rate in Hz. Default is `24000`. Range is `8000` to `48000`. ```bash # Common sample rates: 8000, 16000, 22050, 24000, 44100, 48000 ws://localhost:8081/api/live-text-to-speech?sample_rate=48000 ``` ### Container Parameter Specifies the audio container format. Default is `none` for raw audio. ```bash # Container options: none, wav, ogg ws://localhost:8081/api/live-text-to-speech?container=none ``` ``` -------------------------------- ### Manual Endpoint Verification with Curl Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Performs manual checks on API endpoints using curl and formats the JSON output for readability. ```bash # Manual endpoint verification curl -sf http://localhost:8081/api/metadata | python3 -m json.tool curl -sf http://localhost:8081/api/session | python3 -m json.tool curl -sf http://localhost:8081/health ``` -------------------------------- ### WS /api/live-text-to-speech - WebSocket Text-to-Speech Proxy Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt This WebSocket endpoint acts as a proxy to Deepgram's Live TTS API. It requires JWT authentication and accepts query parameters for customizing the speech synthesis output. ```APIDOC ## WS /api/live-text-to-speech ### Description WebSocket endpoint that proxies connections to Deepgram's Live TTS API. Requires JWT authentication via the `access_token.` subprotocol. Accepts optional query parameters to configure the TTS output. ### Method WS (WebSocket) ### Endpoint /api/live-text-to-speech ### Parameters #### Query Parameters - **model** (string) - Optional - The voice model to use (e.g., `aura-asteria-en`). - **encoding** (string) - Optional - The audio encoding format (e.g., `linear16`). - **sample_rate** (integer) - Optional - The sample rate in Hz (e.g., `24000`). - **container** (string) - Optional - The container format for the audio stream (e.g., `none`). ### Request Body (WebSocket Messages) - **type** (string) - The type of message. Supported types are `Speak` and `Flush`. - For `Speak`: requires a `text` field (string) containing the text to synthesize. - For `Flush`: signals the end of input text. ### Request Example (JavaScript Client) ```javascript // Step 1: Get session token const tokenResponse = await fetch('http://localhost:8081/api/session'); const { token } = await tokenResponse.json(); // Step 2: Connect WebSocket with authentication and TTS parameters const wsUrl = new URL('ws://localhost:8081/api/live-text-to-speech'); wsUrl.searchParams.set('model', 'aura-asteria-en'); // Voice model wsUrl.searchParams.set('encoding', 'linear16'); // Audio encoding wsUrl.searchParams.set('sample_rate', '24000'); // Sample rate in Hz wsUrl.searchParams.set('container', 'none'); // Container format const ws = new WebSocket(wsUrl.toString(), [`access_token.${token}`]); // Step 3: Handle connection and audio streaming ws.onopen = () => { console.log('Connected to TTS WebSocket'); // Send text to synthesize ws.send(JSON.stringify({ type: 'Speak', text: 'Hello, world! This is a test.' })); // Flush the buffer to signal end of text ws.send(JSON.stringify({ type: 'Flush' })); }; ws.onmessage = (event) => { if (event.data instanceof Blob) { // Binary audio data (raw PCM when container=none) event.data.arrayBuffer().then(buffer => { // Process audio buffer for playback const int16Array = new Int16Array(buffer); // Convert Int16 to Float32 for Web Audio API const float32Array = new Float32Array(int16Array.length); for (let i = 0; i < int16Array.length; i++) { float32Array[i] = int16Array[i] / 32768.0; } // Queue for AudioContext playback... }); } else { // JSON metadata/status messages from Deepgram console.log('Received:', event.data); } }; ws.onerror = (error) => console.error('WebSocket error:', error); ws.onclose = (event) => console.log('WebSocket closed:', event.code, event.reason); ``` ### Response #### Success Response (WebSocket Messages) - **Binary Data**: Audio chunks (e.g., PCM data if `container=none`). - **JSON Data**: Metadata or status messages from Deepgram. #### Response Example (JSON) ```json { "type": "metadata", "model_uuid": "...", "request_id": "..." } ``` ``` -------------------------------- ### Stop Running Servers Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Identifies and terminates processes listening on ports 8080 and 8081. ```bash # Stop all running servers lsof -ti:8080,8081 | xargs kill -9 2>/dev/null ``` -------------------------------- ### Request Session Token via cURL Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Fetches a JWT session token required for authenticating WebSocket connections. ```bash # Request a session token curl -s http://localhost:8081/api/session # Response: # {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."} # Use the token to authenticate WebSocket connections via subprotocol # Connect with: Sec-WebSocket-Protocol: access_token. ``` -------------------------------- ### Graceful Disconnect - JavaScript Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Initiates a graceful disconnect from the WebSocket connection. ```javascript // Gracefully close the connection ws.send(JSON.stringify({ type: 'Close' })); ``` -------------------------------- ### Cancel Pending Audio - JavaScript Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Cancels any pending audio that hasn't been synthesized yet. ```javascript // Cancel pending audio ws.send(JSON.stringify({ type: 'Clear' })); ``` -------------------------------- ### Validate WebSocket JWT Token in Rust Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Extracts and validates JWTs from WebSocket subprotocols. It iterates through comma-separated protocols, strips the 'access_token.' prefix, and uses `validate_token` for verification. Returns the full protocol string if valid. ```rust /// Extracts and validates a JWT from WebSocket subprotocols. /// Returns the full protocol string (e.g., "access_token.") if valid. fn validate_ws_token(protocols: &str, secret: &str) -> Option { for protocol in protocols.split(',').map(|p| p.trim()) { if let Some(token) = protocol.strip_prefix("access_token.") { if validate_token(token, secret).is_ok() { return Some(protocol.to_string()); } } } None } ``` -------------------------------- ### WebSocket Message Types Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt These messages are sent over the WebSocket connection to control the text-to-speech synthesis process. ```APIDOC ## WebSocket Message Types ### Speak Message - Queue Text for Synthesis Sends text to Deepgram for synthesis. Multiple Speak messages can be queued sequentially. ```javascript // Queue text for synthesis ws.send(JSON.stringify({ type: 'Speak', text: 'Welcome to the Deepgram Text-to-Speech demo.' })); // Queue additional text ws.send(JSON.stringify({ type: 'Speak', text: 'This sentence will be spoken after the first one.' })); ``` ### Flush Message - Signal End of Text Signals to Deepgram that all text has been sent and the audio buffer should be flushed. ```javascript // After sending all text, flush the buffer ws.send(JSON.stringify({ type: 'Flush' })); ``` ### Clear Message - Cancel Pending Audio Cancels any pending audio that hasn't been synthesized yet. ```javascript // Cancel pending audio ws.send(JSON.stringify({ type: 'Clear' })); ``` ### Close Message - Graceful Disconnect Initiates a graceful disconnect from the WebSocket connection. ```javascript // Gracefully close the connection ws.send(JSON.stringify({ type: 'Close' })); ``` ``` -------------------------------- ### Validate JWT Token in Rust Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Verifies a JWT token using a secret key. It decodes the token and validates the expiration claim. Returns an error if the token is invalid or expired. ```rust /// Verifies a JWT and returns an error if invalid. fn validate_token(token: &str, secret: &str) -> Result<(), jsonwebtoken::errors::Error> { let mut validation = jsonwebtoken::Validation::default(); validation.required_spec_claims.clear(); validation.validate_exp = true; jsonwebtoken::decode::( token, &jsonwebtoken::DecodingKey::from_secret(secret.as_bytes()), &validation, )?; Ok(()) } ``` -------------------------------- ### Signal End of Text - JavaScript Source: https://context7.com/deepgram-starters/rust-live-text-to-speech/llms.txt Signals to Deepgram that all text has been sent and the audio buffer should be flushed. ```javascript // After sending all text, flush the buffer ws.send(JSON.stringify({ type: 'Flush' })); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.