Skip to main content

A tiny proxy that makes local VoiSona Talk speech synthesis available over the network.

Project description

🎙️ VoiSona Talk Proxy

A tiny proxy that makes local VoiSona Talk speech synthesis available over the network.

NOTE: This is an unofficial project and is not affiliated with, endorsed by, or supported by the maker of VoiSona Talk. Please do not contact them for support about this package.

💎 Features

  • 🌐 Access VoiSona Talk speech synthesis from other machines over the network
  • ⚡️ Respond faster by reusing cached audio for repeated requests
  • 🐍 Provide Python client for direct local use

📦 Installation

Requirements:

  • Python 3.11+
  • VoiSona Talk running locally
  • Local VoiSona Talk API available at http://127.0.0.1:32766/api/talk/v1

Install:

pip install voisona-talk-proxy

🚀 Quick Start

Set your VoiSona Talk credentials:

export VOISONA_USERNAME=your-voisona-talk-user
export VOISONA_PASSWORD=your-voisona-talk-password

Start the proxy server:

voisona-talk-proxy --host 0.0.0.0 --port 32777

Underscore command and Python module forms are also available:

voisona_talk_proxy --host 0.0.0.0 --port 32777
python -m voisona_talk_proxy --host 0.0.0.0 --port 32777

Synthesize speech:

curl -X POST http://127.0.0.1:32777/speech-syntheses \
  -H "Content-Type: application/json" \
  -o output.wav \
  -d '{
    "text": "こんにちは",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP"
  }'

You can also mount the proxy inside your own FastAPI app:

from fastapi import FastAPI
from voisona_talk_proxy.proxy import VoisonaProxy

app = FastAPI()
proxy = VoisonaProxy(
    username="your-voisona-talk-user",
    password="your-voisona-talk-password",
)
app.include_router(proxy.get_api_router())

🧩 API Usage

Routes:

  • GET /voices
  • POST /speech-syntheses
  • DELETE /cache
  • DELETE /cache/{voice_name}
  • GET /health
  • compatible /api/talk/v1/... paths for all routes above

NOTE: See the official VoiSona Talk API manual for request payload details.

GET /voices

Returns installed voice libraries from the local VoiSona Talk API.

curl http://127.0.0.1:32777/voices

Example shape:

{
  "items": [
    {
      "voice_name": "tanaka-san_ja_JP",
      "voice_version": "2.0.1",
      "languages": ["ja_JP"]
    }
  ]
}

POST /speech-syntheses

Synthesizes speech and returns audio/wav.

Minimal request:

curl -X POST http://127.0.0.1:32777/speech-syntheses \
  -H "Content-Type: application/json" \
  -o output.wav \
  -d '{
    "text": "Hello!",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP"
  }'

Full request example with /voices values and global_parameters:

import httpx

base_url = "http://127.0.0.1:32777"

voices = httpx.get(f"{base_url}/voices").json()
voice = voices["items"][0]

payload = {
    "text": "こんにちは",
    "language": voice["languages"][0],
    "voice_name": voice["voice_name"],
    "voice_version": voice["voice_version"],
    "global_parameters": {
        "alp": 0.0,
        "huskiness": 0.0,
        "intonation": 1.0,
        "pitch": 0.0,
        "speed": 2.0,
        "style_weights": [],
        "volume": 0.0,
    },
}

audio = httpx.post(f"{base_url}/speech-syntheses", json=payload).content

with open("output.wav", "wb") as f:
    f.write(audio)

GET /health

Returns a simple health check response.

curl http://127.0.0.1:32777/health
{"status": "ok"}

DELETE /cache

Clears cached audio for the default voice cache.

curl -X DELETE http://127.0.0.1:32777/cache
{"cleared": true, "voice_name": "default"}

You can also clear one voice cache by path or query parameter:

curl -X DELETE http://127.0.0.1:32777/cache/tanaka-san_ja_JP
curl -X DELETE "http://127.0.0.1:32777/cache?voice_name=tanaka-san_ja_JP"

🍪 Cache

