139 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			139 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import http.client | |||
|  | import urllib.parse | |||
|  | import json | |||
|  | from aliyunsdkcore.client import AcsClient | |||
|  | from aliyunsdkcore.request import CommonRequest | |||
|  | from core.authorize_tb import Authorize_Tb | |||
|  | import time | |||
|  | from utils import util, config_util | |||
|  | from utils import config_util as cfg | |||
|  | import wave | |||
|  | 
 | |||
|  | class Speech: | |||
|  |     def __init__(self): | |||
|  |         self.key_ali_nls_key_id = cfg.key_ali_tss_key_id | |||
|  |         self.key_ali_nls_key_secret = cfg.key_ali_tss_key_secret | |||
|  |         self.ali_nls_app_key = cfg.key_ali_tss_app_key | |||
|  |         self.token = None | |||
|  |         self.authorize_tb = Authorize_Tb() | |||
|  |         self.__history_data = [] | |||
|  | 
 | |||
|  |     def connect(self): | |||
|  |         pass | |||
|  | 
 | |||
|  |     def __get_history(self, voice_name, style, text): | |||
|  |         for data in self.__history_data: | |||
|  |             if data[0] == voice_name and data[1] == style and data[2] == text: | |||
|  |                 return data[3] | |||
|  |         return None     | |||
|  | 
 | |||
|  |     def set_token(self): | |||
|  |         token = self.__check_token() | |||
|  |         if token is None or token == 'expired': | |||
|  |             token_info = self.__get_token() | |||
|  |             if token_info is not None and  token_info['Id']  is not None: | |||
|  |                 expires_timedelta = token_info['ExpireTime'] | |||
|  |                 expiry_timestamp_in_milliseconds = expires_timedelta * 1000 | |||
|  |                 if token == 'expired': | |||
|  |                     self.authorize_tb.update_by_userid(self.key_ali_nls_key_id, token_info['Id'], expiry_timestamp_in_milliseconds) | |||
|  |                 else: | |||
|  |                     self.authorize_tb.add(self.key_ali_nls_key_id, token_info['Id'], expiry_timestamp_in_milliseconds) | |||
|  |                 token = token_info['Id'] | |||
|  |             else: | |||
|  |                 print(f"请检查阿里云tts对接") | |||
|  |                 token = None | |||
|  |                  | |||
|  |         self.token = token | |||
|  |      | |||
|  | 
 | |||
|  |     def __check_token(self): | |||
|  |         self.authorize_tb.init_tb() | |||
|  |         info = self.authorize_tb.find_by_userid(self.key_ali_nls_key_id) | |||
|  |         if info is not None: | |||
|  |             if info[1] >= int(time.time())*1000: | |||
|  |                 return info[0] | |||
|  |             else: | |||
|  |                 return 'expired' | |||
|  |         else: | |||
|  |             return None  | |||
|  | 
 | |||
|  |     def __get_token(self): | |||
|  |         try: | |||
|  |             global _token | |||
|  |             __client = AcsClient( | |||
|  |                 self.key_ali_nls_key_id, | |||
|  |                 self.key_ali_nls_key_secret, | |||
|  |                 "cn-shanghai" | |||
|  |             ) | |||
|  | 
 | |||
|  |             __request = CommonRequest() | |||
|  |             __request.set_method('POST') | |||
|  |             __request.set_domain('nls-meta.cn-shanghai.aliyuncs.com') | |||
|  |             __request.set_version('2019-02-28') | |||
|  |             __request.set_action_name('CreateToken') | |||
|  |             info = json.loads(__client.do_action_with_exception(__request)) | |||
|  |             _token = info['Token'] | |||
|  |             return info['Token'] | |||
|  |         except Exception as e: | |||
|  |             print(f"阿里云tts对接有误: {str(e)}") | |||
|  |             return None | |||
|  | 
 | |||
|  |      | |||
|  | 
 | |||
|  |     def to_sample(self, text, style) : | |||
|  |         try: | |||
|  |             history = self.__get_history(config_util.config["attribute"]["voice"], style, text) | |||
|  |             if history is not None: | |||
|  |                 return history | |||
|  |             self.set_token() | |||
|  |             if self.token != None:        | |||
|  |                 host = 'nls-gateway-cn-shanghai.aliyuncs.com' | |||
|  |                 url = 'https://' + host + '/stream/v1/tts' | |||
|  |                 # 设置HTTPS Headers。 | |||
|  |                 httpHeaders = { | |||
|  |                     'Content-Type': 'application/json' | |||
|  |                     } | |||
|  |                 text = f"<speak><break time='0.2s'/>{text}</speak>" | |||
|  |                 # 设置HTTPS Body。 | |||
|  |                 body = {'appkey': self.ali_nls_app_key, 'token': self.token,'speech_rate':0, 'text': text, 'format': 'wav', 'sample_rate': 16000, 'voice': config_util.config["attribute"]["voice"]} | |||
|  |                 body = json.dumps(body) | |||
|  |                 conn = http.client.HTTPSConnection(host) | |||
|  |                 conn.request(method='POST', url=url, body=body, headers=httpHeaders) | |||
|  |                 # 处理服务端返回的响应。 | |||
|  |                 response = conn.getresponse() | |||
|  |                 tt = time.time() | |||
|  |                 contentType = response.getheader('Content-Type') | |||
|  |                 body = response.read() | |||
|  |                 if 'audio/mpeg' == contentType : | |||
|  |                     file_url = './samples/sample-' + str(int(time.time() * 1000)) + '.wav' | |||
|  |                     with wave.open(file_url, 'wb') as wf: | |||
|  |                         wf.setnchannels(1) | |||
|  |                         wf.setsampwidth(2) | |||
|  |                         wf.setframerate(16000) | |||
|  |                         wf.writeframes(body) | |||
|  |                  | |||
|  |                 else : | |||
|  |                     util.log(1, "[x] 语音转换失败!") | |||
|  |                     util.log(1, "[x] 原因: " + str(body)) | |||
|  |                     file_url = None | |||
|  |                     return file_url | |||
|  |                 conn.close() | |||
|  |                 print(time.time() - tt)    | |||
|  |                 return file_url | |||
|  |             else: | |||
|  |                 util.log(1, "[x] 语音转换失败!") | |||
|  |                 util.log(1, "[x] 原因: 对接有误" ) | |||
|  |                 file_url = None | |||
|  |                 return file_url | |||
|  |         except Exception as e : | |||
|  |                 util.log(1, "[x] 语音转换失败!") | |||
|  |                 util.log(1, "[x] 原因: " + str(str(e))) | |||
|  |                 file_url = None | |||
|  |                 return file_url | |||
|  | 
 | |||
|  | 
 | |||
|  |     def close(self): | |||
|  |        pass | |||
|  | 
 | |||
|  | 
 |