Metadata-Version: 2.5
Name: pipecat-bithuman
Version: 0.2.0
Summary: bitHuman real-time avatar video service for Pipecat: TTS audio in, lip-synced avatar video and audio out.
Project-URL: Homepage, https://www.bithuman.ai
Project-URL: Documentation, https://docs.bithuman.ai/platforms/pipecat
Project-URL: Source, https://gitlab.com/bithuman/sdk/pipecat-bithuman
Project-URL: Issues, https://gitlab.com/bithuman/sdk/pipecat-bithuman/-/issues
Project-URL: Changelog, https://gitlab.com/bithuman/sdk/pipecat-bithuman/-/blob/main/CHANGELOG.md
Author: bitHuman, Inc.
License-Expression: BSD-2-Clause
License-File: LICENSE
Keywords: avatar,bithuman,lip-sync,pipecat,real-time,video,voice-agent
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Requires-Dist: bithuman<3,>=2.12.0
Requires-Dist: numpy>=1.26
Requires-Dist: pipecat-ai>=1.12.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: essence-2
Requires-Dist: bithuman[essence-2]<3,>=2.12.1; extra == 'essence-2'
Provides-Extra: expression-2
Requires-Dist: bithuman[expression-2]<3,>=2.12.0; extra == 'expression-2'
Description-Content-Type: text/markdown

# pipecat-bithuman

