0
votes

enregistrement de l'audio sur le backend flask

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)});
        }
    })


2 commentaires

Je pense que vous devriez utiliser la fonction b64decode .


Ça a marché! Merci.


3 Réponses :


1
votes

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


0 commentaires

1
votes

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


1 commentaires

J'ai implémenté votre version avec succès. Merci.



1
votes

Pour info. Je développe ce code, pas encore parfait, je perds quelques messages audio.

Frontend

    @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'

Backend

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);
    }

4 commentaires

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. \