WsParamRecognizeObject.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import websocket
  2. import datetime
  3. import hashlib
  4. import base64
  5. import hmac
  6. import json
  7. from urllib.parse import urlencode
  8. import time
  9. import ssl
  10. from wsgiref.handlers import format_date_time
  11. from datetime import datetime
  12. from time import mktime
  13. import threading
  14. """
  15. 调用讯飞模型 语音转文字
  16. """
  17. class WsParamRecognize:
  18. STATUS_FIRST_FRAME = 0
  19. STATUS_CONTINUE_FRAME = 1
  20. STATUS_LAST_FRAME = 2
  21. def __init__(self, APPID, APISecret, APIKey, AudioFile):
  22. self.APPID = APPID
  23. self.APISecret = APISecret
  24. self.APIKey = APIKey
  25. self.AudioFile = AudioFile
  26. self.all_sentences = ""
  27. # 公共参数
  28. self.CommonArgs = {"app_id": self.APPID}
  29. # 业务参数
  30. self.BusinessArgs = {"domain": "iat", "language": "zh_cn", "accent": "mandarin", "vinfo": 1, "vad_eos": 10000}
  31. def create_url(self):
  32. url = 'wss://ws-api.xfyun.cn/v2/iat'
  33. now = datetime.now()
  34. date = format_date_time(mktime(now.timetuple()))
  35. signature_origin = "host: ws-api.xfyun.cn\n" + "date: " + date + "\nGET /v2/iat HTTP/1.1"
  36. signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
  37. digestmod=hashlib.sha256).digest()
  38. signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
  39. authorization_origin = "api_key=\"%s\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"%s\"" % (
  40. self.APIKey, signature_sha)
  41. authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
  42. v = {"authorization": authorization, "date": date, "host": "ws-api.xfyun.cn"}
  43. url = url + '?' + urlencode(v)
  44. return url
  45. def on_message(self, ws, message):
  46. try:
  47. message = json.loads(message)
  48. code = message["code"]
  49. sid = message["sid"]
  50. if code != 0:
  51. errMsg = message["message"]
  52. print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
  53. else:
  54. data = message["data"]["result"]["ws"]
  55. for i in data:
  56. for w in i["cw"]:
  57. self.all_sentences += w["w"]
  58. except Exception as e:
  59. print("receive msg,but parse exception:", e)
  60. def on_error(self, error):
  61. print("### error:", error)
  62. def on_close(self):
  63. print("### closed ###")
  64. def on_open(self, ws):
  65. def run(*args):
  66. frameSize = 8000
  67. intervel = 0.04
  68. status = self.STATUS_FIRST_FRAME
  69. with open(self.AudioFile, "rb") as fp:
  70. while True:
  71. buf = fp.read(frameSize)
  72. if not buf:
  73. status = self.STATUS_LAST_FRAME
  74. if status == self.STATUS_FIRST_FRAME:
  75. d = {"common": self.CommonArgs, "business": self.BusinessArgs,
  76. "data": {"status": 0, "format": "audio/L16;rate=16000",
  77. "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}
  78. ws.send(json.dumps(d))
  79. status = self.STATUS_CONTINUE_FRAME
  80. elif status == self.STATUS_CONTINUE_FRAME:
  81. ws.send(json.dumps({"data": {"status": 1, "format": "audio/L16;rate=16000",
  82. "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}))
  83. elif status == self.STATUS_LAST_FRAME:
  84. ws.send(json.dumps({"data": {"status": 2, "format": "audio/L16;rate=16000",
  85. "audio": str(base64.b64encode(buf), 'utf-8'), "encoding": "raw"}}))
  86. time.sleep(1)
  87. break
  88. time.sleep(intervel)
  89. ws.close()
  90. threading.Thread(target=run).start()
  91. def start(self):
  92. websocket.enableTrace(False)
  93. wsUrl = self.create_url()
  94. self.ws = websocket.WebSocketApp(wsUrl,
  95. on_message=lambda ws, msg: self.on_message(ws, msg),
  96. on_error=self.on_error,
  97. on_close=self.on_close,
  98. on_open=lambda ws: self.on_open(ws))
  99. self.ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
  100. return self.all_sentences