本文主要向大家介绍了机器人之人工智能语音识别系统开发,通过具体的内容向大家展现,希望对大家学习机器人有所帮助。
1.初始教程
1.登录百度云管理中心,点击管理控制台
2.进入后,下拉在已开通服务中选择百度语音
3.点击创建应用,得到以下应用
4.这里也可以查看它的相关技术文档
快速入门链接
2.文字合成语音
1.安装使用Python SDK,终端下:
pip install baidu-aip
技术文档链接
使用
from aip import AipSpeech""" 你的 APPID AK SK """APP_ID = '11793737'API_KEY = 'Mx8wLzbFk2VNVcjybf8lDzFH'SECRET_KEY = 'DEc7I5q18z7aazW22LKDgwGocZ8h9VdR'client = AipSpeech(APP_ID,API_KEY,SECRET_KEY)
result = client.synthesis("第一次把下列文字转成MP3语音","zh",1,{ "spd":4, "vol":7, "pit":8, "per":4})if not isinstance(result,dict): # 创建一个auido.mp3文件
with open("auido.mp3","wb") as f:
f.write(result)print(result) # 打印bytes字节
此时文件中会多出一个mp3结尾的文件,我们把改文字已经转换成语音写入在了该文件中
3.语音转义成文字
参考技术文档说明,这里支持的语音格式文件有:pcm(不压缩)、wav(不压缩,pcm编码)、amr(压缩格式)
我们需要借助第三方工具ffmpeg把任意格式的语音转移成pcm格式
3.1 ffmpeg说明:
FFmpeg 是一个自由软件,可以运行音频和视频多种格式的录影、转换、流功能包含了libavcodec——这是一个用于多个项目中音频和视频的解码器库,
以及libavformat——一个音频与视频格式转换库。说简单点,这个工具可以将wav wma mp3 等音频文件转换为 pcm 无压缩音频文件
下载链接:猛戳此处
或者此处链接:链接: https://pan.baidu.com/s/1-TEQZP9QbJSlGSYedyAUFw 密码: 2z8l
下载后解压缩(我把它放在了D盘下),注意可执行的exe文件是在文件的bin目录,配置我们的环境变量
配置后,在终端测试效果:
使用
技术文档SDK链接
我们用命令行对这个 auido.mp3 进行pcm格式的转换然后得到 audio.pcm
命令是 : ffmpeg -y -i audio.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 audio.pcm
from aip import AipSpeechimport os""" 你的 APPID AK SK """APP_ID = '11793737'API_KEY = 'Mx8wLzbFk2VNVcjybf8lDzFH'SECRET_KEY = 'DEc7I5q18z7aazW22LKDgwGocZ8h9VdR'client = AipSpeech(APP_ID,API_KEY,SECRET_KEY)# 读取文件filePath = "auido.mp3"def get_file_content(filePath): # 用于将任何形式的语音文件格式转化成pcm格式,这里使用的是py3.6的模板语法,其他版本可以使用字符串的格式化语法
os.system(f"ffmpeg -y -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
with open(f"{filePath}.pcm",'rb') as fp: return fp.read()# 识别本地文件liu = get_file_content(filePath)
res = client.asr(liu,'pcm',16000,{ 'dev_pid':1536})print(res) # 查看格式# {'corpus_no': '6599876657908188502', 'err_msg': 'success.', 'err_no': 0, # 'result': ['第一次把下列文字转MP3语音'], 'sn': '465883505901536653530'}if res.get("result"): print(res.get('result')[0])else: print(res)
# 注意这里转化后文件中会搓出一个auido.mp3.pcm格式的文件
相关参数说明:
View Code
4.输入语音实现自动交互
这里需要我们的图灵机器人技术,创建一个机器人
对我们的机器人进行相关设置
4.1 api接口使用
api接口文档说明地址:猛戳此处
接口地址://openapi.tuling123.com/openapi/api/v2
请求方式:只有两种,HTTP POST
测试:
import requestsimport json
apiKey = "d76b3e9669404fe7b5a1949466fd6376"userId = "taylor" # 机器人名称data = { # 请求的类型 0 文本 1 图片 2 音频
"reqType": 0, "perception": { "inputText": { "text": "你是谁"
}
}, "userInfo": { "apiKey": apiKey, "userId": userId
}
}
tuling_url = "//openapi.tuling123.com/openapi/api/v2"res = requests.post(tuling_url,json=data) # 请求url# 将返回信息解码res_dic = json.loads(res.content.decode("utf-8")) # type:dict# 得到返回信息中的文本信息res_type = res_dic.get("results")[0].get("values").get("text")print(res_type)
效果:
现在有文本信息了,我们可以调用上面的文本信息转换成语音,让它实现语音播放
third.py
import osfrom aip import AipSpeechfrom aip import AipNlp""" 你的 APPID AK SK """APP_ID = '11793737'API_KEY = 'Mx8wLzbFk2VNVcjybf8lDzFH'SECRET_KEY = 'DEc7I5q18z7aazW22LKDgwGocZ8h9VdR'client = AipSpeech(APP_ID,API_KEY,SECRET_KEY)# 用于将任何形式的语音文件格式转化成pcm格式# 这里使用的是py3.6的模板语法,其他语言可以使用字符串的格式化语法def get_file_content(filePath):
os.system(f"ffmpeg -y -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
with open(f"{filePath}.pcm",'rb') as fp: return fp.read()def text2audio(text):
result = client.synthesis(text, 'zh', 1, { "spd": 4, 'vol': 7, "pit": 8, "per": 4
}) if not isinstance(result, dict): # 创建一个auido.mp3文件
with open('auido.mp3', 'wb') as f:
f.write(result)
return get_file_content('auido.mp3')
test.py
import requestsimport jsonimport third
apiKey = "d76b3e9669404fe7b5a1949466fd6376"userId = "taylor" # 机器人名称data = { # 请求的类型 0 文本 1 图片 2 音频
"reqType": 0, "perception": { "inputText": { "text": "你是谁"
}
}, "userInfo": { "apiKey": apiKey, "userId": userId
}
}
tuling_url = "//openapi.tuling123.com/openapi/api/v2"res = requests.post(tuling_url,json=data) # 请求url# 将返回信息解码res_dic = json.loads(res.content.decode("utf-8")) # type:dict# 得到返回信息中的文本信息res_type = res_dic.get("results")[0].get("values").get("text")# 调用text2audio函数third.text2audio(res_type)
执行后,此时文件中会多出一个auido.mp3和一个auido.mp3.pcm文件,文件内容就是机器人对我们的文本回复的内容
5.web录音实现互动问答
5.1 websocket监听
ai.py
from flask import Flask,request,render_templatefrom geventwebsocket.handler import WebSocketHandlerfrom gevent.pywsgi import WSGIServerfrom geventwebsocket.websocket import WebSocket
app = Flask(__name__,template_folder="../templates")
@app.route("/index")def index(): # 获取请求的WebSocket对象
user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
print(user_socket) # <geventwebsocket.websocket.WebSocket object at 0x000002718C07F798>
print(request.remote_addr) # 远程ip地址127.0.0.1
while True: # 接收消息
msg = user_socket.receive() print(msg)
@app.route("/")def home(): return render_template("index.html")if __name__ == "__main__":
http_serv = WSGIServer(("0.0.0.0",9520),app,handler_class=WebSocketHandler)
http_serv.serve_forever()
index.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>Title</title></head><body></body><script type="application/javascript">
//创建 WebSocket 对象
var ws = new WebSocket("ws://127.0.0.1:9520/index");</script></html>
这里我们启动我们的程序,在浏览器输入//127.0.0.1:9520/,此时在pycharm上就会传回我们的websocket对象以及远程IP地址
我们利用websocket已经实现了前端与后端的交互吗,现在我们需要通过websocket把我们网页上录的语音换到后端去
5.2 recorder.js录音插件
recorder.js是HTML5录音插件,它可以实现在线录音。
部分浏览器还存在兼容性(如ie,Safari)
Chrome47以上以及QQ浏览器需要HTTPS支持
github下载地址为:https://github.com/mattdiamond/Recorderjs
html5 Audio常用属性和函数事件参考链接:https://blog.csdn.net/bright2017/article/details/80041448
项目构架
./
├── ai.py
├── static
│ └── recorder.js
└── templates
└── index.html
在index.html中导入我们的recorder.js
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>Title</title></head><body>{#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}<audio src="" autoplay controls id="player"></audio><br><button onclick="start_reco()">开始废话</button><br><button onclick="stop_reco()">发送语音</button></body><script src="/static/recorder.js"></script><script type="application/javascript">
// 创建WebSocket对象
var ws = new WebSocket("ws://127.0.0.1:5300/index"); var reco = null; //录音对象
// 创建AudioContext对象
// AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
var audio_context = new AudioContext(); //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
// 这里的|| 表示或者的关系,也就是能支持的浏览器 navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia); // 拿到媒体对象,允许音频对象 navigator.getUserMedia({audio: true}, create_stream, function (err) {
console.log(err)
}); //创建媒体流容器
function create_stream(user_media) { //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
// 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
// 然后来自MediaStream的音频就可以被播放和操作。
// MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
// 是个表现为音频源的AudioNode。
var stream_input = audio_context.createMediaStreamSource(user_media); // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流 reco = new Recorder(stream_input);
} function start_reco() { //开始录音 reco.record(); //往里面写流 } function stop_reco() { //停止录音 reco.stop(); //停止写入流 get_audio(); //调用自定义方法 reco.clear(); //清空容器 } // 获取音频
function get_audio() {
reco.exportWAV(function (wav_file) { // 发送数据给后端 ws.send(wav_file);
})
}</script></html>
启动程序后,点击开始按钮,后台会接收到一个bytearray类型的字符,这就是我们的声音字节,现在需要我们把它写入文件
修改我们的后台程序
from flask import Flask,request,render_templatefrom geventwebsocket.handler import WebSocketHandlerfrom gevent.pywsgi import WSGIServerfrom geventwebsocket.websocket import WebSocket
app = Flask(__name__,template_folder="../templates")
@app.route("/index")def index(): # 获取请求的WebSocket对象
user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
print(user_socket) # <geventwebsocket.websocket.WebSocket object at 0x000002718C07F798>
print(request.remote_addr) # 远程ip地址127.0.0.1
while True: # 接收消息
msg = user_socket.receive() if type(msg) == bytearray: # 写入文件123.wav
with open("123.wav", "wb") as f:
f.write(msg)
@app.route("/")def home(): return render_template("index.html")if __name__ == "__main__":
http_serv = WSGIServer(("0.0.0.0",5300),app,handler_class=WebSocketHandler)
http_serv.serve_forever()
此时重启文件,我们就能把我们的声音录制成一个123.wav格式的文件,这个就是我们录制的声音
5.3 整合以上内容
现在我们需要完成在浏览器输入语音,在线实时和图灵机器人交互的效果,我们把以上代码进行整合
流程:通过浏览器发送语音给后端-->后端将音频文件转成文字发个图灵机器人-->后端再讲图灵回执的文字转成音频文件-->回执的音频文件发送给前端
test.py
import requestsimport jsonimport third
apiKey = "d76b3e9669404fe7b5a1949466fd6376"userId = "taylor" # 机器人名称data = { # 请求的类型 0 文本 1 图片 2 音频
"reqType": 0, "perception": { "inputText": { "text": "你是谁"
}
}, "userInfo": { "apiKey": apiKey, "userId": userId
}
}
tuling_url = "//openapi.tuling123.com/openapi/api/v2"def to_tuling(question,user_id): # 修改请求参数中的inputText,也就是问题
data["perception"]["inputText"]["text"] = question # # 修改userInfo
data["userInfo"]["userId"] = user_id
res = requests.post(tuling_url,json=data) # 请求url
# 将返回信息解码
res_dic = json.loads(res.content.decode("utf-8")) # type:dict
# 得到返回信息中的文本信息
result = res_dic.get("results")[0].get("values").get("text") # print(res_type)
return result
third.py
import osfrom aip import AipSpeechfrom aip import AipNlpimport test""" 你的 APPID AK SK """APP_ID = '11793737'API_KEY = 'Mx8wLzbFk2VNVcjybf8lDzFH'SECRET_KEY = 'DEc7I5q18z7aazW22LKDgwGocZ8h9VdR'client = AipSpeech(APP_ID,API_KEY,SECRET_KEY)
nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)# 用于将任何形式的语音文件格式转化成pcm格式# 这里使用的是py3.6的模板语法,其他语言可以使用字符串的格式化语法def get_file_content(filePath):
os.system(f"ffmpeg -y -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
with open(f"{filePath}.pcm",'rb') as fp: return fp.read()def text2audio(text):
result = client.synthesis(text, 'zh', 1, { "spd": 4, 'vol': 7, "pit": 8, "per": 4
}) if not isinstance(result, dict): # 创建一个auido.mp3文件
with open('audio.mp3', 'wb') as f:
f.write(result) return 'audio.mp3'# 识别本地文件,转义成文本信息def audio2text(file_path):
a = client.asr(get_file_content(file_path), 'pcm', 16000, { 'dev_pid': 1536,
}) if a.get("result") : return a.get("result")[0]def my_nlp(q,uid):
a = test.to_tuling(q,uid) return a
index.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>Title</title></head><body>{#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}<audio src="" autoplay controls id="player"></audio><br><button onclick="start_reco()">开始废话</button><br><button onclick="stop_reco()">发送语音</button></body><script src="/static/recorder.js"></script><script type="application/javascript">
// 创建WebSocket对象,index后面的是userid,是图灵机器人需要的
var ws = new WebSocket("ws://127.0.0.1:5300/index/taylor"); var reco = null; //录音对象
// 创建AudioContext对象
// AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
var audio_context = new AudioContext(); //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
// 这里的|| 表示或者的关系,也就是能支持的浏览器 navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia); // 拿到媒体对象,允许音频对象 navigator.getUserMedia({audio: true}, create_stream, function (err) {
console.log(err)
}); //创建媒体流容器
function create_stream(user_media) { //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
// 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
// 然后来自MediaStream的音频就可以被播放和操作。
// MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
// 是个表现为音频源的AudioNode。
var stream_input = audio_context.createMediaStreamSource(user_media); // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流 reco = new Recorder(stream_input);
} function start_reco() { //开始录音 reco.record(); //往里面写流 } function stop_reco() { //停止录音 reco.stop(); //停止写入流 get_audio(); //调用自定义方法 reco.clear(); //清空容器 } // 获取音频
function get_audio() {
reco.exportWAV(function (wav_file) { // 发送数据给后端 ws.send(wav_file);
})
} // 接收到服务端数据时触发 ws.onmessage = function (data) {
console.log(data.data); //打印文件名 }</script></html>
ai.py -->执行文件
from flask import Flask,request,render_template,send_filefrom geventwebsocket.handler import WebSocketHandlerfrom gevent.pywsgi import WSGIServerfrom geventwebsocket.websocket import WebSocketimport third
app = Flask(__name__,template_folder="../templates",static_folder="../static")
@app.route("/index/<uid>")def index(uid): # 接收uid
# 获取请求的WebSocket对象
user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
print(user_socket) # print(request.remote_addr) # 远程ip地址
while True: # 接收消息
msg = user_socket.receive() if type(msg) == bytearray: # 写入文件123.wav
with open("123.wav", "wb") as f:
f.write(msg) # 将音频文件转换为文字
res_q = third.audio2text("123.wav") # 调用my_nlp函数,内部调用图灵机器人
res_a = third.my_nlp(res_q,uid) # 将文字转换为音频文件
file_name = third.text2audio(res_a) # 发送文件名给前端 user_socket.send(file_name)
@app.route("/")def home_page(): return render_template("index.html")
@app.route("/get_file/<file_name>") # 获取音频文件def get_file(file_name): # 此方法用于前端调取后端的音频文件,用于自动播放
return send_file(file_name)if __name__ == "__main__":
http_serv = WSGIServer(("0.0.0.0",5300),app,handler_class=WebSocketHandler)
http_serv.serve_forever()
相关说明:这里浏览器很关键,很容易失败,多试几个浏览器,我调试的是谷歌浏览器,需要我们把油猴插件关掉,还需要把静态文件路径加上
执行完后,页面打印台会输出一个audio.mp3文件
5.4 实现自动播放
实现页面自动播放生成的audio.mp3文件
index.html -->直接替换上面html的即可
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>Title</title></head><body>{#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}<audio src="" autoplay controls id="player"></audio><br><button onclick="start_reco()">开始废话</button><br><button onclick="stop_reco()">发送语音</button></body><script src="/static/recorder.js"></script><script type="application/javascript">
// 访问后端的get_file,得到一个文件名
var get_file = "//127.0.0.1:5300/get_file/"; // 创建WebSocket对象,index后面的是userid,是图灵机器人需要的
var ws = new WebSocket("ws://127.0.0.1:5300/index/taylor"); var reco = null; //录音对象
// 创建AudioContext对象
// AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
var audio_context = new AudioContext(); //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
// 这里的|| 表示或者的关系,也就是能支持的浏览器 navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia); // 拿到媒体对象,允许音频对象 navigator.getUserMedia({audio: true}, create_stream, function (err) {
console.log(err)
}); //创建媒体流容器
function create_stream(user_media) { //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
// 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
// 然后来自MediaStream的音频就可以被播放和操作。
// MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
// 是个表现为音频源的AudioNode。
var stream_input = audio_context.createMediaStreamSource(user_media); // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流 reco = new Recorder(stream_input);
} function start_reco() { //开始录音 reco.record(); //往里面写流 } function stop_reco() { //停止录音 reco.stop(); //停止写入流 get_audio(); //调用自定义方法 reco.clear(); //清空容器 } // 获取音频
function get_audio() {
reco.exportWAV(function (wav_file) { // 发送数据给后端 ws.send(wav_file);
})
} // 接收到服务端数据时触发 ws.onmessage = function (data) { // console.log(data.data); console.log(get_file + data.data); //打印文件名
// 修改id为player的src属性, document.getElementById("player").src = get_file + data.data;
}</script></html>
ok,下来就可以听到声音了
# 补充说明:这里生成的文件名我们给写死了,最好生成动态文件名,可以引入uuid,否则会出现缓存现象,得不到我们的效果
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标人工智能智能机器人频道!