Funktioniert
This commit is contained in:
46
test_ws.py
46
test_ws.py
@@ -6,6 +6,7 @@ import time
|
||||
import wave
|
||||
import struct
|
||||
import asyncio
|
||||
import re
|
||||
|
||||
try:
|
||||
import websockets
|
||||
@@ -18,12 +19,30 @@ except ImportError:
|
||||
WS_URL = "ws://localhost:8091/v1/audio/speech/stream"
|
||||
OUTPUT_FILE = "test_stream_output.wav"
|
||||
SAMPLE_RATE = 24000
|
||||
WORD_RE = re.compile(r"\S+\s*")
|
||||
|
||||
|
||||
async def stream_tts(text: str, voice: str = "Ryan", language: str = "German"):
|
||||
def iter_words(text: str):
|
||||
"""Yield complete words, preserving trailing whitespace.
|
||||
|
||||
The WebSocket client must not forward raw LLM tokens such as partial
|
||||
subwords. It buffers to words and lets the server detect sentence ends.
|
||||
"""
|
||||
for match in WORD_RE.finditer(text):
|
||||
yield match.group(0)
|
||||
|
||||
|
||||
async def stream_tts(
|
||||
text: str,
|
||||
voice: str = "Ryan",
|
||||
language: str = "German",
|
||||
instructions: str = "Eine warme, ruhige deutsche Stimme, klar artikuliert, freundlich und natuerlich.",
|
||||
seed: int = 42,
|
||||
):
|
||||
print(f"[→] WebSocket connect: {WS_URL}")
|
||||
print(f" text: {text!r}")
|
||||
print(f" voice: {voice}, language: {language}")
|
||||
print(f" voice: {voice}, language: {language}, seed: {seed}")
|
||||
print(f" instruct: {instructions!r}")
|
||||
|
||||
pcm_chunks = []
|
||||
total_bytes = 0
|
||||
@@ -32,21 +51,28 @@ async def stream_tts(text: str, voice: str = "Ryan", language: str = "German"):
|
||||
|
||||
async with websockets.connect(WS_URL) as ws:
|
||||
# Send session config
|
||||
await ws.send(json.dumps({
|
||||
config = {
|
||||
"type": "session.config",
|
||||
"model": "Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice",
|
||||
"task_type": "CustomVoice",
|
||||
"task_type": "VoiceDesign",
|
||||
"voice": voice,
|
||||
"language": language,
|
||||
"instructions": instructions,
|
||||
"seed": seed,
|
||||
"response_format": "pcm",
|
||||
"stream_audio": True,
|
||||
}))
|
||||
"split_granularity": "sentence",
|
||||
}
|
||||
print("[cfg]", json.dumps(config, ensure_ascii=False, sort_keys=True), flush=True)
|
||||
await ws.send(json.dumps(config))
|
||||
|
||||
# Send text
|
||||
await ws.send(json.dumps({
|
||||
"type": "input.text",
|
||||
"text": text,
|
||||
}))
|
||||
# Send word-by-word. Do not split into sentences client-side; the
|
||||
# server still decides when a complete sentence is ready for audio.
|
||||
for word in iter_words(text):
|
||||
await ws.send(json.dumps({
|
||||
"type": "input.text",
|
||||
"text": word,
|
||||
}))
|
||||
await ws.send(json.dumps({"type": "input.done"}))
|
||||
|
||||
# Receive
|
||||
|
||||
Reference in New Issue
Block a user