[![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/x3tMhJvX4X) Questions, demos and challenges: [join the bitHuman Discord](https://discord.gg/x3tMhJvX4X).

A [bitHuman](https://www.bithuman.ai) avatar for your [Pipecat](https://github.com/pipecat-ai/pipecat) bot.
Your TTS audio goes in. A lip-synced avatar video, plus the audio that goes with it, comes out.

The avatar renders in your own process, on your own machine, through the
`bithuman` Python SDK. Both models run live on a standard Linux PC with no GPU.
Expression 2 animates a character from one portrait. Essence 2 is for photoreal people.

Maintained by bitHuman, Inc. (community integration, not maintained by the Pipecat team).

**Tested with Pipecat v1.12.0**, `bithuman` 2.11.18, Python 3.11 to 3.14.

**Demo (37 s, with a barge-in at 10 s):** [docs/demo.mp4](https://gitlab.com/bithuman/sdk/pipecat-bithuman/-/blob/main/docs/demo.mp4), rendered through a Pipecat pipeline by
[`examples/render_demo.py`](https://gitlab.com/bithuman/sdk/pipecat-bithuman/-/blob/main/examples/render_demo.py) (`--interrupt-at 10 --repeat 2`) with the Expression 2 sample avatar Wise Pup.

## Install

```bash
pip install pipecat-bithuman
# Expression 2 avatars (any character from one portrait):
pip install "pipecat-bithuman[expression-2]"
# Essence 2 avatars (photoreal people: essence-2 full body, essence-2f face):
pip install "pipecat-bithuman[essence-2]"
```

Essence 2 avatars stream through `bithuman` 2.12.1 or later; the `essence-2` extra asks for it.

## Get an avatar

`python -m bithuman pull` (from the `bithuman` package this installs) downloads an avatar and
the engine files it needs, and prints the path to pass as `model_path`:

```bash
python -m bithuman list                         # showcase avatars and their model
export BITHUMAN_MODEL_PATH="$(python -m bithuman pull wise-pup)"         # Expression 2
export BITHUMAN_MODEL_PATH="$(python -m bithuman pull sofia-ramirez)"    # Essence 2
export BITHUMAN_MODEL_PATH="$(python -m bithuman pull A00AAA0000)"       # your agent's code
```

Showcase avatars need no API secret to pull. Your own agent's code does. An agent with both
Essence 2 models picks one with `--model essence-2` (full body) or `--model essence-2f` (face).

## Environment variables

| Variable | Needed | What it is |
| --- | --- | --- |
| `BITHUMAN_API_SECRET` | yes | Your bitHuman API secret. Get one at [www.bithuman.ai](https://www.bithuman.ai). The SDK reads it. This package never logs it. |
| `BITHUMAN_MODEL_PATH` | unless you pass `model_path` | Path to the avatar model, as printed by `python -m bithuman pull <avatar>`. |

Session time is metered while the avatar is open (talking or idle).
It closes on `EndFrame`, `CancelFrame` or cleanup.

Rendering bills active session time: 2 credits a minute on your own machine. From 2026-10-12, SDK use requires the Creator plan or higher. See docs.bithuman.ai/pricing.

## Usage

Put `BitHumanVideoService` after the TTS service and before `transport.output()`:

```python
from pipecat_bithuman import BitHumanVideoService

avatar = BitHumanVideoService(model_path="avatar.imx")  # secret from BITHUMAN_API_SECRET

pipeline = Pipeline([
    transport.input(), stt, user_aggregator, llm, tts,
    avatar,                      # TTS audio -> avatar video + audio
    transport.output(),
    assistant_aggregator,
])
```

Turn on video out in the transport (`video_out_enabled=True`). The service logs the
frame size on the first frame; set `video_out_width` / `video_out_height` to match.

### What the service does with frames

| In | Out |
| --- | --- |
| `TTSAudioRawFrame` | Sent to the avatar. Not forwarded as is. |
| (avatar frame) | `OutputImageRawFrame` (RGB), while talking and while idle. |
| (avatar audio) | `TTSAudioRawFrame` (16 kHz mono), paired with each picture. |
| `TTSStoppedFrame` | Held until the avatar has finished speaking the reply. |
| `InterruptionFrame` | The avatar drops the reply in flight and goes back to idle. |
| anything else | Passed on unchanged. |

If the avatar cannot start, or fails mid-session, the service pushes one
`ErrorFrame` upstream. By default TTS audio then passes through unchanged, so the bot
keeps talking without video (`audio_passthrough_on_error=False` turns this off).
Error text is scrubbed of the API secret.

### Options

| Argument | Default | Meaning |
| --- | --- | --- |
| `model_path` | `BITHUMAN_MODEL_PATH` | The avatar model (the path `python -m bithuman pull` prints). |
| `api_secret` | `BITHUMAN_API_SECRET` | The API secret. |
| `sync_video_to_audio` | `True` | Sets `sync_with_audio` on each image. |
| `audio_passthrough_on_error` | `True` | Keep the voice if the avatar fails. |
| `stop_frame_timeout_s` | `2.0` | Release a held `TTSStoppedFrame` after this much quiet. |
| `end_drain_timeout_s` | `30.0` | Longest wait on `EndFrame` for queued speech. |
| `runtime_factory` | SDK | Advanced: your own `BitHumanRuntime` (tests, wrappers). |

## How it maps to the bitHuman Python SDK

| Pipecat | `bithuman.AsyncBithuman` |
| --- | --- |
| `StartFrame` | `AsyncBithuman.create(model_path=..., api_secret=...)`, then `run()` |
| `TTSAudioRawFrame` | `push_audio(pcm, sample_rate, last_chunk=False)` |
| `TTSStoppedFrame` | `flush()` |
| `InterruptionFrame` | `interrupt()` |
| `EndFrame` / `CancelFrame` / cleanup | `shutdown()` |

SDK docs: [docs.bithuman.ai/platforms/python](https://docs.bithuman.ai/platforms/python).

## Run the checked source example

The PyPI wheel installs the plugin package, not this repository's `examples/`
folder. Get the example source first, then install it in a fresh virtual
environment with the framework and SDK versions used for the existing checks:

```bash
git clone https://gitlab.com/bithuman/sdk/pipecat-bithuman.git
cd pipecat-bithuman
git checkout --detach f7e4d005c363a16204ec8ec4d624362a16914ec6
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -c examples/constraints.txt -e ".[expression-2]" "pipecat-ai[daily,deepgram,openai,cartesia,silero]"
export BITHUMAN_API_SECRET=... BITHUMAN_MODEL_PATH=avatar.imx
export DAILY_ROOM_URL=... DEEPGRAM_API_KEY=... OPENAI_API_KEY=... CARTESIA_API_KEY=... CARTESIA_VOICE_ID=...
python examples/bot.py
```

This is the reproducible source path; it does not imply that the source's 0.1.1
version has been released on PyPI. The constraints pin Pipecat 1.12.0 and
bitHuman 2.11.18. The credential-free integration tests cover frame routing,
interruption, cancellation, cleanup and error fallback. Importing the example
checks its API imports; it does not prove a live Daily conversation. Running the
bot still requires the account keys and avatar listed above, and bills the
applicable services.

## Tests

```bash
pip install -e ".[dev]"
pytest            # fakes only: no network, no API secret, no model file
```

One live test talks to the real SDK. It is skipped unless you set
`PIPECAT_BITHUMAN_LIVE=1`, `BITHUMAN_API_SECRET` and `BITHUMAN_MODEL_PATH`.
It opens the avatar for a few seconds, and that time is billed.

## Links

- bitHuman: [www.bithuman.ai](https://www.bithuman.ai)
- Docs: [docs.bithuman.ai/platforms/pipecat](https://docs.bithuman.ai/platforms/pipecat)
- Source and issues: [gitlab.com/bithuman/sdk/pipecat-bithuman](https://gitlab.com/bithuman/sdk/pipecat-bithuman)
- Examples: [gitlab.com/bithuman/sdk/bithuman-examples](https://gitlab.com/bithuman/sdk/bithuman-examples)
- Contact: hello@bithuman.ai

## Licence

BSD 2-Clause, the same as Pipecat. See [LICENSE](https://gitlab.com/bithuman/sdk/pipecat-bithuman/-/blob/main/LICENSE).
Copyright (c) 2026, bitHuman, Inc.
