Reputation: 2209
I'm trying to send a .wav audio file (blob) från JS to Python using Flask. I simply want to save the file on the Python end and be able to play it on my computer. Here is my try:
JS:
fetch(serverUrl, {
method: "post",
body: blob
});
Where blob is of the type Blob {size: 5040, type: "audio/wav;"}
Python:
@app.route('/messages', methods = ['POST'])
def api_message():
# Open file and write binary (blob) data
f = open('./file.wav', 'wb')
f.write(request.data)
f.close()
return "Binary message written!"
The file gets saved but only contains shitloads of [object BlobEvent]
. What am I doing wrong and how can I fix it?
Edit:
The audio samples are collected using MediaRecorder()
const mediaRecorder = new MediaRecorder(stream);
// Start
const chunks = [];
mediaRecorder.ondataavailable = e => {
chunks.push(e);
}
// On stop
blob = new Blob(chunks, {'type': 'audio/wav;'});
I tried playing the audio again on the client side and it works just fine:
const audio = document.createElement('audio');
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
Upvotes: 8
Views: 6975
Reputation: 6120
You can do it with the multipart file upload in javascript
export function uploadAudio(audioBlob) {
let data = new FormData();
data.append('file', audioBlob);
return axios
.post(`http://localhost:3030/audiorecog`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(res => {
console.log(res)
return res
});
}
In Python, you can receive the blob and save it
@app.route('/audiorecog', methods = ['GET', 'POST'])
def audiorecog():
if request.method == 'POST':
print("Recieved Audio File")
file = request.files['file']
print('File from the POST request is: {}'.format(file))
with open("audio.wav", "wb") as aud:
aud_stream = file.read()
aud.write(video_stream)
return "Success"
return 'Call from get'
Upvotes: 0
Reputation: 97672
You are passing an array of event objects to the Blob constructor not the audio data.
The data is e.data
, so your code should be
mediaRecorder.ondataavailable = e => {
chunks.push(e.data);
}
Upvotes: 5
Reputation: 171
Have you tried using FormData?
var form = new FormData();
form.append('file', BLOBDATA, FILENAME);
$.ajax({
type: 'POST',
url: 'ServerURL',
data: form, // Our pretty new form
cache: false,
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log(data);
});
On the python end, you could check if the data's there by doing something like:
@app.route('/messages', methods=['POST'])
def api_message():
app.logger.debug(request.files['file'].filename)
Upvotes: 0