将 blob 作为 Uint8Array 发送到 NodeJS 并将其保存到文件
Sending blob as Uint8Array to NodeJS and saving it to file
我正在尝试将来自 Firefox 中新的 MediaRecorder API 的 blob 发送到 NodeJS 以将其存储在文件中。 blob 包含转换后的 webm 文件形式的记录。
我在发送之前将这个 blob 分块成一定大小,以便能够通过 webrtc 数据通道提供的带宽发送它。这看起来像这样:
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,
new Uint8Array(message.payload)部分后,数组长度还是0,那么应该怎么改呢?
编辑二
在使用 JSON.stringify() 时添加 .toString() 之后,我成功地收到了 UInt8Array。然而,正如上面所示的代码,它只将 [object uint8array] 写入文件。
编辑 III - 解决方案
使用上面的代码可以正常工作。
[object uint8array] 是在 uint8array
上使用 toString
时应该得到的结果。只需将缓冲区转换为字符串并发送该字符串即可。如果你愿意,你可以尝试 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 类型正确。
我正在尝试将来自 Firefox 中新的 MediaRecorder API 的 blob 发送到 NodeJS 以将其存储在文件中。 blob 包含转换后的 webm 文件形式的记录。 我在发送之前将这个 blob 分块成一定大小,以便能够通过 webrtc 数据通道提供的带宽发送它。这看起来像这样:
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,
new Uint8Array(message.payload)部分后,数组长度还是0,那么应该怎么改呢?
编辑二
在使用 JSON.stringify() 时添加 .toString() 之后,我成功地收到了 UInt8Array。然而,正如上面所示的代码,它只将 [object uint8array] 写入文件。
编辑 III - 解决方案
使用上面的代码可以正常工作。
[object uint8array] 是在 uint8array
上使用 toString
时应该得到的结果。只需将缓冲区转换为字符串并发送该字符串即可。如果你愿意,你可以尝试 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 类型正确。