我正在尝试将来自Firefox中的新MediaRecorder API的blob发送到NodeJS以将其存储在文件中。 blob包含记录为转换后的webm文件。 在发送之前,我将此blob分块为一定大小,以便能够通过webrtc datachannel提供的带宽发送它。看起来像这样:
var blobToBuffer = function(blob, cb) {
var reader = new FileReader();
reader.onload = function() {
cb(reader.result);
};
reader.readAsArrayBuffer(blob);
};
blobToBuffer(blob, function(buffer){
var sendInterval = setInterval(function(){
var currentEnd = dataSend + dis._dataChunkSize;
if(currentEnd > buffer.byteLength){
currentEnd = buffer.byteLength;
}
var part = Array.apply([], new Uint8Array(buffer.slice(dataSend, currentEnd)));
dis.dataChannel.send(
JSON.stringify({
payload: part
})
);
dataSend = currentEnd;
if(dataSend + 1 >= buffer.byteLength){
dis.dataChannel.send(JSON.stringify({action: 'dataEnd'}));
clearInterval(sendInterval);
}
}, 1000);
});
在nodeJS方面,我试图将数据转换回webm文件,如下所示:
fs.appendFile('my/path/file.webm', new Buffer(new Uint8Array(message.payload)), function(error){
if(error){
console.log(error);
} else {
console.log('Chunk successfully written');
}
});
它告诉我,块已写入,但文件为空。我使用从blob派生的base64编码字符串尝试了相同的操作,但是由于可能的数据损坏,这似乎是一个坏主意。
我错过了什么?或者有更好的方法将blob从JavaScript传输到NodeJS吗?
修改
uint8array-constructor似乎不接受以字符串形式出现的数据:
'0':39,'1':209,'2':79,'3':0,'4':230,'5':133,
'6':190,'7':138,'8':188,'9':103,'10':131,
在新的Uint8Array(message.payload)部分之后,数组长度仍为0.那么应该如何进行呢?
编辑II
在使用JSON.stringify()时添加.toString()后,我设法收到了想要的UInt8Array。但是,由于代码如上所示,它只将[object uint8array]写入文件。
编辑III - 解决方案
使用上面的代码可以正常工作。
答案 0 :(得分:1)
[object uint8array]是您在toString
上使用uint8array
时应该获得的内容。只需将缓冲区转换为字符串并发送字符串即可。如果你想要你可以尝试base64编码,但我认为你不应该需要它。
var str = ""; // string version of the part
for{var i = 0; i < part.length; i++){
str += String.fromCharCode( part[i] );
}
dis.dataChannel.send(
JSON.stringify({
payload: str
})
);
如果Nodejs不喜欢字符串,那么使用btoa将其转换为base64编码。不要担心你没有腐败,这就是base64阻止某些传输协议误解原始二进制字符串的原因。
dis.dataChannel.send(
JSON.stringify({
payload: btoa(str) // encode string as base64;
})
);
同时确保mime类型正确。