# 导入区域
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import *
import webbrowser,wave,requests,time,base64 # 百度语音要求对本地语音二进制数据进行base64编码
from pyaudio import PyAudio, paInt16
class Application(Frame):
def __init__(self, master=None):
super().__init__(master) #super()代表的是父类的定义,而不是父类对象
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
# ================创建一个图片管理类——设置背景===================
global photo
photo = PhotoImage(file="./image/bg.png")
bgLabel = Label(self,image=photo,compound=CENTER,fg="white")
bgLabel.pack(side=RIGHT)
# ===============识别语音选择(默认普通话)========================
## 五选一,为了保证不选的情况就是普通话,在多处强调devpid=1536,完成后可修改重复
v1 = StringVar(self)
v1.set("普通话(默认)")
om1 = OptionMenu(self, v1, "普通话(默认)", "普通话(带标点)", "英语", "粤语", "四川话")
om1["width"] = 13
om1.place(relx=0.62, rely=0.08)
if v1.get() == "普通话(默认)":
devpid = 1536
elif v1.get() == "普通话(带标点)":
devpid = 1567
elif v1.get() == "英语":
devpid = 1737
elif v1.get() == "粤语":
devpid = 1637
elif v1.get() == "四川话":
devpid = 1837
else:
devpid = 1536
# ==================第1个功能——音频输入=========================
## 提示文字“本地音频输入”
global photo01
photo01 = PhotoImage(file="./image/choose.png")
self.bt01 = Button(self, image=photo01)
self.bt01.place(relx=0.11, rely=0.15)
## 输入框
def choose_file():
selectFileName = askopenfilename(title='选择文件')
e.set(selectFileName)
e = StringVar()
self.entry01 = Entry(self,width=54,bd=8, textvariable=e)
self.entry01.place(relx=0.33, rely=0.15)
audio_path = self.entry01.get()
## 小文件夹Button用于找寻文件路径
global photo02
photo02 = PhotoImage(file="./image/q.png")
self.bt02 = Button(self, image=photo02, command=choose_file)
self.bt02.place(relx=0.81, rely=0.16)
# ================第2个功能——实时输入=========================
# 这两个输入需要用if elif语句,要不然前面的audio_path会被以下代码覆盖,不过目前只测试了实时输入没有问题
## 提示文字“实时输入”
global photo03
photo03 = PhotoImage(file="./image/realt.png")
self.bt03 = Button(self, image=photo03)
self.bt03.place(relx=0.11, rely=0.23)
self.label01 = Label(self, text="请点击右方按钮,录音(时长为4秒)", width=54, height=1, bd=8,bg="white", fg="black", font=("黑体", 10))
self.label01.place(relx=0.33, rely=0.238)
## 小喇叭按钮——录音
### 录音——变量初始化
framerate = 16000 # 采样率
num_samples = 2000 # 采样点
channels = 1 # 声道
sampwidth = 2 # 采样宽度2bytes
audio_path = str(int(time.time())) + '.wav'
### 录音——保存音频文件
def save_wave_file(filepath, data):
wf = wave.open(filepath, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(sampwidth)
wf.setframerate(framerate)
wf.writeframes(b''.join(data))
wf.close()
# ===============第3个功能——实时显示波形图和语谱图================
# 还在研究用于画图的界面matplotlib如何嵌入tkinter中
# 这代码可先看另一个文档
# ===============第4个功能——音频输入与结果显示===================
## 提示文字“识别结果”
global photo05
photo05 = PhotoImage(file="./image/result.png")
self.bt05 = Button(self, image=photo05)
self.bt05.place(relx=0.11, rely=0.70)
## 初始化结果显示的文本框
self.label02 = Label(self, width=54, height=1, bd=8, bg="white", fg="black")
self.label02.place(relx=0.33, rely=0.71)
## 百度api
def baidu_api(devpid=1536):
### 录音
pa = PyAudio()
# 打开一个新的音频stream
stream = pa.open(format=paInt16, channels=channels,
rate=framerate, input=True, frames_per_buffer=num_samples)
my_buf = [] # 存放录音数据
# count = 0
t = time.time()
while time.time() < t + 4: # 设置录音时间(秒)
# 循环read, 每次read 2000frames
string_audio_data = stream.read(num_samples)
my_buf.append(string_audio_data)
self.label01["text"] = "录音结束."
save_wave_file(audio_path, my_buf)
stream.close()
# 组装url
base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
APIKey = "0QKwKuAxo0u2fQZsAftmX0jc"
SecretKey = "PdhfonU6eYYKeW5qfdqgzEUGxhE92hdG"
# 获取token
HOST = base_url % (APIKey, SecretKey)
res = requests.post(HOST)
TOKEN = res.json()['access_token']
# 读入wav
with open(audio_path, 'rb') as f:
speech_data = f.read()
try:
FORMAT = 'wav'
RATE = '16000'
CHANNEL = 1
CUID = '*******'
SPEECH = base64.b64encode(speech_data).decode('utf-8')
data = {
'format': FORMAT,
'rate': RATE,
'channel': CHANNEL,
'cuid': CUID,
'len': len(speech_data),
'speech': SPEECH,
'token': TOKEN,
'dev_pid': devpid
}
url = 'https://vop.baidu.com/server_api'
headers = {'Content-Type': 'application/json'}
# r=requests.post(url,data=json.dumps(data),headers=headers)
r = requests.post(url, json=data, headers=headers)
Result = r.json()
if 'result' in Result:
self.label02["text"] = Result['result'][0]
return Result['result'][0]
else:
self.label02["text"] = Result
return Result
except:
self.label02["text"] = '未能正确识别,请重试'
return '未能正确识别,请重试'
## 小麦克风按钮
global photo04
photo04 = PhotoImage(file="./image/r.png")
self.bt04 = Button(self, image=photo04, command=baidu_api)
self.bt04.place(relx=0.81, rely=0.24)
# ================第5个功能——用户完善数据库====================
## 提示文字“自定义数据库”,还没搞也需要速成
global photo06
photo06 = PhotoImage(file="./image/self.png")
self.bt06 = Button(self, image=photo06)
self.bt06.place(relx=0.11, rely=0.78)
## 小字部分,含百度网站链接,点击可跳转
self.w01 = Text(self,width=56,height=6)
self.w01.place(relx=0.33, rely=0.85)
self.w01.insert(INSERT," good good study,day day up!百度,搜一下就知道"
"\n 请帮助我们完善数据库,"
"\n 查询并选择您所说的垃圾对应的类别")
self.w01.tag_add("good", 1.3, 2.0)
self.w01.tag_config("good", underline=True)
def webshow(event):
webbrowser.open("http://www.baidu.com")
self.w01.tag_bind("good","<Button-1>",webshow)
## 四选一
v = StringVar(self)
v.set("可回收物")
om = OptionMenu(self,v,"厨余垃圾","有害垃圾","其他垃圾","仍不清楚")
om["width"]=10
om.place(relx=0.5, rely=0.93)
if __name__=='__main__':
root = Tk()
root.resizable(width=False, height=False)
root.title("语音识别垃圾分类小程序")
root.iconbitmap('./image/favicon.ico')
app = Application(master=root)
root.mainloop()
GUI main
最新推荐文章于 2023-08-24 21:28:25 发布