Module livekit.plugins.camb
Sub-modules
livekit.plugins.camb.loglivekit.plugins.camb.modelslivekit.plugins.camb.ttslivekit.plugins.camb.version
Functions
async def list_voices(*, api_key: str | None = None, base_url: str = 'https://client.camb.ai/apis') ‑> list[dict]-
Expand source code
async def list_voices( *, api_key: str | None = None, base_url: str = API_BASE_URL, ) -> list[dict]: """ List available voices from Camb.ai. Args: api_key: Camb.ai API key (or use CAMB_API_KEY env var). base_url: API base URL. Returns: List of voice dicts with id, name, gender, age, language. Raises: ValueError: If no API key provided. APIStatusError: If API request fails. """ api_key = api_key or os.environ.get("CAMB_API_KEY") if not api_key: raise ValueError("api_key required (or set CAMB_API_KEY environment variable)") async with aiohttp.ClientSession() as session: async with session.get( f"{base_url}/list-voices", headers={API_KEY_HEADER: api_key}, ) as resp: if resp.status != 200: content = await resp.text() raise APIStatusError( "Failed to list Camb.ai voices", status_code=resp.status, body=content, ) voice_list = await resp.json() voices = [] for voice in voice_list: voice_id = voice.get("id") if voice_id is None: continue gender_int = voice.get("gender") gender = GENDER_MAP.get(gender_int) if gender_int is not None else None voices.append( { "id": voice_id, "name": voice.get("voice_name", ""), "gender": gender, "age": voice.get("age"), "language": voice.get("language"), } ) return voicesList available voices from Camb.ai.
Args
api_key- Camb.ai API key (or use CAMB_API_KEY env var).
base_url- API base URL.
Returns
List of voice dicts with id, name, gender, age, language.
Raises
ValueError- If no API key provided.
APIStatusError- If API request fails.
Classes
class TTS (*,
api_key: str | None = None,
base_url: str = 'https://client.camb.ai/apis',
credentials_info: NotGivenOr[dict] = NOT_GIVEN,
credentials_file: NotGivenOr[str] = NOT_GIVEN,
voice_id: int = 147320,
language: str = 'en-us',
model: SpeechModel = 'mars-flash',
user_instructions: str | None = None,
output_format: OutputFormat = 'pcm_s16le',
enhance_named_entities: bool = False,
sample_rate: int | None = None,
http_session: aiohttp.ClientSession | None = None)-
Expand source code
class TTS(tts.TTS): def __init__( self, *, api_key: str | None = None, base_url: str = API_BASE_URL, credentials_info: NotGivenOr[dict] = NOT_GIVEN, # Future Vertex AI credentials_file: NotGivenOr[str] = NOT_GIVEN, # Future Vertex AI voice_id: int = DEFAULT_VOICE_ID, language: str = DEFAULT_LANGUAGE, model: SpeechModel = DEFAULT_MODEL, user_instructions: str | None = None, output_format: OutputFormat = DEFAULT_OUTPUT_FORMAT, enhance_named_entities: bool = False, sample_rate: int | None = None, http_session: aiohttp.ClientSession | None = None, ) -> None: """ Create a new instance of Camb.ai TTS. ``api_key`` must be set to your Camb.ai API key, either using the argument or by setting the ``CAMB_API_KEY`` environmental variable. Args: api_key: Camb.ai API key. If not provided, reads from CAMB_API_KEY env var. base_url: Camb.ai API base URL. credentials_info: GCP credentials dict for Vertex AI (future support). credentials_file: GCP credentials file path for Vertex AI (future support). voice_id: Voice ID to use. Use list_voices() to discover available voices. language: BCP-47 locale (e.g., 'en-us', 'fr-fr'). model: MARS model to use ('mars-flash', 'mars-pro', 'mars-instruct'). user_instructions: Style/tone guidance (3-1000 chars, requires mars-instruct). output_format: Audio output format (default: 'pcm_s16le'). enhance_named_entities: Enhanced pronunciation for named entities. sample_rate: Audio sample rate in Hz. If None, auto-detected from model. http_session: Optional aiohttp.ClientSession to reuse. """ resolved_sample_rate = sample_rate or MODEL_SAMPLE_RATES.get(model, 22050) super().__init__( capabilities=tts.TTSCapabilities(streaming=False), sample_rate=resolved_sample_rate, num_channels=NUM_CHANNELS, ) self._api_key = api_key or os.environ.get("CAMB_API_KEY") if not self._api_key: raise ValueError( "Camb.ai API key must be provided via api_key parameter or " "CAMB_API_KEY environment variable" ) if is_given(credentials_info) or is_given(credentials_file): logger.warning("Vertex AI credentials provided but not yet implemented - using API key") self._credentials_info = credentials_info self._credentials_file = credentials_file self._base_url = base_url self._session = http_session self._opts = _TTSOptions( voice_id=voice_id, language=language, speech_model=model, output_format=output_format, user_instructions=user_instructions, enhance_named_entities=enhance_named_entities, ) def _ensure_session(self) -> aiohttp.ClientSession: if not self._session: self._session = utils.http_context.http_session() return self._session @property def model(self) -> str: return self._opts.speech_model @property def provider(self) -> str: return "Camb.ai" def update_options( self, *, voice_id: int | None = None, language: str | None = None, model: SpeechModel | None = None, user_instructions: str | None = None, ) -> None: """Update TTS options dynamically.""" if voice_id is not None: self._opts.voice_id = voice_id if language is not None: self._opts.language = language if model is not None: self._opts.speech_model = model self._sample_rate = MODEL_SAMPLE_RATES.get(model, 22050) if user_instructions is not None: self._opts.user_instructions = user_instructions def synthesize( self, text: str, *, conn_options: APIConnectOptions = DEFAULT_API_CONNECT_OPTIONS, ) -> ChunkedStream: return ChunkedStream(tts=self, input_text=text, conn_options=conn_options) async def aclose(self) -> None: passHelper class that provides a standard way to create an ABC using inheritance.
Create a new instance of Camb.ai TTS.
api_keymust be set to your Camb.ai API key, either using the argument or by setting theCAMB_API_KEYenvironmental variable.Args
api_key- Camb.ai API key. If not provided, reads from CAMB_API_KEY env var.
base_url- Camb.ai API base URL.
credentials_info- GCP credentials dict for Vertex AI (future support).
credentials_file- GCP credentials file path for Vertex AI (future support).
voice_id- Voice ID to use. Use list_voices() to discover available voices.
language- BCP-47 locale (e.g., 'en-us', 'fr-fr').
model- MARS model to use ('mars-flash', 'mars-pro', 'mars-instruct').
user_instructions- Style/tone guidance (3-1000 chars, requires mars-instruct).
output_format- Audio output format (default: 'pcm_s16le').
enhance_named_entities- Enhanced pronunciation for named entities.
sample_rate- Audio sample rate in Hz. If None, auto-detected from model.
http_session- Optional aiohttp.ClientSession to reuse.
Ancestors
- livekit.agents.tts.tts.TTS
- abc.ABC
- EventEmitter
- typing.Generic
Instance variables
prop model : str-
Expand source code
@property def model(self) -> str: return self._opts.speech_modelGet the model name/identifier for this TTS instance.
Returns
The model name if available, "unknown" otherwise.
Note
Plugins should override this property to provide their model information.
prop provider : str-
Expand source code
@property def provider(self) -> str: return "Camb.ai"Get the provider name/identifier for this TTS instance.
Returns
The provider name if available, "unknown" otherwise.
Note
Plugins should override this property to provide their provider information.
Methods
async def aclose(self) ‑> None-
Expand source code
async def aclose(self) -> None: pass def synthesize(self,
text: str,
*,
conn_options: APIConnectOptions = APIConnectOptions(max_retry=3, retry_interval=2.0, timeout=10.0)) ‑> ChunkedStream-
Expand source code
def synthesize( self, text: str, *, conn_options: APIConnectOptions = DEFAULT_API_CONNECT_OPTIONS, ) -> ChunkedStream: return ChunkedStream(tts=self, input_text=text, conn_options=conn_options) def update_options(self,
*,
voice_id: int | None = None,
language: str | None = None,
model: SpeechModel | None = None,
user_instructions: str | None = None) ‑> None-
Expand source code
def update_options( self, *, voice_id: int | None = None, language: str | None = None, model: SpeechModel | None = None, user_instructions: str | None = None, ) -> None: """Update TTS options dynamically.""" if voice_id is not None: self._opts.voice_id = voice_id if language is not None: self._opts.language = language if model is not None: self._opts.speech_model = model self._sample_rate = MODEL_SAMPLE_RATES.get(model, 22050) if user_instructions is not None: self._opts.user_instructions = user_instructionsUpdate TTS options dynamically.
Inherited members