189 lines
5.5 KiB
JavaScript
189 lines
5.5 KiB
JavaScript
/*!
|
|
* Jodit Editor (https://xdsoft.net/jodit/)
|
|
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
*/
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
else
|
|
for (var i = decorators.length - 1; i >= 0; i--)
|
|
if (d = decorators[i])
|
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
import { autobind } from "../../../core/decorators/index.js";
|
|
import { Eventify } from "../../../core/event-emitter/eventify.js";
|
|
import { sound } from "./sound.js";
|
|
import { PII, WARN } from "../constants.js";
|
|
export class RecognizeManager extends Eventify {
|
|
set lang(v) {
|
|
this._lang = v;
|
|
this._api.lang = v;
|
|
}
|
|
get lang() {
|
|
return this._lang;
|
|
}
|
|
set continuous(v) {
|
|
this._continuous = v;
|
|
this._api.continuous = v;
|
|
}
|
|
get continuous() {
|
|
return this._continuous;
|
|
}
|
|
set interimResults(v) {
|
|
this._interimResults = v;
|
|
this._api.interimResults = v;
|
|
}
|
|
get interimResults() {
|
|
return this._interimResults;
|
|
}
|
|
constructor(async, api) {
|
|
super();
|
|
this.async = async;
|
|
this._continuous = false;
|
|
this._interimResults = false;
|
|
this.sound = true;
|
|
this._isEnabled = false;
|
|
this._restartTimeout = 0;
|
|
this._onSpeechStart = (e) => {
|
|
if (!this._isEnabled) {
|
|
return;
|
|
}
|
|
this.async.clearTimeout(this._restartTimeout);
|
|
this._restartTimeout = this.async.setTimeout(() => {
|
|
this.restart();
|
|
this.emit('pulse', false);
|
|
this._makeSound(WARN);
|
|
}, 5000);
|
|
this.emit('pulse', true);
|
|
};
|
|
this.__interimResults = '';
|
|
this._api = api;
|
|
RecognizeManager._instances.add(this);
|
|
}
|
|
destruct() {
|
|
this.stop();
|
|
RecognizeManager._instances.delete(this);
|
|
super.destruct();
|
|
}
|
|
get isEnabled() {
|
|
return this._isEnabled;
|
|
}
|
|
start() {
|
|
if (this._isEnabled) {
|
|
return;
|
|
}
|
|
this._isEnabled = true;
|
|
RecognizeManager._instances.forEach(instance => {
|
|
if (instance !== this) {
|
|
instance.stop();
|
|
}
|
|
});
|
|
try {
|
|
this._api.start();
|
|
}
|
|
catch (e) {
|
|
this._onError(e);
|
|
this.stop();
|
|
return;
|
|
}
|
|
this.__on('speechstart', this._onSpeechStart)
|
|
.__on('error', this._onError)
|
|
.__on('result', this._onProgress)
|
|
.__on('end', this._onResults);
|
|
}
|
|
stop() {
|
|
if (!this._isEnabled) {
|
|
return;
|
|
}
|
|
this._api.abort();
|
|
this._api.stop();
|
|
this.__off('speechstart', this._onSpeechStart)
|
|
.__off('error', this._onError)
|
|
.__off('result', this._onProgress)
|
|
.__off('end', this._onResults);
|
|
this.async.clearTimeout(this._restartTimeout);
|
|
this._isEnabled = false;
|
|
this.emit('pulse', false);
|
|
}
|
|
toggle() {
|
|
if (!this._isEnabled) {
|
|
this.start();
|
|
}
|
|
else {
|
|
this.stop();
|
|
}
|
|
}
|
|
restart() {
|
|
this.stop();
|
|
this.start();
|
|
}
|
|
__on(event, callback) {
|
|
this._api.addEventListener(event, callback);
|
|
return this;
|
|
}
|
|
__off(event, callback) {
|
|
this._api.removeEventListener(event, callback);
|
|
return this;
|
|
}
|
|
_onResults(e) {
|
|
this.emit('pulse', false);
|
|
this.emit('result', this.__interimResults);
|
|
this.__interimResults = '';
|
|
this._makeSound(PII);
|
|
this.restart();
|
|
}
|
|
_onProgress(e) {
|
|
if (!this._isEnabled) {
|
|
return;
|
|
}
|
|
this.__interimResults = '';
|
|
if (!e.results) {
|
|
return;
|
|
}
|
|
for (let i = 0; i < e.results.length; i++) {
|
|
const resultItem = e.results.item(i);
|
|
if (resultItem.length) {
|
|
const { transcript } = resultItem.item(0);
|
|
this.__interimResults += transcript;
|
|
}
|
|
}
|
|
if (this.__interimResults) {
|
|
this.emit('progress', this.__interimResults);
|
|
}
|
|
}
|
|
_onError(e) {
|
|
if (e.error === 'voice-unavailable') {
|
|
this.emit('error', 'Voice unavailable');
|
|
}
|
|
if (e.error === 'not-allowed') {
|
|
this.emit('error', 'Not allowed');
|
|
}
|
|
if (e.error === 'language-unavailable' ||
|
|
// @ts-ignore
|
|
e.error === 'language-not-supported') {
|
|
this.emit('error', 'Language unavailable');
|
|
}
|
|
this._makeSound(WARN);
|
|
this.emit('pulse', false);
|
|
this.stop();
|
|
}
|
|
_makeSound(frequency) {
|
|
if (this.sound) {
|
|
sound({ frequency });
|
|
}
|
|
}
|
|
}
|
|
RecognizeManager._instances = new Set();
|
|
__decorate([
|
|
autobind
|
|
], RecognizeManager.prototype, "_onResults", null);
|
|
__decorate([
|
|
autobind
|
|
], RecognizeManager.prototype, "_onProgress", null);
|
|
__decorate([
|
|
autobind
|
|
], RecognizeManager.prototype, "_onError", null);
|