Explorar el Código

讯飞asr测试

Davidliu hace 1 mes
padre
commit
4d95cb9aa1
Se han modificado 2 ficheros con 127 adiciones y 34 borrados
  1. 122 31
      src/core/voip/asr.py
  2. 5 3
      src/core/voip/bot.py

+ 122 - 31
src/core/voip/asr.py

@@ -11,34 +11,14 @@ from aliyunsdkcore.client import AcsClient
 from aliyunsdkcore.request import CommonRequest
 import time
 
-# 获取Token的函数
-def get_token():
-    ak_id = "LTAI5tQ2HmiHCygZkt5BYrYR"
-    ak_secret = "KhmxTd14SUcXafpFk5yofA43FoeM99"
-    client = AcsClient(ak_id, ak_secret, "cn-shanghai")
-    request = CommonRequest()
-    request.set_method('POST')
-    request.set_domain('nls-meta.cn-shanghai.aliyuncs.com')
-    request.set_version('2019-02-28')
-    request.set_action_name('CreateToken')
-
-    try:
-        response = client.do_action_with_exception(request)
-        jss = json.loads(response)
-        if 'Token' in jss and 'Id' in jss['Token']:
-            token = jss['Token']['Id']
-            expire_time = jss['Token']['ExpireTime']
-            print(f"Token: {token}, ExpireTime: {expire_time}")
-            return token, int(expire_time)  # 返回Token和过期时间
-        else:
-            print("Token获取失败,响应内容: ", response)
-    except Exception as e:
-        print(f"获取Token时发生错误: {e}")
-    return None, None
-
-# WebSocket服务地址
-URL = "wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1"
-APPKEY = "OKt6jogp6fRjHQVp"  # 你的Appkey
+import hashlib
+import hmac
+import base64
+from socket import *
+import json, time, threading
+from websocket import create_connection
+import websocket
+from urllib.parse import quote
 
 # 定义实时转写类
 class TestSt:
@@ -48,6 +28,32 @@ class TestSt:
         "expire_time": None
     }
 
+    # 获取Token的函数
+    @classmethod
+    def get_token(cls):
+        ak_id = "LTAI5tQ2HmiHCygZkt5BYrYR"
+        ak_secret = "KhmxTd14SUcXafpFk5yofA43FoeM99"
+        client = AcsClient(ak_id, ak_secret, "cn-shanghai")
+        request = CommonRequest()
+        request.set_method('POST')
+        request.set_domain('nls-meta.cn-shanghai.aliyuncs.com')
+        request.set_version('2019-02-28')
+        request.set_action_name('CreateToken')
+
+        try:
+            response = client.do_action_with_exception(request)
+            jss = json.loads(response)
+            if 'Token' in jss and 'Id' in jss['Token']:
+                token = jss['Token']['Id']
+                expire_time = jss['Token']['ExpireTime']
+                print(f"Token: {token}, ExpireTime: {expire_time}")
+                return token, int(expire_time)  # 返回Token和过期时间
+            else:
+                print("Token获取失败,响应内容: ", response)
+        except Exception as e:
+            print(f"获取Token时发生错误: {e}")
+        return None, None
+
     @classmethod
     def get_cached_token(cls):
         # 检查是否已有缓存的Token且未过期s):
@@ -60,7 +66,7 @@ class TestSt:
             return cls.token_cache["token"]
 
         # 如果没有缓存Token或者Token已过期,重新获取
-        new_token, expire_time = get_token()
+        new_token, expire_time = cls.get_token()
         if new_token:
             cls.token_cache["token"] = new_token
             cls.token_cache["expire_time"] = expire_time
@@ -80,6 +86,10 @@ class TestSt:
         self.message_receiver = message_receiver
         self._Token = self.get_cached_token()
         self.sr = None
+
+        # WebSocket服务地址
+        self.URL = "wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1"
+        self.APPKEY = "OKt6jogp6fRjHQVp"  # 你的Appkey
         self.logger.debug("开始")
 
     def start(self):
