From 198a0b2a0dc84fec5c809f9de067ce0272bd94ec Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sun, 26 Apr 2026 23:46:40 +0200 Subject: [PATCH] Fix: Use /synthesize-direct for correct language selection /synthesize always used the German model. /synthesize-direct uses Edge TTS (with language-aware voice selection) and falls back to Piper with the correct model (Thorsten DE / Lessac EN). Also cleared audio cache to purge wrongly-generated files. Co-Authored-By: Claude Opus 4.6 (1M context) --- backend-lehrer/services/audio.py | 46 ++------------------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/backend-lehrer/services/audio.py b/backend-lehrer/services/audio.py index c022517..a3f1e1b 100644 --- a/backend-lehrer/services/audio.py +++ b/backend-lehrer/services/audio.py @@ -56,56 +56,14 @@ async def synthesize_word( if os.path.exists(cached): return cached - # Call Piper TTS service + # Call Piper TTS service via /synthesize-direct (returns MP3, selects language correctly) try: async with httpx.AsyncClient(timeout=30.0) as client: resp = await client.post( - f"{TTS_SERVICE_URL}/synthesize", + f"{TTS_SERVICE_URL}/synthesize-direct", json={ "text": text, "language": language, - "voice": "thorsten-high" if language == "de" else "lessac-high", - "module_id": "vocabulary", - "content_id": word_id or _cache_key(text, language), - }, - ) - if resp.status_code != 200: - logger.warning(f"TTS service returned {resp.status_code} for '{text}'") - return None - - data = resp.json() - bucket = data.get("bucket") - object_key = data.get("object_key") - - if bucket and object_key: - # Get presigned URL to download the audio - url_resp = await client.post( - f"{TTS_SERVICE_URL}/presigned-url", - json={"bucket": bucket, "object_key": object_key, "expires": 300}, - ) - if url_resp.status_code == 200: - audio_url = url_resp.json().get("url") - if audio_url: - audio_resp = await client.get(audio_url) - if audio_resp.status_code == 200: - with open(cached, "wb") as f: - f.write(audio_resp.content) - logger.info(f"TTS cached: '{text}' ({language}) → {cached}") - return cached - - except Exception as e: - logger.warning(f"TTS service unavailable: {e}") - - # Fallback: try direct MP3 endpoint - try: - async with httpx.AsyncClient(timeout=30.0) as client: - resp = await client.post( - f"{TTS_SERVICE_URL}/synthesize/mp3", - json={ - "text": text, - "language": language, - "voice": "thorsten-high" if language == "de" else "lessac-high", - "module_id": "vocabulary", }, ) if resp.status_code == 200 and resp.headers.get("content-type", "").startswith("audio"):