From 7cdeeee48e6bd7b8cff2a710dcd712455a78a312 Mon Sep 17 00:00:00 2001 From: rerender2021 Date: Mon, 24 Apr 2023 22:02:15 +0800 Subject: [PATCH 1/5] impl custom port for asr --- src/app.tsx | 4 ++-- src/asr/asr.ts | 9 ++++++--- src/asr/base.ts | 1 + src/asr/postasr.ts | 4 +++- src/config/index.ts | 6 +++++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 6f1f078..8eea0ab 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -6,7 +6,7 @@ import { HelsinkiNlpEngine } from "./nlp"; import { containerLayout, controlLayout } from "./layout"; import { iconResource } from "./resource"; import { onMeasure, onTranslate, safe, shadowRelated } from "./shadow"; -import { getAsrConfig, getNlpConfig } from "./config"; +import { AsrConfig, getNlpConfig } from "./config"; import axios from "axios"; function onInit(app: App) { @@ -34,7 +34,7 @@ export function Echo() { const asrEngine = useMemo( () => new VoskAsrEngine({ - ...getAsrConfig(), + ...AsrConfig, }), [] ); diff --git a/src/asr/asr.ts b/src/asr/asr.ts index 2c40a09..34a032a 100644 --- a/src/asr/asr.ts +++ b/src/asr/asr.ts @@ -45,7 +45,8 @@ export class VoskAsrEngine implements IAsrEngine { return new Promise((resolve, reject) => { console.log("asrDir exists, start asr server", asrDir); - const asr = childProcess.spawn(exePath, [], { windowsHide: true, detached: false /** hide console */ }); + const port = this.options.asrPort; + const asr = childProcess.spawn(exePath, [`--port=${port}`], { windowsHide: true, detached: false /** hide console */ }); this.asr = asr; asr.stdout.on("data", (data) => { console.log(`stdout: ${data}`); @@ -78,14 +79,16 @@ export class VoskAsrEngine implements IAsrEngine { } private async asrApi(): Promise { + const port = this.options.asrPort; + if (this.version === AsrVersion.v100) { - const response = await axios.post("http://localhost:8200/asr", {}, { timeout: 2000 }); + const response = await axios.post(`http://localhost:${port}/asr`, {}, { timeout: 2000 }); const result = response?.data?.result; const data = JSON.parse(result || "{}"); const asrText = data.partial || ""; return asrText; } else { - const response = await axios.post("http://localhost:8200/asr_queue", {}, { timeout: 1000 }); + const response = await axios.post(`http://localhost:${port}/asr_queue`, {}, { timeout: 1000 }); const result = response?.data?.result; const data = JSON.parse(result[result.length - 1] || "{}"); const asrText = data.partial || ""; diff --git a/src/asr/base.ts b/src/asr/base.ts index 5602808..eba942e 100644 --- a/src/asr/base.ts +++ b/src/asr/base.ts @@ -5,6 +5,7 @@ export interface ISentence { export interface IAsrEngineOptions { timeout: number + asrPort: number onRecognize?: OnRecognize; onError?: OnError; } diff --git a/src/asr/postasr.ts b/src/asr/postasr.ts index 07d3fdd..af7ddb2 100644 --- a/src/asr/postasr.ts +++ b/src/asr/postasr.ts @@ -1,5 +1,6 @@ import axios from "axios"; import { split } from "sentence-splitter"; +import { AsrConfig } from "../config"; class SessionManager { private prevTextLength: number = Number.MAX_SAFE_INTEGER; @@ -20,7 +21,8 @@ let tokenIndex = 0; async function getTextToPunct(asrText: string) { if (asrText.length >= maxTextLength) { - const punctResponse = await axios.post("http://localhost:8200/punct", { text: asrText }, { timeout: 1000 }); + const port = AsrConfig.asrPort; + const punctResponse = await axios.post(`http://localhost:${port}/punct`, { text: asrText }, { timeout: 1000 }); const withPunct = punctResponse?.data?.text || ""; return withPunct; } else { diff --git a/src/config/index.ts b/src/config/index.ts index 9d7399d..a8e7932 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -6,6 +6,7 @@ import { INlpEngineOptions } from "../nlp/base"; const defaultConfig = { /** timeout for asr and translate api call*/ timeout: 3500, + asrPort: 8200 }; export function getConfig() { @@ -25,13 +26,16 @@ export function getConfig() { } } -export function getAsrConfig(): IAsrEngineOptions { +function getAsrConfig(): IAsrEngineOptions { const config = getConfig(); return { timeout: config?.timeout || defaultConfig.timeout, + asrPort: config?.asrPort || defaultConfig.asrPort }; } +export const AsrConfig: IAsrEngineOptions = getAsrConfig(); + export function getNlpConfig(): INlpEngineOptions { const config = getConfig(); return { From efd0df515c463255ae07e487162cf5e047c2965b Mon Sep 17 00:00:00 2001 From: rerender2021 Date: Mon, 24 Apr 2023 22:50:36 +0800 Subject: [PATCH 2/5] use asr server 1.2.0 --- src/asr/asr.ts | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/asr/asr.ts b/src/asr/asr.ts index 34a032a..ca10c01 100644 --- a/src/asr/asr.ts +++ b/src/asr/asr.ts @@ -7,8 +7,7 @@ import { emptySentence, shadowRelated } from "../shadow"; import { postasr } from "./postasr"; enum AsrVersion { - v100, - v110, + v120, } export class VoskAsrEngine implements IAsrEngine { @@ -18,21 +17,17 @@ export class VoskAsrEngine implements IAsrEngine { constructor(options: IAsrEngineOptions) { this.options = options; - this.version = AsrVersion.v100; + this.version = AsrVersion.v120; } getAsrPath() { - const v110 = path.resolve(process.cwd(), "asr-server-v1.1.0"); - if (fs.existsSync(v110)) { - this.version = AsrVersion.v110; - console.log("use asr-server-v1.1.0"); - return { asrDir: v110, exePath: path.resolve(v110, "./ASR-API.exe") }; - } - - const v100 = path.resolve(process.cwd(), "asr-server"); - if (fs.existsSync(v100)) { - console.log("use asr-server-v1.0.0"); - return { asrDir: v100, exePath: path.resolve(v100, "./ASR-API.exe") }; + const v120 = path.resolve(process.cwd(), "asr-server-v1.2.0"); + if (fs.existsSync(v120)) { + this.version = AsrVersion.v120; + console.log("use asr-server-v1.2.0"); + return { asrDir: v120, exePath: path.resolve(v120, "./ASR-API.exe") }; + } else { + console.error("this version of echo requires >= asr-server-v1.2.0!"); } return { asrDir: "", exePath: "" }; @@ -81,19 +76,15 @@ export class VoskAsrEngine implements IAsrEngine { private async asrApi(): Promise { const port = this.options.asrPort; - if (this.version === AsrVersion.v100) { - const response = await axios.post(`http://localhost:${port}/asr`, {}, { timeout: 2000 }); - const result = response?.data?.result; - const data = JSON.parse(result || "{}"); - const asrText = data.partial || ""; - return asrText; - } else { + if (this.version === AsrVersion.v120) { const response = await axios.post(`http://localhost:${port}/asr_queue`, {}, { timeout: 1000 }); const result = response?.data?.result; const data = JSON.parse(result[result.length - 1] || "{}"); const asrText = data.partial || ""; return asrText; } + + return ""; } async getAsrResult(): Promise { From b5618b730e9c168e97717976e019e59a58631be3 Mon Sep 17 00:00:00 2001 From: rerender2021 Date: Wed, 26 Apr 2023 08:15:54 +0800 Subject: [PATCH 3/5] impl custom port for nlp --- src/app.tsx | 7 ++++--- src/config/index.ts | 8 ++++++-- src/nlp/base.ts | 1 + src/nlp/helsinki-nlp.ts | 9 ++++++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 8eea0ab..24c4ac8 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -6,7 +6,7 @@ import { HelsinkiNlpEngine } from "./nlp"; import { containerLayout, controlLayout } from "./layout"; import { iconResource } from "./resource"; import { onMeasure, onTranslate, safe, shadowRelated } from "./shadow"; -import { AsrConfig, getNlpConfig } from "./config"; +import { AsrConfig, NlpConfig } from "./config"; import axios from "axios"; function onInit(app: App) { @@ -41,7 +41,7 @@ export function Echo() { const nlpEngine = useMemo( () => new HelsinkiNlpEngine({ - ...getNlpConfig(), + ...NlpConfig, }), [] ); @@ -126,7 +126,8 @@ export function Echo() { ); nlpEngine.init().then( safe(async () => { - const response = await axios.get("http://localhost:8100/gpu"); + const port = NlpConfig.nlpPort; + const response = await axios.get(`http://localhost:${port}/gpu`); if (response.data.gpu === "True") { console.log("great! use gpu"); setTitle("Echo (GPU)"); diff --git a/src/config/index.ts b/src/config/index.ts index a8e7932..b278041 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -6,7 +6,8 @@ import { INlpEngineOptions } from "../nlp/base"; const defaultConfig = { /** timeout for asr and translate api call*/ timeout: 3500, - asrPort: 8200 + asrPort: 8200, + nlpPort: 8100 }; export function getConfig() { @@ -36,9 +37,12 @@ function getAsrConfig(): IAsrEngineOptions { export const AsrConfig: IAsrEngineOptions = getAsrConfig(); -export function getNlpConfig(): INlpEngineOptions { +function getNlpConfig(): INlpEngineOptions { const config = getConfig(); return { timeout: config?.timeout || defaultConfig.timeout, + nlpPort: config?.nlpPort || defaultConfig.nlpPort }; } + +export const NlpConfig: INlpEngineOptions = getNlpConfig(); \ No newline at end of file diff --git a/src/nlp/base.ts b/src/nlp/base.ts index cfd896d..47edb9a 100644 --- a/src/nlp/base.ts +++ b/src/nlp/base.ts @@ -4,6 +4,7 @@ export interface ITranslateResult { export interface INlpEngineOptions { timeout: number + nlpPort: number onTranslate?: OnTranslate; onError?: OnError; } diff --git a/src/nlp/helsinki-nlp.ts b/src/nlp/helsinki-nlp.ts index f7e3143..3093818 100644 --- a/src/nlp/helsinki-nlp.ts +++ b/src/nlp/helsinki-nlp.ts @@ -35,7 +35,9 @@ export class HelsinkiNlpEngine implements INlpEngine { if (nlpDir && exePath) { return new Promise((resolve, reject) => { console.log("nlpDir exists, start nlp server", nlpDir); - const nlp = childProcess.spawn(exePath, [`--lang-from=en`, `--lang-to=zh`, `--model-dir=.\\model`], { windowsHide: true, detached: false /** hide console */ }); + + const port = this.options.nlpPort; + const nlp = childProcess.spawn(exePath, [`--lang-from=en`, `--lang-to=zh`, `--model-dir=.\\model`, `--port=${port}`], { windowsHide: true, detached: false /** hide console */ }); this.nlp = nlp; nlp.stdout.on("data", (data) => { console.log(`stdout: ${data}`); @@ -72,9 +74,10 @@ export class HelsinkiNlpEngine implements INlpEngine { if (this.cache[text]) { return { text: this.cache[text] }; } - const timeout = this.options?.timeout || 1000; + const timeout = this.options.timeout; + const port = this.options.nlpPort; const translated = await axios.post( - "http://localhost:8100/translate", + `http://localhost:${port}/translate`, { text, }, From a28c5d964c95a73b9de80b9e998d36a6001b24e7 Mon Sep 17 00:00:00 2001 From: rerender2021 Date: Fri, 5 May 2023 07:43:44 +0800 Subject: [PATCH 4/5] impl custom vosk port --- src/asr/asr.ts | 4 +++- src/asr/base.ts | 1 + src/config/index.ts | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/asr/asr.ts b/src/asr/asr.ts index ca10c01..e6dbec2 100644 --- a/src/asr/asr.ts +++ b/src/asr/asr.ts @@ -41,7 +41,9 @@ export class VoskAsrEngine implements IAsrEngine { console.log("asrDir exists, start asr server", asrDir); const port = this.options.asrPort; - const asr = childProcess.spawn(exePath, [`--port=${port}`], { windowsHide: true, detached: false /** hide console */ }); + const voskPort = this.options.asrSocketPort; + + const asr = childProcess.spawn(exePath, [`--port=${port}`, `--vosk-port=${voskPort}`], { windowsHide: true, detached: false /** hide console */ }); this.asr = asr; asr.stdout.on("data", (data) => { console.log(`stdout: ${data}`); diff --git a/src/asr/base.ts b/src/asr/base.ts index eba942e..a5e3354 100644 --- a/src/asr/base.ts +++ b/src/asr/base.ts @@ -6,6 +6,7 @@ export interface ISentence { export interface IAsrEngineOptions { timeout: number asrPort: number + asrSocketPort: number onRecognize?: OnRecognize; onError?: OnError; } diff --git a/src/config/index.ts b/src/config/index.ts index b278041..2bdcf9c 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -7,6 +7,7 @@ const defaultConfig = { /** timeout for asr and translate api call*/ timeout: 3500, asrPort: 8200, + asrSocketPort: 8210, nlpPort: 8100 }; @@ -31,7 +32,8 @@ function getAsrConfig(): IAsrEngineOptions { const config = getConfig(); return { timeout: config?.timeout || defaultConfig.timeout, - asrPort: config?.asrPort || defaultConfig.asrPort + asrPort: config?.asrPort || defaultConfig.asrPort, + asrSocketPort: config?.asrSocketPort || defaultConfig.asrSocketPort }; } From 05f33e07866e66f37a3ace2a7a90b9de0caa9102 Mon Sep 17 00:00:00 2001 From: rerender2021 Date: Sun, 7 May 2023 07:37:21 +0800 Subject: [PATCH 5/5] to be compatible with prev versions --- src/asr/asr.ts | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/asr/asr.ts b/src/asr/asr.ts index e6dbec2..4b284e2 100644 --- a/src/asr/asr.ts +++ b/src/asr/asr.ts @@ -7,6 +7,8 @@ import { emptySentence, shadowRelated } from "../shadow"; import { postasr } from "./postasr"; enum AsrVersion { + v100, + v110, v120, } @@ -17,17 +19,31 @@ export class VoskAsrEngine implements IAsrEngine { constructor(options: IAsrEngineOptions) { this.options = options; - this.version = AsrVersion.v120; + this.version = AsrVersion.v100; } getAsrPath() { + const port = this.options.asrPort; + const voskPort = this.options.asrSocketPort; + const v120 = path.resolve(process.cwd(), "asr-server-v1.2.0"); if (fs.existsSync(v120)) { this.version = AsrVersion.v120; console.log("use asr-server-v1.2.0"); - return { asrDir: v120, exePath: path.resolve(v120, "./ASR-API.exe") }; - } else { - console.error("this version of echo requires >= asr-server-v1.2.0!"); + return { asrDir: v120, exePath: path.resolve(v120, "./ASR-API.exe"), args: [`--port=${port}`, `--vosk-port=${voskPort}`] }; + } + + const v110 = path.resolve(process.cwd(), "asr-server-v1.1.0"); + if (fs.existsSync(v110)) { + this.version = AsrVersion.v110; + console.log("use asr-server-v1.1.0"); + return { asrDir: v110, exePath: path.resolve(v110, "./ASR-API.exe") }; + } + + const v100 = path.resolve(process.cwd(), "asr-server"); + if (fs.existsSync(v100)) { + console.log("use asr-server-v1.0.0"); + return { asrDir: v100, exePath: path.resolve(v100, "./ASR-API.exe") }; } return { asrDir: "", exePath: "" }; @@ -35,15 +51,12 @@ export class VoskAsrEngine implements IAsrEngine { async init() { console.log("try to init vosk asr engine"); - const { asrDir, exePath } = this.getAsrPath(); + const { asrDir, exePath, args = [] } = this.getAsrPath(); if (asrDir && exePath) { return new Promise((resolve, reject) => { console.log("asrDir exists, start asr server", asrDir); - const port = this.options.asrPort; - const voskPort = this.options.asrSocketPort; - - const asr = childProcess.spawn(exePath, [`--port=${port}`, `--vosk-port=${voskPort}`], { windowsHide: true, detached: false /** hide console */ }); + const asr = childProcess.spawn(exePath, args, { windowsHide: true, detached: false /** hide console */ }); this.asr = asr; asr.stdout.on("data", (data) => { console.log(`stdout: ${data}`); @@ -78,15 +91,19 @@ export class VoskAsrEngine implements IAsrEngine { private async asrApi(): Promise { const port = this.options.asrPort; - if (this.version === AsrVersion.v120) { + if (this.version === AsrVersion.v100) { + const response = await axios.post(`http://localhost:${port}/asr`, {}, { timeout: 2000 }); + const result = response?.data?.result; + const data = JSON.parse(result || "{}"); + const asrText = data.partial || ""; + return asrText; + } else { const response = await axios.post(`http://localhost:${port}/asr_queue`, {}, { timeout: 1000 }); const result = response?.data?.result; const data = JSON.parse(result[result.length - 1] || "{}"); const asrText = data.partial || ""; return asrText; } - - return ""; } async getAsrResult(): Promise {