Skip to content

Repository files navigation

OmniAvatar

Go CIGo LintGo SASTDocsDocsVisualizationLicense

Batteries-included package for AI avatars with two surfaces:

  • live — real-time streaming avatars (LiveKit sessions, PCM audio streaming for lip-sync) for conversational agents
  • render — asynchronous batch avatar video generation (narration audio in, talking-head MP4 out) for offline pipelines such as presentation videos

Provides provider implementations for HeyGen, Tavus, bitHuman, and local rendering via LivePortrait + JoyVASA (Apple Silicon).

For core interfaces only (no provider dependencies), see omniavatar-core.

Quick Start (live)

import (
"github.com/plexusone/omniavatar""github.com/plexusone/omniavatar-core/live"
_ "github.com/plexusone/omniavatar/providers/all"
)
funcmain() {
provider, err:=omniavatar.GetLiveProvider("heygen",
omniavatar.WithAPIKey(os.Getenv("LIVEAVATAR_API_KEY")),
omniavatar.WithExtension("avatar_id", avatarID),
omniavatar.WithExtension("sandbox", true))
iferr!=nil {
log.Fatal(err)
}
session, err:=provider.CreateSession(live.SessionConfig{
AudioConfig: live.DefaultAudioConfig(),
})
iferr!=nil {
log.Fatal(err)
}
// Start with LiveKiterr=session.Start(ctx, &omniavatar.LiveKitStartOptions{
Room: room,
AgentIdentity: "agent-123",
LiveKitURL: os.Getenv("LIVEKIT_URL"),
LiveKitAPIKey: os.Getenv("LIVEKIT_API_KEY"),
LiveKitAPISecret: os.Getenv("LIVEKIT_API_SECRET"),
})
}

Quick Start (render)

import (
"github.com/plexusone/omniavatar""github.com/plexusone/omniavatar-core/render"
_ "github.com/plexusone/omniavatar/providers/all"
)
funcmain() {
provider, err:=omniavatar.GetRenderProvider("bithuman",
omniavatar.WithAPIKey(os.Getenv("BITHUMAN_API_KEY")),
omniavatar.WithExtension("agent_id", agentID))
iferr!=nil {
log.Fatal(err)
}
// Providers with hosting support can upload local narration audio.audioURL:=""ifup, ok:=provider.(render.AudioUploader); ok {
audioURL, err=up.UploadAudio(ctx, "narration.mp3", audioFile)
iferr!=nil {
log.Fatal(err)
}
}
job, err:=provider.Generate(ctx, render.GenerateRequest{
AvatarID: agentID,
AudioURL: audioURL,
})
iferr!=nil {
log.Fatal(err)
}
status, err:=render.Wait(ctx, provider, job.ID, 5*time.Second)
iferr!=nil {
log.Fatal(err)
}
log.Printf("video ready: %s (%.1fs)", status.VideoURL, status.Duration)
out, err:=os.Create("presenter.mp4")
iferr!=nil {
log.Fatal(err)
}
deferout.Close()
iferr:=provider.Download(ctx, job.ID, out); err!=nil {
log.Fatal(err)
}
}

Architecture

Adapters follow the PlexusOne convention: render adapters live in each provider SDK repo (heygen-go/omniavatar, …), depending only on omniavatar-core, so provider-specific knowledge stays with the SDK. The live adapters live here in the batteries-included package, because their LiveKit integration (LiveKitStartOptions, token generation) lives here. This package re-exports both, registered by name via providers/all.

omniavatar-core/ # Core interfaces + shared helpers (no provider deps)
├── live/ # Real-time session interfaces
├── render/ # Batch generation: Provider, AudioUploader,
│ # AvatarLister, GenerateRequest, Wait,
│ # AudioContentType/DownloadURL helpers
└── registry/ # Factory types
heygen-go/omniavatar/ # HeyGen RENDER adapter (core-only) — in the SDK repo
tavus-go/omniavatar/ # Tavus RENDER adapter
bithuman-go/omniavatar/ # bitHuman RENDER adapter
omniavatar/ # Batteries-included (this package)
├── registry.go # Global live + render registries
├── token.go / start_options.go # LiveKit token + start options
└── providers/
├── heygen/ # HeyGen LIVE adapter (LiveAvatar); registers the SDK render adapter
├── tavus/ # Tavus LIVE adapter (CVI)
├── bithuman/ # bitHuman LIVE adapter
├── liveportrait-joyvasa/ # Local RENDER adapter (Apple Silicon); registers core provider
└── all/ # Convenience import (registers every provider)

