speech-to-element
Version:
Add real-time speech to text functionality into your website with no effort
95 lines (94 loc) • 3.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSpeech = void 0;
const webSpeechTranscript_1 = require("./webSpeechTranscript");
const browser_1 = require("../../utils/browser");
const speech_1 = require("../../speech");
// TO-DO - increase the silence timeout:
// https://stackoverflow.com/questions/70653818/web-speech-api-closes-after-some-seconds
class WebSpeech extends speech_1.Speech {
constructor() {
super();
}
start(options) {
var _a;
if (this._extractText === undefined) {
this._extractText = browser_1.Browser.IS_SAFARI() ? webSpeechTranscript_1.WebSpeechTranscript.extractSafari : webSpeechTranscript_1.WebSpeechTranscript.extract;
}
if (this.validate()) {
this.prepareBeforeStart(options);
this.instantiateService(options);
(_a = this._service) === null || _a === void 0 ? void 0 : _a.start();
this._translations = options === null || options === void 0 ? void 0 : options.translations;
}
}
validate() {
if (!WebSpeech.getAPI()) {
this.error('Speech Recognition is unsupported');
return false;
}
return true;
}
instantiateService(options) {
var _a, _b;
const speechRecognition = WebSpeech.getAPI();
this._service = new speechRecognition();
this._service.continuous = true;
this._service.interimResults = (_a = options === null || options === void 0 ? void 0 : options.displayInterimResults) !== null && _a !== void 0 ? _a : true;
this._service.lang = ((_b = options === null || options === void 0 ? void 0 : options.language) === null || _b === void 0 ? void 0 : _b.trim()) || 'en-US';
this.setEvents();
}
setEvents() {
if (!this._service)
return;
this._service.onstart = () => {
this.setStateOnStart();
};
this._service.onerror = (event) => {
// this error is thrown in Safari when the service is restarted
if (browser_1.Browser.IS_SAFARI() && event.message === 'Another request is started')
return;
if (event.error === 'aborted' && this.isRestarting)
return;
// TO-DO - could potentially use this to extend
if (event.error === 'no-speech')
return;
this.error(event.message || event.error);
};
// stop is here because onEnd is fired too late
this._service.onaudioend = () => {
this.setStateOnStop();
};
// setting _stopping here because onend is triggered after extra recognition is fired after sevice has stopped
this._service.onend = () => {
this._stopping = false;
};
// prettier-ignore
this._service.onresult = (event) => {
if (typeof event.results === 'undefined' && this._service) {
this._service.onend = null;
this._service.stop();
// when service is manually stopped - events are still fired
}
else if (this._extractText && !this._stopping) {
const { interimTranscript, finalTranscript, newText } = this._extractText(event, this.finalTranscript, this._translations);
this.updateElements(interimTranscript, finalTranscript, newText);
}
};
}
stop(isDuringReset) {
var _a;
this._stopping = true;
(_a = this._service) === null || _a === void 0 ? void 0 : _a.stop();
this.finalise(isDuringReset);
}
static getAPI() {
return window.webkitSpeechRecognition || window.SpeechRecognition;
}
error(details) {
console.error(details);
this.setStateOnError(details);
this.stop();
}
}
exports.WebSpeech = WebSpeech;