通过AI+图灵机器+Flask实现的只能问答

后端代码AI代码:

 1 from aip import AipSpeech
 2 from  aip import AipNlp
 3 from  uuid import  uuid4
 4 import  tulin
 5 import os
 6 """ 你的 APPID AK SK """
 7 APP_ID = '14940739'
 8 API_KEY = 'xCnr5K8ESsmOVaA5bl5ot5QY'
 9 SECRET_KEY = '4wH7W92hPUp8V7ogY4BZzV2pcZ3nC8LH '
10 
11 client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
12 client_nlp = AipNlp(APP_ID, API_KEY, SECRET_KEY)
13 
14 def get_file_content(filename):
15     os.system(f"ffmpeg -y  -i {filename}  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filename}.pcm")
16     with open(f"{filename}.pcm", 'rb') as fp:
17         res = client.asr(fp.read(), 'pcm', 16000, {
18             'dev_pid': 1536,
19         })
20         print("res",res)
21         return  res.get("result")[0]
22 
23 def  yycd(text):
24     filename = uuid4()
25     result = client.synthesis(text, 'zh', 1, {
26         "spd": 4,
27         'vol': 5,
28         "pit": 8,
29         "per": 4
30     })
31     # 识别正确返回语音二进制 错误则返回dict 参照下面错误码
32     if not isinstance(result, dict):
33         with open(f'{filename}.mp3', 'wb') as f:
34             f.write(result)
35     print("yuyin2",filename)
36     return f'{filename}.mp3'
37 
38 
39 def my_nlp(text):
40 
41     if client_nlp.simnet("你叫什么名字", text).get("score") >= 0.7:
42       return  yycd("我的名字叫大王八")
43 
44     if client_nlp.simnet("你今年多大了", text).get("score") >= 0.7:
45         return yycd("我今年9岁了")
46 
47     else:
48         return  yycd(tulin.tulin(text, "DragonFire"))
后端AI代码

后端Flask代码:

 1 from geventwebsocket.handler import WebSocketHandler
 2 from gevent.pywsgi import WSGIServer
 3 from geventwebsocket.websocket import WebSocket
 4 
 5 from uuid import uuid4
 6 
 7 from flask import Flask,render_template,request,send_file
 8 
 9 import yuyin2
10 
11 app = Flask(__name__)
12 
13 @app.route("/")
14 def index():
15     return render_template("index.html")
16 
17 @app.route("/ws")
18 def ws():
19     user_socket = request.environ.get("wsgi.websocket") # type: WebSocket
20     while 1:
21         audio_file = user_socket.receive()
22         file_name = uuid4()
23         with open(f"{file_name}.wav","wb") as f:
24             f.write(audio_file)
25         text = yuyin2.get_file_content(f"{file_name}.wav")
26         filename = yuyin2.my_nlp(text)
27         print(filename)
28         user_socket.send(filename)
29 
30 @app.route("/get_audio/<filename>")
31 def get_audio(filename):
32     return send_file(filename)
33 
34 
35 
36 if __name__ == '__main__':
37     # app.run()
38     http_serv = WSGIServer(("0.0.0.0",5000),app,handler_class=WebSocketHandler)
39     http_serv.serve_forever()
Flask代码

图灵机器人接口代码

 1 import  requests
 2 
 3 tuling_url = "http://openapi.tuling123.com/openapi/api/v2"
 4 atr = {
 5     "reqType": 0,
 6     "perception": {
 7         "inputText": {
 8             "text": "讲个故事"
 9         },
10     },
11     "userInfo": {
12         "apiKey": "3fbeb66884dc4e789a764c649c2fe19d",
13         "userId": "123"
14     }
15 }
16 def tulin(Q,uid):
17     atr["perception"]["inputText"]["text"]=Q
18     atr["userInfo"]["userId"]=uid
19     res = requests.post(tuling_url, json=atr)
20     res_json=res.json()
21     print(res_json.get("results")[0]["values"]["text"])
22     return res_json.get("results")[0]["values"]["text"]
接口代码

前端代码:

界面需要浏览器使用录音机功能,需要导入Rcorder.js文件

