mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-20 08:40:38 +00:00
108 lines
3.5 KiB
JavaScript
108 lines
3.5 KiB
JavaScript
const Task = require('./task');
|
|
const {TaskName, TaskPreconditions, TranscriptionEvents} = require('../utils/constants');
|
|
|
|
class TaskTranscribe extends Task {
|
|
constructor(logger, opts, parentTask) {
|
|
super(logger, opts);
|
|
this.preconditions = TaskPreconditions.Endpoint;
|
|
|
|
this.transcriptionCallback = this.data.transcriptionCallback;
|
|
this.earlyMedia = this.data.earlyMedia === true || (parentTask && parentTask.earlyMedia);
|
|
if (this.data.recognizer) {
|
|
this.language = this.data.recognizer.language || 'en-US';
|
|
this.vendor = this.data.recognizer.vendor;
|
|
this.interim = this.data.recognizer.interim === true;
|
|
this.dualChannel = this.data.recognizer.dualChannel === true;
|
|
}
|
|
}
|
|
|
|
get name() { return TaskName.Transcribe; }
|
|
|
|
async exec(cs, ep, parentTask) {
|
|
super.exec(cs);
|
|
this.ep = ep;
|
|
try {
|
|
await this._startTranscribing(ep);
|
|
await this.awaitTaskDone();
|
|
} catch (err) {
|
|
this.logger.info(err, 'TaskTranscribe:exec - error');
|
|
}
|
|
ep.removeCustomEventListener(TranscriptionEvents.Transcription);
|
|
ep.removeCustomEventListener(TranscriptionEvents.NoAudioDetected);
|
|
ep.removeCustomEventListener(TranscriptionEvents.MaxDurationExceeded);
|
|
}
|
|
|
|
async kill() {
|
|
super.kill();
|
|
if (this.ep.connected) {
|
|
this.ep.stopTranscription().catch((err) => this.logger.info(err, 'Error TaskTranscribe:kill'));
|
|
|
|
// hangup after 1 sec if we don't get a final transcription
|
|
this._timer = setTimeout(() => this.notifyTaskDone(), 1000);
|
|
}
|
|
else this.notifyTaskDone();
|
|
await this.awaitTaskDone();
|
|
}
|
|
|
|
async _startTranscribing(ep) {
|
|
const opts = {
|
|
GOOGLE_SPEECH_USE_ENHANCED: true,
|
|
GOOGLE_SPEECH_MODEL: 'phone_call'
|
|
};
|
|
if (this.hints) {
|
|
Object.assign(opts, {'GOOGLE_SPEECH_HINTS': this.hints.join(',')});
|
|
}
|
|
if (this.profanityFilter) {
|
|
Object.assign(opts, {'GOOGLE_SPEECH_PROFANITY_FILTER': true});
|
|
}
|
|
if (this.dualChannel) {
|
|
Object.assign(opts, {'GOOGLE_SPEECH_SEPARATE_RECOGNITION_PER_CHANNEL': true});
|
|
}
|
|
await ep.set(opts)
|
|
.catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing'));
|
|
|
|
ep.addCustomEventListener(TranscriptionEvents.Transcription, this._onTranscription.bind(this, ep));
|
|
ep.addCustomEventListener(TranscriptionEvents.NoAudioDetected, this._onNoAudio.bind(this, ep));
|
|
ep.addCustomEventListener(TranscriptionEvents.MaxDurationExceeded, this._onMaxDurationExceeded.bind(this, ep));
|
|
|
|
await this._transcribe(ep);
|
|
}
|
|
|
|
async _transcribe(ep) {
|
|
await this.ep.startTranscription({
|
|
interim: this.interim ? true : false,
|
|
language: this.language || this.callSession.speechRecognizerLanguage,
|
|
channels: this.dualChannel ? 2 : 1
|
|
});
|
|
}
|
|
|
|
_onTranscription(ep, evt) {
|
|
this.logger.debug(evt, 'TaskTranscribe:_onTranscription');
|
|
this.notifyHook(this.transcriptionCallback, 'POST', null, {speech: evt});
|
|
if (this.killed) {
|
|
this.logger.debug('TaskTranscribe:_onTranscription exiting after receiving final transcription');
|
|
this._clearTimer();
|
|
this.notifyTaskDone();
|
|
}
|
|
}
|
|
|
|
_onNoAudio(ep) {
|
|
this.logger.debug('TaskTranscribe:_onNoAudio restarting transcription');
|
|
this._transcribe(ep);
|
|
}
|
|
|
|
_onMaxDurationExceeded(ep) {
|
|
this.logger.debug('TaskTranscribe:_onMaxDurationExceeded restarting transcription');
|
|
this._transcribe(ep);
|
|
}
|
|
|
|
_clearTimer() {
|
|
if (this._timer) {
|
|
clearTimeout(this._timer);
|
|
this._timer = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = TaskTranscribe;
|