昨日内容回顾

  1. . 百度ai开放平台
  2. . AipSpeech技术,语言合成,语言识别
  3. . Nlp技术,短文本相似度
  4. . 实现一个简单的问答机器人
  5. . 语言识别 ffmpeg (目前所有音乐,视频领域,这个工具应用非常广泛)
  6. 在不要求采样率的情况下,它会根据文件后缀名自动转换
  7. ffmpeg a.mp3 a.wav

一、图灵机器人

介绍

图灵机器人 是以语义技术为核心驱动力的人工智能公司,致力于“让机器理解世界”,产品服务包括机器人开放平台、机器人OS和场景方案。

官方地址为:

http://www.tuling123.com/

使用

首先得注册一个账号,或者使用第3方登录,都可以。

登录之后,点击创建机器人

机器人名称,可以是自己定义的名字

选择网站->教育学习->其他 输入简介

创建成功之后,点击终端设置,拉到最后。

可以看到api接入,下面有一个apikey,待会会用到

右侧有一个窗口,可以和机器人聊天

可以设置它的个人信息

测试聊天

星座下面的功能都要花钱的

技能扩展,可以全开

使用api

点击api使用文档,1.0的api已经下线了。目前只有2.0

https://www.kancloud.cn/turing/www-tuling123-com/718227

编码方式

UTF-8(调用图灵API的各个环节的编码方式均为UTF-8)

接口地址

http://openapi.tuling123.com/openapi/api/v2

请求方式

HTTP POST

请求参数

请求参数格式为 json
请求示例:

  1. {
  2. "reqType":0,
  3. "perception": {
  4. "inputText": {
  5. "text": "附近的酒店"
  6. },
  7. "inputImage": {
  8. "url": "imageUrl"
  9. },
  10. "selfInfo": {
  11. "location": {
  12. "city": "北京",
  13. "province": "北京",
  14. "street": "信息路"
  15. }
  16. }
  17. },
  18. "userInfo": {
  19. "apiKey": "",
  20. "userId": ""
  21. }
  22. }

举例:

新建文件 tuling.py,询问天气

  1. import requests
  2. import json
  3.  
  4. apiKey = "6a944508fd5c4d499b9991862ea12345"
  5.  
  6. userId = "xiao" # 名字可以随意,必须是英文
  7. data = {
  8. # 请求的类型 0 文本 1 图片 2 音频
  9. "reqType": 0,
  10. # // 输入信息(必要参数)
  11. "perception": {
  12. # 文本信息
  13. "inputText": {
  14. # 问题
  15. "text": "北京未来七天,天气怎么样"
  16. }
  17. },
  18. # 用户必要信息
  19. "userInfo": {
  20. # 图灵机器人的apikey
  21. "apiKey": apiKey,
  22. # 用户唯一标识
  23. "userId": userId
  24. }
  25. }
  26.  
  27. tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
  28.  
  29. res = requests.post(tuling_url,json=data) # 请求url
  30. # 将返回信息解码
  31. res_dic = json.loads(res.content.decode("utf-8")) # type:dict
  32. # 得到返回信息中的文本信息
  33. res_type = res_dic.get("results")[0].get("values").get("text")
  34. print(res_type)

执行输出:

  1. 北京:周二 0911日,多云 南风微风,最低气温19度,最高气温26

那么输出的文本,可以调用百度api,转换为音频文件,并自动播放!

修改 baidu_ai.py,封装函数text2audio

  1. import os
  2. from aip import AipSpeech
  3. from aip import AipNlp
  4.  
  5. """ 你的 APPID AK SK """
  6. APP_ID = ''
  7. API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
  8. SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
  9.  
  10. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  11. nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
  12.  
  13. # 读取音频文件函数
  14. def get_file_content(filePath):
  15. cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
  16. os.system(cmd_str) # 调用系统命令ffmpeg,传入音频文件名即可
  17. with open(filePath + ".pcm", 'rb') as fp:
  18. return fp.read()
  19.  
  20. def text2audio(text): # 文本转换为音频
  21. ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
  22. if not isinstance(ret, dict):
  23. with open('audio.mp3', 'wb') as f:
  24. f.write(ret)
  25.  
  26. os.system("audio.mp3") # 打开系统默认的音频播放器

