From 6eb0dfced4ab87b3fd831affd806aad84d37dc1f Mon Sep 17 00:00:00 2001
From: Yabin Li <wucong.lyb@alibaba-inc.com>
Date: 星期一, 23 十月 2023 10:48:54 +0800
Subject: [PATCH] Dev server hotwords (#1033)

---
 funasr/runtime/websocket/bin/funasr-wss-server-2pass.cpp                                                |   32 +++++++++-
 funasr/runtime/docs/SDK_advanced_guide_offline_en_zh.md                                                 |    4 +
 funasr/runtime/docs/SDK_advanced_guide_offline.md                                                       |    4 +
 funasr/runtime/docs/SDK_advanced_guide_offline_en.md                                                    |    4 +
 funasr/runtime/docs/SDK_advanced_guide_offline_zh.md                                                    |    4 +
 funasr/runtime/android/AndroidClient/app/src/main/java/com/yeyupiaoling/androidclient/MainActivity.java |   31 ++++++---
 funasr/runtime/docs/SDK_advanced_guide_online_zh.md                                                     |    7 +
 funasr/runtime/docs/SDK_advanced_guide_online.md                                                        |    4 +
 funasr/runtime/websocket/bin/websocket-server.cpp                                                       |   17 ++++-
 funasr/runtime/websocket/hotwords.txt                                                                   |    2 
 funasr/runtime/run_server.sh                                                                            |    7 +
 funasr/runtime/run_server_2pass.sh                                                                      |    7 +
 funasr/runtime/websocket/bin/funasr-wss-server.cpp                                                      |   32 +++++++++-
 funasr/runtime/websocket/bin/websocket-server-2pass.cpp                                                 |   19 +++++-
 14 files changed, 139 insertions(+), 35 deletions(-)

diff --git a/funasr/runtime/android/AndroidClient/app/src/main/java/com/yeyupiaoling/androidclient/MainActivity.java b/funasr/runtime/android/AndroidClient/app/src/main/java/com/yeyupiaoling/androidclient/MainActivity.java
index be14bd3..f45877c 100644
--- a/funasr/runtime/android/AndroidClient/app/src/main/java/com/yeyupiaoling/androidclient/MainActivity.java
+++ b/funasr/runtime/android/AndroidClient/app/src/main/java/com/yeyupiaoling/androidclient/MainActivity.java
@@ -39,6 +39,8 @@
     public static final String TAG = MainActivity.class.getSimpleName();
     // WebSocket鍦板潃
     public String ASR_HOST = "";
+    // 瀹樻柟WebSocket鍦板潃
+    public static final String DEFAULT_HOST = "wss://101.37.77.25:10088";
     // 鍙戦�佺殑JSON鏁版嵁
     public static final String MODE = "2pass";
     public static final String CHUNK_SIZE = "5, 10, 5";
@@ -61,7 +63,6 @@
     // 鎺т欢
     private Button recordBtn;
     private TextView resultText;
-    private WebSocket webSocket;
 
     @SuppressLint("ClickableViewAccessibility")
     @Override
@@ -106,8 +107,8 @@
             ASR_HOST = uri;
         }
         // 璇诲彇鐑瘝
-        String hotWords = sharedPreferences.getString("hotwords", "");
-        if (!hotWords.equals("")) {
+        String hotWords = sharedPreferences.getString("hotwords", null);
+        if (hotWords != null) {
             this.hotWords = hotWords;
         }
     }
@@ -150,6 +151,14 @@
                 editor.apply();
             }
         });
+        builder.setNeutralButton("浣跨敤瀹樻柟鏈嶅姟", (dialog, id) -> {
+            ASR_HOST = DEFAULT_HOST;
+            input.setText(DEFAULT_HOST);
+            Toast.makeText(MainActivity.this, "WebSocket鍦板潃锛�" + ASR_HOST, Toast.LENGTH_SHORT).show();
+            SharedPreferences.Editor editor = sharedPreferences.edit();
+            editor.putString("uri", ASR_HOST);
+            editor.apply();
+        });
         AlertDialog dialog = builder.create();
         dialog.show();
     }
