2

I'm building an app for my friend and I need to record audio and store it on a server. I have successfully done it with text and images, but I can't make it work for audio.

I am probably missing something when creating the file (the file is created but not playable). There has to be a problem with the data conversion from the JS Blob to the actual file.

I managed to get the audio blob and even play it back in JS. But when I create a file from the blob it can't be played (I tried to save it locally with the same outcome - got the file but could not play it). I also tried to save it in different formats with no success (wav, mp3). So the problem has to be in the conversion from the blob to the actual file. With text and images, it was straightforward forward and the files were created from the blob just by saving them with a filename. But I guess that with audio isn't that simple.

My understanding is that I have some binary data (JS Blob), that can be saved as a file. But with audio, there has to be some special conversion or encoding so the output file works and can be played.

here is the frontend code (I am using this with some of the variables because its part of a Vue component)

this.mediaRecorder.addEventListener("stop", () => {
                // tried to save it as WAV with the same result got the file, but couldn't play it
                this.audioBlob = new Blob(this.audioChunks, { 'type' : 'audio/mpeg-3' })
                
                //debugging - playing back the sound in the browser works fine
                const audioUrl = URL.createObjectURL(this.audioBlob);
                const audio = new Audio(audioUrl);
                audio.play();
                
                //adding the blob to the request
                let filename = this.$store.state.counter + "-" + this.$store.state.step
                const formData = new FormData();
                formData.append('file', this.audioBlob, `${filename}.mp3`);
                const config = {
                    headers: { 'content-type': 'multipart/form-data' }
                }
                //sending it to my Flask API (xxx is the name of the folder it gets saved to on the server)
                this.$axios.post('http://localhost:5000/api/v1/file/upload/xxx', formData, config)
            })

here is my endpoint on the server

@app.route('/api/v1/file/upload/<test_id>', methods=['POST'])
def upload_file(test_id):
    uploaded_file = request.files['file']
    filename = secure_filename(uploaded_file.filename)
    if filename != '':
        uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], test_id, filename))
    return jsonify({'message': 'file saved'})

Here is the whole recording code snippet

navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
            this.mediaRecorder = new MediaRecorder(stream);
            // audio.srcObject = stream
            
            this.mediaRecorder.start();

            this.mediaRecorder.addEventListener("dataavailable", event => {
                this.audioChunks.push(event.data)
            })
            this.mediaRecorder.addEventListener("stop", () => {
                this.audioBlob = new Blob(this.audioChunks, { 'type' : 'audio/mpeg-3' })
                
                //debugging - playing back the sound in the browser works fine
                const audioUrl = URL.createObjectURL(this.audioBlob);
                const audio = new Audio(audioUrl);
                audio.play();
                
                //adding the blob to the request
                let filename = this.$store.state.counter + "-" + this.$store.state.step
                const formData = new FormData();
                formData.append('file', this.audioBlob, `${filename}.mp3`);
                const config = {
                    headers: { 'content-type': 'multipart/form-data' }
                }
                //sending it to my Flask API (xxx is the name of the folder it gets saved to on the server)
                this.$axios.post('http://localhost:5000/api/v1/file/upload/xxx', formData, config)
            })
        })
ggorlen
  • 44,755
  • 7
  • 76
  • 106

0 Answers0