修改tuling.py,调用函数text2audio

  1. import requests
  2. import json
  3. import baidu_ai
  4.  
  5. apiKey = "6a944508fd5c4d499b9991862ea12345"
  6.  
  7. userId = "xiao" # 名字可以随意,必须是英文
  8. data = {
  9. # 请求的类型 0 文本 1 图片 2 音频
  10. "reqType": 0,
  11. # // 输入信息(必要参数)
  12. "perception": {
  13. # 文本信息
  14. "inputText": {
  15. # 问题
  16. "text": "北京未来七天,天气怎么样"
  17. }
  18. },
  19. # 用户必要信息
  20. "userInfo": {
  21. # 图灵机器人的apikey
  22. "apiKey": apiKey,
  23. # 用户唯一标识
  24. "userId": userId
  25. }
  26. }
  27.  
  28. tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
  29.  
  30. res = requests.post(tuling_url,json=data) # 请求url
  31. # 将返回信息解码
  32. res_dic = json.loads(res.content.decode("utf-8")) # type:dict
  33. # 得到返回信息中的文本信息
  34. result = res_dic.get("results")[0].get("values").get("text")
  35. # print(res_type)
  36.  
  37. baidu_ai.text2audio(result)

执行tuling.py,它会自动打开音频播放器,说: 北京:周二 09月11日,多云 南风微风,最低气温19度,最高气温26度

关于图灵机器人的参数说明,这里有一份别人整理好的

  1. 图灵机器人2.0
  2. POST: http://openapi.tuling123.com/openapi/api/v2
  3.  
  4. 实现参数:
  5. {
  6. // 返回值类型 0 文本 1图片 2音频
  7. "reqType":0,
  8. // 输入信息(必要参数)
  9. "perception": {
  10. // 文本信息 三者非必填,但必有一填
  11. "inputText": {
  12. // 文本问题
  13. "text": "附近的酒店"
  14. },
  15. // 图片信息
  16. "inputImage": {
  17. // 提交图片地址
  18. "url": "imageUrl"
  19. },
  20. // 音频信息
  21. "inputMedia": {
  22. // 提交音频地址
  23. "url":"mediaUrl"
  24. }
  25. // 客户端属性(非必要)
  26. "selfInfo": {
  27. // 地理位置信息(非必要)
  28. "location": {
  29. // 城市
  30. "city": "北京",
  31. // 省份
  32. "province": "北京",
  33. // 街道
  34. "street": "信息路"
  35. }
  36. }
  37. },
  38. // 用户参数信息(原版的userid)
  39. "userInfo": {
  40. // apikey 应用的key
  41. "apiKey": "",
  42. // 用户唯一标志
  43. "userId": ""
  44. }
  45. }
  46.  
  47. {
  48. // 请求意图
  49. "intent": {
  50. // 输出功能code
  51. "code": 10005,
  52. // 意图名称
  53. "intentName": "",
  54. // 意图动作名称
  55. "actionName": "",
  56. // 功能相关参数
  57. "parameters": {
  58. "nearby_place": "酒店"
  59. }
  60. },
  61. // 输出结果集
  62. "results": [
  63. {
  64. // 返回组 相同的 GroupType 为一组 0为独立
  65. "groupType": 1,
  66. // 返回值类型 : 文本(text);连接(url);音频(voice);视频(video);图片(image);图文(news)
  67. "resultType": "url",
  68. // 返回值
  69. "values": {
  70. "url": "http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=%E4%BF%A1%E6%81%AF%E8%B7%AF
  71.  
  72. "
  73. }
  74. },
  75. {
  76. // 此GroupType与 1 同组
  77. "groupType": 1,
  78. "resultType": "text",
  79. "values": {
  80. "text": "亲,已帮你找到相关酒店信息"
  81. }
  82. }
  83. ]
  84. }

或者参数官方API文档:

https://www.kancloud.cn/turing/www-tuling123-com/718227

接下来,还是使用前面的 whatyouname.m4a。

当问到 你的名字叫什么时?说出:我叫小青龙

当问到 其他问题时,由 图灵机器人回答

修改 baidu_ai.py

  1. from aip import AipSpeech
  2. import time, os
  3. from baidu_nlp import nlp_client
  4. import tuling
  5.  
  6. """ 你的 APPID AK SK """
  7. APP_ID = ''
  8. API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
  9. SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
  10.  
  11. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  12. # nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
  13.  
  14. # 读取音频文件函数
  15. def get_file_content(filePath):
  16. cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
  17. os.system(cmd_str) # 调用系统命令ffmpeg,传入音频文件名即可
  18. with open(filePath + ".pcm", 'rb') as fp:
  19. return fp.read()
  20.  
  21. def text2audio(text): # 文本转换为音频
  22. ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
  23. if not isinstance(ret, dict):
  24. with open('audio.mp3', 'wb') as f:
  25. f.write(ret)
  26.  
  27. os.system("audio.mp3") # 打开系统默认的音频播放器
  28.  
  29. # 识别本地文件
  30. def audio2text(file_path):
  31. a = client.asr(get_file_content(file_path), 'pcm', 16000, {
  32. 'dev_pid': 1536,
  33. })
  34.  
  35. # print(a["result"])
  36. if a.get("result") :
  37. return a.get("result")[0]
  38.  
  39. def my_nlp(q,uid):
  40. a = "我不知道你在说什么"
  41. if nlp_client.simnet(q,"你的名字叫什么").get("score") >= 0.7:
  42. a = "我叫小青龙"
  43. return a
  44.  
  45. a = tuling.to_tuling(q,uid)
  46. return a

修改 baidu_nlp.py

  1. from aip import AipNlp
  2.  
  3. APP_ID = ''
  4. API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
  5. SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
  6.  
  7. nlp_client = AipNlp(APP_ID,API_KEY,SECRET_KEY)
  8.  
  9. """ 调用短文本相似度 """
  10. res = nlp_client.simnet("你叫什么名字","你的名字叫什么")
  11. print(res)
  12.  
  13. # 如果相似度达到70%
  14. if res.get("score") > 0.7:
  15. print("我叫青龙")

修改tuling.py

  1. import requests
  2. import json
  3.  
  4. apiKey = "6a944508fd5c4d499b9991862ea12345"
  5.  
  6. userId = "xiao" # 名字可以随意,必须是英文
  7. data = {
  8. # 请求的类型 0 文本 1 图片 2 音频
  9. "reqType": 0,
  10. # // 输入信息(必要参数)
  11. "perception": {
  12. # 文本信息
  13. "inputText": {
  14. # 问题
  15. "text": "北京今天天气怎么样"
  16. }
  17. },
  18. # 用户必要信息
  19. "userInfo": {
  20. # 图灵机器人的apikey
  21. "apiKey": apiKey,
  22. # 用户唯一标识
  23. "userId": userId
  24. }
  25. }
  26.  
  27. tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
  28.  
  29. def to_tuling(q,user_id):
  30. # 修改请求参数中的inputText,也就是问题
  31. data["perception"]["inputText"]["text"] = q
  32. # 修改userInfo
  33. data["userInfo"]["userId"] = user_id
  34.  
  35. res = requests.post(tuling_url,json=data) # 请求url
  36. # 将返回信息解码
  37. res_dic = json.loads(res.content.decode("utf-8")) # type:dict
  38. # 得到返回信息中的文本信息
  39. result = res_dic.get("results")[0].get("values").get("text")
  40. # print(res_type)
  41.  
  42. return result

创建main.py

  1. import baidu_ai
  2.  
  3. uid = 1234
  4. file_name = "whatyouname.m4a"
  5. q = baidu_ai.audio2text(file_name)
  6. # print(q,'qqqqqqqqqq')
  7. a = baidu_ai.my_nlp(q,uid)
  8. # print(a,'aaaaaaaaa')
  9. baidu_ai.text2audio(a)

执行main.py,执行之后,会打开音频,说: 我叫小青龙

修改 baidu_ai.py,注释掉问题:你的名字叫什么

  1. from aip import AipSpeech
  2. import time, os
  3. from baidu_nlp import nlp_client
  4. import tuling
  5.  
  6. """ 你的 APPID AK SK """
  7. APP_ID = ''
  8. API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
  9. SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
  10.  
  11. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  12. # nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
  13.  
  14. # 读取音频文件函数
  15. def get_file_content(filePath):
  16. cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
  17. os.system(cmd_str) # 调用系统命令ffmpeg,传入音频文件名即可
  18. with open(filePath + ".pcm", 'rb') as fp:
  19. return fp.read()
  20.  
  21. def text2audio(text): # 文本转换为音频
  22. ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
  23. if not isinstance(ret, dict):
  24. with open('audio.mp3', 'wb') as f:
  25. f.write(ret)
  26.  
  27. os.system("audio.mp3") # 打开系统默认的音频播放器
  28.  
  29. # 识别本地文件
  30. def audio2text(file_path):
  31. a = client.asr(get_file_content(file_path), 'pcm', 16000, {
  32. 'dev_pid': 1536,
  33. })
  34.  
  35. # print(a["result"])
  36. if a.get("result") :
  37. return a.get("result")[0]
  38.  
  39. def my_nlp(q,uid):
  40. # a = "我不知道你在说什么"
  41. # if nlp_client.simnet(q,"你的名字叫什么").get("score") >= 0.7:
  42. # a = "我叫小青龙"
  43. # return a
  44.  
  45. a = tuling.to_tuling(q,uid)
  46. return a

