Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

pirms 5 mēnešiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # -*- coding:utf-8 -*-
  2. #
  3. # Author: njnuko
  4. # Email: njnuko@163.com
  5. #
  6. # 这个文档是基于官方的demo来改的,固体官方demo文档请参考官网
  7. #
  8. # 语音听写流式 WebAPI 接口调用示例 接口文档(必看):https://doc.xfyun.cn/rest_api/语音听写(流式版).html
  9. # webapi 听写服务参考帖子(必看):http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=38947&extra=
  10. # 语音听写流式WebAPI 服务,热词使用方式:登陆开放平台https://www.xfyun.cn/后,找到控制台--我的应用---语音听写(流式)---服务管理--个性化热词,
  11. # 设置热词
  12. # 注意:热词只能在识别的时候会增加热词的识别权重,需要注意的是增加相应词条的识别率,但并不是绝对的,具体效果以您测试为准。
  13. # 语音听写流式WebAPI 服务,方言试用方法:登陆开放平台https://www.xfyun.cn/后,找到控制台--我的应用---语音听写(流式)---服务管理--识别语种列表
  14. # 可添加语种或方言,添加后会显示该方言的参数值
  15. # 错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看)
  16. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  17. import websocket
  18. import datetime
  19. import hashlib
  20. import base64
  21. import hmac
  22. import json
  23. from urllib.parse import urlencode
  24. import time
  25. import ssl
  26. from wsgiref.handlers import format_date_time
  27. from datetime import datetime
  28. from time import mktime
  29. import _thread as thread
  30. import os
  31. STATUS_FIRST_FRAME = 0 # 第一帧的标识
  32. STATUS_CONTINUE_FRAME = 1 # 中间帧标识
  33. STATUS_LAST_FRAME = 2 # 最后一帧的标识
  34. #############
  35. #这个参数是用来做输出文件路径的
  36. global outfile
  37. #这个文档是官方文档改的,这个参数是用来做函数调用时用的
  38. global wsParam
  39. ##############
  40. class Ws_Param(object):
  41. # 初始化
  42. def __init__(self, APPID, APIKey, APISecret,BusinessArgs,Text):
  43. self.APPID = APPID
  44. self.APIKey = APIKey
  45. self.APISecret = APISecret
  46. self.BusinessArgs = BusinessArgs
  47. self.Text = Text
  48. # 公共参数(common)
  49. self.CommonArgs = {"app_id": self.APPID}
  50. # 业务参数(business),更多个性化参数可在官网查看
  51. #self.BusinessArgs = {"aue": "raw", "auf": "audio/L16;rate=16000", "vcn": "xiaoyan", "tte": "utf8"}
  52. self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-8')), "UTF8")}
  53. #使用小语种须使用以下方式,此处的unicode指的是 utf16小端的编码方式,即"UTF-16LE"”
  54. #self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-16')), "UTF8")}
  55. # 生成url
  56. def create_url(self):
  57. url = 'wss://tts-api.xfyun.cn/v2/tts'
  58. # 生成RFC1123格式的时间戳
  59. now = datetime.now()
  60. date = format_date_time(mktime(now.timetuple()))
  61. # 拼接字符串
  62. signature_origin = "host: " + "ws-api.xfyun.cn" + "\n"
  63. signature_origin += "date: " + date + "\n"
  64. signature_origin += "GET " + "/v2/tts " + "HTTP/1.1"
  65. # 进行hmac-sha256进行加密
  66. signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
  67. digestmod=hashlib.sha256).digest()
  68. signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
  69. authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
  70. self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
  71. authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
  72. # 将请求的鉴权参数组合为字典
  73. v = {
  74. "authorization": authorization,
  75. "date": date,
  76. "host": "ws-api.xfyun.cn"
  77. }
  78. # 拼接鉴权参数,生成url
  79. url = url + '?' + urlencode(v)
  80. # print("date: ",date)
  81. # print("v: ",v)
  82. # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
  83. # print('websocket url :', url)
  84. return url
  85. def on_message(ws, message):
  86. #输出文件
  87. global outfile
  88. try:
  89. message =json.loads(message)
  90. code = message["code"]
  91. sid = message["sid"]
  92. audio = message["data"]["audio"]
  93. audio = base64.b64decode(audio)
  94. status = message["data"]["status"]
  95. if status == 2:
  96. print("ws is closed")
  97. ws.close()
  98. if code != 0:
  99. errMsg = message["message"]
  100. print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
  101. else:
  102. with open(outfile, 'ab') as f:
  103. f.write(audio)
  104. except Exception as e:
  105. print("receive msg,but parse exception:", e)
  106. # 收到websocket连接建立的处理
  107. def on_open(ws):
  108. global outfile
  109. global wsParam
  110. def run(*args):
  111. d = {"common": wsParam.CommonArgs,
  112. "business": wsParam.BusinessArgs,
  113. "data": wsParam.Data,
  114. }
  115. d = json.dumps(d)
  116. # print("------>开始发送文本数据")
  117. ws.send(d)
  118. if os.path.exists(outfile):
  119. os.remove(outfile)
  120. thread.start_new_thread(run, ())
  121. # 收到websocket错误的处理
  122. def on_error(ws, error):
  123. print("### error:", error)
  124. # 收到websocket关闭的处理
  125. def on_close(ws):
  126. print("### closed ###")
  127. def xunfei_tts(APPID, APIKey, APISecret,BusinessArgsTTS, Text, OutFile):
  128. global outfile
  129. global wsParam
  130. outfile = OutFile
  131. wsParam1 = Ws_Param(APPID,APIKey,APISecret,BusinessArgsTTS,Text)
  132. wsParam = wsParam1
  133. websocket.enableTrace(False)
  134. wsUrl = wsParam.create_url()
  135. ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
  136. ws.on_open = on_open
  137. ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
  138. return outfile