话不多说,直接怼代码,有不懂的,可以留言

简单的实现,前后端的语音交互。

import os
from uuid import uuid4
from aip import AipSpeech
from aip import AipNlp import settings """ 你的 APPID AK SK """
APP_ID = ''
API_KEY = 'KqqpO9GclBimrcSNrSANPhUQ'
SECRET_KEY = 'xc7IFW4w6DVtuNQlMkBX05Ulhx5Mm5zh' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
nlp_client = AipNlp(APP_ID, API_KEY, SECRET_KEY) # 音频转为文本
def audio2text(file_name):
file_path = os.path.join(settings.AUDIO_PCM_DIR, file_name)
cmd_str = f'ffmpeg -y -i {file_path} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {file_path}.pcm'
os.system(cmd_str)
with open(f'{file_path}.pcm', 'rb') as f:
audio_context = f.read()
res = client.asr(audio_context, 'pcm', 16000, {
"dev_pid": 1537
})
print("res",res)
if res.get('err_no'):
return res
return res.get('result')[0] # 文本转为音频
def text2audio(text):
file_name = f"{uuid4()}.mp3"
file_path = os.path.join(settings.AUDIO_DIR, file_name)
res = client.synthesis(text, 'zh', 1, {
"vol": 5,
'pit': 7,
"spd": 4,
"per": 4
})
if isinstance(res, dict):
return res
with open(file_path, 'wb') as f:
f.write(res)
return file_name # 词法的匹配分析
def my_nlp(text):
print("text", nlp_client.simnet('你今年几岁了', text))
if nlp_client.simnet('你今年几岁了', text).get('score') >= 0.72:
return '我今年73了,不然84也行'
elif nlp_client.simnet('你叫什么名字', text).get('score') >= 0.72:
return '我的名字叫傻逼'
elif nlp_client.simnet('你在哪儿学习',text).get('score') >= 0.72:
return '我在老男孩教育'
else:
return '不知道你在说什么'

封装百度的AI接口

