我正在创建一个网络应用程序,该应用程序在浏览器中记录音频并将其发送到烧瓶后端以进行语音到文本转录和意图分类。 当我在不检查方法的情况下运行代码时(该代码已被注释掉),这就是命令行显示的内容。
127.0.0.1 - - [11/Jan/2021 06:50:00] "GET /result HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Admin\Desktop\Voice Assistant web\voice_assistant.py", line 22, in result
file = request.files['audio_data']
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\flask\debughelpers.py", line 96, in __getitem__
return oldcls.__getitem__(self, key)
File "C:\Users\Admin\Desktop\Voice Assistant web\virtualenv\lib\site-packages\werkzeug\datastructures.py", line 442, in __getitem__
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'audio_data'
127.0.0.1 - - [11/Jan/2021 06:50:00] "GET /result?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [11/Jan/2021 06:50:00] "GET /result?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [11/Jan/2021 06:50:00] "GET /result?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [11/Jan/2021 06:50:00] "GET /result?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
hello
2021-01-11 06:50:11.906955: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:116] None of the MLIR optimization passes are enabled (registered 2)
There is 78 percent chance that you are trying to get the weather!
127.0.0.1 - - [11/Jan/2021 06:50:13] "POST /result HTTP/1.1" 200 -
如您所见,它首先尝试使用 GET 方法并返回错误。之后,它尝试使用 POST 请求,结果在命令行中返回,但从未在浏览器中显示 - 错误消息保留在那里。 当我检查该方法是 POST 还是 GET 时,它会使用 GET 执行代码。 如何让它接收 POST 请求?
这是我的python代码。
from flask import Flask, render_template, request, redirect, url_for
from werkzeug.utils import secure_filename
import os
from intent_classification import ICModel
from voice_to_text import VTTModel
IC = ICModel()
VTT = VTTModel()
app=Flask(__name__)
app.config['AUDIO_UPLOADS'] = 'audio_file/'
@app.route("/")
def home():
return render_template("index.html")
@app.route("/result", methods=['POST','GET'])
def result():
#if(request.method=='POST'):
print(request.files)
file = request.files['audio_data']
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['AUDIO_UPLOADS'], filename))
actual_file = 'audio_file/' + filename
text = VTT.infer(actual_file)
print(text)
intent = IC.predict(text)
print(intent)
os.remove(actual_file)
return render_template("result.html", pred = intent, text = text)
#else:
#return redirect(url_for('home'))
if __name__ == "__main__":
app.run(debug=True)
这是我的 html。
{% extends "base.html" %}
{% block content %}
<h1 class="font-bold text-5xl text-white mt-5 mb-10">What is on your mind?</h1>
<div class="flex items-center">
<img id="record" src="/static/images/record.jpg" alt="record"
width="150px" height="150px" class="rounded-xl mx-10"
onClick="startRecording()">
<img id="stop" src="/static/images/stop.jpg" alt="stop"
width="150px" height="150px" class="rounded-xl mx-10"
onClick="stopRecording()">
</div>
<form action="/result" method="POST">
<input type="submit" id="check"
class="rounded-lg bg-green-400 hover:bg-green-600 shadow-lg text-xl text-white font-bold my-6 px-16 py-1"
onclick="upload()" value="Check intent">
</form>
<h2 id="prompt" class="font-bold text-3xl text-white my-10" hidden="true">Listening...</h2>
<div>
<h3 class="text-3xl text-white mt-10 mb-5">
You can request the following:
</h3>
<ul class="text-xl text-white text-center">
<li>adding a song to a playlist</li>
<li>playing music</li>
<li>booking a table at a restaurant</li>
<li>getting the weather</li>
<li>searching for creative work</li>
<li>rating a book</li>
<li>searching for a screening event</li>
</ul>
</div>
<script>
URL = window.URL || window.webkitURL;
var gumStream;
var rec;
var input;
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext;
var constraints = {
audio: true,
video: false
}
var recordButton = document.getElementById("record");
var stopButton = document.getElementById("stop");
var checkButton = document.getElementById("check")
var promptMessage = document.getElementById("prompt");
recordButton.disabled=false;
stopButton.disabled=true;
checkButton.disabled=true;
promptMessage.hidden = true;
function startRecording()
{
console.log("Recording started.")
recordButton.disabled = true;
stopButton.disabled = false;
promptMessage.hidden=false;
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
console.log("getUserMedia() success, stream created, initializing Recorder.js ...");
gumStream = stream;
input = audioContext.createMediaStreamSource(stream);
rec = new Recorder(input, {
numChannels: 1
})
rec.record()
}).catch(function(err) {
recordButton.disabled = false;
stopButton.disabled = true;
promptMessage.hidden=true;
});
}
function stopRecording()
{
console.log("Recording stopped.")
stopButton.disabled = true;
recordButton.disabled = false;
checkButton.disabled = false;
promptMessage.hidden=true;
rec.stop();
gumStream.getAudioTracks()[0].stop();
}
function upload()
{
console.log("Audio being exported.")
checkButton.disabled = true;
var filename = "audio_recording.wav";
rec.exportWAV(function(blob) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
var fd = new FormData();
fd.append('audio_data', blob, filename);
/* try {
let r = await fetch('/result', {method: "POST", body: fd});
console.log('HTTP response code:',r.status);
} catch(e) {
console.log(e);
} */
var xhr = new XMLHttpRequest();
xhr.open('POST', '/result', true);
xhr.send(fd);
});
}
</script>
{% endblock %}
答案 0 :(得分:0)
你说得对。
在通过 fetch 或 XMLHttpRequest 进行传输之前发送表单。您可以使用表单的提交事件来执行您的 javascript 函数。调用 preventDefault
会阻止表单的标准行为。
<form onsubmit="upload(event)">
<input type="submit" value="Check intent" />
</form>
function upload(evt) {
evt.preventDefault();
let filename = "audio_recording.wav";
rec.exportWAV(function(blob) {
let fd = new FormData();
fd.append("audio_data", blob, filename);
fetch("/result", { method: "POST", body: fd })
.then(resp => { console.log(resp); })
.catch(err => { console.error(err); });
});
}
您希望如何使用服务器的响应?
目前您在浏览器中使用 ajax 函数并以 html 页面的形式从服务器发送响应。如果您使用 jsonify
您可以在客户端使用 JSON 格式的服务器响应。
我也建议您检查一下音频文件是否已经传输。
以下是一种快速而肮脏的方法。
from flask import jsonify, make_response # , abort
@app.route('/result', methods=['POST'])
def result():
print(request.files)
af = request.files.get('audio_data')
if not af: # if 'audio_data' not in request.files
# see also abort(400, description='missing audio data')
return make_response(jsonify(error='missing audio data'), 400)
# ... process your audio file here ...
return jsonify(text="lorem ipsum", intent="no-idea");
fetch('/result', { method: "POST", body: fd })
.then(resp => resp.json())
.then(data => {
if ("error" in data) {
console.error(data.error);
} else {
console.log(data);
let elem;
if (elem = document.getElementById("output")) elem.innerHTML = data.text;
if (elem = document.getElementById("intent")) elem.innerHTML = data.intent;
}
})
.catch(err => { console.error(err); });
根据您的要求,您应该查看Web Speech API。