如何将 WAV Blob 保存到 MongoDB,使用 Node 正确检索和服务?

How to save WAV Blob to MongoDB, retrieve and serve correctly with Node?

我找到了很多关于使用 Mongoose Buffer SchemaType 保存二进制文件的帖子。但是,它们中的大多数都处理图像文件,我无法让它们处理 WAV 音频文件。

我正在使用 Recorder.js 来保存来自内置麦克风的录音。我使用 Recorder.js' exportWAV 函数从完成的录音中获取 BLOB,然后使用 FileReader 读取该 blob 并将其发送到 Node/Express 后端,然后将其保存到数据库中。我已经使用 Mongo CLI 进行了检查,并且有数据被保存到相关字段(从 BinData(0,"UklGR.lotsofdatahere..=") 开始。当我尝试通过句子 ID 获取录音时,服务器响应使用无法播放的适当 MIME 类型的 .wav 文件。

我似乎遗漏了文件编码和解码以存储在 MongoDB 中的方式。当读取 Recorder.js 吐出的 blob 时,看起来它已经被 base64 编码了。所以这就是为什么我尝试在保存到 Mongo 之前将其作为 base64 缓冲区加载,然后在输出时从 base64 缓冲区解码。我在这里错过了什么?我该如何解决这些编码问题?谢谢!

注意:我不一定需要 GridFS,因为这些文件小于 16MB。虽然,如果从 GridFS 流式传输文件要快得多,也许我应该切换到该解决方案。但是,我想先弄清楚这种方法有什么问题。

这是来自 Angular 前端的相关代码:

$scope.start = function() {
  $scope.rec.record();
}

$scope.export = function() {
  $scope.rec.stop();

  $scope.rec.exportWAV(function blobCallback(blob) {
    $scope.rec.clear();

    var reader = new FileReader();
    reader.onload = function(event) {
      $.ajax({
        type: 'POST',
        url: '/saveRecording',
        data: {
          audio: event.target.result,
          text: $scope.text,
          timestamp: new Date()
        }
      }).done(function(data) {
        console.log(data);
      });
    }
    reader.readAsDataURL(blob);
  });
}

快递路线:

router.post('/saveRecording', function(request, response, next) {
  var sentence = new Sentence();
  sentence.audio = new Buffer(request.body.audio, 'base64');
  sentence.timestamp = request.body.timestamp;
  sentence.text = request.body.text;


  // Save sentence to DB with Mongoose
  sentence.save(function(error, sentence) {
    if (error) {
      return next(error);
    }

    // If no error, send added sentence back to the client.
    response.json(sentence);
  });
});

router.get('/getRecording/:sentenceId', function(request, response, next) {
  Sentence.findById(request.params.sentenceId,
    function dbCallback (error, sentence) {
      if (error) {
        return next(error);
      }
      if (!sentence) {
        return next(new Error('Can\'t find sentence'));
      }

      var base64Audio = new Buffer(sentence.audio, 'base64');
      response.writeHead(200, {
        'Content-Type': 'audio/x-wav',
        'Content-Length': base64Audio.length
      });

      response.write(base64Audio);
      response.end();
    });
});

句子的 Mongoose 模式:

var SentenceSchema = new mongoose.Schema({
  text: String,
  audio: Buffer,
  timestamp: Date
});

您可以尝试使用 GridFs 来存储您的音频文件 检查 link