再次执行main.py,执行之后,会打开音频,说:叫我图灵机器人就可以了!

这样很麻烦,每次问问题,都要录制一段音频才可以!

接下来介绍使用web录音,实现自动化交互问答

二、web录音实现自动化交互问答

werkzeug

首先,先向大家介绍一下什么是 werkzeug,Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等。

例如我最常用的 Flask 框架就是一 Werkzeug 为基础开发的,它只能处理HTTP请求

WebSocket

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

为什么不用werkzeug

HTTP 协议是一种无状态的、无连接的、单向的应用层协议。HTTP 协议无法实现服务器主动向客户端发起消息!

WebSockets 是长连接(连接长期存在),Web浏览器和服务器都必须实现 WebSockets 协议来建立和维护连接

这里使用flask作为后端程序,使用websocket来接收前端发送的音频。因为不知道用户啥时候发起录音!

正式开始

新建一个文件夹web_ai

创建文件ai.py,使用websocket监听!

  1. from flask import Flask,request,render_template,send_file
  2. from geventwebsocket.handler import WebSocketHandler
  3. from gevent.pywsgi import WSGIServer
  4. from geventwebsocket.websocket import WebSocket
  5.  
  6. app = Flask(__name__)
  7.  
  8. @app.route("/index")
  9. def index():
  10. # 获取请求的WebSocket对象
  11. user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
  12. print(user_socket)
  13. print(request.remote_addr) # 远程ip地址
  14. while True:
  15. # 接收消息
  16. msg = user_socket.receive()
  17. print(msg)
  18.  
  19. @app.route("/")
  20. def home_page():
  21. return render_template("index.html")
  22.  
  23. if __name__ == '__main__':
  24. # 创建一个WebSocket服务器
  25. http_serv = WSGIServer(("0.0.0.0",5000),app,handler_class=WebSocketHandler)
  26. # 开始监听HTTP请求
  27. http_serv.serve_forever()

创建目录templates,在此目录下,新建文件index.html,创建 WebSocket 对象

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6.  
  7. </head>
  8. <body>
  9.  
  10. </body>
  11.  
  12. <script type="application/javascript">
  13. //创建 WebSocket 对象
  14. var ws = new WebSocket("ws://127.0.0.1:5000/index");
  15.  
  16. </script>
  17. </html>

启动flask,访问首页:

注意:此时页面是空白的,不要惊讶!

查看Pycharm控制台输出:

  1. <geventwebsocket.websocket.WebSocket object at 0x000002EA6A3F39A0>
  2. 127.0.0.1

那么网页如何发送音频给后端呢?使用Recorder.js

Recorder

Recorder.js是HTML5录音插件,它可以实现在线录音。

它不支持ie,不支持Safari 其他ok,但是部分版本有点小要求
Chrome47以上以及QQ浏览器需要HTTPS的支持。注意:公网访问时,网页必须是HTTPS方式,否则无法录音!

github下载地址为:

https://github.com/mattdiamond/Recorderjs

关于html5 Audio常用属性和函数事件,请参考链接:

https://blog.csdn.net/bright2017/article/details/80041448

下载之后,解压文件。进入dict目录,将recorder.js复制到桌面上!

打开flask项目web_ai,进入目录static,将recorder.js移动到此目录

项目结构如下:

  1. ./
  2. ├── ai.py
  3. ├── static
  4.    └── recorder.js
  5. └── templates
  6. └── index.html

录制声音

修改index.html,导入recorder.js

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6.  
  7. </head>
  8. <body>
  9. {#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}
  10. <audio src="" autoplay controls id="player"></audio>
  11. <br>
  12. <button onclick="start_reco()">开始废话</button>
  13. <br>
  14. <button onclick="stop_reco()">发送语音</button>
  15. </body>
  16. <script src="/static/recorder.js"></script>
  17. <script type="application/javascript">
  18. // 创建WebSocket对象
  19. var ws = new WebSocket("ws://127.0.0.1:5000/index");
  20. var reco = null; //录音对象
  21. // 创建AudioContext对象
  22. // AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
  23. var audio_context = new AudioContext();
  24. //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
  25. // 这里的|| 表示或者的关系,也就是能支持的浏览器
  26. navigator.getUserMedia = (navigator.getUserMedia ||
  27. navigator.webkitGetUserMedia ||
  28. navigator.mozGetUserMedia ||
  29. navigator.msGetUserMedia);
  30.  
  31. // 拿到媒体对象,允许音频对象
  32. navigator.getUserMedia({audio: true}, create_stream, function (err) {
  33. console.log(err)
  34. });
  35.  
  36. //创建媒体流容器
  37. function create_stream(user_media) {
  38. //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
  39. // 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
  40. // 然后来自MediaStream的音频就可以被播放和操作。
  41. // MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
  42. // 是个表现为音频源的AudioNode。
  43. var stream_input = audio_context.createMediaStreamSource(user_media);
  44. // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流
  45. reco = new Recorder(stream_input);
  46. }
  47.  
  48. function start_reco() { //开始录音
  49. reco.record(); //往里面写流
  50. }
  51.  
  52. function stop_reco() { //停止录音
  53. reco.stop(); //停止写入流
  54. get_audio(); //调用自定义方法
  55. reco.clear(); //清空容器
  56. }
  57.  
  58. // 获取音频
  59. function get_audio() {
  60. reco.exportWAV(function (wav_file) {
  61. // 发送数据给后端
  62. ws.send(wav_file);
  63. })
  64. }
  65.  
  66. </script>
  67. </html>

重启flask,访问网页,效果如下:

点击允许麦克风

点击开始废话,说一段话,再点击停止!

查看Pycharm控制台输出:

  1. <geventwebsocket.websocket.WebSocket object at 0x000002515BFE3C10>
  2. 127.0.0.1
  3. bytearray(b'RIFF$\x00\x04\x00WAVEfmt...\x10')

它返回一个bytearray数据,这些都是流数据,它可以保存为音频文件

修改ai.py,判断类型为bytearray,写入文件

  1. from flask import Flask,request,render_template,send_file
  2. from geventwebsocket.handler import WebSocketHandler
  3. from gevent.pywsgi import WSGIServer
  4. from geventwebsocket.websocket import WebSocket
  5.  
  6. app = Flask(__name__)
  7.  
  8. @app.route("/index")
  9. def index():
  10. # 获取请求的WebSocket对象
  11. user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
  12. print(user_socket)
  13. print(request.remote_addr) # 远程ip地址
  14. while True:
  15. # 接收消息
  16. msg = user_socket.receive()
  17. if type(msg) == bytearray:
  18. # 写入文件123.wav
  19. with open("123.wav", "wb") as f:
  20. f.write(msg)
  21.  
  22. @app.route("/")
  23. def home_page():
  24. return render_template("index.html")
  25.  
  26. if __name__ == '__main__':
  27. # 创建一个WebSocket服务器
  28. http_serv = WSGIServer(("0.0.0.0",5000),app,handler_class=WebSocketHandler)
  29. # 开始监听HTTP请求
  30. http_serv.serve_forever()

重启flask,重新录制一段声音。就会发现项目目录,多了一个文件123.wav

打开这文件,播放一下,就是刚刚录制的声音!

获取文件名

将上一篇写的baidu_ai.py和tuling.py复制过来。

修改 baidu_ai.py,修改text2audio函数,返回文件名

  1. from aip import AipSpeech
  2. import time, os
  3. # from baidu_nlp import nlp_client
  4. import tuling
  5.  
  6. """ 你的 APPID AK SK """
  7. APP_ID = ''
  8. API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
  9. SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
  10.  
  11. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  12. # nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
  13.  
  14. # 读取音频文件函数
  15. def get_file_content(filePath):
  16. cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
  17. os.system(cmd_str) # 调用系统命令ffmpeg,传入音频文件名即可
  18. with open(filePath + ".pcm", 'rb') as fp:
  19. return fp.read()
  20.  
  21. def text2audio(text): # 文本转换为音频
  22. ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
  23. if not isinstance(ret, dict):
  24. with open('audio.mp3', 'wb') as f:
  25. f.write(ret)
  26.  
  27. # os.system("audio.mp3") # 打开系统默认的音频播放器
  28. return 'audio.mp3'
  29.  
  30. # 识别本地文件
  31. def audio2text(file_path):
  32. a = client.asr(get_file_content(file_path), 'pcm', 16000, {
  33. 'dev_pid': 1536,
  34. })
  35.  
  36. # print(a["result"])
  37. if a.get("result") :
  38. return a.get("result")[0]
  39.  
  40. def my_nlp(q,uid):
  41. # a = "我不知道你在说什么"
  42. # if nlp_client.simnet(q,"你的名字叫什么").get("score") >= 0.7:
  43. # a = "我叫小青龙"
  44. # return a
  45.  
  46. a = tuling.to_tuling(q,uid)
  47. return a

修改 tuling.py

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import requests
  4. import json
  5.  
  6. apiKey = "6a944508fd5c4d499b9991862ea12345"
  7.  
  8. userId = "xiao" # 名字可以随意,必须是英文
  9. data = {
  10. # 请求的类型 0 文本 1 图片 2 音频
  11. "reqType": 0,
  12. # // 输入信息(必要参数)
  13. "perception": {
  14. # 文本信息
  15. "inputText": {
  16. # 问题
  17. "text": "北京今天天气怎么样"
  18. }
  19. },
  20. # 用户必要信息
  21. "userInfo": {
  22. # 图灵机器人的apikey
  23. "apiKey": apiKey,
  24. # 用户唯一标识
  25. "userId": userId
  26. }
  27. }
  28.  
  29. tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
  30.  
  31. def to_tuling(q,user_id):
  32. # 修改请求参数中的inputText,也就是问题
  33. data["perception"]["inputText"]["text"] = q
  34. # 修改userInfo
  35. data["userInfo"]["userId"] = user_id
  36.  
  37. res = requests.post(tuling_url,json=data) # 请求url
  38. # 将返回信息解码
  39. res_dic = json.loads(res.content.decode("utf-8")) # type:dict
  40. # 得到返回信息中的文本信息
  41. result = res_dic.get("results")[0].get("values").get("text")
  42. # print(res_type)
  43.  
  44. return result

修改ai.py,导入模块baidu_ai

  1. from flask import Flask,request,render_template,send_file
  2. from geventwebsocket.handler import WebSocketHandler
  3. from gevent.pywsgi import WSGIServer
  4. from geventwebsocket.websocket import WebSocket
  5. import baidu_ai
  6.  
  7. app = Flask(__name__)
  8.  
  9. @app.route("/index/<uid>")
  10. def index(uid): # 接收uid
  11. # 获取请求的WebSocket对象
  12. user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
  13. print(user_socket)
  14. # print(request.remote_addr) # 远程ip地址
  15. while True:
  16. # 接收消息
  17. msg = user_socket.receive()
  18. if type(msg) == bytearray:
  19. # 写入文件123.wav
  20. with open("123.wav", "wb") as f:
  21. f.write(msg)
  22.  
  23. # 将音频文件转换为文字
  24. res_q = baidu_ai.audio2text("123.wav")
  25. # 调用my_nlp函数,内部调用图灵机器人
  26. res_a = baidu_ai.my_nlp(res_q, uid)
  27. # 将文字转换为音频文件
  28. file_name = baidu_ai.text2audio(res_a)
  29. # 发送文件名给前端
  30. user_socket.send(file_name)
  31.  
  32. @app.route("/")
  33. def home_page():
  34. return render_template("index.html")
  35.  
  36. @app.route("/get_file/<file_name>") # 获取音频文件
  37. def get_file(file_name): # 此方法用于前端调取后端的音频文件,用于自动播放
  38. return send_file(file_name)
  39.  
  40. if __name__ == '__main__':
  41. # 创建一个WebSocket服务器
  42. http_serv = WSGIServer(("0.0.0.0",5000),app,handler_class=WebSocketHandler)
  43. # 开始监听HTTP请求
  44. http_serv.serve_forever()

修改index.html,定义ws.onmessage,打印文件名

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6.  
  7. </head>
  8. <body>
  9. {#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}
  10. <audio src="" autoplay controls id="player"></audio>
  11. <br>
  12. <button onclick="start_reco()">开始废话</button>
  13. <br>
  14. <button onclick="stop_reco()">发送语音</button>
  15. </body>
  16. <script src="/static/recorder.js"></script>
  17. <script type="application/javascript">
  18. // 创建WebSocket对象,index后面的是userid,是图灵机器人需要的
  19. var ws = new WebSocket("ws://127.0.0.1:5000/index/xiao");
  20. var reco = null; //录音对象
  21. // 创建AudioContext对象
  22. // AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
  23. var audio_context = new AudioContext();
  24. //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
  25. // 这里的|| 表示或者的关系,也就是能支持的浏览器
  26. navigator.getUserMedia = (navigator.getUserMedia ||
  27. navigator.webkitGetUserMedia ||
  28. navigator.mozGetUserMedia ||
  29. navigator.msGetUserMedia);
  30.  
  31. // 拿到媒体对象,允许音频对象
  32. navigator.getUserMedia({audio: true}, create_stream, function (err) {
  33. console.log(err)
  34. });
  35.  
  36. //创建媒体流容器
  37. function create_stream(user_media) {
  38. //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
  39. // 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
  40. // 然后来自MediaStream的音频就可以被播放和操作。
  41. // MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
  42. // 是个表现为音频源的AudioNode。
  43. var stream_input = audio_context.createMediaStreamSource(user_media);
  44. // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流
  45. reco = new Recorder(stream_input);
  46. }
  47.  
  48. function start_reco() { //开始录音
  49. reco.record(); //往里面写流
  50. }
  51.  
  52. function stop_reco() { //停止录音
  53. reco.stop(); //停止写入流
  54. get_audio(); //调用自定义方法
  55. reco.clear(); //清空容器
  56. }
  57.  
  58. // 获取音频
  59. function get_audio() {
  60. reco.exportWAV(function (wav_file) {
  61. // 发送数据给后端
  62. ws.send(wav_file);
  63. })
  64. }
  65.  
  66. // 接收到服务端数据时触发
  67. ws.onmessage = function (data) {
  68. console.log(data.data); //打印文件名
  69. }
  70.  
  71. </script>
  72. </html>

重启flask,访问网页,重新录制一段声音

查看Pycharm控制台输出:

  1. encoder : Lavc58.19.102 pcm_s16le
  2. size= 35kB time=00:00:01.10 bitrate= 256.0kbits/s speed=42.6x
  3. video:0kB audio:35kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

它正在将文字转换为音频文件,并返回音频的文件名

上面执行完成之后,网页的console,就会返回文件名

这个文件名,就是text2audio函数返回的。

自动播放

那么页面如何自动播放这个audio.mp3文件呢?

只要修改网页id为player的src属性就可以了,路径必须是可以访问的!

修改index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6.  
  7. </head>
  8. <body>
  9. {#audio是HTML5的标签,autoplay表示自动播放,controls表示展示组件#}
  10. <audio src="" autoplay controls id="player"></audio>
  11. <br>
  12. <button onclick="start_reco()">开始废话</button>
  13. <br>
  14. <button onclick="stop_reco()">发送语音</button>
  15. </body>
  16. <script src="/static/recorder.js"></script>
  17. <script type="application/javascript">
  18. // 访问后端的get_file,得到一个文件名
  19. var get_file = "http://127.0.0.1:5000/get_file/";
  20. // 创建WebSocket对象,index后面的是userid,是图灵机器人需要的
  21. var ws = new WebSocket("ws://127.0.0.1:5000/index/xiao");
  22. var reco = null; //录音对象
  23. // 创建AudioContext对象
  24. // AudioContext() 构造方法创建了一个新的 AudioContext 对象 它代表了一个由音频模块链接而成的音频处理图, 每一个模块由 AudioNode 表示
  25. var audio_context = new AudioContext();
  26. //要获取音频和视频,需要用到getUserMedia。桌面平台支持的浏览器包括Chrome, Firefox, Opera和Edge。
  27. // 这里的|| 表示或者的关系,也就是能支持的浏览器
  28. navigator.getUserMedia = (navigator.getUserMedia ||
  29. navigator.webkitGetUserMedia ||
  30. navigator.mozGetUserMedia ||
  31. navigator.msGetUserMedia);
  32.  
  33. // 拿到媒体对象,允许音频对象
  34. navigator.getUserMedia({audio: true}, create_stream, function (err) {
  35. console.log(err)
  36. });
  37.  
  38. //创建媒体流容器
  39. function create_stream(user_media) {
  40. //AudioContext接口的createMediaStreamSource()方法用于创建一个新的MediaStreamAudioSourceNode 对象,
  41. // 需要传入一个媒体流对象(MediaStream对象)(可以从 navigator.getUserMedia 获得MediaStream对象实例),
  42. // 然后来自MediaStream的音频就可以被播放和操作。
  43. // MediaStreamAudioSourceNode 接口代表一个音频接口,是WebRTC MediaStream (比如一个摄像头或者麦克风)的一部分。
  44. // 是个表现为音频源的AudioNode。
  45. var stream_input = audio_context.createMediaStreamSource(user_media);
  46. // 给Recoder 创建一个空间,麦克风说的话,都可以录入。是一个流
  47. reco = new Recorder(stream_input);
  48. }
  49.  
  50. function start_reco() { //开始录音
  51. reco.record(); //往里面写流
  52. }
  53.  
  54. function stop_reco() { //停止录音
  55. reco.stop(); //停止写入流
  56. get_audio(); //调用自定义方法
  57. reco.clear(); //清空容器
  58. }
  59.  
  60. // 获取音频
  61. function get_audio() {
  62. reco.exportWAV(function (wav_file) {
  63. // 发送数据给后端
  64. ws.send(wav_file);
  65. })
  66. }
  67.  
  68. // 接收到服务端数据时触发
  69. ws.onmessage = function (data) {
  70. // console.log(data.data);
  71. console.log(get_file + data.data); //打印文件名
  72. // 修改id为player的src属性,
  73. document.getElementById("player").src = get_file + data.data;
  74. }
  75.  
  76. </script>
  77. </html>

重启flask,刷新网页。重新录制一段声音,说:你叫什么名字?

效果如下:

网页说:在下江湖人称,图灵机器人

声音很萌,附上图片

这只是针对于网页的,那么手机端如何实现呢?

也是同样的打开网页,或者内嵌API。

手机由于输入一段URL访问,非常麻烦。一般采用二维码

这是我做的图灵聊天机器人,注意:只能微信和手机QQ,因为这些APP能调用麦克风

前端使用 recorder.js+ajax

后端使用 flask,调用百度语言识别API+图灵机器人API

python 全栈开发,Day123(图灵机器人,web录音实现自动化交互问答)的更多相关文章

  1. 图灵机器人,web录音实现自动化交互问答

    一.图灵机器人 介绍 图灵机器人 是以语义技术为核心驱动力的人工智能公司,致力于“让机器理解世界”,产品服务包括机器人开放平台.机器人OS和场景方案. 官方地址为: http://www.tuling ...

  2. python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  3. 学习笔记之Python全栈开发/人工智能公开课_腾讯课堂

    Python全栈开发/人工智能公开课_腾讯课堂 https://ke.qq.com/course/190378 https://github.com/haoran119/ke.qq.com.pytho ...

  4. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  5. Win10构建Python全栈开发环境With WSL

    目录 Win10构建Python全栈开发环境With WSL 启动WSL 总结 对<Dev on Windows with WSL>的补充 Win10构建Python全栈开发环境With ...

  6. python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)

    python全栈开发笔记第二模块 第四章 :常用模块(第二部分)     一.os 模块的 详解 1.os.getcwd()    :得到当前工作目录,即当前python解释器所在目录路径 impor ...

  7. python全栈开发目录

    python全栈开发目录 Linux系列 python基础 前端~HTML~CSS~JavaScript~JQuery~Vue web框架们~Django~Flask~Tornado 数据库们~MyS ...

  8. Python全栈开发相关课程

    Python全栈开发 Python入门 Python安装 Pycharm安装.激活.使用 Python基础 Python语法 Python数据类型 Python进阶 面向对象 网络编程 并发编程 数据 ...

  9. Python 全栈开发【第0篇】:目录

    Python 全栈开发[第0篇]:目录   第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基 ...

随机推荐

  1. Spark进阶之路-Spark提交Jar包执行

    Spark进阶之路-Spark提交Jar包执行 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际开发中,使用spark-submit提交jar包是很常见的方式,因为用spark ...

  2. Hadoop生态圈-大数据生态体系快速入门篇

    Hadoop生态圈-大数据生态体系快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.大数据概念 1>.什么是大数据 大数据(big data):是指无法在一定时间 ...

  3. 3、Python-字符串

    下标 name = 'abcdef' print(name[0]) print(name[1]) print(name[2]) # a # b # c 切片 # 切片的语法:[起始:结束:步长] na ...

  4. Linux记录-清空文件内容

    $ : > filename $ > filename $ echo "" > filename $ echo > filename $ cat /dev/ ...

  5. NPOI 2.3

    样例 //设置员工编号单元格为文本格式 循环效率问题? IDataFormat dataformat = workbook.CreateDataFormat(); ICellStyle style1 ...

  6. Java Web之路(五)JSP

    一.jsp的3个指令 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: p ...

  7. u-boot移植(十二)---代码修改---支持DM9000网卡

    一.准备工作 1.1 原理图 CONFIG_DM9000_BASE 片选信号是接在nGCS4引脚,若要确定网卡的基地址,则要根据片选信号的接口去确定. 在三星2440的DATASHEET中memory ...

  8. aircrack-ng套件学习笔记

    Aircrack-ng套件 1.airdecap-ng 该工具主要用于对加密无线数据报文的解码. 1.当无线网络启用了WEP或者WPA-PASK加密,可以使用wireshark过滤,过滤条件为:IEE ...

  9. 列表控件QListWidget

    列表控件可以让我们以列表形式呈现内容,是界面更加有序美观.QListWidget列表控件应当与QListWidgetItem一起使用,后者作为项被添加入列表控件中,也就是说列表控件中的每一项都是一个Q ...

  10. tidb 架构 ~Tidb学习系列(3)

    tidb集群安装测试1 环境 3台机器2 配置   server1 pd服务+tidb-server   server2 tidb-kv   server3 tidb-kv3 环境配置命令   ser ...