# -*- coding: utf-8 -*- from __future__ import division from ..__load__ import * 'Tencent ASR && TTS API' __author__ = 'Charles Li, Joseph Pan' import time import uuid import json import random import requests import hmac import base64 import urllib from hashlib import sha1 class Tencent(object): __slots__ = 'SECRET_ID', 'SECRET_KEY', 'SourceType', 'URL', 'VoiceFormat', 'PrimaryLanguage', 'Text', 'VoiceType', 'Region' def init(self, SECRET_ID, SECRET_KEY): self.SECRET_KEY, self.SECRET_ID = SECRET_KEY, SECRET_ID return self @property def secret_id(self): return self.SECRET_ID @secret_id.setter def secret_id(self, SECRET_ID): if not isinstance(SECRET_ID, str): raise ValueError('SecretId must be a string!') if len(SECRET_ID)==0: raise ValueError('SecretId can not be empty!') self.SECRET_ID = SECRET_ID @property def secret_key(self): return self.SECRET_KEY @secret_key.setter def secret_key(self, SECRET_KEY): if not isinstance(SECRET_KEY, str): raise ValueError('SecretKey must be a string!') if len(SECRET_KEY)==0: raise ValueError('SecretKey can not be empty!') self.SECRET_KEY = SECRET_KEY @property def source_type(self): return self.sourcetype @source_type.setter def source_type(self, SourceType): if not isinstance(SourceType, str): raise ValueError('SecretType must be an string!') if len(SourceType)==0: raise ValueError('SourceType can not be empty!') self.SourceType = SourceType @property def url(self): return self.URL @url.setter def url(self, URL): if not isinstance(URL, str): raise ValueError('url must be an string!') if len(URL)==0: raise ValueError('url can not be empty!') self.URL = URL @property def voiceformat(self): return self.VoiceFormat @voiceformat.setter def voiceformat(self, VoiceFormat): if not isinstance(VoiceFormat, str): raise ValueError('voiceformat must be an string!') if len(VoiceFormat)==0: raise ValueError('voiceformat can not be empty!') self.VoiceFormat = VoiceFormat @property def text(self): return self.Text @text.setter def text(self, Text): if not isinstance(Text, str): raise ValueError('text must be an string!') if len(Text)==0: raise ValueError('text can not be empty!') self.Text = Text @property def region(self): return self.Region @region.setter def region(self, Region): if not isinstance(Region, str): raise ValueError('region must be an string!') if len(Region)==0: raise ValueError('region can not be empty!') self.Region = Region @property def primarylanguage(self): return self.PrimaryLanguage @primarylanguage.setter def primarylanguage(self, PrimaryLanguage): self.PrimaryLanguage = PrimaryLanguage @property def voicetype(self): return self.VoiceType @voicetype.setter def voicetype(self, VoiceType): self.VoiceType = VoiceType def TTS(self, text, voicetype, primarylanguage, region): self.text, self.voicetype, self.primarylanguage, self.region = text, voicetype, primarylanguage, region return self.textToSpeech() def textToSpeech(self): #生成body def make_body(config_dict, sign_encode): ##注意URL编码的时候分str编码,整段编码会丢data body = '' for a, b in config_dict: body += self.quote(a) + '=' + self.quote(str(b)) + '&' return body + 'Signature=' + sign_encode HOST = 'aai.tencentcloudapi.com' config_dict= { 'Action' : 'TextToVoice', 'Version' : '2018-05-22', 'ProjectId' : 0, 'Region' : self.Region, 'VoiceType' : self.VoiceType, 'Timestamp' : int(time.time()), 'Nonce' : random.randint(100000, 200000), 'SecretId' : self.SECRET_ID, 'Text' : self.Text, 'PrimaryLanguage': self.PrimaryLanguage, 'ModelType' : 1, 'SessionId' : uuid.uuid1() } #按key排序 config_dict = sorted(config_dict.items()) signstr = self.formatSignString(config_dict) sign_encode = self.quote(self.encode_sign(signstr, self.SECRET_KEY)) body = make_body(config_dict, sign_encode) #Get URL req_url = "https://aai."+self.region+".tencentcloudapi.com" header = { 'Host' : HOST, 'Content-Type' : 'application/x-www-form-urlencoded', 'Charset' : 'UTF-8' } request = requests.post(req_url, headers = header, data = body) #有些音频utf8解码失败,存在编码错误 s = request.content.decode("utf8","ignore") return json.loads(s) def quote(self, str): if Demeter.checkPy3(): return urllib.parse.quote(str) else: return urllib.quote(str) def ASR(self, URL, voiceformat, sourcetype, region): self.url, self.voiceformat, self.source_type, self.region = URL, voiceformat, sourcetype, region return self.oneSentenceRecognition() def oneSentenceRecognition(self): #生成body def make_body(config_dict, sign_encode): ##注意URL编码的时候分str编码,整段编码会丢data body = '' for a, b in config_dict: body += self.quote(a) + '=' + self.quote(str(b)) + '&' return body + 'Signature=' + sign_encode HOST = 'aai.tencentcloudapi.com' config_dict= { 'Action' : 'SentenceRecognition', 'Version' : '2018-05-22', 'Region' : self.Region, 'ProjectId' : 0, 'SubServiceType' : 2, 'EngSerViceType' : '16k', 'VoiceFormat' : self.VoiceFormat, 'UsrAudioKey' : random.randint(0, 20), 'Timestamp' : int(time.time()), 'Nonce' : random.randint(100000, 200000), 'SecretId' : self.SECRET_ID, 'SourceType' : self.SourceType } if self.SourceType == '0': config_dict['Url'] = self.quote(str(self.url)) else: #不能大于1M file_path = self.URL file = open(file_path, 'rb') content = file.read() config_dict['DataLen'] = len(content) config_dict['Data'] = base64.b64encode(content).decode() #config_dict['Data'] = content file.close() #按key排序 config_dict = sorted(config_dict.items()) signstr = self.formatSignString(config_dict) sign_encode = self.quote(self.encode_sign(signstr, self.SECRET_KEY)) body = make_body(config_dict, sign_encode) #Get URL req_url = "https://aai."+self.region+".tencentcloudapi.com" header = { 'Host' : HOST, 'Content-Type' : 'application/x-www-form-urlencoded', 'Charset' : 'UTF-8' } request = requests.post(req_url, headers = header, data = body) #有些音频utf8解码失败,存在编码错误 s = request.content.decode("utf8","ignore") return s #拼接url和参数 def formatSignString(self, config_dict): signstr="POSTaai.tencentcloudapi.com/?" argArr = [] for a, b in config_dict: argArr.append(a + "=" + str(b)) config_str = "&".join(argArr) return signstr + config_str #生成签名 def encode_sign(self, signstr, SECRET_KEY): myhmac = hmac.new(SECRET_KEY.encode(), signstr.encode(), sha1) code = myhmac.digest() #hmac() 完一定要decode()和 python 2 hmac不一样 signature = base64.b64encode(code).decode() return signature