|
|
|
@ -77,8 +77,8 @@ export async function pronounceWord(req: AuthRequest, res: Response) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const { audio, format } = await generateSpeech(wordText, voiceId); |
|
|
|
const { audio, format } = await generateSpeech(wordText, voiceId); |
|
|
|
|
|
|
|
|
|
|
|
// Store in cache
|
|
|
|
// Store in cache (don't await - cache in background to return faster)
|
|
|
|
await db.execute({ |
|
|
|
db.execute({ |
|
|
|
sql: ` |
|
|
|
sql: ` |
|
|
|
INSERT INTO word_pronunciations (word_id, voice_id, audio_data, audio_format) |
|
|
|
INSERT INTO word_pronunciations (word_id, voice_id, audio_data, audio_format) |
|
|
|
VALUES (?, ?, ?, ?) |
|
|
|
VALUES (?, ?, ?, ?) |
|
|
|
@ -88,9 +88,12 @@ export async function pronounceWord(req: AuthRequest, res: Response) { |
|
|
|
created_at = CURRENT_TIMESTAMP |
|
|
|
created_at = CURRENT_TIMESTAMP |
|
|
|
`,
|
|
|
|
`,
|
|
|
|
args: [wordId, voiceId, audio, format] |
|
|
|
args: [wordId, voiceId, audio, format] |
|
|
|
|
|
|
|
}).catch(err => { |
|
|
|
|
|
|
|
console.error('Error caching pronunciation:', err); |
|
|
|
|
|
|
|
// Don't fail the request if caching fails
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Return audio
|
|
|
|
// Return audio immediately
|
|
|
|
const contentType = format === 'mp3' ? 'audio/mpeg' :
|
|
|
|
const contentType = format === 'mp3' ? 'audio/mpeg' :
|
|
|
|
format === 'wav' ? 'audio/wav' :
|
|
|
|
format === 'wav' ? 'audio/wav' :
|
|
|
|
format === 'ogg' ? 'audio/ogg' : 'audio/mpeg'; |
|
|
|
format === 'ogg' ? 'audio/ogg' : 'audio/mpeg'; |
|
|
|
@ -113,11 +116,22 @@ export async function pronounceWord(req: AuthRequest, res: Response) { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle timeout errors
|
|
|
|
|
|
|
|
if (error.message.includes('timed out')) { |
|
|
|
|
|
|
|
return res.status(504).json({ |
|
|
|
|
|
|
|
success: false, |
|
|
|
|
|
|
|
error: { |
|
|
|
|
|
|
|
code: 'SPEECH_GENERATION_TIMEOUT', |
|
|
|
|
|
|
|
message: 'Speech generation timed out. Please try again.' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return res.status(500).json({ |
|
|
|
return res.status(500).json({ |
|
|
|
success: false, |
|
|
|
success: false, |
|
|
|
error: { |
|
|
|
error: { |
|
|
|
code: 'SPEECH_GENERATION_ERROR', |
|
|
|
code: 'SPEECH_GENERATION_ERROR', |
|
|
|
message: 'Failed to generate speech pronunciation' |
|
|
|
message: error.message || 'Failed to generate speech pronunciation' |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|