Files
call-center/scripts/materialize_tts_prompt.py
T

73 lines
2.3 KiB
Python

from __future__ import annotations
import argparse
import os
from pathlib import Path
import sys
import tempfile
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from services.ai_voice_runtime_service.audiosocket import pcm16le_to_wav_bytes, resample_pcm16le
from services.ai_voice_runtime_service.providers.tts import build_tts_provider
def _parse_args() -> argparse.Namespace:
default_provider = os.getenv("AI_VOICE_TTS_PROVIDER", "yandex").strip() or "yandex"
parser = argparse.ArgumentParser(
description="Generate TTS once, cache it on the server, and materialize a WAV prompt file.",
)
parser.add_argument("--text", required=True, help="Text to synthesize.")
parser.add_argument("--output", required=True, help="Target WAV path.")
parser.add_argument("--language", default=None, help="Optional language hint.")
parser.add_argument(
"--provider",
default=default_provider,
help="TTS provider name. Defaults to AI_VOICE_TTS_PROVIDER or yandex.",
)
parser.add_argument("--sample-rate", type=int, default=8000, help="Target WAV sample rate. Defaults to 8000.")
return parser.parse_args()
def _write_atomic(target: Path, payload: bytes) -> None:
target.parent.mkdir(parents=True, exist_ok=True)
temp_path: str | None = None
try:
with tempfile.NamedTemporaryFile(dir=target.parent, delete=False, suffix=".tmp") as handle:
handle.write(payload)
temp_path = handle.name
Path(temp_path).replace(target)
target.chmod(0o644)
finally:
if temp_path:
try:
Path(temp_path).unlink(missing_ok=True)
except OSError:
pass
def main() -> int:
args = _parse_args()
provider = build_tts_provider(args.provider)
synthesis = provider.synthesize(args.text, language=args.language)
pcm_bytes = resample_pcm16le(
synthesis.audio_bytes,
input_rate_hz=synthesis.sample_rate_hz,
output_rate_hz=max(args.sample_rate, 1),
)
wav_bytes = pcm16le_to_wav_bytes(
pcm_bytes,
sample_rate_hz=max(args.sample_rate, 1),
)
output_path = Path(args.output).expanduser()
_write_atomic(output_path, wav_bytes)
print(output_path)
return 0
if __name__ == "__main__":
raise SystemExit(main())