Signed-off-by: linyueqian <linyueqian@outlook.com> Signed-off-by: wuli666 <djjpro975@gmail.com> Co-authored-by: linyueqian <linyueqian@outlook.com> Co-authored-by: wuli666 <djjpro975@gmail.com>
131 lines
3.3 KiB
Python
131 lines
3.3 KiB
Python
"""OpenAI-compatible client for Step-Audio2 TTS via /v1/audio/speech endpoint.
|
|
|
|
Examples:
|
|
# Basic TTS
|
|
python openai_speech_client.py --text "你好世界"
|
|
|
|
# With custom system prompt
|
|
python openai_speech_client.py --text "Hello, how are you?" \
|
|
--instructions "You are a friendly assistant."
|
|
|
|
# Save to specific file
|
|
python openai_speech_client.py --text "你好世界" -o output.wav
|
|
"""
|
|
|
|
import argparse
|
|
|
|
import httpx
|
|
|
|
DEFAULT_API_BASE = "http://localhost:8092"
|
|
DEFAULT_API_KEY = "EMPTY"
|
|
|
|
|
|
def run_tts_generation(args) -> None:
|
|
"""Run TTS generation via /v1/audio/speech API."""
|
|
payload = {
|
|
"model": args.model,
|
|
"input": args.text,
|
|
"voice": args.voice,
|
|
"response_format": args.response_format,
|
|
}
|
|
|
|
if args.instructions:
|
|
payload["instructions"] = args.instructions
|
|
|
|
print(f"Model: {args.model}")
|
|
print(f"Text: {args.text}")
|
|
print(f"Voice: {args.voice}")
|
|
print("Generating audio...")
|
|
|
|
api_url = f"{args.api_base}/v1/audio/speech"
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {args.api_key}",
|
|
}
|
|
|
|
with httpx.Client(timeout=300.0) as client:
|
|
response = client.post(api_url, json=payload, headers=headers)
|
|
|
|
if response.status_code != 200:
|
|
print(f"Error: {response.status_code}")
|
|
print(response.text)
|
|
return
|
|
|
|
try:
|
|
text = response.content.decode("utf-8")
|
|
if text.startswith('{"error"'):
|
|
print(f"Error: {text}")
|
|
return
|
|
except UnicodeDecodeError:
|
|
pass
|
|
|
|
output_path = args.output or "tts_output.wav"
|
|
with open(output_path, "wb") as f:
|
|
f.write(response.content)
|
|
print(f"Audio saved to: {output_path}")
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description="Step-Audio2 TTS client via /v1/audio/speech",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog=__doc__,
|
|
)
|
|
parser.add_argument(
|
|
"--api-base",
|
|
type=str,
|
|
default=DEFAULT_API_BASE,
|
|
help=f"API base URL (default: {DEFAULT_API_BASE})",
|
|
)
|
|
parser.add_argument(
|
|
"--api-key",
|
|
type=str,
|
|
default=DEFAULT_API_KEY,
|
|
help="API key (default: EMPTY)",
|
|
)
|
|
parser.add_argument(
|
|
"--model",
|
|
"-m",
|
|
type=str,
|
|
default="stepfun-ai/Step-Audio2-mini",
|
|
help="Model name/path",
|
|
)
|
|
parser.add_argument(
|
|
"--text",
|
|
type=str,
|
|
required=True,
|
|
help="Text to synthesize",
|
|
)
|
|
parser.add_argument(
|
|
"--voice",
|
|
type=str,
|
|
default="default",
|
|
help="Voice name (default: default)",
|
|
)
|
|
parser.add_argument(
|
|
"--instructions",
|
|
type=str,
|
|
default=None,
|
|
help="System prompt for the Thinker stage",
|
|
)
|
|
parser.add_argument(
|
|
"--response-format",
|
|
type=str,
|
|
default="wav",
|
|
choices=["wav", "pcm"],
|
|
help="Audio output format (default: wav)",
|
|
)
|
|
parser.add_argument(
|
|
"--output",
|
|
"-o",
|
|
type=str,
|
|
default=None,
|
|
help="Output audio file path (default: tts_output.wav)",
|
|
)
|
|
return parser.parse_args()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = parse_args()
|
|
run_tts_generation(args)
|