RecorderJS uploading recorded blob via AJAX
Asked Answered
S

4

4

I'm using Matt Diamond's recorder.js to navigate the HTML5 audio API, and feel this question probably has an apparent answer, but i'm unable to find any specific documentation.

Question: After recording a wav file, how can I send that wav to the server via ajax? Any suggestions???

Sapindaceous answered 22/2, 2013 at 0:9 Comment(0)
S
5

If you have the blob you'll need to turn it into a url and run the url through an ajax call.

// might be nice to set up a boolean somewhere if you have a handler object
object = new Object();
object.sendToServer = true;

// You can create a callback and set it in the config object.
var config = {
   callback : myCallback
}

// in the callback, send the blob to the server if you set the property to true
function myCallback(blob){
   if( object.sendToServer ){

     // create an object url
     // Matt actually uses this line when he creates Recorder.forceDownload()
     var url = (window.URL || window.webkitURL).createObjectURL(blob);

     // create a new request and send it via the objectUrl
     var request = new XMLHttpRequest();
     request.open("GET", url, true);
     request.responseType = "blob";
     request.onload = function(){
       // send the blob somewhere else or handle it here
       // use request.response
     }
     request.send();
   }
}

// very important! run the following exportWAV method to trigger the callback
rec.exportWAV();

Let me know if this works.. haven't tested it but it should work. Cheers!

Sondrasone answered 22/2, 2013 at 14:39 Comment(5)
@Sapindaceous did this work for you? I'm trying to do the same, see #15796178Unbowed
much appreciated. I had forgotten to select that answer as correct, but yeah, it's been so long I've forgotten if this needed tweaking. I'm pretty sure this code worked like a charm!Sapindaceous
I'm trying to accomplish the same, but I honestly don't understand how the example code is meant to work. Why do we first send a request to the URL we generated? What is request.onload() supposed to do? Why can't we put the blob right into a request? I'd appreciate an explanation, thanks in advance!Sferics
XMLHttpRequests only request urls. In this case the blob has to be referenced via a object URL and the XHR will load it via .send() The onload handler is where you would access the response (the blob data) developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…Sondrasone
This code does not upload or POST the blob file to the server. As I see it it just transforms a blob to object URL and back (see this answer) which is not what is asked. The Jeff Skee and Peter Moses Mohemos answers below are correctSimonasimonds
C
3

I also spent many hours trying to achieve what you are trying to do here. I was able to successfully upload the audio blob data only after implementing a FileReader and calling readAsDataURL() to convert the blob to a data: URL representing the file's data (check out MDN FileReader). Also you must POST, not GET the FormData. Here's a scoped snippet of my working code. Enjoy!

function uploadAudioFromBlob(assetID, blob)
{
    var reader = new FileReader();

    // this is triggered once the blob is read and readAsDataURL returns
    reader.onload = function (event)
    {
        var formData = new FormData();
        formData.append('assetID', assetID);
        formData.append('audio', event.target.result);
        $.ajax({
            type: 'POST'
            , url: 'MyMvcController/MyUploadAudioMethod'
            , data: formData
            , processData: false
            , contentType: false
            , dataType: 'json'
            , cache: false
            , success: function (json)
            {
                if (json.Success)
                {
                    // do successful audio upload stuff
                }
                else
                {
                    // handle audio upload failure reported
                    // back from server (I have a json.Error.Msg)
                }
            }
            , error: function (jqXHR, textStatus, errorThrown)
            {
                alert('Error! '+ textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
                // handle audio upload failure
            }
        });
    }
    reader.readAsDataURL(blob);
}
Carinthia answered 10/1, 2014 at 22:40 Comment(3)
FormData.append also takes blobs, so you can send the audio as a file. formData.append('audio', blob, 'filename.ext');Hijack
@Hijack When I append a blob to FormData it does not show up in the FormCollection object on the server (ASP.NET MVC3). Would love to know if there is a way to pass the blob directly to the server without having to first read it in using the FileReader, but in all my research I have yet to find a way to do it.Carinthia
It will show up as a file. You can send a blob directly with XMLHttpRequest.send but I'm have no idea how you would read that on asp.net.Hijack
S
3

@jeff Skee's answer really helped but I couldn't grasps it at first, so i made something simpler with this little javascript function.

Function parameters
@blob : Blob file to send to server
@url : server side code url e.g. upload.php
@name : File index to reference at the server side file array

jQuery ajax function

function sendToServer(blob,url,name='audio'){
var formData = new FormData();
    formData.append(name,blob);
    $.ajax({
      url:url,
      type:'post',      
      data: formData,
      contentType:false,
      processData:false,
      cache:false,
      success: function(data){
        console.log(data);
      }
    });  }

Server side code (upload.php)

$input = $_FILES['audio']['tmp_name'];
$output = time().'.wav';
if(move_uploaded_file($input, $output))
    exit('Audio file Uploaded');

/*Display the file array if upload failed*/
exit(print_r($_FILES));
Sufferance answered 5/7, 2018 at 2:54 Comment(0)
S
0

Both solutions above use jQuery and $.ajax()

Here's a native XMLHttpRequest solution. Just run this code wherever you have access to the blob element:

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, "filename");
xhr.open("POST","upload.php",true);
xhr.send(fd);

Server-side, upload.php is as simple as:

$input = $_FILES['audio_data']['tmp_name']; //temporary name that PHP gave to the uploaded file
$output = $_FILES['audio_data']['name'].".wav"; //letting the client control the filename is a rather bad idea

//move the file from temp name to local folder using $output name
move_uploaded_file($input, $output)

source | live demo

Simonasimonds answered 12/7, 2018 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.