Sur le frontend, j'ai un blob audio que j'essaie d'envoyer à un backend Flask où je dois faire un traitement sur l'audio.
Actuellement, je poste l'audio sous forme de chaîne base64 dans Flask. Dans Flask, j'encode la chaîne en base64 et j'essaye de la sauvegarder dans le système de fichiers local. Il est enregistré en tant que fichier Webm, mais, lorsque j'essaie de lire l'audio, il est de 0 seconde même si la chaîne base64 est enregistrée dans le fichier.
Savez-vous pourquoi l'audio peut ne pas être jouer correctement? Comment puis-je faire jouer correctement l'audio sur le backend?
Frontend:
@app.route('/api/audio', methods=['POST']) def audio(): content = request.get_json(silent=True) print(type(content["message"])) #This is type string ans = base64.b64encode(bytes(content["message"], 'utf-8')) print(type(ans)) #This is type bytes with open("audioToSave.webm", "wb") as fh: fh.write(base64.b64decode(ans)) theAnswer = 'no' return theAnswer
Backend:
mediaRecorder.addEventListener("stop", () => { const audioBlob = new Blob(audioChunks, { 'type' : 'audio/webm'}); const reader = new FileReader(); reader.readAsDataURL(audioBlob); reader.onload = () => { const base64AudioMessage = reader.result.split(',')[1]; console.log(reader.result) fetch("http://localhost:5000/api/audio", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: base64AudioMessage }) }).then(res => {console.log(res)}); } })
3 Réponses :
Après avoir utilisé le commentaire de Jakub Bláha, j'ai pu le faire fonctionner en modifiant la fonction python comme suit:
@app.route('/api/audio', methods=['POST']) def audio(): content = request.get_json(silent=True) print(type(content["message"])) #This is type string ans = base64.b64decode(bytes(content["message"], 'utf-8')) print(type(ans)) #This is type bytes with open("audioToSave.webm", "wb") as fh: fh.write(ans) theAnswer = 'no' return theAnswer
Je ne pense pas que vous devriez télécharger le fichier audio en tant que base64, il sera ~ 33% plus grand
l'envoyer en tant que données brutes si vous n'envoyez que les données sans métadonnées, champs ou json supplémentaires. sinon utilisez FormData
mediaRecorder.addEventListener("stop", () => { const audioBlob = new Blob(audioChunks, { 'type' : 'audio/webm'}) fetch(url, { method: 'POST', body: audioBlob }) }) // or mediaRecorder.addEventListener("stop", () => { const fd = new FormData() const audioBlob = new Blob(audioChunks, { 'type' : 'audio/webm'}) fd.set('file', audioBlob, 'audioToSave.webm') fetch(url, { method: 'POST', body: fd }) })
vous économiserez de la mémoire et des ressources en évitant de l'encoder et de le décoder
J'ai implémenté votre version avec succès. Merci.
@app.route('/uploader', methods = ['GET', 'POST']) def upload_file(): if request.method == 'POST': f = request.files['audio_data'] f.save('audio.wav') f.flush() f.close() return 'file uploaded successfully'
function blogUpload(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, 'temp.wav'); xhr.open("POST","uploader",true); xhr.onprogress = function (e) { if (e.lengthComputable) { console.log(e.loaded+ " / " + e.total) } } xhr.onloadstart = function (e) { console.log("start") } xhr.onloadend = function (e) { console.log("end") } xhr.send(fd); }
Je viens d'essayer votre approche mais le fichier wave ne semble pas jouer correctement. Savez-vous pourquoi cela pourrait être le cas?
Utilisez-vous record.js ( github.com/mattdiamond/Recorderjs ) pour traiter le blob avant l'envoi?
rec.exportWAV (blob);
ou passez à l'extension / mime de votre script. \
Je pense que vous devriez utiliser la fonction
b64decode
.Ça a marché! Merci.