@@ -166,12 +175,10 @@
         builder.setView(view);
         builder.setPositiveButton("纭畾", (dialog, id) -> {
             String hotwords = input.getText().toString();
-            if (!hotwords.equals("")) {
-                this.hotWords = hotwords;
-                SharedPreferences.Editor editor = sharedPreferences.edit();
-                editor.putString("hotwords", hotwords);
-                editor.apply();
-            }
+            this.hotWords = hotwords;
+            SharedPreferences.Editor editor = sharedPreferences.edit();
+            editor.putString("hotwords", hotwords);
+            editor.apply();
         });
         AlertDialog dialog = builder.create();
         dialog.show();
@@ -225,7 +232,7 @@
         Request request = new Request.Builder()
                 .url(ASR_HOST)
                 .build();
-        webSocket = client.newWebSocket(request, new WebSocketListener() {
+        WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {
 
             @Override
             public void onOpen(@NonNull WebSocket webSocket, @NonNull Response response) {
@@ -311,7 +318,9 @@
             obj.put("chunk_size", array);
             obj.put("chunk_interval", CHUNK_INTERVAL);
             obj.put("wav_name", "default");
-            obj.put("hotwords", hotWords);
+            if (!hotWords.equals("")) {
+                obj.put("hotwords", hotWords);
+            }
             obj.put("wav_format", "pcm");
             obj.put("is_speaking", isSpeaking);
             return obj.toString();
diff --git a/funasr/runtime/docs/SDK_advanced_guide_offline.md b/funasr/runtime/docs/SDK_advanced_guide_offline.md
index 0348308..ac87653 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_offline.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_offline.md
@@ -83,7 +83,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key > log.out 2>&1 &
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
  ```
 
 Introduction to run_server.sh parameters: 
@@ -102,6 +103,7 @@
 --io-thread-num: Number of IO threads that the server starts. Default is 1.
 --certfile <string>: SSL certificate file. Default is ../../../ssl_key/server.crt. If you want to close ssl锛宻et 0
 --keyfile <string>: SSL key file. Default is ../../../ssl_key/server.key. 
+--hotwordsfile   Hotword file path, one line for each hot word, if the client provides hot words, then combined with the hot words provided by the client. Default is ../../hotwords.txt
 ```
 
 ### Shutting Down the FunASR Service
diff --git a/funasr/runtime/docs/SDK_advanced_guide_offline_en.md b/funasr/runtime/docs/SDK_advanced_guide_offline_en.md
index c2599ec..e409376 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_offline_en.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_offline_en.md
@@ -79,7 +79,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt
  ```
 
 Introduction to run_server.sh parameters: 
@@ -98,6 +99,7 @@
 --io-thread-num: Number of IO threads that the server starts. Default is 1.
 --certfile <string>: SSL certificate file. Default is ../../../ssl_key/server.crt. If you want to close ssl锛宻et 0
 --keyfile <string>: SSL key file. Default is ../../../ssl_key/server.key. 
+--hotwordsfile   Hotword file path, one line for each hot word, if the client provides hot words, then combined with the hot words provided by the client. Default is ../../hotwords.txt
 ```
 
 ### Shutting Down the FunASR Service
diff --git a/funasr/runtime/docs/SDK_advanced_guide_offline_en_zh.md b/funasr/runtime/docs/SDK_advanced_guide_offline_en_zh.md
index 48c67c9..90b0963 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_offline_en_zh.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_offline_en_zh.md
@@ -162,7 +162,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key > log.out 2>&1 &
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
  ```
 **run_server.sh鍛戒护鍙傛暟浠嬬粛**
 ```text
@@ -179,6 +180,7 @@
 --io-thread-num  鏈嶅姟绔惎鍔ㄧ殑IO绾跨▼鏁帮紝榛樿涓� 1
 --certfile  ssl鐨勮瘉涔︽枃浠讹紝榛樿涓猴細../../../ssl_key/server.crt锛屽鏋滈渶瑕佸叧闂璼sl锛屽弬鏁拌缃负0
 --keyfile   ssl鐨勫瘑閽ユ枃浠讹紝榛樿涓猴細../../../ssl_key/server.key
+--hotwordsfile   鐑瘝鏂囦欢璺緞锛屾瘡涓�涓儹璇嶄竴琛岋紝濡傛灉瀹㈡埛绔彁渚涚儹璇嶏紝鍒欎笌瀹㈡埛绔彁渚涚殑鐑瘝鍚堝苟涓�璧蜂娇鐢ㄣ�傞粯璁や负锛�../../hotwords.txt
 ```
 
 ### 鍏抽棴FunASR鏈嶅姟
diff --git a/funasr/runtime/docs/SDK_advanced_guide_offline_zh.md b/funasr/runtime/docs/SDK_advanced_guide_offline_zh.md
index c631097..c1b33b6 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_offline_zh.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_offline_zh.md
@@ -165,7 +165,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key > log.out 2>&1 &
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
  ```
 **run_server.sh鍛戒护鍙傛暟浠嬬粛**
 ```text
@@ -182,6 +183,7 @@
 --io-thread-num  鏈嶅姟绔惎鍔ㄧ殑IO绾跨▼鏁帮紝榛樿涓� 1
 --certfile  ssl鐨勮瘉涔︽枃浠讹紝榛樿涓猴細../../../ssl_key/server.crt锛屽鏋滈渶瑕佸叧闂璼sl锛屽弬鏁拌缃负0
 --keyfile   ssl鐨勫瘑閽ユ枃浠讹紝榛樿涓猴細../../../ssl_key/server.key
+--hotwordsfile   鐑瘝鏂囦欢璺緞锛屾瘡涓�涓儹璇嶄竴琛岋紝濡傛灉瀹㈡埛绔彁渚涚儹璇嶏紝鍒欎笌瀹㈡埛绔彁渚涚殑鐑瘝鍚堝苟涓�璧蜂娇鐢ㄣ�傞粯璁や负锛�../../hotwords.txt
 ```
 
 ### 鍏抽棴FunASR鏈嶅姟
diff --git a/funasr/runtime/docs/SDK_advanced_guide_online.md b/funasr/runtime/docs/SDK_advanced_guide_online.md
index 17fb891..c4fac4a 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_online.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_online.md
@@ -72,7 +72,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key > log.out 2>&1 &
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
 
 # If you want to close ssl锛宲lease add锛�--certfile 0
 # If you want to deploy the timestamp or hotword model, please set --model-dir to the corresponding model:
@@ -97,6 +98,7 @@
 --io-thread-num: Number of IO threads that the server starts. Default is 1.
 --certfile <string>: SSL certificate file. Default is ../../../ssl_key/server.crt. If you want to close ssl锛宻et 0
 --keyfile <string>: SSL key file. Default is ../../../ssl_key/server.key. 
+--hotwordsfile   Hotword file path, one line for each hot word, if the client provides hot words, then combined with the hot words provided by the client. Default is ../../hotwords.txt
 ```
 
 ### Shutting Down the FunASR Service
diff --git a/funasr/runtime/docs/SDK_advanced_guide_online_zh.md b/funasr/runtime/docs/SDK_advanced_guide_online_zh.md
index 232701e..a8e7933 100644
--- a/funasr/runtime/docs/SDK_advanced_guide_online_zh.md
+++ b/funasr/runtime/docs/SDK_advanced_guide_online_zh.md
@@ -31,7 +31,8 @@
   --model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx  \
   --online-model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online-onnx  \
   --punc-dir damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx \
-  --itn-dir thuduj12/fst_itn_zh > log.out 2>&1 &
+  --itn-dir thuduj12/fst_itn_zh \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
 
 # 濡傛灉鎮ㄦ兂鍏抽棴ssl锛屽鍔犲弬鏁帮細--certfile 0
 # 濡傛灉鎮ㄦ兂浣跨敤鏃堕棿鎴虫垨鑰呯儹璇嶆ā鍨嬭繘琛岄儴缃诧紝璇疯缃�--model-dir涓哄搴旀ā鍨嬶細
@@ -80,7 +81,8 @@
   --io-thread-num  8 \
   --port 10095 \
   --certfile  ../../../ssl_key/server.crt \
-  --keyfile ../../../ssl_key/server.key > log.out 2>&1 &
+  --keyfile ../../../ssl_key/server.key \
+  --hotwordsfile ../../hotwords.txt > log.out 2>&1 &
  ```
 **run_server_2pass.sh鍛戒护鍙傛暟浠嬬粛**
 ```text
@@ -98,6 +100,7 @@
 --io-thread-num  鏈嶅姟绔惎鍔ㄧ殑IO绾跨▼鏁帮紝榛樿涓� 1
 --certfile  ssl鐨勮瘉涔︽枃浠讹紝榛樿涓猴細../../../ssl_key/server.crt锛屽鏋滈渶瑕佸叧闂璼sl锛屽弬鏁拌缃负0
 --keyfile   ssl鐨勫瘑閽ユ枃浠讹紝榛樿涓猴細../../../ssl_key/server.key
+--hotwordsfile   鐑瘝鏂囦欢璺緞锛屾瘡涓�涓儹璇嶄竴琛岋紝濡傛灉瀹㈡埛绔彁渚涚儹璇嶏紝鍒欎笌瀹㈡埛绔彁渚涚殑鐑瘝鍚堝苟涓�璧蜂娇鐢ㄣ�傞粯璁や负锛�../../hotwords.txt
 ```
 
 ### 鍏抽棴FunASR鏈嶅姟
diff --git a/funasr/runtime/run_server.sh b/funasr/runtime/run_server.sh
index 6869fd9..f75f159 100644
--- a/funasr/runtime/run_server.sh
+++ b/funasr/runtime/run_server.sh
@@ -9,6 +9,7 @@
 port=10095
 certfile="../../../ssl_key/server.crt"
 keyfile="../../../ssl_key/server.key"
+hotwordsfile="../../hotwords.txt"
 
 . ../../egs/aishell/transformer/utils/parse_options.sh || exit 1;
 
@@ -24,7 +25,8 @@
   --io-thread-num  ${io_thread_num} \
   --port ${port} \
   --certfile  "" \
-  --keyfile ""
+  --keyfile "" \
+  --hotwordsfile ${hotwordsfile}
 else
 ./funasr-wss-server  \
   --download-model-dir ${download_model_dir} \
@@ -36,5 +38,6 @@
   --io-thread-num  ${io_thread_num} \
   --port ${port} \
   --certfile  ${certfile} \
-  --keyfile ${keyfile}
+  --keyfile ${keyfile} \
+  --hotwordsfile ${hotwordsfile}
 fi
diff --git a/funasr/runtime/run_server_2pass.sh b/funasr/runtime/run_server_2pass.sh
index 63c2041..941064c 100644
--- a/funasr/runtime/run_server_2pass.sh
+++ b/funasr/runtime/run_server_2pass.sh
@@ -10,6 +10,7 @@
 port=10095
 certfile="../../../ssl_key/server.crt"
 keyfile="../../../ssl_key/server.key"
+hotwordsfile="../../hotwords.txt"
 
 . ../../egs/aishell/transformer/utils/parse_options.sh || exit 1;
 
@@ -26,7 +27,8 @@
   --io-thread-num  ${io_thread_num} \
   --port ${port} \
   --certfile  "" \
-  --keyfile ""
+  --keyfile "" \
+  --hotwordsfile ${hotwordsfile}
 else
 ./funasr-wss-server-2pass  \
   --download-model-dir ${download_model_dir} \
@@ -39,5 +41,6 @@
   --io-thread-num  ${io_thread_num} \
   --port ${port} \
   --certfile  ${certfile} \
-  --keyfile ${keyfile}
+  --keyfile ${keyfile} \
+  --hotwordsfile ${hotwordsfile}
 fi
diff --git a/funasr/runtime/websocket/bin/funasr-wss-server-2pass.cpp b/funasr/runtime/websocket/bin/funasr-wss-server-2pass.cpp
index 1f8b632..4aba830 100644
--- a/funasr/runtime/websocket/bin/funasr-wss-server-2pass.cpp
+++ b/funasr/runtime/websocket/bin/funasr-wss-server-2pass.cpp
@@ -14,6 +14,9 @@
 #include <unistd.h>
 #include "websocket-server-2pass.h"
 
+#include <fstream>
+std::string hotwords = "";
+
 using namespace std;
 void GetValue(TCLAP::ValueArg<std::string>& value_arg, string key,
               std::map<std::string, std::string>& model_path) {
@@ -108,6 +111,15 @@
         "default: ../../../ssl_key/server.key, path of keyfile for WSS "
         "connection",
         false, "../../../ssl_key/server.key", "string");
+
+    TCLAP::ValueArg<std::string> hotwordsfile(
+        "", "hotwordsfile",
+        "default: ../../hotwords.txt, path of hotwordsfile"
+        "connection",
+        false, "../../hotwords.txt", "string");
+
+    // add file
+    cmd.add(hotwordsfile);
 
     cmd.add(certfile);
     cmd.add(keyfile);
@@ -417,6 +429,21 @@
     std::string s_certfile = certfile.getValue();
     std::string s_keyfile = keyfile.getValue();
 
+    std::string s_hotwordsfile = hotwordsfile.getValue();
+    std::string line;
+    std::ifstream file(s_hotwordsfile);
+    LOG(INFO) << "hotwordsfile path: " << s_hotwordsfile;
+
+    if (file.is_open()) {
+        while (getline(file, line)) {
+            hotwords += line+HOTWORD_SEP;
+        }
+        LOG(INFO) << "hotwords: " << hotwords;
+        file.close();
+    } else {
+        LOG(ERROR) << "Unable to open hotwords file: " << s_hotwordsfile;
+    }
+
     bool is_ssl = false;
     if (!s_certfile.empty()) {
       is_ssl = true;
@@ -460,8 +487,7 @@
       websocket_srv.initAsr(model_path, s_model_thread_num);  // init asr model
     }
 
-    std::cout << "asr model init finished. listen on port:" << s_port
-              << std::endl;
+    LOG(INFO) << "asr model init finished. listen on port:" << s_port;
 
     // Start the ASIO network io_service run loop
     std::vector<std::thread> ts;
@@ -480,7 +506,7 @@
     }
 
   } catch (std::exception const& e) {
-    std::cerr << "Error: " << e.what() << std::endl;
+    LOG(ERROR) << "Error: " << e.what();
   }
 
   return 0;
diff --git a/funasr/runtime/websocket/bin/funasr-wss-server.cpp b/funasr/runtime/websocket/bin/funasr-wss-server.cpp
index 55ce07b..c7dba43 100644
--- a/funasr/runtime/websocket/bin/funasr-wss-server.cpp
+++ b/funasr/runtime/websocket/bin/funasr-wss-server.cpp
@@ -13,6 +13,9 @@
 #include "websocket-server.h"
 #include <unistd.h>
 
+#include <fstream>
+std::string hotwords = "";
+
 using namespace std;
 void GetValue(TCLAP::ValueArg<std::string>& value_arg, string key,
               std::map<std::string, std::string>& model_path) {
@@ -94,6 +97,15 @@
     TCLAP::ValueArg<std::string> keyfile("", "keyfile", 
         "default: ../../../ssl_key/server.key, path of keyfile for WSS connection", 
         false, "../../../ssl_key/server.key", "string");
+
+    TCLAP::ValueArg<std::string> hotwordsfile(
+        "", "hotwordsfile",
+        "default: ../../hotwords.txt, path of hotwordsfile"
+        "connection",
+        false, "../../hotwords.txt", "string");
+
+    // add file
+    cmd.add(hotwordsfile);
 
     cmd.add(certfile);
     cmd.add(keyfile);
@@ -331,6 +343,21 @@
     std::string s_certfile = certfile.getValue();
     std::string s_keyfile = keyfile.getValue();
 
+    std::string s_hotwordsfile = hotwordsfile.getValue();
+    std::string line;
+    std::ifstream file(s_hotwordsfile);
+    LOG(INFO) << "hotwordsfile path: " << s_hotwordsfile;
+
+    if (file.is_open()) {
+        while (getline(file, line)) {
+            hotwords += line+HOTWORD_SEP;
+        }
+        LOG(INFO) << "hotwords: " << hotwords;
+        file.close();
+    } else {
+        LOG(ERROR) << "Unable to open hotwords file: " << s_hotwordsfile;
+    }
+
     bool is_ssl = false;
     if (!s_certfile.empty()) {
       is_ssl = true;
@@ -374,8 +401,7 @@
       websocket_srv.initAsr(model_path, s_model_thread_num);  // init asr model
     }
 
-    std::cout << "asr model init finished. listen on port:" << s_port
-              << std::endl;
+    LOG(INFO) << "asr model init finished. listen on port:" << s_port;
 
     // Start the ASIO network io_service run loop
     std::vector<std::thread> ts;
@@ -394,7 +420,7 @@
     }
 
   } catch (std::exception const& e) {
-    std::cerr << "Error: " << e.what() << std::endl;
+    LOG(ERROR) << "Error: " << e.what();
   }
 
   return 0;
diff --git a/funasr/runtime/websocket/bin/websocket-server-2pass.cpp b/funasr/runtime/websocket/bin/websocket-server-2pass.cpp
index 107be40..b64cecb 100644
--- a/funasr/runtime/websocket/bin/websocket-server-2pass.cpp
+++ b/funasr/runtime/websocket/bin/websocket-server-2pass.cpp
@@ -15,7 +15,9 @@
 #include <thread>
 #include <utility>
 #include <vector>
-#include <chrono>
+
+extern std::string hotwords;
+
 context_ptr WebSocketServer::on_tls_init(tls_mode mode,
                                          websocketpp::connection_hdl hdl,
                                          std::string& s_certfile,
@@ -370,17 +372,26 @@
           msg_data->msg["hotwords"] = jsonresult["hotwords"];
           if (!msg_data->msg["hotwords"].empty()) {
             std::string hw = msg_data->msg["hotwords"];
-            LOG(INFO)<<"hotwords: " << hw;
-            std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(tpass_handle, hw, ASR_TWO_PASS);
+            hw = hw + " " + hotwords;
+            LOG(INFO) << "hotwords: " << hw;
+            std::vector<std::vector<float>> new_hotwords_embedding = CompileHotwordEmbedding(tpass_handle, hw, ASR_TWO_PASS);
             msg_data->hotwords_embedding =
                 std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
           }
-        }else{
+        } else {
+          if (hotwords.empty()) {
             std::string hw = "";
             LOG(INFO)<<"hotwords: " << hw;
             std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(tpass_handle, hw, ASR_TWO_PASS);
             msg_data->hotwords_embedding =
                 std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
+          }else {
+            std::string hw = hotwords;
+            LOG(INFO) << "hotwords: " << hw;
+            std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(tpass_handle, hw, ASR_TWO_PASS);
+            msg_data->hotwords_embedding =
+                std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
+          }
         }
       }
       if (jsonresult.contains("audio_fs")) {
diff --git a/funasr/runtime/websocket/bin/websocket-server.cpp b/funasr/runtime/websocket/bin/websocket-server.cpp
index da1ffa5..6e1c211 100644
--- a/funasr/runtime/websocket/bin/websocket-server.cpp
+++ b/funasr/runtime/websocket/bin/websocket-server.cpp
@@ -16,6 +16,8 @@
 #include <utility>
 #include <vector>
 
+extern std::string hotwords;
+
 context_ptr WebSocketServer::on_tls_init(tls_mode mode,
                                          websocketpp::connection_hdl hdl,
                                          std::string& s_certfile,
@@ -266,17 +268,26 @@
           msg_data->msg["hotwords"] = jsonresult["hotwords"];
           if (!msg_data->msg["hotwords"].empty()) {
             std::string hw = msg_data->msg["hotwords"];
-            LOG(INFO)<<"hotwords: " << hw;
-            std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(asr_hanlde, hw);
+            hw = hw + " " + hotwords;
+            LOG(INFO) << "hotwords: " << hw;
+            std::vector<std::vector<float>> new_hotwords_embedding = CompileHotwordEmbedding(asr_hanlde, hw);
             msg_data->hotwords_embedding =
                 std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
           }
-        }else{
+        } else {
+          if (hotwords.empty()) {
             std::string hw = "";
             LOG(INFO)<<"hotwords: " << hw;
             std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(asr_hanlde, hw);
             msg_data->hotwords_embedding =
                 std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
+          }else {
+            std::string hw = hotwords;
+            LOG(INFO) << "hotwords: " << hw;
+            std::vector<std::vector<float>> new_hotwords_embedding= CompileHotwordEmbedding(asr_hanlde, hw);
+            msg_data->hotwords_embedding =
+                std::make_shared<std::vector<std::vector<float>>>(new_hotwords_embedding);
+          }
         }
       }
       if (jsonresult.contains("audio_fs")) {
diff --git a/funasr/runtime/websocket/hotwords.txt b/funasr/runtime/websocket/hotwords.txt
new file mode 100644
index 0000000..6179cbc
--- /dev/null
+++ b/funasr/runtime/websocket/hotwords.txt
@@ -0,0 +1,2 @@
+闃块噷宸村反
+閫氫箟瀹為獙瀹�

--
Gitblit v1.9.1