Rcorder.js文件代码如下:

  1 (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){
  2 "use strict";
  3 
  4 module.exports = require("./recorder").Recorder;
  5 
  6 },{"./recorder":2}],2:[function(require,module,exports){
  7 'use strict';
  8 
  9 var _createClass = (function () {
 10     function defineProperties(target, props) {
 11         for (var i = 0; i < props.length; i++) {
 12             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);
 13         }
 14     }return function (Constructor, protoProps, staticProps) {
 15         if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
 16     };
 17 })();
 18 
 19 Object.defineProperty(exports, "__esModule", {
 20     value: true
 21 });
 22 exports.Recorder = undefined;
 23 
 24 var _inlineWorker = require('inline-worker');
 25 
 26 var _inlineWorker2 = _interopRequireDefault(_inlineWorker);
 27 
 28 function _interopRequireDefault(obj) {
 29     return obj && obj.__esModule ? obj : { default: obj };
 30 }
 31 
 32 function _classCallCheck(instance, Constructor) {
 33     if (!(instance instanceof Constructor)) {
 34         throw new TypeError("Cannot call a class as a function");
 35     }
 36 }
 37 
 38 var Recorder = exports.Recorder = (function () {
 39     function Recorder(source, cfg) {
 40         var _this = this;
 41 
 42         _classCallCheck(this, Recorder);
 43 
 44         this.config = {
 45             bufferLen: 4096,
 46             numChannels: 2,
 47             mimeType: 'audio_pcm/wav'
 48         };
 49         this.recording = false;
 50         this.callbacks = {
 51             getBuffer: [],
 52             exportWAV: []
 53         };
 54 
 55         Object.assign(this.config, cfg);
 56         this.context = source.context;
 57         this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels);
 58 
 59         this.node.onaudioprocess = function (e) {
 60             if (!_this.recording) return;
 61 
 62             var buffer = [];
 63             for (var channel = 0; channel < _this.config.numChannels; channel++) {
 64                 buffer.push(e.inputBuffer.getChannelData(channel));
 65             }
 66             _this.worker.postMessage({
 67                 command: 'record',
 68                 buffer: buffer
 69             });
 70         };
 71 
 72         source.connect(this.node);
 73         this.node.connect(this.context.destination); //this should not be necessary
 74 
 75         var self = {};
 76         this.worker = new _inlineWorker2.default(function () {
 77             var recLength = 0,
 78                 recBuffers = [],
 79                 sampleRate = undefined,
 80                 numChannels = undefined;
 81 
 82             self.onmessage = function (e) {
 83                 switch (e.data.command) {
 84                     case 'init':
 85                         init(e.data.config);
 86                         break;
 87                     case 'record':
 88                         record(e.data.buffer);
 89                         break;
 90                     case 'exportWAV':
 91                         exportWAV(e.data.type);
 92                         break;
 93                     case 'getBuffer':
 94                         getBuffer();
 95                         break;
 96                     case 'clear':
 97                         clear();
 98                         break;
 99                 }
100             };
101 
102             function init(config) {
103                 sampleRate = config.sampleRate;
104                 numChannels = config.numChannels;
105                 initBuffers();
106             }
107 
108             function record(inputBuffer) {
109                 for (var channel = 0; channel < numChannels; channel++) {
110                     recBuffers[channel].push(inputBuffer[channel]);
111                 }
112                 recLength += inputBuffer[0].length;
113             }
114 
115             function exportWAV(type) {
116                 var buffers = [];
117                 for (var channel = 0; channel < numChannels; channel++) {
118                     buffers.push(mergeBuffers(recBuffers[channel], recLength));
119                 }
120                 var interleaved = undefined;
121                 if (numChannels === 2) {
122                     interleaved = interleave(buffers[0], buffers[1]);
123                 } else {
124                     interleaved = buffers[0];
125                 }
126                 var dataview = encodeWAV(interleaved);
127                 var audioBlob = new Blob([dataview], { type: type });
128 
129                 self.postMessage({ command: 'exportWAV', data: audioBlob });
130             }
131 
132             function getBuffer() {
133                 var buffers = [];
134                 for (var channel = 0; channel < numChannels; channel++) {
135                     buffers.push(mergeBuffers(recBuffers[channel], recLength));
136                 }
137                 self.postMessage({ command: 'getBuffer', data: buffers });
138             }
139 
140             function clear() {
141                 recLength = 0;
142                 recBuffers = [];
143                 initBuffers();
144             }
145 
146             function initBuffers() {
147                 for (var channel = 0; channel < numChannels; channel++) {
148                     recBuffers[channel] = [];
149                 }
150             }
151 
152             function mergeBuffers(recBuffers, recLength) {
153                 var result = new Float32Array(recLength);
154                 var offset = 0;
155                 for (var i = 0; i < recBuffers.length; i++) {
156                     result.set(recBuffers[i], offset);
157                     offset += recBuffers[i].length;
158                 }
159                 return result;
160             }
161 
162             function interleave(inputL, inputR) {
163                 var length = inputL.length + inputR.length;
164                 var result = new Float32Array(length);
165 
166                 var index = 0,
167                     inputIndex = 0;
168 
169                 while (index < length) {
170                     result[index++] = inputL[inputIndex];
171                     result[index++] = inputR[inputIndex];
172                     inputIndex++;
173                 }
174                 return result;
175             }
176 
177             function floatTo16BitPCM(output, offset, input) {
178                 for (var i = 0; i < input.length; i++, offset += 2) {
179                     var s = Math.max(-1, Math.min(1, input[i]));
180                     output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
181                 }
182             }
183 
184             function writeString(view, offset, string) {
185                 for (var i = 0; i < string.length; i++) {
186                     view.setUint8(offset + i, string.charCodeAt(i));
187                 }
188             }
189 
190             function encodeWAV(samples) {
191                 var buffer = new ArrayBuffer(44 + samples.length * 2);
192                 var view = new DataView(buffer);
193 
194                 /* RIFF identifier */
195                 writeString(view, 0, 'RIFF');
196                 /* RIFF chunk length */
197                 view.setUint32(4, 36 + samples.length * 2, true);
198                 /* RIFF type */
199                 writeString(view, 8, 'WAVE');
200                 /* format chunk identifier */
201                 writeString(view, 12, 'fmt ');
202                 /* format chunk length */
203                 view.setUint32(16, 16, true);
204                 /* sample format (raw) */
205                 view.setUint16(20, 1, true);
206                 /* channel count */
207                 view.setUint16(22, numChannels, true);
208                 /* sample rate */
209                 view.setUint32(24, sampleRate, true);
210                 /* byte rate (sample rate * block align) */
211                 view.setUint32(28, sampleRate * 4, true);
212                 /* block align (channel count * bytes per sample) */
213                 view.setUint16(32, numChannels * 2, true);
214                 /* bits per sample */
215                 view.setUint16(34, 16, true);
216                 /* data chunk identifier */
217                 writeString(view, 36, 'data');
218                 /* data chunk length */
219                 view.setUint32(40, samples.length * 2, true);
220 
221                 floatTo16BitPCM(view, 44, samples);
222 
223                 return view;
224             }
225         }, self);
226 
227         this.worker.postMessage({
228             command: 'init',
229             config: {
230                 sampleRate: this.context.sampleRate,
231                 numChannels: this.config.numChannels
232             }
233         });
234 
235         this.worker.onmessage = function (e) {
236             var cb = _this.callbacks[e.data.command].pop();
237             if (typeof cb == 'function') {
238                 cb(e.data.data);
239             }
240         };
241     }
242 
243     _createClass(Recorder, [{
244         key: 'record',
245         value: function record() {
246             this.recording = true;
247         }
248     }, {
249         key: 'stop',
250         value: function stop() {
251             this.recording = false;
252         }
253     }, {
254         key: 'clear',
255         value: function clear() {
256             this.worker.postMessage({ command: 'clear' });
257         }
258     }, {
259         key: 'getBuffer',
260         value: function getBuffer(cb) {
261             cb = cb || this.config.callback;
262             if (!cb) throw new Error('Callback not set');
263 
264             this.callbacks.getBuffer.push(cb);
265 
266             this.worker.postMessage({ command: 'getBuffer' });
267         }
268     }, {
269         key: 'exportWAV',
270         value: function exportWAV(cb, mimeType) {
271             mimeType = mimeType || this.config.mimeType;
272             cb = cb || this.config.callback;
273             if (!cb) throw new Error('Callback not set');
274 
275             this.callbacks.exportWAV.push(cb);
276 
277             this.worker.postMessage({
278                 command: 'exportWAV',
279                 type: mimeType
280             });
281         }
282     }], [{
283         key: 'forceDownload',
284         value: function forceDownload(blob, filename) {
285             var url = (window.URL || window.webkitURL).createObjectURL(blob);
286             var link = window.document.createElement('a');
287             link.href = url;
288             link.download = filename || 'output.wav';
289             var click = document.createEvent("Event");
290             click.initEvent("click", true, true);
291             link.dispatchEvent(click);
292         }
293     }]);
294 
295     return Recorder;
296 })();
297 
298 exports.default = Recorder;
299 
300 },{"inline-worker":3}],3:[function(require,module,exports){
301 "use strict";
302 
303 module.exports = require("./inline-worker");
304 },{"./inline-worker":4}],4:[function(require,module,exports){
305 (function (global){
306 "use strict";
307 
308 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; }; })();
309 
310 var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
311 
312 var WORKER_ENABLED = !!(global === global.window && global.URL && global.Blob && global.Worker);
313 
314 var InlineWorker = (function () {
315   function InlineWorker(func, self) {
316     var _this = this;
317 
318     _classCallCheck(this, InlineWorker);
319 
320     if (WORKER_ENABLED) {
321       var functionBody = func.toString().trim().match(/^functions*w*s*([ws,]*)s*{([wW]*?)}$/)[1];
322       var url = global.URL.createObjectURL(new global.Blob([functionBody], { type: "text/javascript" }));
323 
324       return new global.Worker(url);
325     }
326 
327     this.self = self;
328     this.self.postMessage = function (data) {
329       setTimeout(function () {
330         _this.onmessage({ data: data });
331       }, 0);
332     };
333 
334     setTimeout(function () {
335       func.call(self);
336     }, 0);
337   }
338 
339   _createClass(InlineWorker, {
340     postMessage: {
341       value: function postMessage(data) {
342         var _this = this;
343 
344         setTimeout(function () {
345           _this.self.onmessage({ data: data });
346         }, 0);
347       }
348     }
349   });
350 
351   return InlineWorker;
352 })();
353 
354 module.exports = InlineWorker;
355 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
356 },{}]},{},[1])(1)
357 });
Recorder代码
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta http-equiv="x-ua-compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>Title</title>
 8 </head>
 9 <body>
