tencent.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from ..__load__ import *
  4. 'Tencent ASR && TTS API'
  5. __author__ = 'Charles Li, Joseph Pan'
  6. import time
  7. import uuid
  8. import json
  9. import random
  10. import requests
  11. import hmac
  12. import base64
  13. import urllib
  14. class Tencent(object):
  15. __slots__ = 'SECRET_ID', 'SECRET_KEY', 'SourceType', 'URL', 'VoiceFormat', 'PrimaryLanguage', 'Text', 'VoiceType', 'Region'
  16. def init(self, SECRET_ID, SECRET_KEY):
  17. self.SECRET_KEY, self.SECRET_ID = SECRET_KEY, SECRET_ID
  18. @property
  19. def secret_id(self):
  20. return self.SECRET_ID
  21. @secret_id.setter
  22. def secret_id(self, SECRET_ID):
  23. if not isinstance(SECRET_ID, str):
  24. raise ValueError('SecretId must be a string!')
  25. if len(SECRET_ID)==0:
  26. raise ValueError('SecretId can not be empty!')
  27. self.SECRET_ID = SECRET_ID
  28. @property
  29. def secret_key(self):
  30. return self.SECRET_KEY
  31. @secret_key.setter
  32. def secret_key(self, SECRET_KEY):
  33. if not isinstance(SECRET_KEY, str):
  34. raise ValueError('SecretKey must be a string!')
  35. if len(SECRET_KEY)==0:
  36. raise ValueError('SecretKey can not be empty!')
  37. self.SECRET_KEY = SECRET_KEY
  38. @property
  39. def source_type(self):
  40. return self.sourcetype
  41. @source_type.setter
  42. def source_type(self, SourceType):
  43. if not isinstance(SourceType, str):
  44. raise ValueError('SecretType must be an string!')
  45. if len(SourceType)==0:
  46. raise ValueError('SourceType can not be empty!')
  47. self.SourceType = SourceType
  48. @property
  49. def url(self):
  50. return self.URL
  51. @url.setter
  52. def url(self, URL):
  53. if not isinstance(URL, str):
  54. raise ValueError('url must be an string!')
  55. if len(URL)==0:
  56. raise ValueError('url can not be empty!')
  57. self.URL = URL
  58. @property
  59. def voiceformat(self):
  60. return self.VoiceFormat
  61. @voiceformat.setter
  62. def voiceformat(self, VoiceFormat):
  63. if not isinstance(VoiceFormat, str):
  64. raise ValueError('voiceformat must be an string!')
  65. if len(VoiceFormat)==0:
  66. raise ValueError('voiceformat can not be empty!')
  67. self.VoiceFormat = VoiceFormat
  68. @property
  69. def text(self):
  70. return self.Text
  71. @text.setter
  72. def text(self, Text):
  73. if not isinstance(Text, str):
  74. raise ValueError('text must be an string!')
  75. if len(Text)==0:
  76. raise ValueError('text can not be empty!')
  77. self.Text = Text
  78. @property
  79. def region(self):
  80. return self.Region
  81. @region.setter
  82. def region(self, Region):
  83. if not isinstance(Region, str):
  84. raise ValueError('region must be an string!')
  85. if len(Region)==0:
  86. raise ValueError('region can not be empty!')
  87. self.Region = Region
  88. @property
  89. def primarylanguage(self):
  90. return self.PrimaryLanguage
  91. @primarylanguage.setter
  92. def primarylanguage(self, PrimaryLanguage):
  93. self.PrimaryLanguage = PrimaryLanguage
  94. @property
  95. def voicetype(self):
  96. return self.VoiceType
  97. @voicetype.setter
  98. def voicetype(self, VoiceType):
  99. self.VoiceType = VoiceType
  100. def TTS(self, text, voicetype, primarylanguage, region):
  101. self.text, self.voicetype, self.primarylanguage, self.region = text, voicetype, primarylanguage, region
  102. return self.textToSpeech()
  103. def textToSpeech(self):
  104. #生成body
  105. def make_body(config_dict, sign_encode):
  106. ##注意URL编码的时候分str编码,整段编码会丢data
  107. body = ''
  108. for a, b in config_dict:
  109. body += urllib.parse.quote(a) + '=' + urllib.parse.quote(str(b)) + '&'
  110. return body + 'Signature=' + sign_encode
  111. HOST = 'aai.tencentcloudapi.com'
  112. config_dict= {
  113. 'Action' : 'TextToVoice',
  114. 'Version' : '2018-05-22',
  115. 'ProjectId' : 0,
  116. 'Region' : self.Region,
  117. 'VoiceType' : self.VoiceType,
  118. 'Timestamp' : int(time.time()),
  119. 'Nonce' : random.randint(100000, 200000),
  120. 'SecretId' : self.SECRET_ID,
  121. 'Text' : self.Text,
  122. 'PrimaryLanguage': self.PrimaryLanguage,
  123. 'ModelType' : 1,
  124. 'SessionId' : uuid.uuid1()
  125. }
  126. #按key排序
  127. config_dict = sorted(config_dict.items())
  128. signstr = self.formatSignString(config_dict)
  129. sign_encode = urllib.parse.quote(self.encode_sign(signstr, self.SECRET_KEY))
  130. body = make_body(config_dict, sign_encode)
  131. #Get URL
  132. req_url = "https://aai.tencentcloudapi.com"
  133. header = {
  134. 'Host' : HOST,
  135. 'Content-Type' : 'application/x-www-form-urlencoded',
  136. 'Charset' : 'UTF-8'
  137. }
  138. request = requests.post(req_url, headers = header, data = body)
  139. #有些音频utf8解码失败,存在编码错误
  140. s = request.content.decode("utf8","ignore")
  141. return json.loads(s)
  142. def ASR(self, URL, voiceformat, sourcetype, region):
  143. self.url, self.voiceformat, self.source_type, self.region = URL, voiceformat, sourcetype, region
  144. return self.oneSentenceRecognition()
  145. def oneSentenceRecognition(self):
  146. #生成body
  147. def make_body(config_dict, sign_encode):
  148. ##注意URL编码的时候分str编码,整段编码会丢data
  149. body = ''
  150. for a, b in config_dict:
  151. body += urllib.parse.quote(a) + '=' + urllib.parse.quote(str(b)) + '&'
  152. return body + 'Signature=' + sign_encode
  153. HOST = 'aai.tencentcloudapi.com'
  154. config_dict= {
  155. 'Action' : 'SentenceRecognition',
  156. 'Version' : '2018-05-22',
  157. 'Region' : self.Region,
  158. 'ProjectId' : 0,
  159. 'SubServiceType' : 2,
  160. 'EngSerViceType' : '16k',
  161. 'VoiceFormat' : self.VoiceFormat,
  162. 'UsrAudioKey' : random.randint(0, 20),
  163. 'Timestamp' : int(time.time()),
  164. 'Nonce' : random.randint(100000, 200000),
  165. 'SecretId' : self.SECRET_ID,
  166. 'SourceType' : self.SourceType
  167. }
  168. if self.SourceType == '0':
  169. config_dict['Url'] = urllib.parse.quote(str(self.url))
  170. else:
  171. #不能大于1M
  172. file_path = self.URL
  173. file = open(file_path, 'rb')
  174. content = file.read()
  175. config_dict['DataLen'] = len(content)
  176. config_dict['Data'] = base64.b64encode(content).decode()
  177. #config_dict['Data'] = content
  178. file.close()
  179. #按key排序
  180. config_dict = sorted(config_dict.items())
  181. signstr = self.formatSignString(config_dict)
  182. sign_encode = urllib.parse.quote(self.encode_sign(signstr, self.SECRET_KEY))
  183. body = make_body(config_dict, sign_encode)
  184. #Get URL
  185. req_url = "https://aai.tencentcloudapi.com"
  186. header = {
  187. 'Host' : HOST,
  188. 'Content-Type' : 'application/x-www-form-urlencoded',
  189. 'Charset' : 'UTF-8'
  190. }
  191. request = requests.post(req_url, headers = header, data = body)
  192. #有些音频utf8解码失败,存在编码错误
  193. s = request.content.decode("utf8","ignore")
  194. return s
  195. #拼接url和参数
  196. def formatSignString(self, config_dict):
  197. signstr="POSTaai.tencentcloudapi.com/?"
  198. argArr = []
  199. for a, b in config_dict:
  200. argArr.append(a + "=" + str(b))
  201. config_str = "&".join(argArr)
  202. return signstr + config_str
  203. #生成签名
  204. def encode_sign(self, signstr, SECRET_KEY):
  205. myhmac = hmac.new(SECRET_KEY.encode(), signstr.encode(), digestmod = 'sha1')
  206. code = myhmac.digest()
  207. #hmac() 完一定要decode()和 python 2 hmac不一样
  208. signature = base64.b64encode(code).decode()
  209. return signature