tts.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright (C) 2025 AIDC-AI
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS,
  9. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. # See the License for the specific language governing permissions and
  11. # limitations under the License.
  12. """
  13. TTS (Text-to-Speech) endpoints
  14. """
  15. from fastapi import APIRouter, HTTPException
  16. from loguru import logger
  17. from api.dependencies import PixelleVideoDep
  18. from api.schemas.tts import TTSSynthesizeRequest, TTSSynthesizeResponse
  19. from pixelle_video.utils.tts_util import get_audio_duration
  20. router = APIRouter(prefix="/tts", tags=["Basic Services"])
  21. @router.post("/synthesize", response_model=TTSSynthesizeResponse)
  22. async def tts_synthesize(
  23. request: TTSSynthesizeRequest,
  24. pixelle_video: PixelleVideoDep
  25. ):
  26. """
  27. Text-to-Speech synthesis endpoint
  28. Convert text to speech audio using ComfyUI workflows.
  29. - **text**: Text to synthesize
  30. - **workflow**: TTS workflow key (optional, uses default if not specified)
  31. - **ref_audio**: Reference audio for voice cloning (optional)
  32. - **voice_id**: (Deprecated) Voice ID for legacy compatibility
  33. Returns path to generated audio file and duration.
  34. Examples:
  35. ```json
  36. {
  37. "text": "Hello, welcome to Pixelle-Video!",
  38. "workflow": "runninghub/tts_edge.json"
  39. }
  40. ```
  41. With voice cloning:
  42. ```json
  43. {
  44. "text": "Hello, this is a cloned voice",
  45. "workflow": "runninghub/tts_index2.json",
  46. "ref_audio": "path/to/reference.wav"
  47. }
  48. ```
  49. """
  50. try:
  51. logger.info(f"TTS synthesis request: {request.text[:50]}...")
  52. # Build TTS parameters
  53. tts_params = {"text": request.text}
  54. # Add workflow if specified
  55. if request.workflow:
  56. tts_params["workflow"] = request.workflow
  57. # Add ref_audio if specified
  58. if request.ref_audio:
  59. tts_params["ref_audio"] = request.ref_audio
  60. # Legacy voice_id support (deprecated)
  61. if request.voice_id and not request.workflow:
  62. logger.warning("voice_id parameter is deprecated, please use workflow instead")
  63. tts_params["voice"] = request.voice_id
  64. # Call TTS service
  65. audio_path = await pixelle_video.tts(**tts_params)
  66. # Get audio duration
  67. duration = get_audio_duration(audio_path)
  68. return TTSSynthesizeResponse(
  69. audio_path=audio_path,
  70. duration=duration
  71. )
  72. except Exception as e:
  73. logger.error(f"TTS synthesis error: {e}")
  74. raise HTTPException(status_code=500, detail=str(e))