feat: Add XTTS v2 support, refactor Docker/GPU infra, and improve Piper engine
- Add XTTS v2 configuration to .env.example - Refactor Dockerfile to multi-stage build with CUDA 12.1 support - Update Makefile with Kokoro and XTTS test environment targets - Refactor Piper engine (app/engines/piper.py) to use python module execution - Add comprehensive documentation for Kokoro and XTTS plans - Add helper scripts and patches for build process
This commit is contained in:
79
scripts/tts_client.py
Executable file
79
scripts/tts_client.py
Executable file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
A simple CLI client to test the AudioEngineHub TTS server.
|
||||
|
||||
This script requires the 'requests' library.
|
||||
Install it with: pip install requests
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import requests
|
||||
import os
|
||||
from urllib.parse import urljoin
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="CLI client for AudioEngineHub TTS server.")
|
||||
parser.add_argument("--server-url", required=True, help="Base URL of the TTS server (e.g., http://localhost:8000).")
|
||||
parser.add_argument("--text", required=True, help="Text to synthesize.")
|
||||
parser.add_argument("--engine", required=True, help="TTS engine to use (e.g., piper).")
|
||||
parser.add_argument("--model", help="Model to use (optional).")
|
||||
parser.add_argument("--speaker", help="Speaker to use (optional).")
|
||||
parser.add_argument("--output", required=True, help="Path to save the output audio file (e.g., output.ogg).")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# --- 1. Make the TTS request ---
|
||||
tts_url = urljoin(args.server_url, "/tts")
|
||||
payload = {
|
||||
"text": args.text,
|
||||
"engine": args.engine,
|
||||
"format": "ogg" # Or determine from output file extension
|
||||
}
|
||||
if args.model:
|
||||
payload["model"] = args.model
|
||||
if args.speaker:
|
||||
payload["speaker"] = args.speaker
|
||||
|
||||
print(f"Requesting synthesis from {tts_url} with payload: {payload}")
|
||||
# Add a short delay to mitigate potential connection race conditions
|
||||
import time
|
||||
time.sleep(1)
|
||||
try:
|
||||
response = requests.post(tts_url, json=payload)
|
||||
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"ERROR: Could not connect to the server: {e}")
|
||||
return
|
||||
|
||||
try:
|
||||
data = response.json()
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
print(f"ERROR: Failed to decode JSON response from server. Response text: {response.text}")
|
||||
return
|
||||
|
||||
if "audio_url" not in data:
|
||||
print(f"ERROR: Server response did not contain 'audio_url'. Response: {data}")
|
||||
return
|
||||
|
||||
# --- 2. Download the audio file ---
|
||||
audio_url = urljoin(args.server_url, data["audio_url"])
|
||||
print(f"Downloading audio from {audio_url}...")
|
||||
|
||||
try:
|
||||
audio_response = requests.get(audio_url, stream=True)
|
||||
audio_response.raise_for_status()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"ERROR: Could not download the audio file: {e}")
|
||||
return
|
||||
|
||||
# --- 3. Save the audio file ---
|
||||
try:
|
||||
with open(args.output, "wb") as f:
|
||||
for chunk in audio_response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
print(f"Successfully saved audio to '{args.output}'")
|
||||
except IOError as e:
|
||||
print(f"ERROR: Could not write to output file '{args.output}': {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user