File size: 3,721 Bytes
05abd64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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();