File size: 6,470 Bytes
c9aef91 8a9ef43 c9aef91 8a9ef43 c9aef91 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | # HTTP API
`gsv_server` exposes an api_v2-compatible subset over HTTP. The machine-readable description
is served by the server itself: `GET /docs` or `GET /openapi.json` (OpenAPI 3).
## Basics
- Default address: `http://127.0.0.1:9880` (see `--host` / `--port`).
- Auth: when started with `--token <T>`, every request must send `Authorization: Bearer <T>`
or `?token=<T>`. Binding to a non-loopback address requires `--token`.
- File access: `ref_audio_path` must live under one of the `--allow-path` directories, or under
the upload directory created by `POST /reference`. Otherwise the server answers `403`.
- Errors are JSON: `{"code": "<error_code>", "message": "<human readable>"}` with HTTP status
`400` (bad request), `401` (auth), `403` (path), `500` (engine), `501` (not implemented),
`503` (busy / sidecar down), `504` (timeout).
- Responses carry `X-Request-Id` (supply your own via the header if you want it echoed).
## POST /tts
Synthesize one text.
```json
{
"text": "δ½ ε₯½οΌζ¬’θΏδ½Ώη¨θ―ι³εζη³»η»γ",
"text_lang": "zh",
"ref_audio_path": "/path/to/ref.wav",
"prompt_text": "reference transcript",
"prompt_lang": "zh",
"sample_steps": 4,
"cfg_rate": 0.0,
"seed": 20261014,
"stream": false
}
```
| field | type | default | notes |
|---|---|---|---|
| `text` | string | β | required, <= 4000 bytes |
| `text_lang` | string | `zh` | `zh` / `en` / `ja` / `ko` / `yue` |
| `ref_audio_path` | string | β | required unless a default reference was set |
| `prompt_text` | string | β | required unless a default reference was set |
| `prompt_lang` | string | `zh` | language of `prompt_text` |
| `voice` | string | current | registered voice name |
| `sample_steps` | int | per voice | 1..1000 (v5turbo 4, v5dev 32) |
| `cfg_rate` | float | per voice | <= 20 |
| `seed` | int | -1 | -1 = random |
| `top_k`, `top_p`, `temperature`, `repetition_penalty` | | AR defaults (15/1/1/1.35) | |
| `speed_factor` | float | 1.0 | (0, 4] |
| `text_split_method` | string | `cut5` | `cut0`..`cut5` |
| `fragment_interval` | float | 0.3 | silence between segments, seconds (0..5) |
| `dbcache` | string | `auto` | cache-dit: `off` / `auto` / `f4` / `f8` / `f16` |
| `media_type` | string | `wav` | only `wav` |
| `stream` | bool | `false` | see below |
`GET /tts` accepts the same fields as query parameters.
Non-stream response: `audio/wav`, 48 kHz mono 16-bit, whole-request peak-normalized to 0.708.
### Streaming (`stream: true`)
`POST /tts` with `stream: true` answers `Transfer-Encoding: chunked` with `audio/wav`:
- the 44-byte WAV header is sent immediately (RIFF/data sizes are `0xFFFFFFFF`, as usual for
streaming WAV; players read until the connection closes);
- PCM is flushed after every text segment, plus `fragment_interval` of silence between segments;
- segments use a finer splitter than `cut5` (sentence-sized, >= 4 chars, <= 60 chars per chunk),
so the first audio arrives earlier; `text_split_method=cut0` disables splitting;
- streamed audio is **not** peak-normalized (per-segment normalization would pump the volume);
- streamed requests bypass the AR batching scheduler, so total time can be higher than
non-streaming for the same text; use streaming for latency, not throughput.
Measured on the dev box (CPU, 3 sentences): header in 13 ms, first PCM after the first segment,
total roughly the sum of the segments.
## GET /health, GET /metrics
`/health` β readiness: `{"ok":true,"engine":"ready","voice":"default","sidecar":true,"queue":0,...}`.
`/metrics` β counters: `tts_requests`, `errors`, `jobs`, `timeouts`, `busy`, `reloads`,
`ar_batches`, `ar_tasks`, `sched_batches`, `sched_texts`, `queue`, `waiters`, `last_total_ms`.
## Batch
- `POST /batch` with `{"texts":[...], ...same fields as /tts}` β `{"job_id":"<id>","total":N}`.
- `GET /jobs/<id>` β state (`queued` / `running` / `done` / `canceled` / `failed`).
- `GET /jobs/<id>/result/<i>` β WAV of item `i`.
- `DELETE /jobs/<id>` β cancel / drop.
## References
- `GET /change_refer?refer_wav_path=...&prompt_text=...&prompt_lang=zh` (POST also accepts a JSON
body) stores a **default reference**. Later `/tts` calls may omit `ref_audio_path` /
`prompt_text` / `prompt_lang`.
- `GET /set_refer_audio?...` is an alias of `/change_refer`.
- `POST /reference` with a raw WAV body uploads a reference to the temp directory and returns
`{"path": "...", "bytes": N}`; that path is implicitly allowed for `ref_audio_path`.
## Misc
- `GET /models` β voices and the current one; `?rescan=1` re-scans `models/voices`.
- `GET /progress` β coarse progress of the current synthesis:
`{"stage":1,"cur":0,"total":0}` where stage is `0` idle, `1` text frontend, `2` AR,
`3` DiT/CFM, `4` vocoder, `5` done; `cur/total` counts AR tokens or DiT steps.
The GAG GUI polls this for its progress bar.
- `GET /control` without `command` β `400 {"message":"command is required ..."}`. This is the
api_v2-compatible liveness probe (the upstream GUI treats `400` as "API ready"); prefer
`/health` for new clients.
- `GET /control?command=exit` β graceful shutdown (used by tests); `?command=restart` reloads
the current voice.
- `GET /asr` β `501`, ASR is not part of this engine.
- `GET /docs`, `GET /openapi.json` β OpenAPI 3 document.
- `GET /tts_ws` β `501`: this build has no WebSocket support; use `POST /tts` with
`stream: true` instead.
- `--parent-pid PID` (CLI) makes the server exit when that process disappears; the Windows
one-click package uses it so closing the GUI frees the GPU.
## Examples
```bash
# one-shot
curl -s -X POST http://127.0.0.1:9880/tts -H 'Content-Type: application/json' \
-d '{"text":"δ½ ε₯½","text_lang":"zh","ref_audio_path":"/models/ref.wav",
"prompt_text":"εθι³ι’ζζ¬","sample_steps":4}' -o out.wav
# streaming to a player
curl -sN -X POST http://127.0.0.1:9880/tts -H 'Content-Type: application/json' \
-d '{"text":"第δΈε₯γ第δΊε₯γ","ref_audio_path":"/models/ref.wav",
"prompt_text":"εθι³ι’ζζ¬","stream":true}' | ffplay -autoexit -
# default reference, then synthesize
curl -s "http://127.0.0.1:9880/change_refer?refer_wav_path=/models/ref.wav&prompt_text=%E5%8F%82%E8%80%83"
curl -s -X POST http://127.0.0.1:9880/tts -H 'Content-Type: application/json' -d '{"text":"δ½ ε₯½"}'
```
|