单词发音,为语音识别准备素材
- 环境
- windows下安装pyttsx3
- linux下安装pyttsx3
- 界面展示
- 图形化界面
- 输出文档
- 写作过程
- 注意事项
- 完整代码
环境
这里我用的是python3.7.9。pycharm编译器。windows系统。
windows下安装pyttsx3
pip install pyttsx3
linux下安装pyttsx3
linux下安装pyttsx3时,要先安装两个插件,要不用起来会报错
sudo apt-get install alsa-utils
sudo apt-get install espeak
pip install pyttsx3
界面展示
图形化界面
图形化界面,很简陋的一个
输出文档
是我做好之后的音频素材文档
保存单词的word.txt
单词发音
写作过程
1.导入相关包。
os,用来进行文件的读写。re,正则匹配。pyttsx3,文字读语音。
import os
import tkinter
from tkinter.filedialog import *
from tkinter import ttk
import pyttsx3
import re
2.这里我准备了一个类来做图形化界面,函数功能也直接在类里面实现了。结果就是看起来十分臃肿,一点都不美观。不过这解决了函数放在类外面出现的一些问题。比如说变量调用很麻烦之类的。
里面变量有些数字大的在前面,这是因为我写的时候是按照从小到大开始写的,但刚开始有些功能没有想明白,把新代码插在了中间。
self.path: 存放文件的输入框
self.path1: 单词的输入框
self.language: 选择发音
self.prompt_statement: 提示语句
self.batch_file: 批文件的输入框。文件里面存放多个英文单词
self.words: 文件里面的单词数量
class painting():def __init__(self):self.app1 = tkinter.Tk()self.app1.title("单词音频保存")self.app1.geometry("760x430")self.path = tkinter.StringVar()self.path1 = tkinter.StringVar()self.languages = tkinter.StringVar()self.prompt_statement = tkinter.StringVar()self.prompt_statement.set('提示语句!')self.batch_file = tkinter.StringVar()self.words = []# 初始化输入框# self.path.set(os.path.abspath('.'))self.label1 = tkinter.Label(self.app1, text="单词:", width=9).place(x=70, y=30)self.entry1 = tkinter.Entry(self.app1, width=50, textvariable=self.path1).place(x=130, y=30)self.button1 = tkinter.Button(self.app1, text="下载", command=self.audio_save).place(x=500, y=25)self.label4 = tkinter.Label(self.app1, text="批量下载:", width=9).place(x=70, y=65)self.entry4 = tkinter.Entry(self.app1, textvariable=self.batch_file, width=50).place(x=130, y=65)self.button4 = tkinter.Button(self.app1, text="批量导入", command=self.batch_load).place(x=500, y=65)self.button5 = tkinter.Button(self.app1, text="批量下载", command=self.batch_save).place(x=580, y=65)self.label2 = tkinter.Label(self.app1, text="保存目录:", width=9).place(x=70, y=100)self.entry2 = tkinter.Entry(self.app1, width=50, textvariable=self.path).place(x=130, y=100)self.button2 = tkinter.Button(self.app1, text="选择目录", command=self.output_file_path).place(x=500, y=100)self.label3 = tkinter.Label(self.app1, text="发音语言:", width=9).place(x=70, y=150)self.values = ["Chinese", "English"]self.dropdown_box = ttk.Combobox(values=self.values, textvariable=self.languages).place(x=130, y=150)self.label4 = tkinter.Label(self.app1, textvariable=self.prompt_statement).place(x=200, y=200)self.app1.mainloop()
3.图像化界面创建好了,接下来就可以写功能了。以下功能写在类里面。
定义输出文件。
# 定义输出文件def output_file_path(self):# 打开文件# file_name=str(askopenfile())[25:-28]# 选择文件夹file_path = askdirectory()self.path.set(file_path)# print(file_path)
检查文字与发音选择是否对应:
# 检测发音def detect_languages(self):language = self.languages.get()if language == "Chinese":if not self.is_Chinese(self.path1.get()):# print('不是中文!')self.prompt_statement.set('不是中文')return Falsereturn "Chinese"elif language == "English":return "English"else:# print('发音选择错误,请重新开始选择!')self.prompt_statement.set('发音选择错误,请重新开始选择!')return False
里面用到了判断是否是中文的函数。这是因为在linux下中文如果用不小心用了英文发音器,只会发出letter,letter的声音。很不友好。
# 判断是否中文def is_Chinese(self, word):for ch in word:if '\u4e00' <= ch <= '\u9fff':return Truereturn False
检查单词长度。这里我们不希望单词太长,对单词长度做了限制。
# 检查单词长度def detect_word_length(self):word = self.path1.get()if len(word) > 10:self.prompt_statement.set("单词太长了!")return Falseelse:return word
单词发音,没有储存目录则默认不会存储。
# 单词发音转音频,未选择保存目录则只发音不保存音频def word_to_audio(self, word, output_path, language):engine = pyttsx3.init()# 增大音量volume = engine.getProperty('volume')volume = engine.setProperty('volume', volume + 10)# 选择是否中文if language == "Chinese":voices = engine.getProperty('voices')engine.setProperty('voice', voices[0].id)engine.say(word)engine.save_to_file(word, output_path)# print("language:","Chinese")self.prompt_statement.set("Language: Chinese")else:# 默认英文。voices = engine.getProperty('voices')engine.setProperty('voice', voices[1].id)engine.say(word)engine.save_to_file(word, output_path)# print("language:", "English")self.prompt_statement.set("Language:English")engine.runAndWait()
存储文件的路径问题:
# 发音保存def audio_save(self):word = self.detect_word_length()if word:word_save_folder = self.path.get() + "/" + wordif os.path.exists(word_save_folder):word_save_path = word_save_folder + '/' + word + '.wav'else:os.mkdir(word_save_folder)word_save_path = word_save_folder + '/' + word + '.wav'language = self.detect_languages()if language:# print(language)# print(word,word_save_path,"English")self.word_to_audio(word, word_save_path, language)else:return False
4.一个个单词发音太麻烦了。这里,我选择从文本导入英文单词,执行发音函数。当然,也可以选择从网上爬取英文单词和音频。不过我爬虫学的不怎么好,这里就不献丑了。
这里我只选择了前四个单词作输入。我单词文本第一行不是英文。
# 批量导入英文单词def batch_load(self):file_path = askopenfilename()self.batch_file.set(file_path)file_name = self.batch_file.get()f = open(file_name, 'r', encoding='utf-8')try:content = f.readlines()[1:5]for i in range(len(content)):word = re.match(r'[A-Za-z0-9]*', content[i])self.words.append(word.group(0))finally:f.close()print(self.words)
批量保存:
# 批量下载def batch_save(self):if not self.words:# print('没有单词')self.prompt_statement.set("没有单词!")return Falseif self.path.get() == '':self.prompt_statement.set('批量下载输出路径没有定义!')return Falsefor word in self.words:word_save_folder = self.path.get() + "/" + wordif os.path.exists(word_save_folder):word_save_path = word_save_folder + '/' + word + '.wav'else:os.mkdir(word_save_folder)word_save_path = word_save_folder + '/' + word + '.wav'self.word_to_audio(word, word_save_path, 'English')
注意事项
1.在创建图像化界面的时候,点击函数对应的功能。记住函数后面不能带"()"。否则打开图像化界面,按钮就被默认点击了一次,里面的函数也会同步执行一次。
错误:self.button1 = tkinter.Button(self.app1, text=“下载”, command=self.audio_save()).place(x=500, y=25)
正确:self.button1 = tkinter.Button(self.app1, text=“下载”, command=self.audio_save).place(x=500, y=25)
2.在linux执行保存音频的时候,出现了错误。查找之后发现是python版本的问题。**python3.7以下不能用pyttsx3保存音频。**由于我做机器学习linux下的python版本用的是python3.6,所以这个准备素材的活在Windows下写了。
3.Linux下选择中文发音器时。普通话中文发音器是倒数第二个,而windows下是第一个。
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[-2].id)
完整代码
# tkinter进行图像化设计
import os
import tkinter
from tkinter.filedialog import *
from tkinter import ttk
import pyttsx3
import reclass painting():def __init__(self):self.app1 = tkinter.Tk()self.app1.title("单词音频保存")self.app1.geometry("760x430")self.path = tkinter.StringVar()self.path1 = tkinter.StringVar()self.languages = tkinter.StringVar()self.prompt_statement = tkinter.StringVar()self.prompt_statement.set('提示语句!')self.batch_file = tkinter.StringVar()self.words = []# 初始化输入框# self.path.set(os.path.abspath('.'))self.label1 = tkinter.Label(self.app1, text="单词:", width=9).place(x=70, y=30)self.entry1 = tkinter.Entry(self.app1, width=50, textvariable=self.path1).place(x=130, y=30)self.button1 = tkinter.Button(self.app1, text="下载", command=self.audio_save).place(x=500, y=25)self.label4 = tkinter.Label(self.app1, text="批量下载:", width=9).place(x=70, y=65)self.entry4 = tkinter.Entry(self.app1, textvariable=self.batch_file, width=50).place(x=130, y=65)self.button4 = tkinter.Button(self.app1, text="批量导入", command=self.batch_load).place(x=500, y=65)self.button5 = tkinter.Button(self.app1, text="批量下载", command=self.batch_save).place(x=580, y=65)self.label2 = tkinter.Label(self.app1, text="保存目录:", width=9).place(x=70, y=100)self.entry2 = tkinter.Entry(self.app1, width=50, textvariable=self.path).place(x=130, y=100)self.button2 = tkinter.Button(self.app1, text="选择目录", command=self.output_file_path).place(x=500, y=100)self.label3 = tkinter.Label(self.app1, text="发音语言:", width=9).place(x=70, y=150)self.values = ["Chinese", "English"]self.dropdown_box = ttk.Combobox(values=self.values, textvariable=self.languages).place(x=130, y=150)self.label4 = tkinter.Label(self.app1, textvariable=self.prompt_statement).place(x=200, y=200)self.app1.mainloop()# 检查单词长度def detect_word_length(self):word = self.path1.get()if len(word) > 10:self.prompt_statement.set("单词太长了!")return Falseelse:return word# 判断是否中文def is_Chinese(self, word):for ch in word:if '\u4e00' <= ch <= '\u9fff':return Truereturn False# 检测发音def detect_languages(self):language = self.languages.get()if language == "Chinese":if not self.is_Chinese(self.path1.get()):# print('不是中文!')self.prompt_statement.set('不是中文')return Falsereturn "Chinese"elif language == "English":return "English"else:# print('发音选择错误,请重新开始选择!')self.prompt_statement.set('发音选择错误,请重新开始选择!')return False# 单词发音转音频,未选择保存目录则只发音不保存音频def word_to_audio(self, word, output_path, language):engine = pyttsx3.init()# 增大音量volume = engine.getProperty('volume')volume = engine.setProperty('volume', volume + 10)# 选择是否中文if language == "Chinese":voices = engine.getProperty('voices')engine.setProperty('voice', voices[0].id)engine.say(word)engine.save_to_file(word, output_path)# print("language:","Chinese")self.prompt_statement.set("Language: Chinese")else:# 默认英文。voices = engine.getProperty('voices')engine.setProperty('voice', voices[1].id)engine.say(word)engine.save_to_file(word, output_path)# print("language:", "English")self.prompt_statement.set("Language:English")engine.runAndWait()# 发音保存def audio_save(self):word = self.detect_word_length()if word:word_save_folder = self.path.get() + "/" + wordif os.path.exists(word_save_folder):word_save_path = word_save_folder + '/' + word + '.wav'else:os.mkdir(word_save_folder)word_save_path = word_save_folder + '/' + word + '.wav'language = self.detect_languages()if language:# print(language)# print(word,word_save_path,"English")self.word_to_audio(word, word_save_path, language)else:return False# 定义输出文件def output_file_path(self):# 打开文件# file_name=str(askopenfile())[25:-28]# 选择文件夹file_path = askdirectory()self.path.set(file_path)# print(file_path)# 批量导入英文单词def batch_load(self):file_path = askopenfilename()self.batch_file.set(file_path)file_name = self.batch_file.get()f = open(file_name, 'r', encoding='utf-8')try:content = f.readlines()[1:5]for i in range(len(content)):word = re.match(r'[A-Za-z0-9]*', content[i])self.words.append(word.group(0))finally:f.close()print(self.words)# 批量下载def batch_save(self):if not self.words:# print('没有单词')self.prompt_statement.set("没有单词!")return Falseif self.path.get() == '':self.prompt_statement.set('批量下载输出路径没有定义!')return Falsefor word in self.words:word_save_folder = self.path.get() + "/" + wordif os.path.exists(word_save_folder):word_save_path = word_save_folder + '/' + word + '.wav'else:os.mkdir(word_save_folder)word_save_path = word_save_folder + '/' + word + '.wav'self.word_to_audio(word, word_save_path, 'English')if __name__ == '__main__':painting()