mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-10-09 21:14:00 +00:00
TTS/STT languages and voices for each provider (#281)
* wip * wip * wip * wip * wip * wip * add testcase
This commit is contained in:
@@ -5,8 +5,9 @@ const SpeechCredential = require('../../models/speech-credential');
|
||||
const sysError = require('../error');
|
||||
const {decrypt, encrypt} = require('../../utils/encrypt-decrypt');
|
||||
const {parseAccountSid, parseServiceProviderSid, parseSpeechCredentialSid} = require('./utils');
|
||||
const {decryptCredential, testWhisper, testDeepgramTTS} = require('../../utils/speech-utils');
|
||||
const {DbErrorUnprocessableRequest, DbErrorForbidden} = require('../../utils/errors');
|
||||
const {decryptCredential, testWhisper, testDeepgramTTS,
|
||||
getLanguagesAndVoicesForVendor} = require('../../utils/speech-utils');
|
||||
const {DbErrorUnprocessableRequest, DbErrorForbidden, DbErrorBadRequest} = require('../../utils/errors');
|
||||
const {
|
||||
testGoogleTts,
|
||||
testGoogleStt,
|
||||
@@ -24,7 +25,6 @@ const {
|
||||
testElevenlabs,
|
||||
testAssemblyStt
|
||||
} = require('../../utils/speech-utils');
|
||||
const bent = require('bent');
|
||||
const {promisePool} = require('../../db');
|
||||
|
||||
const validateAdd = async(req) => {
|
||||
@@ -751,89 +751,30 @@ router.get('/:sid/test', async(req, res) => {
|
||||
* Fetch speech voices and languages
|
||||
*/
|
||||
|
||||
router.post('/voices', async(req, res) => {
|
||||
router.get('/speech/supportedLanguagesAndVoices', async(req, res) => {
|
||||
const logger = req.app.locals.logger;
|
||||
const {vendor, label} = req.body;
|
||||
const account_sid = req.user.account_sid || req.body.account_sid;
|
||||
const service_provider_sid = req.user.service_provider_sid ||
|
||||
req.body.service_provider_sid || parseServiceProviderSid(req);
|
||||
try {
|
||||
res.status(200).json(await getTtsVoices(vendor, label, service_provider_sid, account_sid));
|
||||
const {vendor, label} = req.query;
|
||||
if (!vendor) {
|
||||
throw new DbErrorBadRequest('vendor is required');
|
||||
}
|
||||
const account_sid = req.user.account_sid || req.body.account_sid;
|
||||
const service_provider_sid = req.user.service_provider_sid ||
|
||||
req.body.service_provider_sid || parseServiceProviderSid(req);
|
||||
|
||||
const credentials = await SpeechCredential.getSpeechCredentialsByVendorAndLabel(
|
||||
service_provider_sid, account_sid, vendor, label);
|
||||
const tmp = credentials && credentials.length > 0 ? credentials[0] : null;
|
||||
const cred = tmp ? JSON.parse(decrypt(tmp.credential)) : null;
|
||||
try {
|
||||
const data = await getLanguagesAndVoicesForVendor(logger, vendor, cred);
|
||||
res.status(200).json(data);
|
||||
} catch (err) {
|
||||
throw new DbErrorUnprocessableRequest(err.message);
|
||||
}
|
||||
} catch (err) {
|
||||
sysError(logger, res, err);
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/languages', async(req, res) => {
|
||||
const logger = req.app.locals.logger;
|
||||
const {vendor, label} = req.body;
|
||||
const account_sid = req.user.account_sid || req.body.account_sid;
|
||||
const service_provider_sid = req.user.service_provider_sid ||
|
||||
req.body.service_provider_sid || parseServiceProviderSid(req);
|
||||
try {
|
||||
res.status(200).json(await getTtsLanguages(vendor, label, service_provider_sid, account_sid));
|
||||
} catch (err) {
|
||||
sysError(logger, res, err);
|
||||
}
|
||||
});
|
||||
|
||||
const getTtsVoices = async(vendor, label, service_provider_sid, account_sid) => {
|
||||
const credentials = await SpeechCredential.getSpeechCredentialsByVendorAndLabel(
|
||||
service_provider_sid, account_sid, vendor, label);
|
||||
const tmp = credentials && credentials.length > 0 ? credentials[0] : null;
|
||||
const cred = tmp ? JSON.parse(decrypt(tmp.credential)) : null;
|
||||
if (vendor === 'elevenlabs') {
|
||||
const get = bent('https://api.elevenlabs.io', 'GET', 'json', {
|
||||
...(cred && {
|
||||
'xi-api-key' : cred.api_key
|
||||
})
|
||||
});
|
||||
const resp = await get('/v1/voices');
|
||||
return resp ? resp.voices.map((v) => {
|
||||
let name = `${v.name}${v.category !== 'premade' ? ` (${v.category})` : ''} -
|
||||
${v.labels.accent ? ` ${v.labels.accent},` : ''}
|
||||
${v.labels.description ? ` ${v.labels.description},` : ''}
|
||||
${v.labels.age ? ` ${v.labels.age},` : ''}
|
||||
${v.labels.gender ? ` ${v.labels.gender},` : ''}
|
||||
${v.labels['use case'] ? ` ${v.labels['use case']},` : ''}
|
||||
`;
|
||||
const lastIndex = name.lastIndexOf(',');
|
||||
if (lastIndex !== -1) {
|
||||
name = name.substring(0, lastIndex);
|
||||
}
|
||||
return {
|
||||
value: v.voice_id,
|
||||
name
|
||||
};
|
||||
}).sort((a, b) => a.name.localeCompare(b.name)) : [];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const getTtsLanguages = async(vendor, label, service_provider_sid, account_sid) => {
|
||||
const credentials = await SpeechCredential.getSpeechCredentialsByVendorAndLabel(
|
||||
service_provider_sid, account_sid, vendor, label);
|
||||
const tmp = credentials && credentials.length > 0 ? credentials[0] : null;
|
||||
const cred = tmp ? JSON.parse(decrypt(tmp.credential)) : null;
|
||||
if (vendor === 'elevenlabs') {
|
||||
if (!cred) {
|
||||
return [];
|
||||
}
|
||||
const get = bent('https://api.elevenlabs.io', 'GET', 'json', {
|
||||
'xi-api-key' : cred.api_key
|
||||
});
|
||||
const resp = await get('/v1/models');
|
||||
if (!resp || resp.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const model = resp.find((m) => m.model_id === cred.model_id);
|
||||
return model ? model.languages.map((l) => {
|
||||
return {
|
||||
value: l.language_id,
|
||||
name: l.name
|
||||
};
|
||||
}).sort((a, b) => a.name.localeCompare(b.name)) : [];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user