|
|
@@ -11,7 +11,7 @@ from dashscope.audio.tts import ResultCallback, SpeechSynthesizer, SpeechSynthes
|
|
|
|
|
|
import requests
|
|
|
|
|
|
-from ..schemas.speech import TextToSpeechResponse, DataPayload
|
|
|
+from ..schemas.base import DataResponse, TextToSpeechPayload
|
|
|
from ..core.config import get_settings
|
|
|
from ..core.logger import get_logger
|
|
|
|
|
|
@@ -30,7 +30,7 @@ def _safe_filename(name: str) -> str:
|
|
|
|
|
|
|
|
|
class SpeechProvider:
|
|
|
- def text_to_speech(self, volume: int, pitch: float, rate: float, filename: str, text: str, *, model: Optional[str] = None, format: Optional[str] = None) -> TextToSpeechResponse:
|
|
|
+ def text_to_speech(self, volume: int, pitch: float, rate: float, filename: str, text: str, *, model: Optional[str] = None, format: Optional[str] = None) -> DataResponse:
|
|
|
# Resolve output path under project-root/temp and ensure directory exists
|
|
|
project_root = Path(__file__).resolve().parents[2] # repo root
|
|
|
audio_dir = project_root / "temp"
|
|
|
@@ -38,21 +38,21 @@ class SpeechProvider:
|
|
|
audio_dir.mkdir(parents=True, exist_ok=True)
|
|
|
except Exception as e:
|
|
|
logger.error("Failed to create audio directory %s: %s", audio_dir, e, exc_info=True)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=f"create audio dir failed: {e}")
|
|
|
+ return DataResponse(code=1, data=None, msg=f"create audio dir failed: {e}")
|
|
|
|
|
|
# Basic input validation
|
|
|
if not isinstance(text, str) or not text.strip():
|
|
|
msg = "text is required"
|
|
|
logger.error(msg)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=msg)
|
|
|
+ return DataResponse(code=1, data=None, msg=msg)
|
|
|
if not isinstance(filename, str) or not filename.strip():
|
|
|
msg = "filename is required"
|
|
|
logger.error(msg)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=msg)
|
|
|
+ return DataResponse(code=1, data=None, msg=msg)
|
|
|
if not dashscope.api_key:
|
|
|
msg = "DASHSCOPE_API_KEY is missing"
|
|
|
logger.error(msg)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=msg)
|
|
|
+ return DataResponse(code=1, data=None, msg=msg)
|
|
|
|
|
|
# determine desired output format (default mp3 for smaller size)
|
|
|
audio_format = (format or 'mp3').lower()
|
|
|
@@ -97,7 +97,7 @@ class SpeechProvider:
|
|
|
callback.on_complete()
|
|
|
except Exception:
|
|
|
pass
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=str(e))
|
|
|
+ return DataResponse(code=1, data=None, msg=str(e))
|
|
|
|
|
|
if callback.had_error:
|
|
|
# TTS reported an error via callback
|
|
|
@@ -108,7 +108,7 @@ class SpeechProvider:
|
|
|
else:
|
|
|
msg = base_msg
|
|
|
logger.error("TTS callback error: %s", msg)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=msg)
|
|
|
+ return DataResponse(code=1, data=None, msg=msg)
|
|
|
|
|
|
# After synthesis completes, upload the file to OSS
|
|
|
try:
|
|
|
@@ -118,15 +118,15 @@ class SpeechProvider:
|
|
|
Path(out_path).unlink(missing_ok=True)
|
|
|
except Exception as del_err:
|
|
|
logger.warning("Failed to delete local audio %s: %s", out_path, del_err)
|
|
|
- return TextToSpeechResponse(
|
|
|
+ return DataResponse(
|
|
|
code=0,
|
|
|
- data=DataPayload(audio_url=url),
|
|
|
+ data=TextToSpeechPayload(audio_url=url),
|
|
|
msg='success'
|
|
|
)
|
|
|
except Exception as e:
|
|
|
# Keep local file for inspection; report error message
|
|
|
logger.error("Upload failed", exc_info=True)
|
|
|
- return TextToSpeechResponse(code=1, data=None, msg=str(e))
|
|
|
+ return DataResponse(code=1, data=None, msg=str(e))
|
|
|
|
|
|
|
|
|
class Callback(ResultCallback):
|