@@ -102,9 +112,9 @@ class TestSt:
         self.__event.clear()
         while not self.__event.is_set():
             self.sr = nls.NlsSpeechTranscriber(
-                url=URL,
+                url=self.URL,
                 token=self._Token,
-                appkey=APPKEY,
+                appkey=self.APPKEY,
                 on_sentence_begin=self.test_on_sentence_begin,
                 on_sentence_end=self.test_on_sentence_end,
                 on_start=self.test_on_start,
@@ -169,3 +179,84 @@ class TestSt:
     def test_on_completed(self, message, *args):
         # self.logger.debug("on_completed:args=>{} message=>{}".format(args, message))
         pass
+
+
+# 讯飞ASR实时转写
+class XfAsr:
+    def __init__(self, tid, logger, message_receiver=None):
+        app_id = "1ec1097b"
+        api_key = "60b7d2d8d172b065b1c3e723e5ba0696"
+        base_url = "ws://rtasr.xfyun.cn/v1/ws"
+
+        ts = str(int(time.time()))
+        tt = (app_id + ts).encode('utf-8')
+        md5 = hashlib.md5()
+        md5.update(tt)
+        baseString = md5.hexdigest()
+        baseString = bytes(baseString, encoding='utf-8')
+
+        apiKey = api_key.encode('utf-8')
+        signa = hmac.new(apiKey, baseString, hashlib.sha1).digest()
+        signa = base64.b64encode(signa)
+        signa = str(signa, 'utf-8')
+        self.end_tag = "{\"end\": true}"
+        self.tid = tid
+        self.logger = logger
+        self.message_receiver = message_receiver
+        self.ws = create_connection(base_url + "?appid=" + app_id + "&ts=" + ts + "&signa=" + quote(signa))
+        self.trecv = threading.Thread(target=self.recv)
+
+    def start(self):
+        self.trecv.start()
+
+    def send(self, file_path):
+        file_object = open(file_path, 'rb')
+        try:
+            index = 1
+            while True:
+                chunk = file_object.read(1280)
+                if not chunk:
+                    break
+                self.ws.send(chunk)
+
+                index += 1
+                time.sleep(0.04)
+        finally:
+            file_object.close()
+
+        self.ws.send(bytes(self.end_tag.encode('utf-8')))
+        print("send end tag success")
+
+    def send_audio(self, chunk):
+        self.ws.send(chunk)
+
+    def close(self):
+        self.ws.send(bytes(self.end_tag.encode('utf-8')))
+        self.ws.close()
+        print("connection closed")
+
+    def recv(self):
+        try:
+            while self.ws.connected:
+                result = str(self.ws.recv())
+                if len(result) == 0:
+                    print("receive result end")
+                    break
+                result_dict = json.loads(result)
+                # 解析结果
+                if result_dict["action"] == "started":
+                    print("handshake success, result: " + result)
+
+                if result_dict["action"] == "result":
+                    result_1 = result_dict
+                    # result_2 = json.loads(result_1["cn"])
+                    # result_3 = json.loads(result_2["st"])
+                    # result_4 = json.loads(result_3["rt"])
+                    print("rtasr result: " + result_1["data"])
+
+                if result_dict["action"] == "error":
+                    print("rtasr error: " + result)
+                    self.ws.close()
+                    return
+        except websocket.WebSocketConnectionClosedException:
+            print("receive result end")

+ 5 - 3
src/core/voip/bot.py

@@ -34,7 +34,7 @@ calls = {}
 # recording_file = '/code/src/core/voip/incoming_call.wav'
 # player_file1 = '/code/src/core/voip/test111.wav'
 # player_file2 = '/code/src/core/voip/test222.wav'
-from src.core.voip.asr import TestSt
+from src.core.voip.asr import TestSt, XfAsr
 
 class BotStatus(Enum):
     # 等待用户讲话,未超时
@@ -216,7 +216,8 @@ class MyCall(pj.Call):
 
         self.cur_player_file = None   #当前播放的文件
 
-        self.asr = TestSt(self.session_id, logger=self.logger, message_receiver=self.on_receiver_asr_result)  # 创建ASR实例
+        # self.asr = TestSt(self.session_id, logger=self.logger, message_receiver=self.on_receiver_asr_result)  # 创建ASR实例
+        self.asr = XfAsr(self.session_id, logger=self.logger, message_receiver=self.on_receiver_asr_result)  # 创建ASR实例
         self.asr.start()  # 启动ASR线程
 
         self.start_time = time.time()  # 当前机器人对话开始时间
@@ -605,7 +606,8 @@ class BotAgent:
             media_cfg.jbMinPre = 4  # Minimum pre-fetch frames
             media_cfg.jbMaxPre = 16  # Maximum pre-fetch frames
             media_cfg.noVad = True  # Disable Voice Activity Detection if needed
-            media_cfg.clockRate = 8000
+            media_cfg.clockRate = 16000
+            # media_cfg.clockRate = 8000
             self.ep.medConfig = media_cfg  # Apply media config to endpoint
 
             # Create SIP transport. Error handling sample is shown