去官网申请一个百度API,可以参考链接: https://blog.csdn.net/weixin_38753698/article/details/103142965?utm_source=app&app_version=4.5.2.
注册图灵机器人现在有免费、标准、专业、叠加包四个版本,下面介绍各个版本:
作者本次因个人使用,所以只选了免费版(虽然写的是免费版本,实际意思是比其他三个版本便宜,只需19.9人名币/月)
进入图灵官网注册账号,官网地址: http://www.tuling123.com.
import os
import wx
import pyttsx3
import requests
from bs4 import BeautifulSoup
import chardet
from lxml import etree
import urllib
import pygame
import pyaudio
import wave
import win32com.client
from aip import AipSpeech
import pyttsx3
import time
import base64
import random
from binascii import hexlify
from Crypto.Cipher import AES
import json
# 导入录音接口的包
import pyaudio
# 导入打开录音文件并设置音频参数的包
import wave
import win32com.client
from aip import AipSpeech
from bs4 import BeautifulSoup
import requests
import chardet
from lxml import etree
import pyttsx3
import pygame
import time
# 初始化语音:SpVoice类是支持语音合成(TTS)的核心类,通过SpVoice对象调用TTS引擎,实现朗读功能
speaker = win32com.client.Dispatch("SAPI.SpVoice")
def record(file_path):
"""pyaudio参数"""
CHUNK = 1024 # 数据包或者数据片段
FORMAT = pyaudio.paInt16 # pyaudio.paInt16表示我们使用量化位数 16位来进行录音
CHANNELS = 1 # 声道,1为单声道,2为双声道
RATE = 16000 # 采样率,每秒钟16000次
RECORD_SECONDS = 5 # 录音时间
WAVE_OUTPUT_FILENAME = file_path # 录音文件保存为WAVE_OUTPUT_FILENAME
pau = pyaudio.PyAudio()
stream = pau.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK, )
frames = []
print("开始录音")
speaker.Speak("开始录音")
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("录音结束")
speaker.Speak("录音结束")
stream.stop_stream()
stream.close()
pau.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(pau.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
def voice2text(APP_ID, API_KEY, SECRET_KEY, file_path):
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
ret = client.asr(get_data(file_path), 'pcm', 16000, {'dev_pid': 1536}, )
return ret['result']
def get_data(file_path):
with open(file_path, 'rb') as fp:
return fp.read()
#人机互动
import requests
import time
import pygame
import requests
# 导入文本转语音的包
import pyttsx3
# 初始化语音库
engine = pyttsx3.init()
# 向api发送请求
def get_response(msg):
apiUrl = 'http://www.tuling123.com/openapi/api'
data = {
'key': '你的图灵appkey',
'info': msg,
'userid': 'pth-robot',
}
try:
r = requests.post(apiUrl, data=data).json()
engine.say(r.get('text'))
engine.runAndWait()
print(r.get('text'))
except:
return
def say():
global chat_message
# 存放的文件名称的文件夹data
file_path = "data/chat-audio.wav"
# 百度需要的参数
APP_ID = '你的APP_ID'
API_KEY = '你的API_KEY'
SECRET_KEY = 'SECRET_KEY'
# 先调用录音函数
record(file_path)
# 语音转成文字的内容
chat_message = voice2text(APP_ID, API_KEY, SECRET_KEY, file_path)
print(chat_message)
# 设定人机交互次数函数(即人与图灵机器人的对话次数,注意这里初始值为0小于10,只能调用9次而不是10次)
def chatwithrobot():
i=0
while i < 10:
say()
get_response(chat_message)
i = i+1
# 音乐播放
import base64
import random
from binascii import hexlify
# 特别注意Crypto模块的首字母要改成大写,这是一个加解密模块,在爬取音乐评论用到
from Crypto.Cipher import AES
import json
import requests
import urllib, requests
import pyttsx3
import pygame
class GetMusic:
def __init__(self):
self.key = GetParamsAndEncSecKey()
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'Referer': 'http://music.163.com/'}
self.session = requests.Session()
self.session.headers = self.headers
self.conmment_url = 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_{}?csrf_token=' # 评论
self.lyric_url = 'https://music.163.com/weapi/song/lyric?csrf_token=' # 歌词
self.music_url = 'https://music.163.com/weapi/song/enhance/player/url?csrf_token=' # 歌曲
self.url = 'https://music.163.com/weapi/cloudsearch/get/web?csrf_token=' # 搜索歌曲列表,无歌曲链接
def get_params_and_encSecKey(self, song=None):
'''
获取什么就返回所需要两个参数
1. 歌曲
2. 歌词
3. 评论 默认
4. 搜索的歌曲列表
:param song:
:return:
'''
if isinstance(song, int):
data = {"ids": [song], "br": 128000, "csrf_token": ""}
elif isinstance(song, str) and song.isdigit():
data = {"id": song, "lv": -1, "tv": -1, "csrf_token": ""}
elif song == None:
data = {}
else:
data = {"hlpretag": "", "hlposttag": "", "s": song, "type": "1", "offset": "0",
"total": "true", "limit": "30", "csrf_token": ""}
song = json.dumps(data)
data = self.key.get(song)
return data
def get_music_list_info(self, name):
'''
获取歌曲详情:歌名+歌曲id+作者
:param name:
:return:
'''
data = self.get_params_and_encSecKey(name)
res = self.session.post(self.url, data=data) # 歌曲
song_info = res.json()['result']['songs']
for song in song_info:
song_name = song['name']
song_id = song['id']
songer = song['ar'][0]['name']
print(song_name, '\t', song_id, '\t', songer)
global SongName # 定义为全局变量
global SongId # 定义为全局变量
global Songer # 定义为全局变量
SongName=song_name
SongId=song_id
Songer=songer
self.get_music_url(song_id)
self.get_music_lyric(song_id)
self.get_music_comment(song_id)
break
def get_music_url(self, id):
'''
获取歌曲URL链接
:param id:
:return:
'''
global Song_url # 定义为全局变量
data = self.get_params_and_encSecKey(id)
res = self.session.post(self.music_url, data=data)
song_url = res.json()['data'][0]['url']
Song_url=song_url
#print(song_url)
def get_music_lyric(self, id_str):
'''
获取歌词
:param id_str:
:return:
'''
data = self.get_params_and_encSecKey(str(id_str))
res = self.session.post(self.lyric_url, data=data)
lyric = res.json()['lrc']['lyric']
#print(lyric)
def get_music_comment(self, song_id):
'''
获取歌曲评论: 评论人+内容+头像
:param song_id:
:return:
'''
data = self.get_params_and_encSecKey()
comment = self.session.post(self.conmment_url.format(str(song_id)), data=data)
com_list = comment.json()['hotComments']
for com in com_list:
content = com['content']
nickname = com['user']['nickname']
user_img = com['user']['avatarUrl']
#print(nickname, '!!!!' + content + '!!!!', user_img)
class GetParamsAndEncSecKey:
def __init__(self):
self.txt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
self.i = ''.join(random.sample(self.txt, 16)) # 16为随机数
self.first_key = '0CoJUm6Qyw8W8jud'
def get(self, song):
'''
获取加密的参数
params是两次加密的
:param song:
:return:
'''
res = self.get_params(song, self.first_key)
params = self.get_params(res, self.i)
encSecKey = self.get_encSecKey()
return {
'params': params,
'encSecKey': encSecKey
}
def get_params(self, data, key):
'''
获得params,加密字符长度要是16的倍数
:param data:
:param key:
:return:
'''
iv = '0102030405060708'
num = 16 - len(data) % 16
data = data + num * chr(num) # 补足
cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
result = cipher.encrypt(data.encode())
result_str = base64.b64encode(result).decode('utf-8')
return result_str
def get_encSecKey(self):
'''
获取encSecKey,256个字符串
hexlify--->转换为btyes类型
pow--->两个参数是幂,三个参数是先幂在取余
format(rs, 'x').zfill(256)-->256位的16进制
:return:
'''
enc_key = '010001'
modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
rs = pow(int(hexlify(self.i[::-1].encode('utf-8')), 16), int(enc_key, 16), int(modulus, 16))
return format(rs, 'x').zfill(256)
def music():
file_path="data/music.wav"
# 百度需要的参数
APP_ID = '你的APP_ID'
API_KEY = '你的API_KEY'
SECRET_KEY = 'SECRET_KEY'
# 先调用录音函数
record(file_path)
# 语音转成文字的内容
song_message = voice2text(APP_ID, API_KEY, SECRET_KEY, file_path)
print(song_message)
input2=''.join(song_message) #转换成字符串
song_name=input2[2:]
Msuic = GetMusic()
Msuic.get_music_list_info(song_name)
songid=str(SongId)
url = 'https://music.163.com/song/media/outer/url?id='+songid
headers = { 'User-agent':
'Mozilla/5.0 (X11; Linux x86_64; rv:57.0)Gecko/20100101 Firefox/57.0',
'Host':'music.163.com',
'Referer':'https://music.163.com'}
req = requests.get(url, headers=headers, allow_redirects=False) #拒绝默认的301/302重定向
musicLink = req.headers['Location'] #从而可以通过html.headers[‘Location’]拿到重定向的URL。
urllib.request.urlretrieve(musicLink,'data/'+SongName+".mp3") #下载并重命名文件
# 初始化engine
engine = pyttsx3.init()
# 合成语音
engine.say("即将为您播放 "+Songer+' 的 '+SongName)
engine.runAndWait()
# 初始化混响器
pygame.mixer.init()
filename = 'data/' + SongName+'.mp3'
# 加载音乐
pygame.mixer.music.load(filename)
# 循环播放
pygame.mixer.music.play()
# 天气播报
def weather():
# 存放的文件名称
file_path='data/weather-audio.wav'
# 百度需要的参数
APP_ID = '你的APP_ID'
API_KEY = '你的API_KEY'
SECRET_KEY = 'SECRET_KEY'
# 图灵需要的参数
TULING_KEY = '你的图灵appkey'
# 先调用录音函数
record(file_path)
# 语音转成文字的内容
weather_message =voice2text(APP_ID, API_KEY, SECRET_KEY, file_path)
print(weather_message)
#抓取中国天气网指定城主天气
#input_message=['播放杭州天气情况']
input2=''.join(weather_message) #转换成字符串
city_name=input2[2:4]
url='http://www.weather.com.cn/weather1d/101080101.shtml'
r = requests.get(url)
r.encoding = 'utf-8'
# 提取相关天气信息
date=r.json()["result"]['result']["date"]
templow=r.json()["result"]['result']["templow"]
temphigh=r.json()["result"]['result']["temphigh"]
tempnow=r.json()["result"]['result']["temp"]
week=r.json()["result"]['result']["week"]
tip=r.json()["result"]['result']["index"][3]["detail"]
weather=r.json()["result"]['result']['daily'][0]['night']['weather']
add=r.json()["result"]['result']["city"]
wind=r.json()["result"]['result']['winddirect']
WS=r.json()["result"]['result']["windpower"]
t = time.localtime() # 当前时间的纪元值
fmt = "%H %M"
now = time.strftime(fmt, t) # 将纪元值转化为包含时、分的字符串
now = now.split(' ') #以空格切割,将时、分放入名为now的列表中
hour = now[0]
minute = now[1]
wea='你好,今天是%s%s,现在北京时间%s时%s分,%s天气 %s,气温%s摄氏度~%s摄氏度,现在为%s摄氏度,%s,风力%s,%s'%(date,week,hour,minute,add,weather,templow,temphigh,tempnow,wind,WS,tip)
print(wea)
engine = pyttsx3.init()
engine.say('即将为您播放'+city_name+"天气情况")
engine.say(wea)
engine.runAndWait()
#GUI界面
import os
import wx
import pyttsx3
import requests
from bs4 import BeautifulSoup
import chardet
from lxml import html
from PIL import ImageFile
import urllib
import pygame
import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
# 注意要将界面用到的图片放到和main.py文件同级目录下
class Panel1(wx.Panel):
"""class Panel1 creates a panel with an image on it, inherits wx.Panel"""
def __init__(self, parent, id):
# create the panel
wx.Panel.__init__(self, parent,id)
try:
image_file = 'bg.png'
bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.bitmap1 = wx.StaticBitmap(self, -1, bmp1, (0, 0))
except IOError:
print ("Image file is not found") % ImageFile
raise SystemExit
pic1 = wx.Image("yinyue.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
pic2 = wx.Image("hudong.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
pic3 = wx.Image("tianqiqing.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
# 绘图按钮1,默认风格3D
self.button1 = wx.BitmapButton(self.bitmap1, -1, pic1, pos=(400, 350), style=0, size=(50, 50))
self.Bind(wx.EVT_BUTTON, self.On2Click, self.button1)
self.button1.SetDefault()
#绘图按钮2,默认风格3D
self.button2 = wx.BitmapButton(self.bitmap1, -1, pic2, pos = (80, 350),style=0,size=(50,50))
self.Bind(wx.EVT_BUTTON, self.On1Click, self.button2)
self.button2.SetDefault()
#绘图按钮3,默认风格3D
self.button3 = wx.BitmapButton(self.bitmap1, -1, pic3, pos = (240, 350),style=0,size=(50,50))
self.Bind(wx.EVT_BUTTON, self.On3Click, self.button3)
self.button3.SetDefault()
def On2Click(self, event):
print("音乐播放")
speaker.Speak("您已选择音乐播放模式 ")
music()
event.Skip()
def On1Click(self, event):
print("人机交互")
speaker.Speak("您已选择人机交互模式 ")
chatwithrobot()
event.Skip()
def On3Click(self, event):
print("天气播报")
speaker.Speak("您已选择天气播报模式 ")
weather()
event.Skip()
app = wx.App(False)
frame1 = wx.Frame(None, -1, title='小T', size=(600, 640))
# create the class instance
panel1 = Panel1(frame1, -1)
frame1.Show(True)
app.MainLoop()
原文链接: https://blog.csdn.net/aqqwvfbukn/article/details/106349903
本人小白一枚,刚写博客不久,不喜勿喷,如果有什么问题,还请各位指点,虚心求教