Django.fun

Save WAV file in Django backend

I am trying to record a voice message in the frontend and send it to the Django backend to test it against a ML algorithm of voice gender prediction. In the frontend I record the voice and I use AJAX to send the blob to the backend where I try to use wave to save the file as a valid .wav. The problem is that the file that gets saved on the backend is only noise without hearing the voice at all. On the frontend I can listen to the voice recording just fine, sounding exactly as it should. I am wondering how could I save on the backend the blob that I receive as a valid WAV file?

Here is the recording and blob sending logic on the frontend:

<div>
    <div id='gUMArea'>
      <button class="home-btn"  id='gUMbtn'>Request Stream</button>
    </div>
    <div id='btns'>
      <button class="home-btn" id='start'>Start</button>
      <button class="home-btn" id='stop'>Stop</button>
    </div>
    <div>
      <ul class="list-unstyled" id='ul'></ul>
    </div>
    <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <script>
        'use strict'

        let log = console.log.bind(console),
          id = val => document.getElementById(val),
          ul = id('ul'),
          gUMbtn = id('gUMbtn'),
          start = id('start'),
          stop = id('stop'),
          stream,
          recorder,
          counter=1,
          chunks,
          media;
        
        gUMbtn.onclick = e => {
          let mv = id('mediaVideo'),
              mediaOptions = {
                audio: {
                  tag: 'audio',
                  type: 'audio/wav',
                  ext: '.wav',
                  gUM: {audio: true}
                }
            };

          media = mediaOptions.audio;
          navigator.mediaDevices.getUserMedia(media.gUM).then(_stream => {
            stream = _stream;
            id('gUMArea').style.display = 'none';
            id('btns').style.display = 'inherit';
            start.removeAttribute('disabled');
            recorder = new MediaRecorder(stream);
            recorder.ondataavailable = e => {
              chunks.push(e.data);
              if(recorder.state == 'inactive')  makeLink();
            };
            log('got media successfully');
          }).catch(log);
        }

        start.onclick = e => {
          start.disabled = true;
          stop.removeAttribute('disabled');
          chunks=[];
          recorder.start();
        }

        stop.onclick = e => {
          stop.disabled = true;
          recorder.stop();
          start.removeAttribute('disabled');
        }

        function makeLink(){
          let blob = new Blob(chunks, {type: media.type })
            , url = URL.createObjectURL(blob)
            , li = document.createElement('li')
            , mt = document.createElement(media.tag)
            , hf = document.createElement("button");
          ;
         
          mt.controls = true;
          mt.src = url;
          hf.download = `${counter++}${media.ext}`;
          hf.innerHTML = `Submit ${hf.download}`;
          hf.className = "home-btn";
          hf.onclick = function(){
            $.ajax({
                type: "POST",
                url: "{% url 'detector' %}",
                processData: false,
                contentType: false,
                data: blob,
                success: function(data){
                    console.log("success");
                    console.log(data);
                },
                failure: function(data){
                    console.log("failure");
                    console.log(data);
                },
            });
          }
          li.appendChild(mt);
          li.appendChild(hf);
          ul.appendChild(li);
        }
    </script>
</div>

And here is my logic on the Django backend:

def post(self, request):
        audio = wave.open('test.wav', 'wb')
        audio.setnchannels(1)
        audio.setnframes(1)
        audio.setsampwidth(1)
        audio.setframerate(8000)
        audio.writeframes(request.body)
        audio.close()

What am I doing wrong? Is there a way to create a valid WAV file having the same content as the blob that I record on the frontend?

Answers: 0