LiveKit Go SDK

repository·main·Indexed 18 days ago

https://github.com/livekit/server-sdk-go

The LiveKit Go SDK allows developers to interact with LiveKit server APIs and act as a participant within a room. It is used for backend management (creating rooms, moderating, dispatching agents) and for building real-time clients such as bots and recording agents. The SDK provides tools for minting JWT access tokens, managing rooms via LiveKitAPI, publishing media files (VP8/Opus and H.264/Opus), streaming raw PCM16 audio, and managing agent lifecycles through AgentClient and AgentDispatchServiceClient.

Tokens
36.7K
Snippets
137
Records
178
Agent score
62%

What's inside livekit-server-sdk-go

  1. Authenticate with LiveKit Server APIs

    main

    The LiveKitAPI client supports two authentication modes:

    1. API Key & Secret: Recommended for backend services. The SDK signs requests using your credentials. You can provide these via environment variables (LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET) or explicitly via functional options.
    2. Access Token: Used for client-side/frontend scenarios where you want to use a pre-signed token. Pass the token using lksdk.WithToken("token").

    Explicitly provided values take precedence over environment variables.

    // Backend (API key & secret) using environment variables or explicit options
    api, _ := lksdk.NewLiveKitAPI(lksdk.WithURL(hostURL), lksdk.WithAPIKey("api-key", "api-secret"))
    
    // Frontend (pre-signed access token)
    api, _ := lksdk.NewLiveKitAPI(lksdk.WithToken("token"))
  2. Enable a pacer for video publishing

    main

    To prevent bitrate spikes during keyframe transmission (which can cause packet loss), you can enable a pacer when connecting to a room. This maintains a consistent packet flow by controlling the total output bitrate and maximum latency.

    import "github.com/livekit/mediatransportutil/pkg/pacer"
    
    // Control total output bitrate to 10Mbps with 1s max latency
    pf := pacer.NewPacerFactory(
    	pacer.LeakyBucketPacer,
    	pacer.WithBitrate(10000000),
    	pacer.WithMaxLatency(time.Second),
    )
    
    room, err := lksdk.ConnectToRoom(hostURL, lksdk.ConnectInfo{
        APIKey:              apiKey,
        APISecret:           apiSecret,
        RoomName:            roomName,
        ParticipantIdentity: identity,
    }, &lksdk.RoomCallback{
        ParticipantCallback: lksdk.ParticipantCallback{
            OnTrackSubscribed: onTrackSubscribed,
        },
    }, lksdk.WithPacer(pf))
  3. Prepare media files for publishing (VP8/Opus and H.264/Opus)

    main

    To publish existing files to a LiveKit room using the Go SDK, you must first encode them into compatible formats. The SDK supports VP8/Opus and H.264/Opus.

    VP8 / Opus encoding command: Encodes VP8 at an average of 1Mbps / max 2Mbps with a minimum keyframe interval of 120.

    H.264 / Opus encoding command: Encodes H264 with a Constant Bitrate (CBS) of 2Mbps and a minimum keyframe interval of 120.

    # VP8 / Opus
    ffmpeg -i <input.mp4> \
      -c:v libvpx -keyint_min 120 -qmax 50 -maxrate 2M -b:v 1M <output.ivf> \
      -c:a libopus -page_duration 20000 -vn <output.ogg>
    
    # H.264 / Opus
    ffmpeg -i <input.mp4> \
      -c:v libx264 -bsf:v h264_mp4toannexb -b:v 2M -profile baseline -pix_fmt yuv420p \
        -x264-params keyint=120 -max_delay 0 -bf 0 <output.h264> \
      -c:a libopus -page_duration 20000 -vn <output.ogg>
  4. Use X-Livekit-Request-Id for request idempotency

    main

    The LiveKit Go SDK uses the X-Livekit-Request-Id HTTP header to provide idempotency for API requests.

    When a request is made, the SDK automatically generates a unique UUID and attaches it to this header if one is not already present in the context. This allows the server to identify and deduplicate repeated requests during automatic retries (failover) performed by the SDK's transport layer. If you need to provide your own idempotency key, ensure it is set in the request headers before the call is made.

  5. Handle RTCEngine lifecycle and signaling events

    main

    The RTCEngine implements several callback interfaces (like SignalProcessor and SignalTransportHandler) to react to real-time events. When building an application using the SDK, you typically provide an engineHandler (implementing EngineHandler) that responds to these events:

    • Connection Events: OnJoinResponse (room joined), OnReconnectResponse (reconnected), OnLeave (disconnected/reconnecting).
    • Track Events: OnLocalTrackPublished, OnLocalTrackUnpublished, OnLocalTrackSubscribed, OnTrackRemoteMuted.
    • Participant/Room Events: OnParticipantUpdate, OnSpeakersChanged, OnConnectionQuality, OnRoomUpdate, OnRoomMoved.
    • Media Events: OnSubscribedQualityUpdate, OnSubscribedAudioCodecUpdate, OnMediaSectionsRequirement.
  6. How region failover works in the Go SDK

    main

    Region failover is a mechanism used to ensure high availability for API requests, specifically for LiveKit Cloud. When a request fails due to a transport error or an HTTP 5xx response, the SDK performs the following steps:

    1. Discovers Regions: It calls the /settings/regions endpoint to find alternative available regions.
    2. Replays Request: It replays the original request (including body and headers) against the next available region.
    3. Exponential Backoff: It waits between attempts using an exponential backoff starting at 200ms.
    4. Per-Attempt Budget: Each retry attempt is granted the full original timeout budget. For example, if you set a 10s timeout, each individual attempt gets up to 10s, rather than the total time across all retries being capped at 10s.

    Terminal Conditions:

    • A successful response (2xx/3xx).
    • A non-retryable error (HTTP 4xx).
    • Caller cancellation (if the user's context is cancelled, failover stops).
    • Exhaustion of all available regions or maximum attempts (3).
  7. Implement the engineHandler interface

    main

    To receive events from the RTCEngine, you must implement the engineHandler interface. This interface provides hooks for various real-time events. Key methods include:

    • OnMediaTrack(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver): Called when a remote media track is received.
    • OnDataPacket(identity string, dataPacket DataPacket): Called when a data packet is received.
    • OnRoomUpdate(room *livekit.Room): Called when the room state changes.
    • OnDisconnected(reason livekit.DisconnectReason): Called when the connection is lost.
    • OnTranscription(*livekit.Transcription): Called when transcription data is received.
    • OnRpcRequest(...), OnRpcAck(...), OnRpcResponse(...): Hooks for the RPC protocol over data channels.
  8. Configure authentication options for API requests

    main

    When making authenticated calls to the LiveKit server using the Go SDK, you can provide various grant types to the authentication mechanism. The SDK uses an authOption interface to apply specific permissions to an access token.

    Available grant types that implement authOption include:

    • withVideoGrant (using auth.VideoGrant)
    • withSIPGrant (using auth.SIPGrant)
    • withAgentGrant (using auth.AgentGrant)

    These options are applied during the context preparation phase to ensure the generated JWT contains the necessary permissions for the requested operation.

  9. How LocalTrack handles media timing and synchronization

    main

    The LocalTrack class is designed to abstract away the complexities of RTP timing. It uses several strategies to calculate the correct RTP timestamp for samples:

    1. PacketTimestamp: If the media.Sample provides a PacketTimestamp, that is used directly.
    2. Timestamp + Duration: If a wall-clock Timestamp and Duration are provided, the track calculates the next timestamp based on the elapsed time.
    3. Duration only: If neither is provided, the track uses the Duration to increment the lastRTPTimestamp from the previous sample.

    Clock Drift & Timing: When using StartWrite with a SampleProvider, the track uses a time.Ticker to sleep between samples. It calculates the sleepDuration by comparing the current time to the nextSampleTime (calculated as lastSampleTime + sample.Duration), which helps account for clock drift and ensures media is published at the intended frequency.

  10. Understand the TrackPublication interface

    main

    The TrackPublication interface provides a unified way to inspect track metadata regardless of whether the track is local (published by you) or remote (published by someone else).

    Common methods available on all publications:

    • Name(): Returns the track name.
    • SID(): Returns the unique Track SID.
    • Source(): Returns the livekit.TrackSource (e.g., Audio, Video).
    • Kind(): Returns the TrackKind (Audio or Video).
    • MimeType(): Returns the media MIME type.
    • IsMuted(): Returns true if the track is muted.
    • IsSubscribed(): Returns true if the track is currently subscribed to (relevant for remote tracks).
    • TrackInfo(): Returns a *livekit.TrackInfo object containing metadata.
    • Track(): Returns the underlying Track abstraction.
  11. Manage Data Streams (Text and Byte)

    main

    The SDK manages streaming data through OnStreamHeader, OnStreamChunk, and OnStreamTrailer.

    • Text Streams: Handled via TextStreamHandler. These are useful for sending structured text data over a specific Topic.
    • Byte Streams: Handled via ByteStreamHandler. These are used for raw binary data transfers.

    Streams are identified by a StreamId and are associated with a Topic. The SDK uses TextStreamReader and ByteStreamReader to manage the lifecycle and buffering of these streams.