The proxy caches generated audio under voisona_talk_cache/<voice_name>/<cache_key>.wav.

If voice_name is missing, the cache goes under default.

Set the proxy cache directory with --cache-dir:

voisona-talk-proxy --host 0.0.0.0 --port 32777 --cache-dir /path/to/cache

Or use VOISONA_CACHE_DIR:

export VOISONA_CACHE_DIR=/path/to/cache
voisona-talk-proxy --host 0.0.0.0 --port 32777

When mounting the proxy in your own FastAPI app, pass cache_dir to VoisonaProxy:

from fastapi import FastAPI
from voisona_talk_proxy.proxy import VoisonaProxy

app = FastAPI()
proxy = VoisonaProxy(
    username="your-voisona-talk-user",
    password="your-voisona-talk-password",
    cache_dir="/path/to/cache",
)
app.include_router(proxy.get_api_router())

⚙️ Configurations

CLI arguments take precedence over environment variables.

Setting CLI argument Environment variable Default
Listen host --host - 127.0.0.1
Listen port --port - 32777
VoiSona Talk API URL --voisona-url VOISONA_BASE_URL http://127.0.0.1:32766/api/talk/v1
Username --username VOISONA_USERNAME -
Password --password VOISONA_PASSWORD -
Cache directory --cache-dir VOISONA_CACHE_DIR voisona_talk_cache
Log level --log-level VOISONA_LOG_LEVEL info

Example:

export VOISONA_BASE_URL=http://127.0.0.1:32766/api/talk/v1
export VOISONA_USERNAME=your-voisona-talk-user
export VOISONA_PASSWORD=your-voisona-talk-password
export VOISONA_CACHE_DIR=/path/to/cache
export VOISONA_LOG_LEVEL=debug

voisona-talk-proxy --host 0.0.0.0 --port 32777

NOTE: For more advanced FastAPI or Uvicorn settings, create your own main program and mount VoisonaProxy there.

🐍 Python Local Mode

from voisona_talk_proxy.client import VoisonaTalkClient

client = VoisonaTalkClient(
    base_url="http://127.0.0.1:32766/api/talk/v1",
)

audio = await client.synthesize({
    "text": "Hello!",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP",
})

with open("output.wav", "wb") as f:
    f.write(audio)

await client.close()

You can also use get_voices() and pass values from an installed voice library. This is useful when you want to choose voices dynamically.

voices = await client.get_voices()
voice = voices["items"][0]

audio = await client.synthesize({
    "text": "Hello!",
    "language": voice["languages"][0],
    "voice_name": voice["voice_name"],
    "voice_version": voice["voice_version"],
})

🧪 Tests

The tests use the real local VoiSona Talk API, not mocks. Put your local API URL and credentials in pytest.ini, then run:

python -m pytest tests/

🌧️ Thanks

We built this repository to make 🌧️ 雨衣 / Ui's voice easier to use in all kinds of scenes. Thank you for the wonderful voice! ✨🙏✨

⚖️ License

MIT. Use it freely, and please share what you create with it on SNS!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

voisona_talk_proxy-0.1.0.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

voisona_talk_proxy-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file voisona_talk_proxy-0.1.0.tar.gz.

File metadata

  • Download URL: voisona_talk_proxy-0.1.0.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for voisona_talk_proxy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bd98c89ab027eb2976a56550d31bdfed68b23e51d709e5e0e942df7f0a6e90db
MD5 c51489a94152cda3858a62e984dca534
BLAKE2b-256 cb80840c40f4cb4a32c0eca6ea2f2688430e8c21c654e78030dee216729f1733

See more details on using hashes here.

File details

Details for the file voisona_talk_proxy-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for voisona_talk_proxy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 564e18fa984bc7d792f420a42ee6ed882a034707e1bddf831ea99d114b2b994c
MD5 0423b53532ace134fedd36558e1793e3
BLAKE2b-256 1ec16c04d366e814625c8ac88d7a83e0b58dd8a9aeda1a9e08b92f0ad9729faf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page