将大块字节附加到缓冲区并将缓冲区保存到文件

时间:2015-08-08 15:16:27

标签: c# node.js buffer concat corruption

我有一个简单的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;
});

这是正确的做法吗?

1 个答案:

答案 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)