"""TTS 合成 API Schema。""" from __future__ import annotations from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel, Field class TTSSynthesizeRequest(BaseModel): """TTS 合成请求。""" text: str = Field(..., min_length=1, max_length=10000, description="合成文本") voice_id: str = Field("", description="音色 ID") output_name: str = Field("", description="输出文件名") language: str = Field("zh-CN", description="语言") speed: float = Field(1.0, ge=0.5, le=2.0, description="语速") voice_model: str = Field("", description="语音模型名称") voice_clone_profile_id: str = Field("", description="关联的音色克隆档案 ID") format: str = Field("mp3", description="输出格式(mp3/wav/pcm)") metadata_: Optional[Dict[str, Any]] = Field(default=None, alias="metadata", description="额外元数据") class Config: populate_by_name = True class TTSJobResponse(BaseModel): """TTS 任务响应。""" id: str user_id: str input_text: str voice_id: str = "" voice_model: str = "" project_id: str = "" voice_clone_profile_id: str = "" status: str output_audio_url: str = "" output_audio_key: str = "" duration: float = 0.0 file_size: int = 0 sample_rate: int = 22050 format: str = "mp3" error_message: str = "" retry_count: int = 0 max_retries: int = 3 metadata_: Optional[Dict[str, Any]] = Field(default=None, alias="metadata", description="额外元数据") started_at: Optional[datetime] = None completed_at: Optional[datetime] = None created_at: datetime updated_at: datetime class Config: populate_by_name = True class TTSStatusResponse(BaseModel): """TTS 任务状态响应(用于轮询)。""" id: str status: str output_audio_url: str = "" error_message: str = "" duration: float = 0.0 retry_count: int = 0 created_at: datetime updated_at: datetime class TTSSynthesizeResponse(BaseModel): """TTS 合成创建响应。""" job_id: str status: str message: str = "合成任务已创建" class ListTTSJobResponse(BaseModel): """TTS 任务列表响应。""" items: List[TTSJobResponse] total: int page: int page_size: int class SaveToLibraryRequest(BaseModel): """保存到配音库请求。""" name: Optional[str] = Field(None, description="配音素材名称,留空则自动生成") class SaveToLibraryResponse(BaseModel): """保存到配音库响应。""" id: str name: str audio_url: str duration: float voice_id: str voice_name: str status: str