Provider Registry

Priority System

Providers register with a priority level:

PriorityConstantDescription
0PriorityThinMinimal implementations
10PriorityThickFull SDK implementations

Higher priority providers override lower priority registrations for the same name.

Auto-Registration

Providers auto-register both surfaces via init() when imported:

// Import specific providerimport _ "github.com/plexusone/omniavatar/providers/heygen"// Or import all providersimport _ "github.com/plexusone/omniavatar/providers/all"

Registry Functions

// Live (real-time sessions)provider, err:=omniavatar.GetLiveProvider("heygen", opts...)
names:=omniavatar.ListLiveProviders()
ok:=omniavatar.HasLiveProvider("heygen")
// Render (batch video generation)provider, err:=omniavatar.GetRenderProvider("heygen", opts...)
names:=omniavatar.ListRenderProviders()
ok:=omniavatar.HasRenderProvider("heygen")

Supported Providers

HeyGen

Live: real-time avatar with lip-sync using HeyGen LiveAvatar LITE mode. Render: HeyGen Video Generation API (v2).

Note: the live surface uses the LiveAvatar API key (LIVEAVATAR_API_KEY); the render surface uses the HeyGen API key (HEYGEN_API_KEY). They are different credentials.

// Liveprovider, err:=omniavatar.GetLiveProvider("heygen",
omniavatar.WithAPIKey(os.Getenv("LIVEAVATAR_API_KEY")),
omniavatar.WithExtension("avatar_id", "josh_lite3_20230714"),
omniavatar.WithExtension("sandbox", true), // 60s limit, no creditsomniavatar.WithExtension("video_quality", "high"), // very_high, high, medium, low
)
// Renderprovider, err:=omniavatar.GetRenderProvider("heygen",
omniavatar.WithAPIKey(os.Getenv("HEYGEN_API_KEY")),
omniavatar.WithExtension("avatar_id", avatarID),
)
SurfaceOptionDescription
liveavatar_idAvatar UUID (required)
livesandboxEnable sandbox mode (recommended for dev)
livevideo_qualityVideo quality preset
renderavatar_idDefault avatar ID
renderupload_base_urlCustom asset upload service URL (default: upload.heygen.com)
render requesttalking_photo_idUse a talking photo instead of an avatar
render requestavatar_stylenormal, circle, closeUp
render requestvoice_idTTS voice for Script input
render requesttestWatermarked test video, no credits

The HeyGen render provider implements render.AudioUploader via the HeyGen asset upload API (MP3/audio/mpeg is the documented audio asset type).

Tavus

Live: real-time avatar using Tavus PAL (Personalized AI Likeness). Render: Tavus Video Generation using replicas.

// Liveprovider, err:=omniavatar.GetLiveProvider("tavus",
omniavatar.WithAPIKey(os.Getenv("TAVUS_API_KEY")),
omniavatar.WithExtension("pal_id", "pal_xxx"), // Optionalomniavatar.WithExtension("face_id", "face_xxx"), // Optional
)
// Renderprovider, err:=omniavatar.GetRenderProvider("tavus",
omniavatar.WithAPIKey(os.Getenv("TAVUS_API_KEY")),
omniavatar.WithExtension("replica_id", "rep_xxx"),
)
SurfaceOptionDescription
livepal_idPAL ID (optional, uses stock avatar if not set)
liveface_idFace override (optional)
renderreplica_idDefault replica ID
render requestfastFaster generation (disables some features)
render requestcallback_urlCompletion webhook URL

Tavus has no audio upload API; supply a publicly fetchable GenerateRequest.AudioURL (.wav or .mp3).

bitHuman

