我发现了许多使用Mongoose Buffer SchemaType保存二进制文件的帖子。但是,他们中的大多数处理图像文件,我还没能让他们使用WAV音频文件。
我使用Recorder.js保存内置麦克风的录音。我使用Recorder.js' exportWAV函数从完成的记录中获取BLOB,然后使用FileReader读取blob并将其发送到Node / Express后端,然后将其保存到DB。我已经使用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();
});
});
句子的猫鼬模式:
var SentenceSchema = new mongoose.Schema({
text: String,
audio: Buffer,
timestamp: Date
});