piper-tts-server
Paced, streaming Piper TTS for real-time voice pipelines — Asterisk AudioSocket, RTP, or a browser WebSocket. Optional ElevenLabs cloud voices with automatic local fallback.
If you have tried to bolt Piper onto a phone call and hit dead air before the greeting, the first few words clipped, or the caller only hearing the tail of each sentence — this library is the fix. It packages the three things that make Piper work in a real-time loop:
- Process-wide voice cache.
PiperVoice.load()costs 2.5–5.5 s. Loading per request means that much dead air before every utterance. Voices load once and are reused. - A single synthesis lock. Piper phonemizes via espeak-ng, whose C API is not thread-safe. All synthesis is serialized behind one lock so concurrent calls don't corrupt each other.
- Deadline-based frame pacing. Real-time transports forward each frame the instant it arrives; bursting a whole utterance overruns the far end's jitter buffer.
PacedWriterreleases exactly one frame per interval on a monotonic deadline — and re-clamps every frame so a synthesis stall never turns into a catch-up burst that clips the next words.
Install
pip install "piper-tts-server[all]" # library + server + piper + elevenlabs
# or minimal:
pip install piper-tts-server # library core (numpy only)
pip install "piper-tts-server[piper,server]"
Download a Piper voice (.onnx + .onnx.json) into a voices/ directory — see the Piper voices list.
Run the service
PIPER_TTS_VOICES_DIR=voices PIPER_TTS_DEFAULT_VOICE=en_US-amy-medium \
piper-tts-server # listens on 127.0.0.1:8080
# one-shot WAV
curl -X POST localhost:8080/synthesize \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from Piper."}' --output hello.wav
# paced streaming slin16 frames (feed straight to AudioSocket/RTP)
curl -N -X POST localhost:8080/synthesize/stream \
-H 'Content-Type: application/json' \
-d '{"text":"Your call is being connected.","paced":true}' --output frames.slin
| Endpoint | Purpose |
|---|---|
GET /health |
status + cached voices |
POST /warm {voice_id} |
preload a voice into the cache |
POST /synthesize {text, voice_id, provider, format} |
one-shot wav (default) or raw pcm |
POST /synthesize/stream {text, …, paced} |
chunked frames; paced:true = deadline-clocked |
Use as a library (no HTTP in the media path)
from piper_tts_server import StreamingTTS, PacedWriter, tts_sanitize
tts = StreamingTTS(voices_dir="voices", default_voice_path="voices/en_US-amy-medium.onnx")
await tts.start()
writer = PacedWriter(my_audiosocket_write, frame_ms=20) # sink: async fn(bytes)
async for frame in tts.synthesise(tts_sanitize(text)):
await writer.write(frame) # 320 bytes / 20 ms, paced
See examples/asterisk_audiosocket.md for the full AudioSocket wiring and streaming-LLM sentence chunking.
Configuration
All via env (or ServerConfig): PIPER_TTS_HOST, PIPER_TTS_PORT, PIPER_TTS_VOICES_DIR, PIPER_TTS_DEFAULT_VOICE, PIPER_TTS_PROVIDER (piper|elevenlabs), PIPER_TTS_ELEVENLABS_API_KEY, PIPER_TTS_SAMPLE_RATE (default 8000), PIPER_TTS_FRAME_MS (default 20), PIPER_TTS_WARM_ON_START.
Default output is 8 kHz slin16 / 20 ms frames (telephony). Set PIPER_TTS_SAMPLE_RATE=16000 for wideband.
ElevenLabs with local fallback
Set PIPER_TTS_PROVIDER=elevenlabs + PIPER_TTS_ELEVENLABS_API_KEY and pass a voice_id. Any failure falls back to the local Piper default voice so the stream never goes silent; a 401/403 disables further cloud attempts for that engine.
Development
pip install "piper-tts-server[dev]"
pytest # pure-DSP, sanitize, and pacing tests run without Piper installed
Licensing
This package is MIT licensed and contains no Piper source code. Piper is an optional extra, imported lazily only when the local engine is used — the core library installs with numpy alone, and the test suite runs without Piper present.
Piper itself is a separate project under a different licence. The maintained release (OHF-Voice/piper1-gpl, PyPI piper-tts) is GPL-3.0-or-later; the older MIT rhasspy/piper is archived. If you install the [piper] or [all] extra, the resulting combined installation is subject to GPL-3.0 terms. The ElevenLabs provider, and the pacing and sanitising helpers on their own, pull in no GPL code.
Not affiliated with, or endorsed by, the Open Home Foundation or the Piper project. This is an independent server and library that drives Piper as one of several backends.
Provenance & credits
Extracted and generalized from the TTS layer of ICTContact's AI Voice Agent, by ICT Innovations / ICT Vision. Author: Tahir Almas. Companion project: asterisk-ai-voice-agent.
MIT licensed — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file piper_tts_server-0.1.0.tar.gz.
File metadata
- Download URL: piper_tts_server-0.1.0.tar.gz
- Upload date:
- Size: 17.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ae9b0413d9bda8697883aeb13c3fd5ad92f62184a39f6ebc3c7bd63d8839783
|
|
| MD5 |
ca3f97b0763f0cf596a644fd0f1105e8
|
|
| BLAKE2b-256 |
946a02debb0dcc9187ee43edf58a190cb41f4d6981aa197b58b396cf7ec7c5df
|
Provenance
The following attestation bundles were made for piper_tts_server-0.1.0.tar.gz:
Publisher:
publish.yml on ictinnovations/piper-tts-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piper_tts_server-0.1.0.tar.gz -
Subject digest:
7ae9b0413d9bda8697883aeb13c3fd5ad92f62184a39f6ebc3c7bd63d8839783 - Sigstore transparency entry: 2453694443
- Sigstore integration time:
-
Permalink:
ictinnovations/piper-tts-server@3d82e33eee78a06ec6bb2dca6dc4712b83a0748f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ictinnovations
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d82e33eee78a06ec6bb2dca6dc4712b83a0748f -
Trigger Event:
push
-
Statement type:
File details
Details for the file piper_tts_server-0.1.0-py3-none-any.whl.
File metadata
- Download URL: piper_tts_server-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16b08ab7b1f86185ef568f52434acc5a96d4d0ee0cfba4f08e916ecb4bfc2c67
|
|
| MD5 |
264df021feaa73f52c3f392ec11c1002
|
|
| BLAKE2b-256 |
d39877b98dd3ee1f72aceb8ac957b030f541890f320c6f5998e5d6b6a739f67b
|
Provenance
The following attestation bundles were made for piper_tts_server-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ictinnovations/piper-tts-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piper_tts_server-0.1.0-py3-none-any.whl -
Subject digest:
16b08ab7b1f86185ef568f52434acc5a96d4d0ee0cfba4f08e916ecb4bfc2c67 - Sigstore transparency entry: 2453694605
- Sigstore integration time:
-
Permalink:
ictinnovations/piper-tts-server@3d82e33eee78a06ec6bb2dca6dc4712b83a0748f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ictinnovations
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d82e33eee78a06ec6bb2dca6dc4712b83a0748f -
Trigger Event:
push
-
Statement type: