一,項目說明
将漢文轉漢語、英文轉英語,同時又有逗号<###English###>,<,,,>和句号<...>标志符用于檔案處理。其中英文包含在### 英文 ###中。
程式A:三個逗号<,,,>和三個句号<...>前面的句段獨立成塊小分段,同時三個句号<...>前面的句段劃分成為另一種較大的分段。其中程式中有控制<,,,>和<...>重複次數的數值
程式A輸入樣例1:
1 ###bring###拿來,帶來,,,
2 ###Bronze###青銅色的...
3 ###brush###刷;檫,,,
4 ###build###建築;造,,,
5 ###building###建築物;房屋;大樓...
程式A輸出樣例1:(下文為音頻發音的内容)
程式A輸出樣例1:(下文為音頻發音的内容)
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:
###Bronze###青銅色的...
###brush###刷;檫,,,
###build###建築;造,,,
###building###建築物;房屋;大樓...
程式B輸出樣例1:(下文為音頻發音的内容)
Bronze青銅色的
brush刷;檫brush刷;檫brush刷;檫
build建築;造build建築;造造build建築;造
building建築物;房屋;大樓
bring拿來,帶來Bronze青銅色的brush刷;檫build建築;造building建築物;房屋;大樓
備注:上文中的程式A、程式B都是使用的預設配置
二,界面解析

圖1 主界面
圖2 文本導入界面(支援txt和docx檔案格式)
圖3 參數設定界面
圖4 近期調用統計圖(更新2019-06-16,尾款到手不再更新)
三,源碼開放
界面顯示(主函數) ui2show.pyw
import netWork
import split2summary
import tkinter.filedialog
import os
import shutil
import docx
from configobj import ConfigObj
from tkinter import ttk
from tkinter import messagebox
import struct
class ui2show(tk.Tk):
def __init__(self):
super().__init__()
rootPath = os.path.split(os.path.realpath(__file__))[0]
os.chdir(rootPath)
self.dictSpace = {0: 'chinese', 1: 'english'}
# *** 系統初始化檢測網絡 *** #
self.netWork = netWork.netWork()
self.netState, self.textShow = self.netWork.isConnected()
# *** 提前加載功能庫 *** #
self.split2summary = split2summary.split2summary()
self.config = ConfigObj("config.ini", encoding='UTF8')
#print(self.config)
self.vartext = tk.StringVar()
self.vartext.set(self.textShow)
self.geometry('597x100')
self.resizable(0, 0)
self.title('文字處理&音頻合成')
self.fileFeedback = []
self.homePage()
def homePage(self): # 預設首頁
self.top1 = tk.Frame()
self.top1.pack(fill="x")
tk.Button(self.top1, text='文本導入', width=27, command=self.file4manage).grid(row=0, column=0)
tk.Button(self.top1, text='參數設定', width=27, command=self.config4set).grid(row=0, column=1)
tk.Button(self.top1, text='音頻合成', width=27, command=self.txt2run).grid(row=0, column=2)
tk.Label(self.top1, height=3, textvariable=self.vartext, bg='white', font=('黑體', 10), anchor='w').grid(row=1,
column=0,
columnspan=3)
def file4manage(self): # 檔案初始化 成功√
path = tkinter.filedialog.askopenfilename(initialdir='C:\\Users\\Administrator\\Desktop', filetypes=(
("txt or docx files", "*.txt;*.docx"), ("All files", "*.*")))
if path == "":
self.fileState, self.textShow, self.fileFeedback = False, '未導入任何檔案', []
else: # 已導入檔案
p, f = os.path.split(path)
path_directory = os.path.dirname(os.path.realpath(__file__)) + '\\data\\' + str(os.path.splitext(f)[0])
isExists = os.path.exists(path_directory)
if not isExists: # 如果不存在這個目錄
os.makedirs(path_directory) # 建立一個新的路徑
shutil.copyfile(path, path_directory + '\\' + f)
if str(os.path.splitext(f)[1]) == '.txt':
file_object = open(path, 'r')
file_context = file_object.read()
file_object.close()
elif str(os.path.splitext(f)[1]) == '.docx':
document = docx.Document(path)
file_context = ''
for paragraph in document.paragraphs:
file_context += paragraph.text
self.fileState, self.textShow, self.fileFeedback = True, '已導入文本資料', [path_directory, file_context]
self.vartext.set(self.textShow)
def config4set(self): # 參數配置界面
self.top2 = tk.Toplevel()
self.top2.title('參數配置')
self.txtShow = [] # 直接全部設定成int型檔案
for i in range(16):
if i == 11 or 15:
self.txtShow.append(tk.StringVar())
else:
self.txtShow.append(tk.IntVar())
txtShow = []
#print(self.config['txtA'])
txtA = self.config['txtA']
for i in enumerate(txtA['name']):
txtShow.append(int(txtA[i[1]]))
txtB = self.config['txtB']
for i in enumerate(txtB['name']):
txtShow.append(int(txtB[i[1]]))
txtC = self.config['chinese']
for i in enumerate(txtC['name']):
txtShow.append(int(txtC[i[1]]))
txtD = self.config['english']
for i in enumerate(txtD['name']):
txtShow.append(int(txtD[i[1]]))
# print(txtShow)
for keyi, valuei in enumerate(txtShow):
self.txtShow[keyi].set(valuei)
tk.Label(self.top2, text='程式A', width=30).grid(row=0, column=0, columnspan=2)
tk.Label(self.top2, text='逗号次數', width=10).grid(row=1, column=0, columnspan=1)
tk.Label(self.top2, text='句号次數', width=10).grid(row=2, column=0, columnspan=1)
tk.Label(self.top2, text='全部文本次數', width=10).grid(row=3, column=0, columnspan=1)
tk.Label(self.top2, text='是否生成音頻', width=10).grid(row=4, column=0, columnspan=1)
tk.Entry(self.top2, textvariable=self.txtShow[0], width=10).grid(row=1, column=1)
tk.Entry(self.top2, textvariable=self.txtShow[1], width=10).grid(row=2, column=1)
tk.Entry(self.top2, textvariable=self.txtShow[2], width=10).grid(row=3, column=1)
checkA = tk.Checkbutton(self.top2, text="是", variable=self.txtShow[3], width=10)
checkA.select()
checkA.grid(column=1, row=4, sticky=tk.W)
tk.Label(self.top2, text='程式B', width=30).grid(row=0, column=2, columnspan=2)
tk.Label(self.top2, text='逗号次數', width=10).grid(row=1, column=2, columnspan=1)
tk.Label(self.top2, text='句号次數', width=10).grid(row=2, column=2, columnspan=1)
tk.Label(self.top2, text='全部文本次數', width=10).grid(row=3, column=2, columnspan=1)
tk.Label(self.top2, text='是否生成音頻', width=10).grid(row=4, column=2, columnspan=1)
tk.Entry(self.top2, textvariable=self.txtShow[4], width=10).grid(row=1, column=3)
tk.Entry(self.top2, textvariable=self.txtShow[5], width=10).grid(row=2, column=3)
tk.Entry(self.top2, textvariable=self.txtShow[6], width=10).grid(row=3, column=3)
checkB = tk.Checkbutton(self.top2, text="是", variable=self.txtShow[7], width=10)
checkB.select()
checkB.grid(column=3, row=4, sticky=tk.W)
tk.Label(self.top2, text='漢語', width=10).grid(row=0, column=4, columnspan=2)
tk.Label(self.top2, text='音量', width=10).grid(row=1, column=4, columnspan=1)
tk.Label(self.top2, text='語速', width=10).grid(row=2, column=4, columnspan=1)
tk.Label(self.top2, text='語調', width=10).grid(row=3, column=4, columnspan=1)
tk.Label(self.top2, text='發言人', width=10).grid(row=4, column=4, columnspan=1)
tk.Entry(self.top2, textvariable=self.txtShow[8], width=13).grid(row=1, column=5)
tk.Entry(self.top2, textvariable=self.txtShow[9], width=13).grid(row=2, column=5)
tk.Entry(self.top2, textvariable=self.txtShow[10], width=13).grid(row=3, column=5)
chosenC = ttk.Combobox(self.top2, textvariable=self.txtShow[11], width=10)
chosenC['values'] = (
'Xiaoyun', 'Xiaogang', 'Ruoxi', 'Xiaomeng', 'Xiaowei', 'Amei', 'Xiaoxue', 'Siqi', 'Sijia', 'Sicheng',
'Siyue',
'Xiaomei', 'Sitong', 'Ninger', 'Xiaobei', 'Yina', 'Sijing', 'Shanshan')
chosenC.current(txtShow[11])
chosenC.grid(row=4, column=5)
tk.Label(self.top2, text='英語', width=10).grid(row=0, column=6, columnspan=2)
tk.Label(self.top2, text='音量', width=10).grid(row=1, column=6, columnspan=1)
tk.Label(self.top2, text='語速', width=10).grid(row=2, column=6, columnspan=1)
tk.Label(self.top2, text='語調', width=10).grid(row=3, column=6, columnspan=1)
tk.Label(self.top2, text='發言人', width=10).grid(row=4, column=6, columnspan=1)
tk.Entry(self.top2, textvariable=self.txtShow[12], width=13).grid(row=1, column=7)
tk.Entry(self.top2, textvariable=self.txtShow[13], width=13).grid(row=2, column=7)
tk.Entry(self.top2, textvariable=self.txtShow[14], width=13).grid(row=3, column=7)
chosenD = ttk.Combobox(self.top2, textvariable=self.txtShow[15], width=10)
chosenD['values'] = ('Wendy', 'William', 'Halen', 'Harry')
chosenD.current(txtShow[15])
chosenD.grid(row=4, column=7)
tk.Button(self.top2, text='确定', command=self.config2ok, width=27).grid(row=5, column=0, columnspan=2)
tk.Button(self.top2, text='重置', command=self.config2reset, width=27).grid(row=5, column=2, columnspan=2)
tk.Button(self.top2, text='幫助', command=self.config2help, width=27).grid(row=5, column=4, columnspan=2)
# for keyi,valuei in enumerate(txtShow):
self.txtShow[3].set(txtShow[3])
self.txtShow[7].set(txtShow[7])
def config2ok(self): # 參數設定-成功√
txtShow = []
for i in self.txtShow:
txtShow.append(i.get())
txtShow[11] = self.config['chinese']['voice_parameter'].index(txtShow[11])
txtShow[15] = self.config['english']['voice_parameter'].index(txtShow[15])
# print('txtShow:',txtShow[3],txtShow[7])
for i in enumerate(txtShow[:4]):
self.config['txtA'][self.config['txtA']['name'][i[0]]] = i[1]
for i in enumerate(txtShow[4:8]):
self.config['txtB'][self.config['txtB']['name'][i[0]]] = i[1]
for i in enumerate(txtShow[8:12]):
self.config['chinese'][self.config['chinese']['name'][i[0]]] = i[1]
for i in enumerate(txtShow[12:16]):
self.config['english'][self.config['english']['name'][i[0]]] = i[1]
self.config.write()
def config2reset(self): # 恢複出廠設定 成功√
for i in ['txtA', 'txtB', 'chinese', 'english']:
for j in self.config[i]['name']:
self.config[i][j] = self.config[i]['default_' + j][1]
self.config.write()
txtShow = [] # 擷取最新的參數配置并更新界面資料
txtA = self.config['txtA']
for i in enumerate(txtA['name']):
txtShow.append(int(txtA[i[1]]))
txtB = self.config['txtB']
for i in enumerate(txtB['name']):
txtShow.append(int(txtB[i[1]]))
txtC = self.config['chinese']
for i in enumerate(txtC['name']):
txtShow.append(int(txtC[i[1]]))
txtD = self.config['english']
for i in enumerate(txtD['name']):
txtShow.append(int(txtD[i[1]]))
for keyi, valuei in enumerate(txtShow):
self.txtShow[keyi].set(valuei)
self.txtShow[11].set(self.config['chinese']['voice_parameter'][txtShow[11]])
self.txtShow[15].set(self.config['english']['voice_parameter'][txtShow[15]])
def config2help(self):
tk.messagebox.showinfo("參數設定幫助", "語音合成參數設定範圍:\n1,音量範圍0~100;\n2,語速範圍-500~500;\n3,語調範圍-500~500;")
def txt2run(self):
if len(self.fileFeedback) == 0:
self.textShow = '沒有導入文本檔案\n請先進行{文本導入}'
self.vartext.set(self.textShow)
else: # 已正常導入【路徑,文本】
# self.dictSpace
dataASet = []
for i in self.config['txtA']['name']:
dataASet.append(int(self.config['txtA'][i]))
dataBSet = []
for i in self.config['txtB']['name']:
dataBSet.append(int(self.config['txtB'][i]))
if dataASet[-1]+dataBSet[-1]==0:
self.textShow='設定中未勾選{是否生成音頻}\n請先勾選相關選項再做操作'
self.vartext.set(self.textShow)
return None
txt_value, txt_state = self.split2summary.txt2split(self.fileFeedback[1])
self.textShow = '正在将文字轉化為音頻...'
self.vartext.set(self.textShow)
for keyi, valuei in enumerate(txt_value):
for keyj, valuej in enumerate(valuei):
for keyk, valuek in enumerate(valuej):
txt_value[keyi][keyj][keyk] = self.netWork.txt2audio(txt_value[keyi][keyj][keyk],
self.dictSpace[
txt_state[keyi][keyj][keyk]])
# *** 合成音頻完整性測試 *** # 測試成功√
# audioTest=[]
# for keyi, valuei in enumerate(txt_value): # 句号
# for keyj, valuej in enumerate(valuei):
# for keyk, valuek in enumerate(valuej):
# pathTest = self.fileFeedback[0] + '\\' + self.fileFeedback[0].split('\\')[-1] + str(keyi)+str(keyj)+str(keyk) +'Test.wav'
# with open(pathTest, mode='wb') as f:
# f.write(txt_value[keyi][keyj][keyk])
# *** 音頻檔案合并成逗号分段 *** #
wav_format = txt_value[0][0][0][:44] # wav音頻檔案的幀頭資訊,後續儲存檔案需要進行二次修改
for keyi, valuei in enumerate(txt_value): # 句号
for keyj, valuej in enumerate(valuei):
# str_comma = []
for keyk, valuek in enumerate(valuej):
if keyk == 0:
str_comma = txt_value[keyi][keyj][keyk]
else:
str_comma += txt_value[keyi][keyj][keyk][44:]
txt_value[keyi][keyj] = str_comma
# *** 合成音頻英漢合并完整性測試 *** # 測試成功√
# audioTest=[]
# for keyi, valuei in enumerate(txt_value): # 句号
# for keyj, valuej in enumerate(valuei):
# pathTest = self.fileFeedback[0] + '\\' + self.fileFeedback[0].split('\\')[-1] + 'comma'+str(keyi)+str(keyj)+'Test.wav'
# with open(pathTest, mode='wb') as f:
# f.write(txt_value[keyi][keyj])
# *** 程式A *** #
if dataASet[-1]:
self.textShow = '正在生成音頻A'
self.vartext.set(self.textShow)
# print('runA',dataASet)
pathA = self.fileFeedback[0] + '\\' + self.fileFeedback[0].split('\\')[-1] + 'A.wav'
audioA = self.split2summary.programA(txt_value, dataASet)
audioA_len = len(audioA)
wav_format = wav_format[:4] + struct.pack('<L', audioA_len + 44) + wav_format[8:]
wav_format = wav_format[:40] + struct.pack('<L', audioA_len) + wav_format[44:]
with open(pathA, mode='wb') as f:
f.write(wav_format + audioA)
self.textShow = '已生成音頻A'
self.vartext.set(self.textShow)
# *** 程式B *** #
if dataBSet[-1]:
self.textShow += '正在成音頻B'
self.vartext.set(self.textShow)
pathB = self.fileFeedback[0] + '\\' + self.fileFeedback[0].split('\\')[-1] + 'B.wav'
audioB = self.split2summary.programB(txt_value, dataBSet)
audioB_len = len(audioB)
wav_format = wav_format[:4] + struct.pack('<L', audioB_len + 44) + wav_format[8:]
wav_format = wav_format[:40] + struct.pack('<L', audioB_len) + wav_format[44:]
with open(pathB, mode='wb') as f:
f.write(wav_format + audioB)
if dataASet[-1] and dataBSet[-1]:
self.textShow='已合成音頻A、B'
elif dataBSet[-1]:
self.textShow = '已合成音頻B'
elif dataASet[-1]:
self.textShow = '已合成音頻A'
self.vartext.set(self.textShow)
if __name__ == '__main__':
# *** 測試ui界面顯示 *** #
ui2show = ui2show()
ui2show.mainloop()
網絡相關支援函數 netWork.pyw
from configobj import ConfigObj # config.ini參數操作函數
import urllib.parse
import requests # 網絡操作函數
import http.client
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import json
import datetime
# *** 網絡連接配接函數 *** #
class netWork:
# def __init__(self):
# pass
def isConnected(self): # 檢測網絡是否已正常連接配接
try:
html = requests.get("https://www.baidu.com/", timeout=2)
except:
return False, '無法連接配接網絡,請檢查網絡是否正常連接配接'
return True, '網絡連接配接正常'
def getToken(self): # 擷取token值,後續需要在version3.0解決
config = ConfigObj("config.ini", encoding='UTF8')
client = AcsClient(config['user']['AccessKeyID'], config['user']['AccessKeySecret'], "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')
response = client.do_action_with_exception(request)
response = json.loads(str(response, 'utf-8'))
return response['Token']['Id']
def txt2audio(self, text, type): # 小段文本轉音頻的程式,輸入text、
config = ConfigObj("config.ini", encoding='UTF8')
if config['user']['nowTime']!=str(datetime.datetime.now())[:10]: # 按天進行token值更新
config['user']['nowTime'] = str(datetime.datetime.now())[:10]
config['user']['&token'] = self.getToken()
config.write()
conn = http.client.HTTPSConnection(config['user']['host'])
du = config['user']
dc = config[type] # 這裡分漢文、英文
url = ''
url = 'https://' + du['host'] + '/stream/v1/tts'
url = url + '?appkey=' + du['?appkey']
url = url + '&token=' + du['&token']
url = url + '&format=' + du['&format']
url = url + '&sample_rate=' + du['&sample_rate']
url = url + '&voice=' + dc['voice_parameter'][int(dc['&voice'])]
url = url + '&volume=' + dc['&volume']
url = url + '&speech_rate=' + dc['&speech_rate']
url = url + '&pitch_rate=' + dc['&pitch_rate']
if type == 'chinese':
if len(text) < 300: # 滿足文本長度要求
list_text = [text]
else: # 不滿足文本長度要求
list_text = text.split('.') # 很少有文本能夠一段超過300字
elif type == 'english':
num = len(text.split()) # 英文和漢文不同使用空格區分單詞
if num < 300:
list_text = [text]
else:
list_text = text.split('.')
list_audio = []
for i in list_text:
textUrlencode = urllib.parse.quote_plus(i)
textUrlencode = textUrlencode.replace("+", "%20")
textUrlencode = textUrlencode.replace("*", "%2A")
textUrlencode = textUrlencode.replace("%7E", "~")
conn.request(method='GET', url=url + '&text=' + textUrlencode)
response = conn.getresponse()
body = response.read()
list_audio.append(body)
conn.close()
audio_all = list_audio[0]
if len(list_text) > 1:
for i in list_audio[1:]:
audio_all += i
return audio_all
if __name__ == '__main__':
net = netWork()
# *** 測試網絡連接配接是否正常 *** # 成功√
netState, feedbackWord=net.isConnected()
print(netState, feedbackWord)
# *** 測試自動擷取token值 *** # 成功√
# Token=net.getToken()
# print(Token)
# *** 測試語音合成是否正常 *** # 成功√
# text = '你好,萬雨。測試成功'
# type = 'chinese'
# fileName = 'testAudio1.wav'
# audio = net.txt2audio(text, type)
# with open(fileName, mode='wb') as f:
# f.write(audio)
文本處理相關函數 split2summary.pyw
"""
函數說明:
①将原始文本進行拆分-合并
②将獲得音頻進行按要求重複合并
"""
class split2summary:
def findCE(self, text): # 區分漢文英文
index = []
for i in range(len(text) - 2):
if text[i:i + 3] == '###':
index.append(i)
# elif text[i:i + 3] == '>>>':
# index.append(i)
# print(index)
if len(index) == 0:
return [text], [0]
text_list = []
text_state = []
index_history = [0, 0]
for key, value in enumerate(index):
# print(key,value)
if key % 2 == 0: # 漢文
if index[key] == 0:
continue
index_history = [index_history[1], index[key]]
if key == 0:
text_list.append(text[index_history[0]:index_history[1]])
else:
text_list.append(text[index_history[0] + 3:index_history[1]])
text_state.append(0)
else: # 英文
index_history = [index_history[1], index[key]]
text_list.append(text[index_history[0] + 3:index_history[1]])
text_state.append(1)
# 解決句尾的問題
if index[-1] + 3 != len(text):
text_list.append(text[index[-1] + 3:len(text)])
text_state.append(0)
return text_list, text_state
def txt2split(self, text):
txt_mid = text.split('...')
for i in range(len(txt_mid)):
txt_mid[i] = txt_mid[i].split(',,,')
txt_value = []
txt_state = []
for i in txt_mid[:-1]:
txt_state_mid = []
txt_value_mid = []
for j in i:
text_list, text_state = self.findCE(j)
txt_value_mid.append(text_list)
txt_state_mid.append(text_state)
txt_value.append(txt_value_mid)
txt_state.append(txt_state_mid)
return txt_value, txt_state
# *** 将最小分段合并一級到逗号分段 *** #
def value2comma(self, value):
for keyi, valuei in enumerate(value): # 句号
for keyj, valuej in enumerate(valuei):
for keyk, valuek in enumerate(valuej):
if keyk == 0:
str_comma = value[keyi][keyj][keyk]
else:
str_comma += value[keyi][keyj][keyk]
value[keyi][keyj] = str_comma
return value
# *** 處理分段函數A 成功√ *** #
def programA(self, value, dataASet):
valueA = []
for keyi, valuei in enumerate(value): # 句号
value_end = []
for keyj, valuej in enumerate(valuei):
if keyj == 0 and (dataASet[0] != 0 or dataASet[1] != 0):
value_end = value[keyi][keyj]
if dataASet[0] != 0:
for times in range(dataASet[0] - 1):
value_end += value[keyi][keyj]
elif dataASet[0] != 0:
for times in range(dataASet[0]):
value_end += value[keyi][keyj]
elif dataASet[1] != 0:
value_end += value[keyi][keyj]
if keyi == 0 and dataASet[0] != 0:
valueA = value_end
elif dataASet[0] != 0:
valueA += value_end
# *** 專門針對句号分段 *** #
# for keyi, valuei in enumerate(value):
for times in range(dataASet[1]):
for keyj, valuej in enumerate(valuei):
if (keyi == 0 and keyj == 0) and (dataASet[0] == 0 and valueA == []):
valueA = value[keyi][keyj]
else:
valueA += value[keyi][keyj]
# *** 專門針對整個篇幅的分段 *** #
for times in range(dataASet[2]):
for keyi, valuei in enumerate(value): # 句号
for keyj, valuej in enumerate(valuei):
# print(keyi, keyj)
if (keyi, keyj) == (0, 0) and valueA == []:
valueA = value[keyi][keyj]
else:
valueA += value[keyi][keyj]
# print(valueA)
return valueA
def programB(self, value, dataBSet):
valueB=[]
# *** 逗号分段處理 *** #
for keyi, valuei in enumerate(value): # 句号
value_end = []
for keyj, valuej in enumerate(valuei[:-1]):
if keyj == 0 and (dataBSet[0] != 0 or dataBSet[1] != 0):
value_end = value[keyi][keyj]
if dataBSet[0] != 0:
for times in range(dataBSet[0] - 1):
value_end += value[keyi][keyj]
elif dataBSet[0] != 0:
for times in range(dataBSet[0]):
value_end += value[keyi][keyj]
elif dataBSet[1] != 0:
value_end += value[keyi][keyj]
if keyi == 0 and dataBSet[0] != 0:
valueB = value_end
elif dataBSet[0] != 0:
valueB += value_end
# *** 專門針對句号分段 *** #
for times in range(dataBSet[1]):
if (keyi == 0) and (valueB == []):
valueB = value[keyi][-1]
else:
valueB += value[keyi][-1]
# *** 專門針對整個篇幅的分段 *** #
for times in range(dataBSet[2]):
for keyi, valuei in enumerate(value): # 句号
for keyj, valuej in enumerate(valuei):
if (keyi, keyj) == (0, 0) and valueB == []:
# print('run')
valueB = value[keyi][keyj]
else:
valueB += value[keyi][keyj]
# print(valueB)
return valueB
if __name__=="__main__":
split2summary = split2summary()
text = '1你好<<<2don\'t do that>>>,,,<<<3I have a dream>>>4萬雨...5什麼<<<6hello>>>,,,<<<7Game of thrones>>>8爛尾了...'
dataASet=[0,0,1,1]
dataBSet=[2,0,0,1]
txt_value, txt_state = split2summary.txt2split(text)
print(txt_value)
print(txt_state)
value = split2summary.value2comma(txt_value)
print(value)
split2summary.programA(value,dataASet)
# split2summary.programB(value,dataBSet)
參數配置檔案 config.ini
# 參數說明:
# ①txtA:程式A的處理參數
# name其他參數的名稱,comma逗号重複次數,end句号重複次數,full全文重複次數,run是否運作,default預設參數
# ②txtB:程式B的處理參數
# ③chinese:标準漢語語音合成參數設定
# volume音量大小,tones音調,speed語速,spokesman發言人
# ④english:标準英語語音合成參數設定
# ⑤user:token需要自己更新資料,這是一個有期限的資料
[user]
name = url, ?appkey, &token, &format, &sample_rate
nowTime = 2019-05-17
&token = 07ee4200162547a39aebcd4325679219
AccessKeyID = UfVpojYxi3HXUNjV
AccessKeySecret = oPSg3IswMi8kNOpkRaAhkZBTtOPgkr
host = nls-gateway.cn-shanghai.aliyuncs.com
url = https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts
?appkey = 2BxzqedudhJmByrY
&format = wav
&sample_rate = 16000
wav_format = "b'RIFF\xac\xdc9\x00WAVEfmt\x10\x00\x00\x00\x01\x00\x01\x00\x80>\x00\x00\x00}\x00\x00\x02\x00\x10\x00data\x80\xdc9\x00'"
[txtA]
name = comma, end, full, run
comma = 2
end = 2
full = 1
run = 0
default_comma = 1, 2, 5
default_end = 1, 2, 5
default_full = 0, 1, 3
default_run = 0, 1
[txtB]
name = comma, end, full, run
comma = 3
end = 1
full = 1
run = 0
default_comma = 1, 3, 5
default_end = 1, 1, 5
default_full = 0, 1, 3
default_run = 0, 1
[chinese]
# voice發言人、volume音量、speech_rate語速、pitch_rate語調
name = &volume, &speech_rate, &pitch_rate, &voice
&volume = 50
&speech_rate = 0
&pitch_rate = 0
&voice = 9
default_&volume = 0, 50, 100
default_&speech_rate = -500, 0, 500
default_&pitch_rate = -500, 0, 500
default_&voice = 0, 9, 18
voice_parameter = Xiaoyun, Xiaogang, Ruoxi, Xiaomeng, Xiaowei, Amei, Xiaoxue, Siqi, Sijia, Sicheng, Siyue, Xiaomei, Sitong, Ninger, Xiaobei, Yina, Sijing, Shanshan
[english]
# voice發言人、volume音量、speech_rate語速、pitch_rate語調
name = &volume, &speech_rate, &pitch_rate, &voice
&volume = 50
&speech_rate = 0
&pitch_rate = 0
&voice = 1
default_&volume = 0, 50, 100
default_&speech_rate = -500, 0, 500
default_&pitch_rate = -500, 0, 500
default_&voice = 0, 1, 3
voice_parameter = Wendy, William, Halen, Harry
[help]
[about]
四,總結
使用tkinter建構UI界面,ini檔案充當參數配置檔案,其中WAV音頻檔案合并過程中遇到一些問題,但是後續通過學習WAV音頻格式檔案的資料幀資訊也順利的解決了相關問題
五,參考連結
阿裡雲自動擷取token值(python)
https://www.cnblogs.com/Mufasa/p/10880698.htmlWAV格式檔案無損合并&幀頭資料體解析(python)(原創)
https://www.cnblogs.com/Mufasa/p/10878777.htmlpython讀寫增删修改ini配置檔案
https://www.cnblogs.com/Mufasa/p/10845535.html探究未知是最大樂趣