阿里云语音合成(汉语英语)带UI界面的小程序(python)
一,项目说明
将汉文转汉语、英文转英语,同时又有逗号<###English###>,<,,,>和句号<...>标志符用于文件处理。其中英文包含在### 英文 ###中。
程序A:三个逗号<,,,>和三个句号<...>前面的句段独立成块小分段,同时三个句号<...>前面的句段划分成为另一种较大的分段。其中程序中有控制<,,,>和<...>重复次数的数值
程序A输入样例1:
1 ###bring###拿来,带来,,, 2 ###Bronze###青铜色的... 3 ###brush###刷;檫,,, 4 ###build###建筑;造,,, 5 ###building###建筑物;房屋;大楼...
程序A输出样例1:(下文为音频发音的内容)
1 bring拿来,带来bring拿来,带来 2 Bronze青铜色的Bronze青铜色的 3 4 bring拿来,带来Bronze青铜色的 5 6 brush刷;檫brush刷;檫 7 build建筑;造build建筑;造 8 building建筑物;房屋;大楼building建筑物;房屋;大楼 9 10 brush刷;檫build建筑;造building建筑物;房屋;大楼 11 12 bring拿来,带来Bronze青铜色的brush刷;檫build建筑;造building建筑物;房屋;大楼
程序B输入样例1:
###bring###拿来,带来,,, ###Bronze###青铜色的... ###brush###刷;檫,,, ###build###建筑;造,,, ###building###建筑物;房屋;大楼...
程序B输出样例1:(下文为音频发音的内容)
1 bring拿来,带来bring拿来,带来bring拿来,带来 2 3 Bronze青铜色的 4 5 brush刷;檫brush刷;檫brush刷;檫 6 build建筑;造build建筑;造造build建筑;造 7 8 building建筑物;房屋;大楼 9 10 bring拿来,带来Bronze青铜色的brush刷;檫build建筑;造building建筑物;房屋;大楼
备注:上文中的程序A、程序B都是使用的默认配置
二,界面解析
图1 主界面
图2 文本导入界面(支持txt和docx文件格式)
图3 参数设置界面
图4 近期调用统计图(更新2019-06-16,尾款到手不再更新)
三,源码开放
界面显示(主函数) ui2show.pyw
1 import tkinter as tk 2 import netWork 3 import split2summary 4 import tkinter.filedialog 5 import os 6 import shutil 7 import docx 8 from configobj import ConfigObj 9 from tkinter import ttk 10 from tkinter import messagebox 11 import struct 12 13 14 class ui2show(tk.Tk): 15 def __init__(self): 16 super().__init__() 17 18 rootPath = os.path.split(os.path.realpath(__file__))[0] 19 os.chdir(rootPath) 20 self.dictSpace = {0: \'chinese\', 1: \'english\'} 21 22 # *** 系统初始化检测网络 *** # 23 self.netWork = netWork.netWork() 24 self.netState, self.textShow = self.netWork.isConnected() 25 26 # *** 提前加载功能库 *** # 27 self.split2summary = split2summary.split2summary() 28 self.config = ConfigObj("config.ini", encoding=\'UTF8\') 29 #print(self.config) 30 31 self.vartext = tk.StringVar() 32 self.vartext.set(self.textShow) 33 self.geometry(\'597x100\') 34 self.resizable(0, 0) 35 self.title(\'文字处理&音频合成\') 36 self.fileFeedback = [] 37 38 self.homePage() 39 40 def homePage(self): # 默认主页 41 self.top1 = tk.Frame() 42 self.top1.pack(fill="x") 43 44 tk.Button(self.top1, text=\'文本导入\', width=27, command=self.file4manage).grid(row=0, column=0) 45 tk.Button(self.top1, text=\'参数设置\', width=27, command=self.config4set).grid(row=0, column=1) 46 tk.Button(self.top1, text=\'音频合成\', width=27, command=self.txt2run).grid(row=0, column=2) 47 tk.Label(self.top1, height=3, textvariable=self.vartext, bg=\'white\', font=(\'黑体\', 10), anchor=\'w\').grid(row=1, 48 column=0, 49 columnspan=3) 50 51 def file4manage(self): # 文件初始化 成功√ 52 path = tkinter.filedialog.askopenfilename(initialdir=\'C:\\Users\\Administrator\\Desktop\', filetypes=( 53 ("txt or docx files", "*.txt;*.docx"), ("All files", "*.*"))) 54 if path == "": 55 self.fileState, self.textShow, self.fileFeedback = False, \'未导入任何文件\', [] 56 else: # 已导入文件 57 p, f = os.path.split(path) 58 path_directory = os.path.dirname(os.path.realpath(__file__)) + \'\\data\\\' + str(os.path.splitext(f)[0]) 59 isExists = os.path.exists(path_directory) 60 if not isExists: # 如果不存在这个目录 61 os.makedirs(path_directory) # 创建一个新的路径 62 shutil.copyfile(path, path_directory + \'\\\' + f) 63 64 if str(os.path.splitext(f)[1]) == \'.txt\': 65 file_object = open(path, \'r\') 66 file_context = file_object.read() 67 file_object.close() 68 69 elif str(os.path.splitext(f)[1]) == \'.docx\': 70 document = docx.Document(path) 71 file_context = \'\' 72 for paragraph in document.paragraphs: 73 file_context += paragraph.text 74 self.fileState, self.textShow, self.fileFeedback = True, \'已导入文本数据\', [path_directory, file_context] 75 self.vartext.set(self.textShow) 76 77 def config4set(self): # 参数配置界面 78 self.top2 = tk.Toplevel() 79 self.top2.title(\'参数配置\') 80 81 self.txtShow = [] # 直接全部设置成int型文件 82 for i in range(16): 83 if i == 11 or 15: 84 self.txtShow.append(tk.StringVar()) 85 else: 86 self.txtShow.append(tk.IntVar()) 87 88 txtShow = [] 89 #print(self.config[\'txtA\']) 90 txtA = self.config[\'txtA\'] 91 for i in enumerate(txtA[\'name\']): 92 txtShow.append(int(txtA[i[1]])) 93 txtB = self.config[\'txtB\'] 94 for i in enumerate(txtB[\'name\']): 95 txtShow.append(int(txtB[i[1]])) 96 txtC = self.config[\'chinese\'] 97 for i in enumerate(txtC[\'name\']): 98 txtShow.append(int(txtC[i[1]])) 99 txtD = self.config[\'english\'] 100 for i in enumerate(txtD[\'name\']): 101 txtShow.append(int(txtD[i[1]])) 102 103 # print(txtShow) 104 for keyi, valuei in enumerate(txtShow): 105 self.txtShow[keyi].set(valuei) 106 107 tk.Label(self.top2, text=\'程序A\', width=30).grid(row=0, column=0, columnspan=2) 108 tk.Label(self.top2, text=\'逗号次数\', width=10).grid(row=1, column=0, columnspan=1) 109 tk.Label(self.top2, text=\'句号次数\', width=10).grid(row=2, column=0, columnspan=1) 110 tk.Label(self.top2, text=\'全部文本次数\', width=10).grid(row=3, column=0, columnspan=1) 111 tk.Label(self.top2, text=\'是否生成音频\', width=10).grid(row=4, column=0, columnspan=1) 112 tk.Entry(self.top2, textvariable=self.txtShow[0], width=10).grid(row=1, column=1) 113 tk.Entry(self.top2, textvariable=self.txtShow[1], width=10).grid(row=2, column=1) 114 tk.Entry(self.top2, textvariable=self.txtShow[2], width=10).grid(row=3, column=1) 115 checkA = tk.Checkbutton(self.top2, text="是", variable=self.txtShow[3], width=10) 116 checkA.select() 117 checkA.grid(column=1, row=4, sticky=tk.W) 118 119 tk.Label(self.top2, text=\'程序B\', width=30).grid(row=0, column=2, columnspan=2) 120 tk.Label(self.top2, text=\'逗号次数\', width=10).grid(row=1, column=2, columnspan=1) 121 tk.Label(self.top2, text=\'句号次数\', width=10).grid(row=2, column=2, columnspan=1) 122 tk.Label(self.top2, text=\'全部文本次数\', width=10).grid(row=3, column=2, columnspan=1) 123 tk.Label(self.top2, text=\'是否生成音频\', width=10).grid(row=4, column=2, columnspan=1) 124 tk.Entry(self.top2, textvariable=self.txtShow[4], width=10).grid(row=1, column=3) 125 tk.Entry(self.top2, textvariable=self.txtShow[5], width=10).grid(row=2, column=3) 126 tk.Entry(self.top2, textvariable=self.txtShow[6], width=10).grid(row=3, column=3) 127 checkB = tk.Checkbutton(self.top2, text="是", variable=self.txtShow[7], width=10) 128 checkB.select() 129 checkB.grid(column=3, row=4, sticky=tk.W) 130 131 tk.Label(self.top2, text=\'汉语\', width=10).grid(row=0, column=4, columnspan=2) 132 tk.Label(self.top2, text=\'音量\', width=10).grid(row=1, column=4, columnspan=1) 133 tk.Label(self.top2, text=\'语速\', width=10).grid(row=2, column=4, columnspan=1) 134 tk.Label(self.top2, text=\'语调\', width=10).grid(row=3, column=4, columnspan=1) 135 tk.Label(self.top2, text=\'发言人\', width=10).grid(row=4, column=4, columnspan=1) 136 tk.Entry(self.top2, textvariable=self.txtShow[8], width=13).grid(row=1, column=5) 137 tk.Entry(self.top2, textvariable=self.txtShow[9], width=13).grid(row=2, column=5) 138 tk.Entry(self.top2, textvariable=self.txtShow[10], width=13).grid(row=3, column=5) 139 chosenC = ttk.Combobox(self.top2, textvariable=self.txtShow[11], width=10) 140 chosenC[\'values\'] = ( 141 \'Xiaoyun\', \'Xiaogang\', \'Ruoxi\', \'Xiaomeng\', \'Xiaowei\', \'Amei\', \'Xiaoxue\', \'Siqi\', \'Sijia\', \'Sicheng\', 142 \'Siyue\', 143 \'Xiaomei\', \'Sitong\', \'Ninger\', \'Xiaobei\', \'Yina\', \'Sijing\', \'Shanshan\') 144 chosenC.current(txtShow[11]) 145 chosenC.grid(row=4, column=5) 146 147 tk.Label(self.top2, text=\'英语\', width=10).grid(row=0, column=6, columnspan=2) 148 tk.Label(self.top2, text=\'音量\', width=10).grid(row=1, column=6, columnspan=1) 149 tk.Label(self.top2, text=\'语速\', width=10).grid(row=2, column=6, columnspan=1) 150 tk.Label(self.top2, text=\'语调\', width=10).grid(row=3, column=6, columnspan=1) 151 tk.Label(self.top2, text=\'发言人\', width=10).grid(row=4, column=6, columnspan=1) 152 tk.Entry(self.top2, textvariable=self.txtShow[12], width=13).grid(row=1, column=7) 153 tk.Entry(self.top2, textvariable=self.txtShow[13], width=13).grid(row=2, column=7) 154 tk.Entry(self.top2, textvariable=self.txtShow[14], width=13).grid(row=3, column=7) 155 chosenD = ttk.Combobox(self.top2, textvariable=self.txtShow[15], width=10) 156 chosenD[\'values\'] = (\'Wendy\', \'William\', \'Halen\', \'Harry\') 157 chosenD.current(txtShow[15]) 158 chosenD.grid(row=4, column=7) 159 160 tk.Button(self.top2, text=\'确定\', command=self.config2ok, width=27).grid(row=5, column=0, columnspan=2) 161 tk.Button(self.top2, text=\'重置\', command=self.config2reset, width=27).grid(row=5, column=2, columnspan=2) 162 tk.Button(self.top2, text=\'帮助\', command=self.config2help, width=27).grid(row=5, column=4, columnspan=2) 163 164 # for keyi,valuei in enumerate(txtShow): 165 self.txtShow[3].set(txtShow[3]) 166 self.txtShow[7].set(txtShow[7]) 167 168 def config2ok(self): # 参数设置-成功√ 169 txtShow = [] 170 for i in self.txtShow: 171 txtShow.append(i.get()) 172 173 txtShow[11] = self.config[\'chinese\'][\'voice_parameter\'].index(txtShow[11]) 174 txtShow[15] = self.config[\'english\'][\'voice_parameter\'].index(txtShow[15]) 175 # print(\'txtShow:\',txtShow[3],txtShow[7]) 176 177 for i in enumerate(txtShow[:4]): 178 self.config[\'txtA\'][self.config[\'txtA\'][\'name\'][i[0]]] = i[1] 179 for i in enumerate(txtShow[4:8]): 180 self.config[\'txtB\'][self.config[\'txtB\'][\'name\'][i[0]]] = i[1] 181 for i in enumerate(txtShow[8:12]): 182 self.config[\'chinese\'][self.config[\'chinese\'][\'name\'][i[0]]] = i[1] 183 for i in enumerate(txtShow[12:16]): 184 self.config[\'english\'][self.config[\'english\'][\'name\'][i[0]]] = i[1] 185 self.config.write() 186 187 def config2reset(self): # 恢复出厂设置 成功√ 188 for i in [\'txtA\', \'txtB\', \'chinese\', \'english\']: 189 for j in self.config[i][\'name\']: 190 self.config[i][j] = self.config[i][\'default_\' + j][1] 191 self.config.write() 192 193 txtShow = [] # 获取最新的参数配置并更新界面数据 194 txtA = self.config[\'txtA\'] 195 for i in enumerate(txtA[\'name\']): 196 txtShow.append(int(txtA[i[1]])) 197 txtB = self.config[\'txtB\'] 198 for i in enumerate(txtB[\'name\']): 199 txtShow.append(int(txtB[i[1]])) 200 txtC = self.config[\'chinese\'] 201 for i in enumerate(txtC[\'name\']): 202 txtShow.append(int(txtC[i[1]])) 203 txtD = self.config[\'english\'] 204 for i in enumerate(txtD[\'name\']): 205 txtShow.append(int(txtD[i[1]])) 206 207 for keyi, valuei in enumerate(txtShow): 208 self.txtShow[keyi].set(valuei) 209 self.txtShow[11].set(self.config[\'chinese\'][\'voice_parameter\'][txtShow[11]]) 210 self.txtShow[15].set(self.config[\'english\'][\'voice_parameter\'][txtShow[15]]) 211 212 def config2help(self): 213 tk.messagebox.showinfo("参数设置帮助", "语音合成参数设置范围:\n1,音量范围0~100;\n2,语速范围-500~500;\n3,语调范围-500~500;") 214 215 def txt2run(self): 216 if len(self.fileFeedback) == 0: 217 self.textShow = \'没有导入文本文件\n请先进行{文本导入}\' 218 self.vartext.set(self.textShow) 219 else: # 已正常导入【路径,文本】 220 # self.dictSpace 221 dataASet = [] 222 for i in self.config[\'txtA\'][\'name\']: 223 dataASet.append(int(self.config[\'txtA\'][i])) 224 dataBSet = [] 225 for i in self.config[\'txtB\'][\'name\']: 226 dataBSet.append(int(self.config[\'txtB\'][i])) 227 if dataASet[-1]+dataBSet[-1]==0: 228 self.textShow=\'设置中未勾选{是否生成音频}\n请先勾选相关选项再做操作\' 229 self.vartext.set(self.textShow) 230 return None 231 txt_value, txt_state = self.split2summary.txt2split(self.fileFeedback[1]) 232 self.textShow = \'正在将文字转化为音频...\' 233 self.vartext.set(self.textShow) 234 for keyi, valuei in enumerate(txt_value): 235 for keyj, valuej in enumerate(valuei): 236 for keyk, valuek in enumerate(valuej): 237 txt_value[keyi][keyj][keyk] = self.netWork.txt2audio(txt_value[keyi][keyj][keyk], 238 self.dictSpace[ 239 txt_state[keyi][keyj][keyk]]) 240 241 # *** 合成音频完整性测试 *** # 测试成功√ 242 # audioTest=[] 243 # for keyi, valuei in enumerate(txt_value): # 句号 244 # for keyj, valuej in enumerate(valuei): 245 # for keyk, valuek in enumerate(valuej): 246 #
请发表评论