Initial import with GitLab CI/CD and registry deploy flow
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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", "openai").strip() or "openai"
|
||||
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 openai.",
|
||||
)
|
||||
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())
|
||||
Reference in New Issue
Block a user