LT-ML / backend /controllers /tts.controller.js
WokoVN's picture
Upload 75 files
bb57163 verified
import ttsService from '../services/tts.service.js';
import ttsJobService from '../services/ttsJob.service.js';
import audioTranscodeService from '../services/audioTranscode.service.js';
class TtsController {
handleServiceError(error, res, defaultMessage) {
console.error('[TTS Bridge] Error:', error.message);
if (error.response) {
return res.status(error.response.status).json({
error: defaultMessage,
details: error.response.data
});
}
return res.status(500).json({
error: defaultMessage,
details: error.message
});
}
async health(req, res) {
try {
const data = await ttsService.health();
return res.json(data);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to reach TTS service');
}
}
async synthesize(req, res) {
try {
const { text, language, speaker_audio } = req.body;
if (!text) {
return res.status(400).json({ error: 'Text is required' });
}
const data = await ttsService.synthesize({
text,
language,
speaker_audio
});
if (!data?.audio_base64) {
return res.status(502).json({ error: 'TTS service returned empty audio payload' });
}
const wavBuffer = Buffer.from(data.audio_base64, 'base64');
const mp3Buffer = await audioTranscodeService.convertWavToMp3(wavBuffer);
const responsePayload = {
...data,
audio_base64: mp3Buffer.toString('base64'),
format: 'mp3',
mime_type: 'audio/mpeg',
size_bytes: mp3Buffer.length
};
return res.json(responsePayload);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to synthesize speech');
}
}
async createTask(req, res) {
try {
const { text, language, speaker_audio } = req.body;
if (!text) {
return res.status(400).json({ error: 'Text is required' });
}
const data = await ttsService.createTask({
text,
language,
speaker_audio
});
return res.status(202).json(data);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to dispatch TTS task');
}
}
async getTask(req, res) {
try {
const { taskId } = req.params;
if (!taskId) {
return res.status(400).json({ error: 'taskId is required' });
}
const data = await ttsService.getTask(taskId);
return res.json(data);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to fetch TTS task status');
}
}
async createStorageJob(req, res) {
try {
const { text, language, speaker_audio } = req.body;
if (!text) {
return res.status(400).json({ error: 'Text is required' });
}
const data = ttsJobService.createJob({
text,
language,
speaker_audio
});
return res.status(202).json(data);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to create TTS storage job');
}
}
async getStorageJob(req, res) {
try {
const { key } = req.params;
if (!key) {
return res.status(400).json({ error: 'key is required' });
}
const data = ttsJobService.getJob(key);
if (!data) {
return res.status(404).json({ error: 'TTS job not found' });
}
return res.json(data);
} catch (error) {
return this.handleServiceError(error, res, 'Failed to fetch TTS storage job');
}
}
}
export default new TtsController();