Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion examples/foundational/43-heygen-transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pipecat.services.cartesia.tts import CartesiaTTSService
from pipecat.services.deepgram.stt import DeepgramSTTService
from pipecat.services.google.llm import GoogleLLMService
from pipecat.services.heygen.api_liveavatar import LiveAvatarNewSessionRequest
from pipecat.transports.heygen.transport import HeyGenParams, HeyGenTransport, ServiceType
from pipecat.turns.user_stop import TurnAnalyzerUserTurnStopStrategy
from pipecat.turns.user_turn_strategies import UserTurnStrategies
Expand All @@ -46,7 +47,12 @@ async def main():
params=HeyGenParams(
audio_in_enabled=True,
audio_out_enabled=True,
vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2)),
),
session_request=LiveAvatarNewSessionRequest(
is_sandbox=True,
# Sandbox mode only works with this specific avatar
# https://docs.liveavatar.com/docs/developing-in-sandbox-mode#sandbox-mode-behaviors
avatar_id="dd73ea75-1218-4ef3-92ce-606d5f7fbc0a",
),
)

Expand Down Expand Up @@ -75,6 +81,7 @@ async def main():
TurnAnalyzerUserTurnStopStrategy(turn_analyzer=LocalSmartTurnAnalyzerV3())
]
),
vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2)),
),
)

Expand Down
7 changes: 7 additions & 0 deletions examples/foundational/43a-heygen-video-service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pipecat.services.cartesia.tts import CartesiaTTSService
from pipecat.services.deepgram.stt import DeepgramSTTService
from pipecat.services.google.llm import GoogleLLMService
from pipecat.services.heygen.api_liveavatar import LiveAvatarNewSessionRequest
from pipecat.services.heygen.client import ServiceType
from pipecat.services.heygen.video import HeyGenVideoService
from pipecat.transports.base_transport import BaseTransport, TransportParams
Expand Down Expand Up @@ -75,6 +76,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
api_key=os.getenv("HEYGEN_LIVE_AVATAR_API_KEY"),
service_type=ServiceType.LIVE_AVATAR,
session=session,
session_request=LiveAvatarNewSessionRequest(
is_sandbox=True,
# Sandbox mode only works with this specific avatar
# https://docs.liveavatar.com/docs/developing-in-sandbox-mode#sandbox-mode-behaviors
avatar_id="dd73ea75-1218-4ef3-92ce-606d5f7fbc0a",
),
)

messages = [
Expand Down
45 changes: 43 additions & 2 deletions src/pipecat/services/heygen/api_liveavatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
API to communicate with LiveAvatar Streaming API.
"""

from enum import Enum
from typing import Any, Dict, Optional

import aiohttp
Expand Down Expand Up @@ -46,17 +47,43 @@ class CustomSDKLiveKitConfig(BaseModel):
livekit_client_token: str


class VideoEncoding(str, Enum):
"""Enum representing the video encoding."""

H264 = "H264"
VP8 = "VP8"


class VideoQuality(str, Enum):
"""Enum representing different avatar quality levels."""

low = "low"
medium = "medium"
high = "high"
very_high = "very_high"


class VideoSettings(BaseModel):
"""Video encoding settings for session configuration."""

encoding: VideoEncoding
quality: VideoQuality = VideoQuality.high


class LiveAvatarNewSessionRequest(BaseModel):
"""Request model for creating a LiveAvatar session token.

Parameters:
mode (str): Session mode (default: "CUSTOM").
mode (str): Session mode (default: "LITE").
avatar_id (str): Unique identifier for the avatar.
is_sandbox (bool): Enable sandbox mode (default: False).
avatar_persona (AvatarPersona): Avatar persona configuration.
"""

mode: str = "CUSTOM"
avatar_id: str
video_settings: Optional[VideoSettings] = VideoSettings(encoding=VideoEncoding.VP8)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect that HeyGen changed their API and started sending video using H.264 instead of VP8 by default.

While this works on other platforms, it looks like the LiveKit Python SDK on macOS is unable to decode H.264, so we don’t receive any video frames in Pipecat.

We will use VP8 as the default codec, while still allowing users to switch codecs in case H.264 works on other platforns.

is_sandbox: Optional[bool] = False
avatar_persona: Optional[AvatarPersona] = None
livekit_config: Optional[CustomSDKLiveKitConfig] = None

Expand Down Expand Up @@ -219,7 +246,7 @@ async def create_session_token(
Session token information.
"""
params: dict[str, Any] = {
"mode": request_data.mode,
"mode": request_data.mode if request_data.mode is not None else "LITE",
"avatar_id": request_data.avatar_id,
}

Expand All @@ -234,6 +261,20 @@ async def create_session_token(
avatar_persona = {k: v for k, v in avatar_persona.items() if v is not None}
params["avatar_persona"] = avatar_persona

if request_data.is_sandbox is not None:
params["is_sandbox"] = request_data.is_sandbox

if request_data.video_settings is not None:
video_settings = {
"encoding": request_data.video_settings.encoding.value,
"quality": request_data.video_settings.quality.value,
}
params["video_settings"] = video_settings
else:
# Fall back to VP8 encoding if video_settings is not provided
params["video_settings"] = {"encoding": VideoEncoding.VP8.value}

logger.debug(f"Creating LiveAvatar session token with params: {params}")
response = await self._request("POST", "/sessions/token", params)
logger.debug(f"LiveAvatar session token created")

Expand Down