LiveKit Transport Provider
The LiveKit provider implements bidirectional audio transport through LiveKit rooms. LiveKit is treated as a transport layer — it provides WebRTC connectivity while Beluga handles all STT, LLM, and TTS processing through the frame-based pipeline.
Choose LiveKit when you need a self-hostable, open-source WebRTC infrastructure for production voice deployments. LiveKit provides room management, access token authentication, and scalable media routing. Beluga treats LiveKit as a pure transport layer, handling all voice processing in the frame-based pipeline. For a managed alternative, consider Daily.
Installation
Section titled “Installation”go get github.com/lookatitude/beluga-ai/v2/voice/transport/providers/livekitConfiguration
Section titled “Configuration”| Field | Required | Default | Description |
|---|---|---|---|
URL | Yes | — | LiveKit server URL (wss://...) |
Token | Yes | — | LiveKit access token |
SampleRate | No | 16000 | Audio sample rate in Hz |
Channels | No | 1 | Audio channels (1=mono, 2=stereo) |
Extra configuration:
| Key | Type | Description |
|---|---|---|
room | string | LiveKit room name to join |
Basic Usage
Section titled “Basic Usage”package main
import ( "context" "fmt" "log"
"github.com/lookatitude/beluga-ai/v2/voice/transport" _ "github.com/lookatitude/beluga-ai/v2/voice/transport/providers/livekit")
func main() { t, err := transport.New("livekit", transport.Config{ URL: "wss://myapp.livekit.cloud", Token: "your-livekit-token", Extra: map[string]any{ "room": "voice-room", }, }) if err != nil { log.Fatal(err) } defer t.Close()
// Receive incoming audio frames for frame, err := range t.Recv(context.Background()) { if err != nil { log.Fatal(err) } fmt.Printf("Received %d bytes of audio\n", len(frame.Data)) }}Advanced Features
Section titled “Advanced Features”Sending Audio
Section titled “Sending Audio”Write processed audio back to the LiveKit room using voice.NewAudioFrame:
frame := voice.NewAudioFrame(processedPCM, 16000)err := t.Send(ctx, frame)if err != nil { log.Printf("send failed: %v", err)}Room Configuration
Section titled “Room Configuration”Pass the room name through the Extra map:
t, err := transport.New("livekit", transport.Config{ URL: "wss://myapp.livekit.cloud", Token: token, Extra: map[string]any{ "room": "my-voice-room", },})Voice Pipeline Integration
Section titled “Voice Pipeline Integration”Wrap the transport for use with Beluga’s voice pipeline:
import "github.com/lookatitude/beluga-ai/v2/voice/transport"
audioTransport, err := transport.New("livekit", cfg)if err != nil { log.Fatal(err)}
voiceTransport := &transport.AsVoiceTransport{T: audioTransport}// Use voiceTransport with the voice pipelineDirect Construction
Section titled “Direct Construction”import "github.com/lookatitude/beluga-ai/v2/voice/transport/providers/livekit"
t, err := livekit.New(transport.Config{ URL: "wss://myapp.livekit.cloud", Token: "your-livekit-token", SampleRate: 16000, Channels: 1, Extra: map[string]any{"room": "voice-room"},})Error Handling
Section titled “Error Handling”transport.New("livekit", ...) currently always fails with an error wrapping transport.ErrNotImplemented, so check for it and fall back to a working transport:
t, err := transport.New("livekit", cfg)if errors.Is(err, transport.ErrNotImplemented) { // livekit is not implemented yet; use the built-in WebSocket transport t, err = transport.NewWebSocketTransport(ctx, wsURL)}if err != nil { log.Fatal(err)}defer t.Close()Refer to the LiveKit documentation for server setup, room management, and token generation.