LiveKit Node SDKs

repository·main·Indexed 42 days ago

https://github.com/livekit/node-sdks

Tools for Node.js developers to integrate real-time audio, video, and data capabilities. Includes @livekit/rtc-node for real-time media participation and livekit-server-sdk for server-side API management, access token generation, and webhook verification.

Tokens
31.3K
Snippets
123
Records
133
Agent score
54%

What's inside LiveKit

  1. Overview of LiveKit Node SDKs

    main

    The LiveKit Node SDKs allow you to add real-time video, audio, and data features to your Node.js applications. You can connect to LiveKit Cloud or a self-hosted LiveKit server to build applications like multi-modal AI, live streaming, or video calling services.

    The repository is organized into two primary packages:

    • livekit-server-sdk: Used to interact with LiveKit server APIs (e.g., managing rooms, tokens, or webhooks).
    • @livekit/rtc-node: Used to connect to LiveKit as a server-side participant, enabling the publishing and subscribing of audio, video, and data tracks.
  2. Distinction between Node SDKs and LiveKit Agents

    main

    It is important to choose the correct SDK based on your use case:

    LiveKit Node SDKs

    Use these for general-purpose Node.js integration, such as managing server-side logic, interacting with the LiveKit API, or acting as a participant in a room to publish/subscribe to media.

    LiveKit Agents

    If you are building Voice AI or code-first real-time voice agents, use the LiveKit Agents framework instead. The Agents framework provides high-level abstractions for:

    • STT (Speech-to-Text)
    • LLM (Large Language Models)
    • TTS (Text-to-Speech)
    • Turn detection and expressive speech
    • Tool usage and telephony

    Agents are available in both Python and Node.js.

  3. Authenticate with LiveKitAPI

    main

    The LiveKitAPI class is the main entry point for server APIs. It supports two authentication modes:

    1. API key & secret: Recommended for backend use. The SDK signs requests using your credentials.
    2. Access token: Used for client-side/frontend use where the API secret must not be exposed. You pass a pre-signed token that already contains the necessary grants.
    import { LiveKitAPI } from 'livekit-server-sdk';
    
    // Backend mode (uses LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET env vars)
    const api = new LiveKitAPI();
    
    // Backend mode (explicit override)
    const api = new LiveKitAPI({ host: 'https://my.livekit.host', apiKey: 'api-key', secret: 'secret-key' });
    
    // Frontend mode (using a pre-signed token)
    const api = new LiveKitAPI({ token });
  4. Use RPC to perform method calls between participants

    main

    Remote Procedure Call (RPC) allows participants to invoke predefined methods on other participants. This is useful for agent-to-client communication.

    Registering a method

    Use room.localParticipant.registerRpcMethod(methodName, handler) to define a method that this participant can handle. The handler receives RpcInvocationData (containing callerIdentity and payload) and a responseTimeout indicating how long you have to respond.

    Performing a request

    Use room.localParticipant.performRpc({ destinationIdentity, method, payload }) to call a method on a specific participant. You can pass a responseTimeout to control how long the caller waits.

    Error Handling

    • If you throw an RpcError with a message in your handler, the caller receives that exact message.
    • Other errors are caught and returned to the caller as error code 1500 ("Application Error").
    // Registering an RPC method
    room.localParticipant?.registerRpcMethod(
      'greet',
      async (data: RpcInvocationData) => {
        console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
        return `Hello, ${data.callerIdentity}!`;
      },
    );
    
    // Performing an RPC request
    try {
      const response = await room.localParticipant!.performRpc({
        destinationIdentity: 'recipient-identity',
        method: 'greet',
        payload: 'Hello from RPC!',
      });
      console.log('RPC response:', response);
    } catch (error) {
      console.error('RPC call failed:', error);
    }
  5. Migrate from v1.x to v2.x

    main

    Key changes in v2.x:

    1. Async Token APIs: AccessToken.toJwt() and WebhookReceiver.receive() are now asynchronous and must be awaited.
    2. Egress API Updates: Request types have changed from interfaces to classes. Fields using oneof patterns now require an explicit case field and a value field.

    Egress Example (v2):

    const fileOutput = new EncodedFileOutput({
      filepath: 'dz/davids-room-test.mp4',
      output: {
        case: 's3',
        value: new S3Upload({
          accessKey: 'aws-access-key',
          secret: 'aws-access-secret',
          bucket: 'my-bucket',
        }),
      },
    });
    
    const info = await egressClient.startRoomCompositeEgress('my-room', {
      file: fileOutput,
    });
  6. Publish an audio track in @livekit/rtc-node

    main

    You can publish audio by creating an AudioSource, wrapping it in a LocalAudioTrack, and then publishing it via the localParticipant.

    When working with raw audio buffers (e.g., converting Uint8Array to Int16Array), use buffer.subarray instead of buffer.slice to avoid undefined behavior and noise in Node.js. Use source.captureFrame to feed audio data into the track.

    import {
      AudioFrame,
      AudioSource,
      LocalAudioTrack,
      TrackPublishOptions,
      TrackSource,
    } from '@livekit/rtc-node';
    import { readFileSync } from 'node:fs';
    
    // set up audio track
    const source = new AudioSource(16000, 1);
    const track = LocalAudioTrack.createAudioTrack('audio', source);
    const options = new TrackPublishOptions();
    options.source = TrackSource.SOURCE_MICROPHONE;
    
    // note: use buffer.subarray instead of buffer.slice to avoid noise
    const sample = readFileSync(pathToFile);
    var buffer = new Int16Array(sample.buffer);
    
    await room.localParticipant.publishTrack(track, options);
    await source.captureFrame(new AudioFrame(buffer, 16000, 1, buffer.byteLength / 2));
    
    // cleanup resources
    await track.close();
  7. Set up environment variables for LiveKit webhooks in Next.js

    main

    The webhook handler in this example uses livekit-server-sdk to validate incoming requests. You must provide your LiveKit API key and secret via environment variables. In a Next.js project, you can add these to a .env.local file.

    LIVEKIT_API_KEY=your-api-key
    LIVEKIT_API_SECRET=your-api-secret
  8. Run the Receive Audio Example

    main

    This example demonstrates how to receive the first audio track published in a LiveKit room and write that audio data to a .wav file.

    To run this example, follow these steps:

    1. Configure Environment Variables: Copy .env.example to .env and fill in the required LiveKit credentials.
    2. Install Dependencies: Run pnpm install in the root folder of the repository.
    3. Execute the Script: Run tsx index.ts from within the examples/receive-audio directory.
    4. Trigger Audio: From a separate LiveKit client, join the room named test-room and publish an audio track to begin recording.
    # Setup environment
    cp .env.example .env
    
    # Install dependencies (from repo root)
    pnpm install
    
    # Run the example
    tsx index.ts
  9. Run the LiveKit RPC Example

    main

    This example demonstrates Remote Procedure Call (RPC) capabilities between two participants in a LiveKit session. It covers two specific scenarios:

    1. Simple Greeting Exchange: A basic request-response pattern.
    2. Function-Calling Service: A more complex implementation using JSON data payloads and multiple method types to simulate a service.

    Prerequisites

    • Node.js installed.
    • A running LiveKit server (local or remote).
    • LiveKit API Key and Secret.

    Setup

    1. Install dependencies using pnpm:
      pnpm install
    2. Create a .env.local file in the example directory and populate it with your credentials:
      LIVEKIT_API_KEY=your_api_key
      LIVEKIT_API_SECRET=your_api_secret
      LIVEKIT_URL=your_livekit_url

    Execution

    Run the example with the following command:

    pnpm run start

    Output will be logged directly to your terminal.

    pnpm install
    # Create .env.local with LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL
    pnpm run start
  10. Set up the LiveKit Node SDKs monorepo for development

    main

    If you are contributing to the project or running the included examples, follow these steps to set up your environment. This repository uses pnpm workspaces and Turborepo.

    1. Install Dependencies

    Clone the repository and run pnpm install at the root level:

    pnpm install

    2. Build the Packages

    To link initial dependencies and verify the installation, run the build command at the root:

    pnpm build

    This builds all packages in /packages and all examples in /examples.

    3. Initialize Submodules

    If the repository uses submodules, initialize them with:

    git submodule update --init --recursive

    Then run pnpm build again to ensure everything is up to date.

  11. Run the Data Streams Example

    main

    This example demonstrates how to use LiveKit DataStreams to stream and receive both text and files from other participants.

    Prerequisites

    • Node.js installed.
    • A running LiveKit server (local or remote).
    • LiveKit API key and secret.

    Setup

    1. Install dependencies using pnpm:
      pnpm install
    2. Create a .env.local file in the example directory and populate it with your credentials:
      LIVEKIT_API_KEY=your_api_key
      LIVEKIT_API_SECRET=your_api_secret
      LIVEKIT_URL=your_livekit_url

    Execution

    Run the example with:

    pnpm run start

    Output will be logged directly to your terminal.

    pnpm install
    # Create .env.local with LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL
    pnpm run start