10 <audio  controls autoplay id="player" src="/static/audio.mp3"></audio>
11 <button onclick="start_reco()">开始录音</button>
12 <button  onclick="stop_reco()">发送消息</button>
13 
14 </body>
15 <script src="/static/Recorder.js"></script>
16 <script type="text/javascript">
17     var reco = null;
18     var ws = new WebSocket("ws://127.0.0.1:5000/ws");
19     ws.onmessage=function (data) {
20         console.log(data.data);
21         document.getElementById("player").src = "http://127.0.0.1:5000/get_audio/" + data.data;
22     };
23     var audio_context = new AudioContext();
24     navigator.getUserMedia = (navigator.getUserMedia ||
25         navigator.webkitGetUserMedia ||
26         navigator.mozGetUserMedia ||
27         navigator.msGetUserMedia);
28 
29     navigator.getUserMedia({audio: true}, create_stream, function (err) {
30         console.log(err)
31     });
32 
33     function create_stream(user_media) {
34         var stream_input = audio_context.createMediaStreamSource(user_media);
35         reco = new Recorder(stream_input);
36     }
37 
38     function start_reco() {
39         reco.record();
40     }
41 
42     function stop_reco() {
43         reco.stop();
44         get_audio();
45         reco.clear();
46     }
47 
48      function get_audio() {
49         reco.exportWAV(function (wav_file) {
50           //wav_file 录音文件 Blob
51             console.log(wav_file);
52             ws.send(wav_file)
53         })
54     }
55 
56 </script>
57 </html>
前端代码
原文地址:https://www.cnblogs.com/duanhaoxin/p/10028953.html