mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-21 09:08:02 +00:00
feat fallback speech
This commit is contained in:
110
lib/tasks/say.js
110
lib/tasks/say.js
@@ -59,15 +59,28 @@ class TaskSay extends Task {
|
||||
const vendor = this.synthesizer.vendor && this.synthesizer.vendor !== 'default' ?
|
||||
this.synthesizer.vendor :
|
||||
cs.speechSynthesisVendor;
|
||||
const fallbackVendor = this.synthesizer.fallbackVendor && this.synthesizer.fallbackVendor !== 'default' ?
|
||||
this.synthesizer.fallbackVendor :
|
||||
cs.fallbackSpeechSynthesisVendor;
|
||||
const language = this.synthesizer.language && this.synthesizer.language !== 'default' ?
|
||||
this.synthesizer.language :
|
||||
cs.speechSynthesisLanguage ;
|
||||
const fallbackLanguage = this.synthesizer.fallbackLanguage && this.synthesizer.fallbackLanguage !== 'default' ?
|
||||
this.synthesizer.fallbackLanguage :
|
||||
cs.fallbackSpeechSynthesisLanguage ;
|
||||
let voice = this.synthesizer.voice && this.synthesizer.voice !== 'default' ?
|
||||
this.synthesizer.voice :
|
||||
cs.speechSynthesisVoice;
|
||||
const fallbackVoice = this.synthesizer.fallbackVoice && this.synthesizer.fallbackVoice !== 'default' ?
|
||||
this.synthesizer.fallbackVoice :
|
||||
cs.fallbackSpeechSynthesisVoice;
|
||||
const fallbackLabel = this.synthesizer.fallbackLabel && this.synthesizer.fallbackLabel !== 'default' ?
|
||||
this.synthesizer.fallbackLabel :
|
||||
cs.fallbackSpeechSynthesisLabel;
|
||||
const engine = this.synthesizer.engine || 'standard';
|
||||
const salt = cs.callSid;
|
||||
let credentials = cs.getSpeechCredentials(vendor, 'tts', this.data.synthesizer?.label || cs.speechSynthesisLabel);
|
||||
let credentials = cs.getSpeechCredentials(vendor, 'tts', this.data.synthesizer ?
|
||||
this.data.synthesizer?.label : cs.speechSynthesisLabel);
|
||||
|
||||
/* parse Nuance voices into name and model */
|
||||
let model;
|
||||
@@ -118,6 +131,8 @@ class TaskSay extends Task {
|
||||
'tts.language': language,
|
||||
'tts.voice': voice
|
||||
});
|
||||
let filePathUrl, isFromCache, roundTripTime;
|
||||
let executedVendor, executedLanguage;
|
||||
try {
|
||||
const {filePath, servedFromCache, rtt} = await synthAudio(stats, {
|
||||
account_sid: cs.accountSid,
|
||||
@@ -131,37 +146,98 @@ class TaskSay extends Task {
|
||||
credentials,
|
||||
disableTtsCache : this.disableTtsCache
|
||||
});
|
||||
this.logger.debug(`file ${filePath}, served from cache ${servedFromCache}`);
|
||||
if (filePath) cs.trackTmpFile(filePath);
|
||||
|
||||
span.setAttributes({'tts.cached': servedFromCache});
|
||||
span.end();
|
||||
|
||||
if (!servedFromCache && !lastUpdated) {
|
||||
lastUpdated = true;
|
||||
updateSpeechCredentialLastUsed(credentials.speech_credential_sid)
|
||||
.catch(() => {/*already logged error */});
|
||||
}
|
||||
span.setAttributes({'tts.cached': servedFromCache});
|
||||
span.end();
|
||||
if (!servedFromCache && rtt) {
|
||||
this.notifyStatus({
|
||||
event: 'synthesized-audio',
|
||||
vendor,
|
||||
language,
|
||||
characters: text.length,
|
||||
elapsedTime: rtt
|
||||
|
||||
filePathUrl = filePath;
|
||||
isFromCache = servedFromCache;
|
||||
roundTripTime = rtt;
|
||||
executedVendor = vendor;
|
||||
executedLanguage = language;
|
||||
|
||||
} catch (error) {
|
||||
if (fallbackVendor) {
|
||||
const fallbackcredentials = cs.getSpeechCredentials(fallbackVendor, 'tts', fallbackLabel);
|
||||
const {span: fallbackSpan} = this.startChildSpan('fallback-tts-generation', {
|
||||
'tts.vendor': fallbackVendor,
|
||||
'tts.language': fallbackLanguage,
|
||||
'tts.voice': fallbackVoice
|
||||
});
|
||||
|
||||
try {
|
||||
const {filePath, servedFromCache, rtt} = await synthAudio(stats, {
|
||||
account_sid: cs.accountSid,
|
||||
text,
|
||||
fallbackVendor,
|
||||
fallbackLanguage,
|
||||
fallbackVoice,
|
||||
engine,
|
||||
model,
|
||||
salt,
|
||||
credentials: fallbackcredentials,
|
||||
disableTtsCache : this.disableTtsCache
|
||||
});
|
||||
|
||||
fallbackSpan.setAttributes({'tts.cached': servedFromCache});
|
||||
fallbackSpan.end();
|
||||
|
||||
if (!servedFromCache && !lastUpdated) {
|
||||
lastUpdated = true;
|
||||
updateSpeechCredentialLastUsed(credentials.speech_credential_sid)
|
||||
.catch(() => {/*already logged error */});
|
||||
}
|
||||
|
||||
filePathUrl = filePath;
|
||||
isFromCache = servedFromCache;
|
||||
roundTripTime = rtt;
|
||||
executedVendor = fallbackVendor;
|
||||
executedLanguage = fallbackLanguage;
|
||||
|
||||
} catch (err){
|
||||
this.logger.info({err}, 'fallback Speech failed to synthesize audio');
|
||||
fallbackSpan.end();
|
||||
writeAlerts({
|
||||
account_sid: cs.accountSid,
|
||||
alert_type: AlertType.TTS_FAILURE,
|
||||
vendor: fallbackVendor,
|
||||
detail: err.message
|
||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for fallback tts failure'));
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
} catch (err) {
|
||||
this.logger.info({err}, 'Error synthesizing tts');
|
||||
|
||||
this.logger.info({error}, 'Error synthesizing tts');
|
||||
span.end();
|
||||
writeAlerts({
|
||||
account_sid: cs.accountSid,
|
||||
alert_type: AlertType.TTS_FAILURE,
|
||||
vendor,
|
||||
detail: err.message
|
||||
detail: error.message
|
||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for tts failure'));
|
||||
this.notifyError({msg: 'TTS error', details: err.message || err});
|
||||
this.notifyError({msg: 'TTS error', details: error.message || error});
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug(`file ${filePathUrl}, served from cache ${isFromCache}`);
|
||||
if (filePathUrl) cs.trackTmpFile(filePathUrl);
|
||||
|
||||
if (!isFromCache && roundTripTime) {
|
||||
this.notifyStatus({
|
||||
event: 'synthesized-audio',
|
||||
vendor: executedVendor,
|
||||
language: executedLanguage,
|
||||
characters: text.length,
|
||||
elapsedTime: roundTripTime
|
||||
});
|
||||
}
|
||||
|
||||
return filePathUrl;
|
||||
};
|
||||
|
||||
const arr = this.text.map((t) => generateAudio(t));
|
||||
|
||||
Reference in New Issue
Block a user