看了复联后,各种羡慕斯塔克,成为不了钢铁侠,那就自己给自己造一个贾维斯出来吧。不仅能控制电脑,还能和我智能聊天
这是主文件,创建一个可视化的桌面,及主要业务功能
#!/usr/bin/python3
# @Time : 2019/5/30 14:54
# @Author : 老杨
# @FileName : iron.py
# @Software : PyCharm
# pip install baidu-aip
# pip install pyttsx3
# pip install requests
# http://ai.baidu.com/docs#/ASR-Online-Python-SDK/top
from tkinter import *
from aip import AipSpeech
import Recorder
import Control
import pyttsx3
import requests
import json
# pip install jsonpath
# import jsonpath
def action():
data = entry1.get().strip()
control = Control.Order()
control.run(data)
rec = Recorder.Recorder()
def ok(event):
print('开始录音')
rec.start()
def no():
print('结束录音')
# 结束录音
rec.stop()
# 保存音频
file = rec.save('audio')
# 调用百度aip语音识别转义成文字
APP_ID = '你的百度ID'
API_KEY = '你的百度API_KEY'
SECRET_KEY = '你的百度SECRET_KEY'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
with open(file,'rb') as fp:
data = fp.read()
result = client.asr(data,'wav',16000,{
'dev_pid':1536
})
print(result)
try:
data = result['result'][0]
except Exception as err:
exit(err)
return data
def voiceControl(event):
result = no()
print(result)
# 提取前三位,判断是操控还是聊天
data = result[0:3]
order = result[3:]
if data =='贾维斯':
control = Control.Order()
control.run(order)
else:
show(result)
# def show(content):
# # 构造请求参数
# request_data = {
# "reqType":0,
# "perception": {
# "inputText": {
# "text": content
# },
# },
# "userInfo": {
# "apiKey": "d3c006b99ee94e28b6d8340f68577f02",
# "userId": "laoYang"
# }
# }
# # 构造请求url
# url = "http://openapi.tuling123.com/openapi/api/v2"
# # 发送请求
# request_data = json.dumps(request_data)
# result = requests.post(url,request_data)
# # 转换成json格式
# response = json.loads(result.text)
# # 通过jsonpath取到对应的值
# data = jsonpath.jsonpath(response,'$..text')
# # 语音输出
# engine = pyttsx3.init()
# engine.say(data)
# engine.runAndWait()
def show(content):
# 构造请求参数
request_data = {
"key":"你的图灵机器人key",
"info":content,
"userid":"你的图灵机器人ID"
}
# 构造请求url
url = "http://www.tuling123.com/openapi/api"
# 发送请求
result = requests.post(url,request_data)
# 转换格式
response = json.loads(result.text)
# 语音输出
engine = pyttsx3.init()
engine.say(response['text'])
engine.runAndWait()
# exit()
# 实例化 创建一个GUI对象
master = Tk()
# 设置标题
master.title('贾维斯')
# 设置窗体大小以及出现在屏幕上面的位置
# 宽x高+X轴+Y轴
# 此处有坑,不是*,而是x
master.geometry('300x100+450+300')
master.resizable(False,False)
# 设置标签
# # 网格布局
Label(master,text='输入指令:',font=('黑体',18),fg='blue').grid()
# Label(master,text.txt='结果:',font=('黑体',18),fg='blue').grid(row=1,column=0)
# 设置第一个输入框
entry1 = Entry(master)
# 网格布局
entry1.grid(row=0,column=1)
button1 = Button(master,text='运行',width=10,command=action)
button1.grid(row=1,column=0)
button = Button(master,text='声控',width=10)
button.grid(row=1,column=1)
button.bind("" ,ok)
button.bind("" ,voiceControl)
# 消息循环
master.mainloop()
控制电脑的文件
#!/usr/bin/python3
# @Time : 2019/5/25 13:07
# @Author : 老杨
# @FileName : Order.py
# @Software : PyCharm
# pip install pypiwin32
# pip install pyttsx3
import os
import time
import win32api
import pyttsx3
class Order():
def set_order(self,orderName,path):
"""
设置指令,判断指令
:param orderName: 指令名称
:param path: 程序路径
:return: None
"""
if orderName == ''or path=='':
raise Exception('请补充完整您的指令名称或路径')
try:
file = self.get_order(orderName)
if file == None:
self.add_order(orderName,path)
self.tell('指令添加成功')
else:
self.tell('当前指令已经存在')
except FileNotFoundError as err:
self.tell('我是你的贾维斯')
self.add_order(orderName,path)
def add_order(self,orderName,path):
"""
添加指令
:param orderName: 指令名称
:param path: 程序路径
:return: None
"""
data = orderName + '路径为->' + path + '\n'
with open('order.txt', 'a+', encoding='utf-8') as f:
f.write(data)
self.tell('指令添加成功')
def get_order(self,name,returnData='orderPath'):
"""
根据指令,获取对应值
:param name: 指令名称
:param returnData:返回的结果
:return:返回指定结果
"""
with open('order.txt', 'r+', encoding='utf-8') as f:
data = f.readlines()
for key,value in enumerate(data):
result = value.split('路径为->')
try:
response = dict()
response['orderName'] = result[0].replace('\n','').strip()
if name == response['orderName']:
response['orderPath'] = result[1].replace('\n','').strip()
response['exeName'] = response['orderPath'][response['orderPath'].rfind('\\')+1:]
return response[returnData]
except TypeError as err:
info = '第'+str(key)+'行不符合格式\n请按格式修改'
exit(info)
# raise Exception(info)
# https://www.cnblogs.com/xknight/articles/1291111.html
def startOrder(self,orderName,hwnd=0,op='open',params='',dir='',bShow=1):
"""
根据指令,打开相应程序
:param orderName: 指令名
:param hwnd: 父窗口的句柄,如果没有父窗口,则为0。
:param op: 要进行的操作,为“open”、“print”或者为空。
:param params: 要运行的程序,或者打开的脚本。
:param dir: 要向程序传递的参数,如果打开的为文件,则为空。
:param bShow: 是否显示窗口。
:return: None
"""
file = self.get_order(orderName)
if file != None:
win32api.ShellExecute(hwnd,op,file,params,dir,bShow)
self.tell('正在打开'+orderName)
else:
self.tell('没有找到对应的指令')
def tell(self,data):
"""
语音提醒
:param data: 需要提醒的话
:return:
"""
engine = pyttsx3.init()
engine.say(data)
engine.runAndWait()
def stopOrder(self,orderName):
"""
关闭程序
:param orderName: 指令名
:return:
"""
file = self.get_order(orderName)
if file != None:
res = 'TASKKILL /F /IM '+self.get_order(orderName,'exeName')
os.system('TASKKILL /F /IM '+self.get_order(orderName,'exeName'))
self.tell(orderName+'已经退出')
else:
self.tell('没有找到对应的指令')
def run(self,orderName):
"""
运行指令
:param orderName: 需要执行的指令
:return: None
"""
if orderName=='关机':
self.tell('即将为您关闭电脑')
os.sys('shutdown /s /t 0')
elif orderName=='重启':
self.tell('即将为您重启电脑')
os.sys('shutdown /r /t 0')
else:
keyWord = orderName[0:2]
orderWord = orderName[2:]
if keyWord == '打开':
self.startOrder(orderWord)
elif keyWord == '退出':
self.stopOrder(orderWord)
else:
try:
os.sys(orderName)
except Exception as err:
self.tell('请输入正确指令')
# demo 添加指令
# test = Order()
# orderName = "微信"
# path ="C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"
# test.set_order(orderName,path)
实现录制音频的文件
#!/usr/bin/python3
# @Time : 2019/5/25 13:07
# @Author : 老杨
# @FileName : Order.py
# @Software : PyCharm
# pip install PyAudio
import pyaudio
import time
import threading
import wave
import os
class Recorder():
def __init__(self, chunk=1024, bits=pyaudio.paInt16, channels=1, rate=16000):
"""
初始设置
:param chunk: wav文件是由若干个CHUNK组成的,CHUNK我们就理解成数据包或者数据片段
:param format: 这个参数后面写的pyaudio.paInt16表示我们使用量化位数 16位来进行录音
:param channels:代表的是声道,这里使用的单声道
:param rate: 采样率16k
:return: 生成的文件路径
"""
self.CHUNK = chunk
self.FORMAT = bits
self.CHANNELS = channels
self.RATE = rate
self._running = True
self._frames = []
self._startTime = 0
self._stopTime = 0
self._duration = 0
def start(self):
"""
生成新的线程
"""
threading._start_new_thread(self.__recording, ())
def __recording(self):
"""
开始录音
"""
self._startTime = time.time()
self._running = True
self._frames = []
p = pyaudio.PyAudio()
stream = p.open(format=self.FORMAT,
channels=self.CHANNELS,
rate=self.RATE,
input=True,
frames_per_buffer=self.CHUNK)
while (self._running):
data = stream.read(self.CHUNK)
self._frames.append(data)
stream.stop_stream()
stream.close()
p.terminate()
def stop(self):
"""
停止录音
:return: 录音时长
"""
self._stopTime = time.time()
self._running = False
self._duration = int(self._stopTime-self._startTime)
return self._duration
def save(self, dirName,fileName=''):
"""
保存文件
:param fileName: 需要保存的文件路径
:return: 生成的文件路径
"""
p = pyaudio.PyAudio()
if not os.path.exists(dirName):
os.mkdir(dirName)
if not fileName:
fileName = time.strftime('%Y-%m-%d %H-%M-%S',time.localtime(time.time()))+".wav"
fileName = os.path.join(dirName, fileName)
if not fileName.endswith(".wav"):
filename = fileName + ".wav"
fileName = os.path.join(dirName,fileName)
wf = wave.open(fileName, 'wb')
wf.setnchannels(self.CHANNELS)
wf.setsampwidth(p.get_sample_size(self.FORMAT))
wf.setframerate(self.RATE)
wf.writeframes(b''.join(self._frames))
wf.close()
return fileName
def getDuration(self):
"""
获取录音时长
:return: 录音时长
"""
return self._duration