Implement script generation endpoint (Task 18)
- Added ScriptRequest, ScriptResponse, and ScriptSegment Pydantic models - Created /api/tts/script POST endpoint in main.py - Integrated with TTSService to generate script segments using AI - Added generate_script_segments method to TTSService - Returns segments with unique IDs for frontend tracking - Handles errors gracefully when AI segmentation fails - Falls back to pattern-based segmentation when Ollama unavailable - Added comprehensive tests for the endpoint - Validates: Requirements 15.1, 15.2
This commit is contained in:
@@ -288,6 +288,62 @@ class TTSService:
|
||||
|
||||
return concatenated
|
||||
|
||||
async def generate_script_segments(
|
||||
self,
|
||||
text: str,
|
||||
roles: List[str]
|
||||
) -> List[Tuple[str, str]]:
|
||||
"""
|
||||
Generates script segments with speaker assignments using AI.
|
||||
|
||||
This method is used for the script preview feature, allowing users to
|
||||
review and edit speaker assignments before generating audio.
|
||||
|
||||
Args:
|
||||
text: Input text to segment
|
||||
roles: List of detected role IDs/names
|
||||
|
||||
Returns:
|
||||
List of tuples: (speaker_name, text_content)
|
||||
|
||||
Raises:
|
||||
Exception: If both AI and pattern-based segmentation fail
|
||||
"""
|
||||
logger.info(f"Generating script segments for {len(text)} chars with {len(roles)} roles")
|
||||
|
||||
# Try AI segmentation first
|
||||
try:
|
||||
is_available = await self.ollama_service.is_available()
|
||||
if is_available:
|
||||
logger.info("Using AI for script segmentation")
|
||||
segments = await self.ollama_service.segment_text(text, roles)
|
||||
|
||||
if segments:
|
||||
logger.info(f"AI segmentation produced {len(segments)} segments")
|
||||
return segments
|
||||
else:
|
||||
logger.warning("AI segmentation returned empty result")
|
||||
else:
|
||||
logger.info("Ollama not available for script segmentation")
|
||||
except Exception as e:
|
||||
logger.warning(f"AI segmentation failed: {e}")
|
||||
|
||||
# Fall back to pattern-based segmentation
|
||||
logger.info("Using pattern-based segmentation as fallback")
|
||||
|
||||
# Create a dummy role_voice_map for pattern-based segmentation
|
||||
# We don't need actual voices here, just role assignments
|
||||
role_voice_map = {role: self.DEFAULT_VOICE for role in roles}
|
||||
|
||||
# Use existing segment_text method
|
||||
segments_with_voice = self.segment_text(text, role_voice_map)
|
||||
|
||||
# Convert from (role, voice, text) to (role, text)
|
||||
segments = [(role, text) for role, voice, text in segments_with_voice]
|
||||
|
||||
logger.info(f"Pattern-based segmentation produced {len(segments)} segments")
|
||||
return segments
|
||||
|
||||
async def generate_audiobook(
|
||||
self,
|
||||
text: str,
|
||||
|
||||
Reference in New Issue
Block a user