Live: ultra-low latency real-time avatars. Render: bitHuman video generation, including audio upload support (render.AudioUploader).

// Liveprovider, err:=omniavatar.GetLiveProvider("bithuman",
omniavatar.WithAPIKey(os.Getenv("BITHUMAN_API_KEY")),
omniavatar.WithExtension("agent_id", "agent_xxx"),
)
// Renderprovider, err:=omniavatar.GetRenderProvider("bithuman",
omniavatar.WithAPIKey(os.Getenv("BITHUMAN_API_KEY")),
omniavatar.WithExtension("agent_id", "agent_xxx"),
)
SurfaceOptionDescription
liveagent_idbitHuman agent ID (required)
renderagent_idDefault agent ID
render requestvoice_idTTS voice for Script input

LivePortrait + JoyVASA (Local)

Render-only: on-device audio-driven talking-head video generation on Apple Silicon. No cloud API required — connects to a local Python gRPC server.

// Render (no API key needed)provider, err:=omniavatar.GetRenderProvider("liveportrait-joyvasa")
// Upload local audio (returns local:// URL)audioURL, _:=provider.(render.AudioUploader).UploadAudio(ctx, "narration.wav", f)
job, _:=provider.Generate(ctx, render.GenerateRequest{
AvatarID: "john", // avatar bundle name in ~/.omniavatar/avatars/AudioURL: audioURL,
Extensions: map[string]any{
"seed": int64(42), // deterministic output"motion_scale": float32(1.2), // adjust expressiveness
},
})
OptionDescription
endpointCustom Unix socket path (default: /tmp/omniavatar-liveportrait-joyvasa.sock)
seedRandom seed for deterministic output
motion_scaleFacial movement intensity (default: 1.0)

Setup: The provider requires a running Python server. See the omniavatar-core local render guide for server setup and avatar bundle format.

Performance: ~5 min for 13.7s output at 512×512 on Apple Silicon (M-series).

Session Lifecycle (live)

1. Get Provider → omniavatar.GetLiveProvider("heygen", opts...)
2. Create Session → provider.CreateSession(cfg)
3. Start → session.Start(ctx, &LiveKitStartOptions{...})
4. Wait for Join → session.WaitForJoin(ctx, 30*time.Second)
5. Stream Audio → session.AudioOutput().CaptureFrame(ctx, pcm)
6. Close → session.Close(ctx)

Job Lifecycle (render)

1. Get Provider → omniavatar.GetRenderProvider("heygen", opts...)
2. Upload Audio → provider.(render.AudioUploader).UploadAudio(...) [optional]
3. Generate → provider.Generate(ctx, render.GenerateRequest{...})
4. Wait → render.Wait(ctx, provider, job.ID, interval)
5. Download → provider.Download(ctx, job.ID, dst)

LiveKit Integration

Token Generation

Generate tokens for avatar participants to join LiveKit rooms:

token, err:=omniavatar.GenerateAvatarToken(omniavatar.TokenOptions{
APIKey: os.Getenv("LIVEKIT_API_KEY"),
APISecret: os.Getenv("LIVEKIT_API_SECRET"),
RoomName: "my-room",
Identity: "avatar-heygen-abc123",
Provider: "heygen",
AgentIdentity: "agent-123",
TTL: time.Hour,
})

Start Options

typeLiveKitStartOptionsstruct {
Room*lksdk.Room// LiveKit room referenceAgentIdentitystring// Agent's participant identityLiveKitURLstring// LiveKit server URLLiveKitAPIKeystring// API key for token generationLiveKitAPISecretstring// API secret for token generation
}

Audio Format (live)

Default audio configuration:

ParameterValue
Sample Rate24000 Hz
Channels1 (mono)
EncodingPCM16 (linear16)

Provider Comparison

ProviderLive LatencyVideo QualityVoice CloningRender Audio Upload
HeyGen~500msExcellentYesYes (asset API, MP3)
Tavus~300msExcellentYes (via PAL)No (URL only)
bitHuman~200msGoodNoYes

Specs

Resources

About

Batteries-included package for real-time AI avatars. Provides provider implementations for HeyGen, Tavus, and bitHuman.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages