一. 图灵机器人
介绍
图灵机器人是以语义技术为核心驱动的人工智能公司, 致力于 "让机器理解世界", 产品服务包括机器人开放平台. 机器人 os 和场景方案.\
官方地址为:
http://www.tuling123.com/
使用
首先得注册一个账号, 或者使用第 3 方登录, 都可以.
登录之后, 点击创建机器人
机器人名称, 可以是自己定义的名字
选择网站 -> 教育学习 -> 其他 输入简介
创建成功之后, 点击终端设置, 拉到最后.
可以看到 API 接入, 下面有一个 apikey, 待会会用到
右侧有一个窗口, 可以和机器人聊天
可以设置它的个人信息
测试聊天
星座下面的功能都要花钱的
技能扩展, 可以全开
使用 API
点击 API 文档, 1.0 的 API 已经下线了, 目前只有 2.0
编码方式
UTF-8(提搜用图灵 API 各个环节的编码方式均为 UTF-8)
接口地址
http://openapi.tuling123.com/openapi/api/v2
请求方式
HTTP POST
请求参数
请求参数为 JSON
请求实例
- {
- "reqType":0,
- "perception": {
- "inputText": {
- "text": "附近的酒店"
- },
- "inputImage": {
- "url": "imageUrl"
- },
- "selfInfo": {
- "location": {
- "city": "北京",
- "province": "北京",
- "street": "信息路"
- }
- }
- },
- "userInfo": {
- "apiKey": "",
- "userId": ""
- }
- }
- View Code
举例:
新建文件 tuling.py, 询问天气
- import requests
- import JSON
- apiKey = "6a944508fd5c4d499b9991862ea12345"
- userId = "xiao" # 名字可以随意, 必须是英文
- data = {
- # 请求的类型 0 文本 1 图片 2 音频
- "reqType": 0,
- # // 输入信息 (必要参数)
- "perception": {
- # 文本信息
- "inputText": {
- # 问题
- "text": "北京未来七天, 天气怎么样"
- }
- },
- # 用户必要信息
- "userInfo": {
- # 图灵机器人的 apikey
- "apiKey": apiKey,
- # 用户唯一标识
- "userId": userId
- }
- }
- tuling_url = "http://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)
- View Code
执行输出:
北京: 周二 09 月 11 日, 多云 南风微风, 最低气温 19 度, 最高气温 26 度
那么输出的文本, 可以调用百度 API, 转换为音频文件, 并自动播放!
修改 baidu_ai.py, 封装函数 text2audio
- import os
- from aip import AipSpeech
- from aip import AipNlp
- """你的 APPID AK SK"""
- APP_ID = '11212345'
- API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
- SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
- client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
- nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
- # 读取音频文件函数
- def get_file_content(filePath):
- cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
- os.system(cmd_str) # 调用系统命令 FFMPEG, 传入音频文件名即可
- with open(filePath + ".pcm", 'rb') as fp:
- return fp.read()
- def text2audio(text): # 文本转换为音频
- ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
- if not isinstance(ret, dict):
- with open('audio.mp3', 'wb') as f:
- f.write(ret)
- os.system("audio.mp3") # 打开系统默认的音频播放器
- View Code
修改 tuling.py, 调用函数 text2audio
- import requests
- import JSON
- import baidu_ai
- apiKey = "6a944508fd5c4d499b9991862ea12345"
- userId = "xiao" # 名字可以随意, 必须是英文
- data = {
- # 请求的类型 0 文本 1 图片 2 音频
- "reqType": 0,
- # // 输入信息 (必要参数)
- "perception": {
- # 文本信息
- "inputText": {
- # 问题
- "text": "北京未来七天, 天气怎么样"
- }
- },
- # 用户必要信息
- "userInfo": {
- # 图灵机器人的 apikey
- "apiKey": apiKey,
- # 用户唯一标识
- "userId": userId
- }
- }
- tuling_url = "http://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
- # 得到返回信息中的文本信息
- result = res_dic.get("results")[0].get("values").get("text")
- # print(res_type)
- baidu_ai.text2audio(result)
- View Code
执行 tuling.py, 它会自动打开音频播放器, 说: 北京: 周二 09 月 11 日, 多云 南风微风, 最低气温 19 度, 最高气温 26 度
关于图灵机器人的参数说明, 这里有一份别人整理好的
图灵机器人 2.0
POST: http://openapi.tuling123.com/openapi/api/v2
实现参数:
- {
- // 返回值类型 0 文本 1 图片 2 音频
- "reqType":0,
- // 输入信息 (必要参数)
- "perception": {
- // 文本信息 三者非必填, 但必有一填
- "inputText": {
- // 文本问题
- "text": "附近的酒店"
- },
- // 图片信息
- "inputImage": {
- // 提交图片地址
- "url": "imageUrl"
- },
- // 音频信息
- "inputMedia": {
- // 提交音频地址
- "url":"mediaUrl"
- }
- // 客户端属性 (非必要)
- "selfInfo": {
- // 地理位置信息 (非必要)
- "location": {
- // 城市
- "city": "北京",
- // 省份
- "province": "北京",
- // 街道
- "street": "信息路"
- }
- }
- },
- // 用户参数信息 (原版的 userid)
- "userInfo": {
- // apikey 应用的 key
- "apiKey": "",
- // 用户唯一标志
- "userId": ""
- }
- }
- {
- // 请求意图
- "intent": {
- // 输出功能 code
- "code": 10005,
- // 意图名称
- "intentName": "",
- // 意图动作名称
- "actionName": "",
- // 功能相关参数
- "parameters": {
- "nearby_place": "酒店"
- }
- },
- // 输出结果集
- "results": [
- {
- // 返回组 相同的 GroupType 为一组 0 为独立
- "groupType": 1,
- // 返回值类型 : 文本 (text); 连接 (url); 音频 (voice); 视频 (video); 图片 (image); 图文 (news)
- "resultType": "url",
- // 返回值
- "values": {
- "url": "http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=信息路
- "
- }
- },
- {
- // 此 GroupType 与 1 同组
- "groupType": 1,
- "resultType": "text",
- "values": {
- "text": "亲, 已帮你找到相关酒店信息"
- }
- }
- ]
- }
- View Code
或者参数官方 API 文档:
接下来, 还是使用前面的 whatyouname.m4a.
当问到 你的名字叫什么时? 说出: 我叫小青龙
当问到 其他问题时, 由 图灵机器人回答
修改 baidu_ai.py
- from aip import AipSpeech
- import time, os
- from baidu_nlp import nlp_client
- import tuling
- """你的 APPID AK SK"""
- APP_ID = '11212345'
- API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
- SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
- client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
- # nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
- # 读取音频文件函数
- def get_file_content(filePath):
- cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
- os.system(cmd_str) # 调用系统命令 FFMPEG, 传入音频文件名即可
- with open(filePath + ".pcm", 'rb') as fp:
- return fp.read()
- def text2audio(text): # 文本转换为音频
- ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
- if not isinstance(ret, dict):
- with open('audio.mp3', 'wb') as f:
- f.write(ret)
- os.system("audio.mp3") # 打开系统默认的音频播放器
- # 识别本地文件
- def audio2text(file_path):
- a = client.asr(get_file_content(file_path), 'pcm', 16000, {
- 'dev_pid': 1536,
- })
- # print(a["result"])
- if a.get("result") :
- return a.get("result")[0]
- def my_nlp(q,uid):
- a = "我不知道你在说什么"
- if nlp_client.simnet(q,"你的名字叫什么").get("score")>= 0.7:
- a = "我叫小青龙"
- return a
- a = tuling.to_tuling(q,uid)
- return a
- View Code
修改 baidu_nlp.py
- from aip import AipNlp
- APP_ID = '11212345'
- API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
- SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
- nlp_client = AipNlp(APP_ID,API_KEY,SECRET_KEY)
- """调用短文本相似度"""
- res = nlp_client.simnet("你叫什么名字","你的名字叫什么")
- print(res)
- # 如果相似度达到 70%
- if res.get("score")> 0.7:
- print("我叫青龙")
- View Code
修改 tuling.py
- import requests
- import JSON
- apiKey = "6a944508fd5c4d499b9991862ea12345"
- userId = "xiao" # 名字可以随意, 必须是英文
- data = {
- # 请求的类型 0 文本 1 图片 2 音频
- "reqType": 0,
- # // 输入信息 (必要参数)
- "perception": {
- # 文本信息
- "inputText": {
- # 问题
- "text": "北京今天天气怎么样"
- }
- },
- # 用户必要信息
- "userInfo": {
- # 图灵机器人的 apikey
- "apiKey": apiKey,
- # 用户唯一标识
- "userId": userId
- }
- }
- tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
- def to_tuling(q,user_id):
- # 修改请求参数中的 inputText, 也就是问题
- data["perception"]["inputText"]["text"] = q
- # 修改 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
- View Code
创建 main.py
- import baidu_ai
- uid = 1234
- file_name = "whatyouname.m4a"
- q = baidu_ai.audio2text(file_name)
- # print(q,'qqqqqqqqqq')
- a = baidu_ai.my_nlp(q,uid)
- # print(a,'aaaaaaaaa')
- baidu_ai.text2audio(a)
- View Code
执行 main.py, 执行之后, 会打开音频, 说: 我叫小青龙
修改 baidu_ai.py, 注释掉问题: 你的名字叫什么
执行 main.py, 执行之后, 会打开音频, 说: 我叫小青龙
修改 baidu_ai.py, 注释掉问题: 你的名字叫什么
View Code
再次执行 main.py, 执行之后, 会打开音频, 说: 叫我图灵机器人就可以了!
这样很麻烦, 每次问问题, 都要录制一段音频才可以!
接下来介绍使用 Web 录音, 实现自动化交互问答
二. Web 录音实现自动化交互问答
werkzeug
首先, 向大家介绍一下什么是 werkzeug,werkzeug 是一个 wsgi 工具包, 他也可以作为一个 Web 框架的底层库. 这里稍微说一下, werkzeug 不是一个微博服务器, 也不是一个 Web 框架, 而是一个工具包, 官方介绍说是一个 wsgi 工具包, 他可以作为一个 Web 框架的底层库, 因为它封装了好多 Web 框架的东西, 例如 request,response 等等.
例如我最常用的 flask 框架就是一个 werkzeug 为基础开发的, 它只能处理 HTTP 请求.
websocket
websocket 是一种网络通信协议, RFC6455 定义了它的通信标准
websocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行双全工通讯的协议.
为什么不用 werkzeug
HTTP 是一种无状态的, 无连接的, 单项应用层协议. HTTP 协议无法实现服务器主动向客户端发起消息!
websocket 是长连接 (连接长期存在),websocket 来接受前段发送的音频. 因为不知道用户什么时候发起录音!
正式开始
新建一个文件夹 web_ai
创建文件 ai.py, 使用 websocket 监听!
- from flask import Flask,request,render_template,send_file
- from geventwebsocket.handler import WebSocketHandler
- from gevent.pywsgi import WSGIServer
- from geventwebsocket.websocket import WebSocket
- App = Flask(__name__)
- @App.route("/index")
- def index():
- # 获取请求的 WebSocket 对象
- user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
- print(user_socket)
- print(request.remote_addr) # 远程 ip 地址
- while True:
- # 接收消息
- msg = user_socket.receive()
- print(msg)
- @App.route("/")
- def home_page():
- return render_template("index.html")
- if __name__ == '__main__':
- # 创建一个 WebSocket 服务器
- http_serv = WSGIServer(("0.0.0.0",5000),App,handler_class=WebSocketHandler)
- # 开始监听 HTTP 请求
- http_serv.serve_forever()
- View Code
创建目录 templates, 在此目录下, 新建文件 index.HTML, 创建 WebSocket 对象
- <!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:5000/index");
- </script>
- </HTML>
View Code
启动 flask, 访问首页:
注意: 此时页面是空白的, 不要惊讶!
查看 Pycharm 控制台输出:
- <geventwebsocket.websocket.WebSocket object at 0x000002EA6A3F39A0>
- 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 常用属性和函数事件, 请参考链接:
下载之后, 解压文件. 进入 dict 目录, 将 recorder.JS 复制到桌面上!
打开 flask 项目 web_ai, 进入目录 static, 将 recorder.JS 移动到此目录
项目结构如下:
./
├── 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:5000/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>
View Code
重启 flask, 访问网页, 效果如下:
点击允许麦克风
点击开始废话, 说一段话, 再点击停止!
查看 Pycharm 控制台输出:
- <geventwebsocket.websocket.WebSocket object at 0x000002515BFE3C10>
- 127.0.0.1 bytearray(b'RIFF$\x00\x04\x00WAVEfmt...\x10')
它返回一个 bytearray 数据, 这些都是流数据, 它可以保存为音频文件
修改 ai.py, 判断类型为 bytearray, 写入文件
- from flask import Flask,request,render_template,send_file
- from geventwebsocket.handler import WebSocketHandler
- from gevent.pywsgi import WSGIServer
- from geventwebsocket.websocket import WebSocket
- App = Flask(__name__)
- @App.route("/index")
- def index():
- # 获取请求的 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)
- @App.route("/")
- def home_page():
- return render_template("index.html")
- if __name__ == '__main__':
- # 创建一个 WebSocket 服务器
- http_serv = WSGIServer(("0.0.0.0",5000),App,handler_class=WebSocketHandler)
- # 开始监听 HTTP 请求
- http_serv.serve_forever()
- View Code
重启 flask, 重新录制一段声音. 就会发现项目目录, 多了一个文件 123.wav
打开这文件, 播放一下, 就是刚刚录制的声音!
获取文件名
将上一篇写的 baidu_ai.py 和 tuling.py 复制过来.
修改 baidu_ai.py, 修改 text2audio 函数, 返回文件名
- from aip import AipSpeech
- import time, os
- # from baidu_nlp import nlp_client
- import tuling
- """你的 APPID AK SK"""
- APP_ID = '11212345'
- API_KEY = 'pVxdhsXS1BIaiwYYNT712345'
- SECRET_KEY = 'BvHQOts27LpGFbt3RAOv84WfPCW12345'
- client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
- # nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
- # 读取音频文件函数
- def get_file_content(filePath):
- cmd_str = "ffmpeg -y -i %s -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm"%(filePath,filePath)
- os.system(cmd_str) # 调用系统命令 FFMPEG, 传入音频文件名即可
- with open(filePath + ".pcm", 'rb') as fp:
- return fp.read()
- def text2audio(text): # 文本转换为音频
- ret = client.synthesis(text, 'zh', 1, {'spd': 4, 'vol': 5, 'pit': 8, 'per': 4})
- if not isinstance(ret, dict):
- with open('audio.mp3', 'wb') as f:
- f.write(ret)
- # os.system("audio.mp3") # 打开系统默认的音频播放器
- return 'audio.mp3'
- # 识别本地文件
- def audio2text(file_path):
- a = client.asr(get_file_content(file_path), 'pcm', 16000, {
- 'dev_pid': 1536,
- })
- # print(a["result"])
- if a.get("result") :
- return a.get("result")[0]
- def my_nlp(q,uid):
- # a = "我不知道你在说什么"
- # if nlp_client.simnet(q,"你的名字叫什么").get("score")>= 0.7:
- # a = "我叫小青龙"
- # return a
- a = tuling.to_tuling(q,uid)
- return a
- View Code
修改 tuling.py
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import requests
- import JSON
- apiKey = "6a944508fd5c4d499b9991862ea12345"
- userId = "xiao" # 名字可以随意, 必须是英文
- data = {
- # 请求的类型 0 文本 1 图片 2 音频
- "reqType": 0,
- # // 输入信息 (必要参数)
- "perception": {
- # 文本信息
- "inputText": {
- # 问题
- "text": "北京今天天气怎么样"
- }
- },
- # 用户必要信息
- "userInfo": {
- # 图灵机器人的 apikey
- "apiKey": apiKey,
- # 用户唯一标识
- "userId": userId
- }
- }
- tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
- def to_tuling(q,user_id):
- # 修改请求参数中的 inputText, 也就是问题
- data["perception"]["inputText"]["text"] = q
- # 修改 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
- View Code
修改 ai.py, 导入模块 baidu_ai
- from flask import Flask,request,render_template,send_file
- from geventwebsocket.handler import WebSocketHandler
- from gevent.pywsgi import WSGIServer
- from geventwebsocket.websocket import WebSocket
- import baidu_ai
- App = Flask(__name__)
- @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 = baidu_ai.audio2text("123.wav")
- # 调用 my_nlp 函数, 内部调用图灵机器人
- res_a = baidu_ai.my_nlp(res_q, uid)
- # 将文字转换为音频文件
- file_name = baidu_ai.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__':
- # 创建一个 WebSocket 服务器
- http_serv = WSGIServer(("0.0.0.0",5000),App,handler_class=WebSocketHandler)
- # 开始监听 HTTP 请求
- http_serv.serve_forever()
- View Code
修改 index.HTML, 定义 ws.onmessage, 打印文件名
- <!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:5000/index/xiao");
- 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>
View Code
重启 flask, 访问网页, 重新录制一段声音
查看 Pycharm 控制台输出:
encoder : Lavc58.19.102 pcm_s16le size= 35kB time=00:00:01.10 bitrate= 256.0kbits/s speed=42.6x 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
<!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 = "http://127.0.0.1:5000/get_file/"; // 创建 WebSocket 对象, index 后面的是 userid, 是图灵机器人需要的 var ws = new WebSocket("ws://127.0.0.1:5000/index/xiao"); 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>
View Code
重启 flask, 刷新网页. 重新录制一段声音, 说: 你叫什么名字?
效果如下:
网页说: 在下江湖人称, 图灵机器人
声音很萌, 附上图片
来源: http://www.bubuko.com/infodetail-2922158.html