|
@@ -0,0 +1,112 @@
|
|
|
+import websocket
|
|
|
+import datetime
|
|
|
+import hashlib
|
|
|
+import base64
|
|
|
+import hmac
|
|
|
+import json
|
|
|
+from urllib.parse import urlencode
|
|
|
+import time
|
|
|
+import ssl
|
|
|
+from wsgiref.handlers import format_date_time
|
|
|
+from datetime import datetime
|
|
|
+from time import mktime
|
|
|
+import _thread as thread
|
|
|
+
|
|
|
+"""
|
|
|
+调用讯飞模型 语音转文字
|
|
|
+"""
|
|
|
+
|
|
|
+class WsParamRecognize:
|
|
|
+ STATUS_FIRST_FRAME = 0
|
|
|
+ STATUS_CONTINUE_FRAME = 1
|
|
|
+ STATUS_LAST_FRAME = 2
|
|
|
+
|
|
|
+ def __init__(self, APPID, APISecret, APIKey, AudioFile):
|
|
|
+ self.APPID = APPID
|
|
|
+ self.APISecret = APISecret
|
|
|
+ self.APIKey = APIKey
|
|
|
+ self.AudioFile = AudioFile
|
|
|
+ self.all_sentences = ""
|
|
|
+
|
|
|
+ # 公共参数
|
|
|
+ self.CommonArgs = {"app_id": self.APPID}
|
|
|
+ # 业务参数
|
|
|
+ self.BusinessArgs = {"domain": "iat", "language": "zh_cn", "accent": "mandarin", "vinfo": 1, "vad_eos": 10000}
|
|
|
+
|
|
|
+ def create_url(self):
|
|
|
+ url = 'wss://ws-api.xfyun.cn/v2/iat'
|
|
|
+ now = datetime.now()
|
|
|
+ date = format_date_time(mktime(now.timetuple()))
|
|
|
+ signature_origin = "host: ws-api.xfyun.cn\n" + "date: " + date + "\nGET /v2/iat HTTP/1.1"
|
|
|
+ signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
|
|
|
+ digestmod=hashlib.sha256).digest()
|
|
|
+ signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
|
|
|
+ authorization_origin = "api_key=\"%s\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"%s\"" % (
|
|
|
+ self.APIKey, signature_sha)
|
|
|
+ authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
|
|
|
+ v = {"authorization": authorization, "date": date, "host": "ws-api.xfyun.cn"}
|
|
|
+ url = url + '?' + urlencode(v)
|
|
|
+ return url
|
|
|
+
|
|
|
+ def on_message(self, ws, message):
|
|
|
+ try:
|
|
|
+ message = json.loads(message)
|
|
|
+ code = message["code"]
|
|
|
+ sid = message["sid"]
|
|
|
+ if code != 0:
|
|
|
+ errMsg = message["message"]
|
|
|
+ print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
|
|
|
+ else:
|
|
|
+ data = message["data"]["result"]["ws"]
|
|
|
+ for i in data:
|
|
|
+ for w in i["cw"]:
|
|
|
+ self.all_sentences += w["w"]
|
|
|
+ except Exception as e:
|
|
|
+ print("receive msg,but parse exception:", e)
|
|
|
+
|
|
|
+ def on_error(self, error):
|
|
|
+ print("### error:", error)
|
|
|
+
|
|
|
+ def on_close(self):
|
|
|
+ print("### closed ###")
|
|
|
+
|
|
|
+ def on_open(self, ws):
|
|
|
+ def run(*args):
|
|
|
+ frameSize = 8000
|
|
|
+ intervel = 0.04
|
|
|
+ status = self.STATUS_FIRST_FRAME
|
|
|
+
|
|
|
+ with open(self.AudioFile, "rb") as fp:
|
|
|
+ while True:
|
|
|
+ buf = fp.read(frameSize)
|
|
|
+ if not buf:
|
|
|
+ status = self.STATUS_LAST_FRAME
|
|
|
+ if status == self.STATUS_FIRST_FRAME:
|
|
|
+ d = {"common": self.CommonArgs, "business": self.BusinessArgs,
|
|
|
+ "data": {"status": 0, "format": "audio/L16;rate=16000",
|
|
|
+ "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}
|
|
|
+ ws.send(json.dumps(d))
|
|
|
+ status = self.STATUS_CONTINUE_FRAME
|
|
|
+ elif status == self.STATUS_CONTINUE_FRAME:
|
|
|
+ ws.send(json.dumps({"data": {"status": 1, "format": "audio/L16;rate=16000",
|
|
|
+ "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}))
|
|
|
+ elif status == self.STATUS_LAST_FRAME:
|
|
|
+ ws.send(json.dumps({"data": {"status": 2, "format": "audio/L16;rate=16000",
|
|
|
+ "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}))
|
|
|
+ time.sleep(1)
|
|
|
+ break
|
|
|
+ time.sleep(intervel)
|
|
|
+ ws.close()
|
|
|
+
|
|
|
+ thread.start_new_thread(run, ())
|
|
|
+
|
|
|
+ def start(self):
|
|
|
+ websocket.enableTrace(False)
|
|
|
+ wsUrl = self.create_url()
|
|
|
+ self.ws = websocket.WebSocketApp(wsUrl,
|
|
|
+ on_message=lambda ws, msg: self.on_message(ws, msg),
|
|
|
+ on_error=self.on_error,
|
|
|
+ on_close=self.on_close,
|
|
|
+ on_open=lambda ws: self.on_open(ws))
|
|
|
+ self.ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
|
|
+ return self.all_sentences
|