fix: Improve Piper TTS error handling and user messaging
- Added proper error handling for missing voice models in preview endpoint - Return 404 with helpful message when Piper models not found - Added user-friendly alert in frontend when preview fails - Added prominent warning in UI when Piper is selected about manual setup - Check for empty audio before returning to prevent decode errors Users now get clear feedback when Piper voice models are missing instead of cryptic 'media could not be decoded' errors.
This commit is contained in:
@@ -414,6 +414,10 @@ async def preview_voice(request: VoicePreviewRequest):
|
||||
else:
|
||||
raise ValueError(f"Unknown engine: {tts_service.engine_name}")
|
||||
|
||||
# Check if audio was generated
|
||||
if audio is None or len(audio) == 0:
|
||||
raise ValueError("No audio generated - voice model may be missing")
|
||||
|
||||
# Convert to WAV bytes
|
||||
buffer = io.BytesIO()
|
||||
sf.write(buffer, audio, sample_rate, format='WAV')
|
||||
@@ -427,7 +431,31 @@ async def preview_voice(request: VoicePreviewRequest):
|
||||
media_type="audio/wav",
|
||||
headers={"Content-Disposition": "inline; filename=preview.wav"}
|
||||
)
|
||||
|
||||
|
||||
except FileNotFoundError as e:
|
||||
logger.error(f"Voice model not found: {str(e)}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
content={
|
||||
"error": "VoiceModelNotFound",
|
||||
"message": f"Voice model '{request.voice}' not found. Please download Piper voice models manually.",
|
||||
"details": {
|
||||
"voice": request.voice,
|
||||
"engine": tts_service.engine_name,
|
||||
"setup_guide": "See backend/PIPER_SETUP.md for instructions"
|
||||
}
|
||||
}
|
||||
)
|
||||
except ValueError as e:
|
||||
logger.error(f"Validation error during preview: {str(e)}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
content={
|
||||
"error": "ValidationError",
|
||||
"message": str(e),
|
||||
"details": {"voice": request.voice, "engine": tts_service.engine_name}
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error during voice preview: {str(e)}", exc_info=True)
|
||||
return JSONResponse(
|
||||
|
||||
1
backend/piper_models/en_US-lessac-medium.onnx.json
Normal file
1
backend/piper_models/en_US-lessac-medium.onnx.json
Normal file
@@ -0,0 +1 @@
|
||||
Entry not found
|
||||
@@ -262,6 +262,11 @@ export default function VoiceAssignmentSection({
|
||||
} catch (error) {
|
||||
console.error('Preview failed:', error);
|
||||
setPreviewingRole(null);
|
||||
|
||||
// Show user-friendly error message
|
||||
if (error instanceof Error) {
|
||||
alert(`Voice preview failed: ${error.message}\n\nIf using Piper TTS, make sure voice models are downloaded. See backend/PIPER_SETUP.md for instructions.`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -350,10 +355,19 @@ export default function VoiceAssignmentSection({
|
||||
</button>
|
||||
</div>
|
||||
{currentEngine === 'piper' && (
|
||||
<div className="mt-3 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<p className="text-sm text-blue-900">
|
||||
<strong>✨ Pitch Control:</strong> Piper allows you to adjust voice pitch per character (coming soon in UI)
|
||||
</p>
|
||||
<div className="mt-3 space-y-2">
|
||||
<div className="p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<p className="text-sm text-blue-900">
|
||||
<strong>✨ Pitch Control:</strong> Piper allows you to adjust voice pitch per character (coming soon in UI)
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 bg-yellow-50 border border-yellow-300 rounded-lg">
|
||||
<p className="text-sm text-yellow-900">
|
||||
<strong>⚠️ Setup Required:</strong> Piper voice models must be downloaded manually.
|
||||
See <code className="bg-yellow-100 px-1 rounded">backend/PIPER_SETUP.md</code> for instructions.
|
||||
If voices don't work, you may need to download the model files first.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user