html页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<audio autoplay="autoplay"
controls id="play_mp3"
src="http://127.0.0.1:5000/getfile/ad74226f-3646-40d5-9548-7e817f1cb405.mp3">
浏览器不支持
</audio>
<button onclick="start_reco()">开始录音</button>
<button onclick="stop_reco()">结束录音</button>
</body>
<script type="text/javascript" src="/static/Recorder.js"></script>
<script type="text/javascript">
//建立 websocket 连接
var ws = new WebSocket('ws://127.0.0.1:5000/upload');
// ws.onopen = function () {
// ws.send("hello")
// }; // 如何录音
var reco = null;
// 创建一个录音audiocontext对象
var audio_context = new AudioContext();
// 解决浏览器的兼容问题
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia); navigator.getUserMedia({audio:true},create_stream,function (err) {
console.log(err)
}); function create_stream(stream) {
var stream_input = audio_context.createMediaStreamSource(stream);
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 (ev) {
// 从ev.data中获取参数
var data = JSON.parse(ev.data);
document.getElementById("play_mp3").src = "http://127.0.0.1:5000/getfile/"+data.filename;
} </script>
</html>

后端flask 实现逻辑

import os
import json
from uuid import uuid4 from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.websocket import WebSocket
from gevent.pywsgi import WSGIServer
from flask import Flask,request,render_template,send_file
import baidu_aip
import settings app = Flask(__name__) # type:Flask @app.route('/index')
def index():
return render_template('index.html') @app.route('/getfile/<filename>')
def getfile(filename):
file_path = os.path.join(settings.AUDIO_DIR,filename)
return send_file(file_path) @app.route('/upload')
def upload():
ws = request.environ.get('wsgi.websocket')
if not ws:
return '请使用websocket连接' while True:
message = ws.receive()
if isinstance(message,bytearray):
# if message:
file_name = f"{uuid4()}.wav"
file_path = os.path.join(settings.AUDIO_PCM_DIR,file_name)
with open(file_path,'wb') as f:
f.write(message)
asr_str = baidu_aip.audio2text(file_name)
answer = baidu_aip.my_nlp(asr_str)
file_mp3_name = baidu_aip.text2audio(answer)
send_dic = json.dumps({
"filename":file_mp3_name,
"play_type":'audio',
"sendtime":111
})
ws.send(send_dic)
else:
ws.close() if __name__ == '__main__':
http_server = WSGIServer(('127.0.0.1',5000),app,handler_class=WebSocketHandler)
http_server.serve_forever()

附上Recorder.js源码

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Recorder = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict"; module.exports = require("./recorder").Recorder; },{"./recorder":2}],2:[function(require,module,exports){
'use strict'; var _createClass = (function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
})(); Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Recorder = undefined; var _inlineWorker = require('inline-worker'); var _inlineWorker2 = _interopRequireDefault(_inlineWorker); function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
} function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
} var Recorder = exports.Recorder = (function () {
function Recorder(source, cfg) {
var _this = this; _classCallCheck(this, Recorder); this.config = {
bufferLen: 4096,
numChannels: 2,
mimeType: 'audio_pcm/wav'
};
this.recording = false;
this.callbacks = {
getBuffer: [],
exportWAV: []
}; Object.assign(this.config, cfg);
this.context = source.context;
this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels); this.node.onaudioprocess = function (e) {
if (!_this.recording) return; var buffer = [];
for (var channel = 0; channel < _this.config.numChannels; channel++) {
buffer.push(e.inputBuffer.getChannelData(channel));
}
_this.worker.postMessage({
command: 'record',
buffer: buffer
});
}; source.connect(this.node);
this.node.connect(this.context.destination); //this should not be necessary var self = {};
this.worker = new _inlineWorker2.default(function () {
var recLength = 0,
recBuffers = [],
sampleRate = undefined,
numChannels = undefined; self.onmessage = function (e) {
switch (e.data.command) {
case 'init':
init(e.data.config);
break;
case 'record':
record(e.data.buffer);
break;
case 'exportWAV':
exportWAV(e.data.type);
break;
case 'getBuffer':
getBuffer();
break;
case 'clear':
clear();
break;
}
}; function init(config) {
sampleRate = config.sampleRate;
numChannels = config.numChannels;
initBuffers();
} function record(inputBuffer) {
for (var channel = 0; channel < numChannels; channel++) {
recBuffers[channel].push(inputBuffer[channel]);
}
recLength += inputBuffer[0].length;
} function exportWAV(type) {
var buffers = [];
for (var channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
var interleaved = undefined;
if (numChannels === 2) {
interleaved = interleave(buffers[0], buffers[1]);
} else {
interleaved = buffers[0];
}
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type }); self.postMessage({ command: 'exportWAV', data: audioBlob });
} function getBuffer() {
var buffers = [];
for (var channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength));
}
self.postMessage({ command: 'getBuffer', data: buffers });
} function clear() {
recLength = 0;
recBuffers = [];
initBuffers();
} function initBuffers() {
for (var channel = 0; channel < numChannels; channel++) {
recBuffers[channel] = [];
}
} function mergeBuffers(recBuffers, recLength) {
var result = new Float32Array(recLength);
var offset = 0;
for (var i = 0; i < recBuffers.length; i++) {
result.set(recBuffers[i], offset);
offset += recBuffers[i].length;
}
return result;
} function interleave(inputL, inputR) {
var length = inputL.length + inputR.length;
var result = new Float32Array(length); var index = 0,
inputIndex = 0; while (index < length) {
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
} function floatTo16BitPCM(output, offset, input) {
for (var i = 0; i < input.length; i++, offset += 2) {
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
} function writeString(view, offset, string) {
for (var i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
} function encodeWAV(samples) {
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer); /* RIFF identifier */
writeString(view, 0, 'RIFF');
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, 'WAVE');
/* format chunk identifier */
writeString(view, 12, 'fmt ');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, numChannels, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
view.setUint32(28, sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, numChannels * 2, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
writeString(view, 36, 'data');
/* data chunk length */
view.setUint32(40, samples.length * 2, true); floatTo16BitPCM(view, 44, samples); return view;
}
}, self); this.worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate,
numChannels: this.config.numChannels
}
}); this.worker.onmessage = function (e) {
var cb = _this.callbacks[e.data.command].pop();
if (typeof cb == 'function') {
cb(e.data.data);
}
};
} _createClass(Recorder, [{
key: 'record',
value: function record() {
this.recording = true;
}
}, {
key: 'stop',
value: function stop() {
this.recording = false;
}
}, {
key: 'clear',
value: function clear() {
this.worker.postMessage({ command: 'clear' });
}
}, {
key: 'getBuffer',
value: function getBuffer(cb) {
cb = cb || this.config.callback;
if (!cb) throw new Error('Callback not set'); this.callbacks.getBuffer.push(cb); this.worker.postMessage({ command: 'getBuffer' });
}
}, {
key: 'exportWAV',
value: function exportWAV(cb, mimeType) {
mimeType = mimeType || this.config.mimeType;
cb = cb || this.config.callback;
if (!cb) throw new Error('Callback not set'); this.callbacks.exportWAV.push(cb); this.worker.postMessage({
command: 'exportWAV',
type: mimeType
});
}
}], [{
key: 'forceDownload',
value: function forceDownload(blob, filename) {
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var link = window.document.createElement('a');
link.href = url;
link.download = filename || 'output.wav';
var click = document.createEvent("Event");
click.initEvent("click", true, true);
link.dispatchEvent(click);
}
}]); return Recorder;
})(); exports.default = Recorder; },{"inline-worker":3}],3:[function(require,module,exports){
"use strict"; module.exports = require("./inline-worker");
},{"./inline-worker":4}],4:[function(require,module,exports){
(function (global){
"use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var WORKER_ENABLED = !!(global === global.window && global.URL && global.Blob && global.Worker); var InlineWorker = (function () {
function InlineWorker(func, self) {
var _this = this; _classCallCheck(this, InlineWorker); if (WORKER_ENABLED) {
var functionBody = func.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1];
var url = global.URL.createObjectURL(new global.Blob([functionBody], { type: "text/javascript" })); return new global.Worker(url);
} this.self = self;
this.self.postMessage = function (data) {
setTimeout(function () {
_this.onmessage({ data: data });
}, 0);
}; setTimeout(function () {
func.call(self);
}, 0);
} _createClass(InlineWorker, {
postMessage: {
value: function postMessage(data) {
var _this = this; setTimeout(function () {
_this.self.onmessage({ data: data });
}, 0);
}
}
}); return InlineWorker;
})(); module.exports = InlineWorker;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}]},{},[1])(1)
});

