kkawabat
kkawabat

Reputation: 1677

How to upload large audio file to a django server given a blob url?

I've got a javascript that records audio using MediaRecorder and pushes the binary data into an array chunk. Once the user finishes recording, the data is converted into a blob and loaded to an HTML's audio element for playback. My issue is now trying to load this data onto the Django server at the same time. Most sample upload script I've seen has users manually loading an audio file into a form's input element and manually hitting a submit button, but my data is already loaded into a blob file so I am not sure how to proceed.

HTML

<div id="buttons">
    <form>
        <button id="record_btn" style="">Record</button>
        <input id="stop_btn" type="submit" value="Stop" disabled>
        <audio id="audio" controls>
            <source id="source" src="" type="audio/ogg"/>
        </audio>
    </form>
</div> 

Javascript

var record = document.querySelector('#record_btn');   
var stop = document.querySelector('#stop_btn');

  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
     console.log('getUserMedia supported.');
     navigator.mediaDevices.getUserMedia (
        // constraints - only audio needed for this app
        {
           audio: true
        })

        // Success callback
        .then(function(stream) {
          var mediaRecorder = new MediaRecorder(stream);
          record.onclick = function() {
            mediaRecorder.start();
            record.disabled = true;
            stop.disabled = false;
            console.log(mediaRecorder.state);
            console.log("recorder started");
            record.style.background = "red";
            record.style.color = "black";
          }

          var chunks = [];

          mediaRecorder.ondataavailable = function(e) {
            chunks.push(e.data);
          }
          stop.onclick = function() {
            mediaRecorder.stop();
            record.disabled = false;
            stop.disabled = true;
            console.log(mediaRecorder.state);
            console.log("recorder stopped");
            record.style.background = "";
            record.style.color = "";
          }

          mediaRecorder.onstop = function(e) {
            console.log("recorder stopped");
            var audio = document.querySelector('#audio');
            var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
            chunks = [];
            var audioURL = window.URL.createObjectURL(blob);
            $("#source").attr("src", audioURL);
            $("#audio")[0].load();
            stream.getTracks()[0].stop();

            //CODE TO UPLOAD BLOB DATA TO DJANGO SERVER
            ????????? 
            //
          }
        })

        // Error callback
        .catch(function(err) {
           console.log('The following getUserMedia error occured: ' + err);
        }
     );   } else {
     console.log('getUserMedia not supported on your browser!');   }

Would the current setup work well for an hour-long recording? If there are any better way of recording audio on the client side and uploading it to server I would greatly appreciate any guidence.

Upvotes: 5

Views: 2593

Answers (1)

Satendra
Satendra

Reputation: 6865

You can use JQuery Ajax to send blob data to Django server

var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });

console.log("start sending binary data...");
var form = new FormData();
form.append('audio', blob);

$.ajax({
    url: 'http://localhost:8000/<your api endpoint>/',
    type: 'POST',
    data: form,
    processData: false,
    contentType: false,
    success: function (data) {
        console.log('response' + JSON.stringify(data));
    },
    error: function () {
       // handle error case here
    }
});

And in Django view, you can easily retrieve blob using

audio_data = request.FILES['audio']
# you can directly assign audio_data to FileField model attribute

Note: Above code will work fine if the data is not that large, which exceeds your server timeout


If the file is really large then I will recommend you to upload your file using tus protocol

This approach offers you to upload a large file in chunks. For the Django project, you can use django-tus package.

Upvotes: 5

Related Questions