正在将.wav文件从前端发送到Flask后端



我正在尝试从浏览器中的麦克风中捕获音频,将其转换为wav格式,并将其发送到烧瓶后端,以便对其进行转录并对请求进行意图分类。然而,出现此错误:

werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'audio_data'
Traceback (most recent call last)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflask_compat.py", line 39, in reraise
raise value
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflask_compat.py", line 39, in reraise
raise value
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskapp.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:UsersAdminDesktopVoice Assistant webvoice_assistant.py", line 17, in result
data = request.files['audio_data']
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packagesflaskdebughelpers.py", line 96, in __getitem__
return oldcls.__getitem__(self, key)
File "C:UsersAdminDesktopVoice Assistant webvirtualenvlibsite-packageswerkzeugdatastructures.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'

这是我的python代码:

from flask import Flask, render_template, request, redirect, url_for
from intent_classification import ICModel
from voice_to_text import VTTModel
IC = ICModel()
VTT = VTTModel()
app=Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
@app.route("/result", methods=['POST','GET'])
def result():
if(request.method=='POST'):
data = request.data['audio_data']
text = VTT.infer(data)
print(text)
intent = IC.predict(text)
print(intent)
return render_template("result.html", pred = intent, text = text)
else:
return redirect(url_for('home'))
if __name__ == "__main__":
app.run(debug=True)

这是我的前端:

{% 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>
<a id="check" href="/result" method="POST" 
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()">Check intent</a>
<h2 id="prompt" class="font-bold text-3xl text-white my-10">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 = new Date().toISOString();
rec.download()
rec.exportWAV(function(blob) {
/* var xhr = new XMLHttpRequest();
xhr.onload = function(e) {
if (this.readyState === 4) {
console.log("Server returned: ", e.target.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 %}

正如您所看到的,我也尝试过使用XMLHttpRequest来执行此操作,但没有成功——同样的错误也发生了。我分不清是从后端还是从前端。我看了其他模拟问题,看起来我没有做错什么。如果有任何帮助,我将不胜感激。

我认为您应该使用request.files来访问服务器端传输的数据。

@app.route('/result', methods=['GET', 'POST'])
def result():
if request.method == 'POST':
print(request.files)
data = request.files['audio_data'].read()
print(data)

# ...

return render_template('result.html', **locals())
else:
return redirect(url_for('home'))

最新更新