148 lines
5.5 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tempfile
import os
import json
import nls
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import time
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parent.parent.parent))
from tools.log import CustomLogger
import os
current_file_path = os.path.abspath(__file__)
Language_Path = os.path.dirname(os.path.dirname(os.path.dirname(current_file_path)))
MassageRobot_Dobot_Path = os.path.dirname(Language_Path)
print("MassageRobot_Dobot_Path:",MassageRobot_Dobot_Path)
sys.path.append(MassageRobot_Dobot_Path)
from VortXDB.client import VTXClient
# aliyun语音合成
class SpeechSynthesizer:
def __init__(self):
vtxdb = VTXClient()
self.url = vtxdb.get("robot_config", "Language.Speech_processor.aliyun_synthesize_config.url")
self.appkey = vtxdb.get("robot_config", "Language.Speech_processor.aliyun_synthesize_config.appkey")
self.api_id = vtxdb.get("robot_config", "Language.Speech_processor.aliyun_synthesize_config.api_id")
self.api_key = vtxdb.get("robot_config", "Language.Speech_processor.aliyun_synthesize_config.api_key")
self.logger = CustomLogger()
self.token = self.get_Text_To_Speech_token()
def on_metainfo(self, message, *args):
self.phoneme = message # 记录音素级别的时间戳
# print("on_metainfo message=>{}".format(message))
return
def on_error(self, message, *args):
print("on_error args=>{}".format(args))
def on_close(self, *args):
# print("on_close: args=>{}".format(args))
try:
self.__file.close()
except Exception as e:
print("close failed:", e)
def on_data(self, data, *args):
try:
self.__file.write(data)
except Exception as e:
print("write data failed:", e)
def on_completed(self, message, *args):
# print("on_completed:args=>{} message=>{}".format(args, message))
return
def speech_synthesize(self, text, speech_rate = -250, output_file=None):
try:
time1=time.time()
if output_file:
self.__file = open(output_file, "wb")
else:
# Create a temporary file
fd, tmpfile_name = tempfile.mkstemp(suffix='.mp3')
os.close(fd) # Close the file descriptor
self.__file = open(tmpfile_name, "wb")
self.__text = text
self.__speech_rate = speech_rate
self.__voice = "zhimiao_emo"
self.ex = {'enable_subtitle':True,"enable_phoneme_timestamp":True} # 记录音素级别的时间戳
tts = nls.NlsSpeechSynthesizer(
url=self.url,
token=self.token,
appkey=self.appkey,
on_metainfo=self.on_metainfo,
on_data=self.on_data,
on_completed=self.on_completed,
on_error=self.on_error,
on_close=self.on_close
)
result = tts.start(self.__text, voice=self.__voice, speech_rate=self.__speech_rate, aformat="mp3",ex=self.ex)
# Close the file after writing
self.__file.close()
# Return the path to the temporary file
time2=time.time()
# self.logger.log_blue(f"语音合成时间:{time2-time1}")
return output_file if output_file else tmpfile_name
except Exception as e:
self.logger.log_error("Failded to Synthesizer")
return
# 语音合成获取tokenaliyun
def get_Text_To_Speech_token(self):
client = AcsClient(
self.api_id,
self.api_key,
"cn-shanghai"
)
# 创建request并设置参数。
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')
try:
response = client.do_action_with_exception(request)
# print(response)
jss = json.loads(response)
if 'Token' in jss and 'Id' in jss['Token']:
token = jss['Token']['Id']
expireTime = jss['Token']['ExpireTime']
self.logger.log_info("Successfully get Synthesizer token!!!")
return token
except Exception as e:
# print("Error occurred while getting Synthesizer token")
self.logger.log_error(f"{e}")
raise e
if __name__ == '__main__':
import argparse
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parent.parent.parent))
from tools.yaml_operator import read_yaml
from Audio_player import AudioPlayer
def parse_args():
parser = argparse.ArgumentParser(description='Speech processor')
parser.add_argument('--synthesizer_config_path', type=str, default='/home/jsfb/jsfb_ws/MassageRobot_Dobot/Language/Speech_processor/config/aliyun_synthesize_config.yaml')
args = parser.parse_args()
return args
args = parse_args()
config = read_yaml(args.synthesizer_config_path)
synthesizer = SpeechSynthesizer()
player = AudioPlayer()
# #天气和新闻
# file = synthesizer.speech_synthesize("现在使用砭石手法为您。", output_file="xxx.mp3")
# 默认路径
file = synthesizer.speech_synthesize("现在使用砭石手法为您。")
# print(file)
player.play(file,True)
# print(synthesizer.phoneme)