基于flask和百度AI接口实现前后端的语音交互的更多相关文章

  1. 基于Flask和百度AI实现与机器人对话

    实现对话机器人主要有个步骤 : 一.前端收集语音传入后端 二.后端基于百度AI接口进行语音识别,转换成文字 三.对文字进行自定义验证或通过图灵端口进行处理,生成回复内容 四.将文字通过百度AI接口合成 ...

  2. [初识]使用百度AI接口,图灵机器人实现简单语音对话

    一.准备 1.百度ai开放平台提供了优质的接口资源https://ai.baidu.com/  (基本免费) 2.在语音识别的接口中, 对中文来说, 讯飞的接口是很好的选择https://www.xf ...

  3. Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)

    Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享)  点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...

  4. RESTful、共用接口、前后端分离、接口约定的实践 (转)

    出处:  某小公司RESTful.共用接口.前后端分离.接口约定的实践 前言 随着互联网高速发展,公司对项目开发周期不断缩短,我们面对各种需求,使用原有对接方式,各端已经很难快速应对各种需求,更难以提 ...

  5. 微信小程序aes前后端加密解密交互

    aes前后端加密解密交互 小程序端 1. 首先引入aes.js /** * [description] CryptoJS v3.1.2 * [description] zhuangzhudada so ...

  6. 前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构

    前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构

  7. Python人工智能-基于百度AI接口

    参考百度AI官网:http://ai.baidu.com/ 准备工作: 支持Python版本:2.7.+ ,3.+ 安装使用Python SDK有如下方式 >如果已经安装了pip,执行 pip ...

  8. 使用百度ai接口加图灵机器人完成简单web版语音对话

    app文件 from flask import Flask, request, render_template, jsonify, send_file from uuid import uuid4 i ...

  9. django--调用百度AI接口实现人脸注册登录

    面部识别----考勤打卡.注册登录.面部支付等等...感觉很高大上,又很方便,下面用python中的框架--django完成一个注册登录的功能,调用百度AI的接口,面部识别在网上也有好多教程,可以自己 ...

随机推荐

  1. redux connect的浅比较说明

    redux的connect方法是一个高阶组件,对包装的组件会在ShouldComponentUpdate中实现一个默认的浅比较. connect形式如下: connect([mapStateToPro ...

  2. jq的$.each遍历数组

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Codeforces Round #341 (Div. 2)B

    B. Wet Shark and Bishops time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  4. Network LCA修改点权

    Problem Description The ALPC company is now working on his own network system, which is connecting a ...

  5. 在Linux防火墙上过滤外来的ICMP timestamp

    ICMP timestamp请求响应漏洞 解决方案:  * 在您的防火墙上过滤外来的ICMP timestamp(类型13)报文以及外出的ICMP timestamp回复报文.     具体解决方式就 ...

  6. 深度解析Java多线程的内存模型

    内部java内存模型 硬件层面的内存模型 Java内存模型和硬件内存模型的联系 共享对象的可见性 资源竞速 Java内存模型很好的说明了JVM是如何在内存里工作的,JVM可以理解为java执行的一个操 ...

  7. java 7修改文件权限

    Full control over file attributes is available in Java 7, as part of the "new" New IO faci ...

  8. 【Contest Hunter【弱省胡策】Round #0-Flower Dance】组合数学+DP

    题目链接: http://ch.ezoj.tk/contest/%E3%80%90%E5%BC%B1%E7%9C%81%E8%83%A1%E7%AD%96%E3%80%91Round%20%230/F ...

  9. 【BZOJ】1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

    [题意]给定n头牛,k个特色,给出每头牛拥有哪些特色的二进制对应数字,[i,j]平衡当且仅当第i~j头牛的所有特色数量都相等,求最长区间长度. [算法]平衡树+数学转化 [题解]统计前缀和sum[i] ...

  10. oracle scott用户不存在

    scott用户拥有一些基础的数据表,可以供我们练习sql.先执行 alter user scott account unlock; 查看scott用户是否存在 当scott用户不存在,我们就需要在$O ...