2

I am using Recorder.js, which allows you to display an audio recording like so

recorder.exportWAV(function(blob) {
  var url = URL.createObjectURL(blob);
  var au = document.createElement('audio');
  au.controls = true;
  au.src = url;
}

But how can I save the blob to the database? Assuming I have a Recordings collection:

recorder.exportWAV(function(blob) {
  Recordings.insert({data: blob});
}

will only store this

{data: { "type" : "audio/wav", "size" : 704556 }}

which does not have the actual content.

user2191332
  • 1,059
  • 3
  • 17
  • 24

2 Answers2

2

After watching the file upload episode from eventedmind.com, it turns out the way to do it is to use the FileReader to read a blob as ArrayBuffer, which is then converted to Uint8Array to be stored in mongo:

var BinaryFileReader = {
  read: function(file, callback){
    var reader = new FileReader;

    var fileInfo = {
      name: file.name,
      type: file.type,
      size: file.size,
      file: null
    }

    reader.onload = function(){
      fileInfo.file = new Uint8Array(reader.result);
      callback(null, fileInfo);
    }
    reader.onerror = function(){
      callback(reader.error);
    }

    reader.readAsArrayBuffer(file);
  }
}

The exportWAV callback is then

recorder.exportWAV(function(blob) {
  BinaryFileReader.read(blob, function(err, fileInfo){
    Recordings.insert(fileInfo)
  });
});

Then I can display one of my recordings by:

Deps.autorun(function(){
  var rec = Recordings.findOne();
  if (rec){
    var au = document.createElement('audio');    
    au.controls = true;
    var blob = new Blob([rec.file],{type: rec.type});
    au.src = URL.createObjectURL(blob);
    document.getElementById("recordingslist").appendChild(au);
  }
})

I don't know if the previous snippet works in other browsers, but this may:

var base64Data = btoa(String.fromCharCode.apply(null, rec.file))
var au = document.createElement('audio');
au.controls = true;
au.src = "data:"+rec.type+";base64,"+base64Data
user2191332
  • 1,059
  • 3
  • 17
  • 24
0

Just in case, did you notice this line in their example

Make sure you are using a recent version of Google Chrome, at the moment this only works with Google Chrome Canary.

I will soon need to look into this for my own project, hope you get it running.

Jim Mack
  • 1,437
  • 11
  • 16
  • I can record, replay and download the wav file, which is what I think that comment is referring to. I have also seen examples of how to do it in php in this post http://stackoverflow.com/questions/13333378/how-can-javascript-upload-a-blob and I am just having a hard time translating it to meteor. I tried to use collectionapi to translate the solution, but couldn't. I also saw binaryjs, but it seems to require the server object, which I don't know where to get. – user2191332 Sep 02 '13 at 00:49