我有一个简单的c#应用程序,用ffmpeg记录屏幕,并将以块发送的standardoutput重定向到node.js服务器,但是我遇到了一些文件损坏的问题。
我通过将块保存到内存流并将其保存到文件流来测试c#中的输出。
以下是一些c#(使用Quobject.SocketIoClientDotNet)
while (!theProcess.HasExited)
{
int count = 0;
var b = new byte[32768]; // 32k
while ((count = theProcess.StandardOutput.BaseStream.Read(b, 0, b.Length)) > 0)
{
// The chunk to be sent
byte[] actual = b.Take(count).ToArray();
// Chuck being sent to node
clientSocket.Emit("videoChunk", actual);
if (!ffWorkerIsWorking)
{
ffWorker.CancelAsync();
theProcess.Kill();
break;
}
}
}
以下是节点服务器
var buffer = new Buffer(32768);
var isBufferingDone = false;
var i = 0;
socket.on('videoChunk', function(data) {
if (!isBufferingDone) {
var incomingBuffer = new Buffer(data);
buffer = Buffer.concat([buffer, incomingBuffer]);
i++;
console.log('Received packages: ' + i);
}
});
socket.on('cancelVideo', function() {
isBufferingDone = true;
var wstream = fs.createWriteStream('public/test.webm');
wstream.write(buffer);
wstream.end
buffer = new Buffer(32768);
i = 0;
});
当缓冲区进入时它们连接在一起,当它是取消请求时,进程停止并且连接的缓冲区被写入文件。
该文件已损坏,我不明白为什么。有人想看看吗?非常感谢任何帮助。
更新
我最终通过将javascript改写为:
来解决这个问题var buffer = new Buffer(32768);
var isBufferingDone = false;
var i = 0;
var wstream;
socket.on('videoChunk', function(data) {
if (i === 0) {
wstream = fs.createWriteStream('public/'+socket.id+'_video.webm');
}
if (!isBufferingDone) {
wstream.write(data);
i++;
console.log('Received packages: ' + i);
}
});
socket.on('cancelVideo', function() {
isBufferingDone = true;
wstream.end
fs.unlink('public/'+socket.id+'_video.webm');
buffer = new Buffer(32768);
i = 0;
});
这是正确的做法吗?
答案 0 :(得分:0)
你的缓冲解决方案的问题在于你最初连接什么"随机"当您使用实际视频数据new Buffer(32768)
时操作系统为您提供的字节数。
尽管在内存中缓冲是一个坏主意,但以下是解决该解决方案的方法:
var buffer = '';
socket.on('videoChunk', function(data) {
if (buffer !== null)
buffer += data;
});
socket.on('cancelVideo', function() {
fs.writeFile('public/test.webm', buffer, { encoding: 'binary' }, function(err) {
// Done writing!
});
buffer = null;
});
该解决方案假定传入的data
字符串是二进制字符串。如果您正在发送除此之外的其他内容,例如base64编码的二进制数据,那么您需要稍微调整该示例,以便encoding: 'binary'
中的fs.writeFile()
为encoding: 'base64'
。
此外,对于您的流媒体解决方案,您可以完全避免new Buffer(32768)
。