Добавить куски байтов в буфер и сохранить буфер в файл

111
11

У меня есть простое приложение С#, которое записывает экран с помощью ffmpeg и перенаправляет стандартный вывод, который отправляется кусками на сервер node.js, но у меня возникают проблемы с повреждением файла.

У меня есть testet вывод в С#, сохраняя куски в memystream и сохраняя его в поток файлов.

Вот некоторые С# (с использованием 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;
});

Это правильный способ сделать это?

спросил(а) 2015-08-08T18:16:00+03:00 5 лет, 5 месяцев назад
1
Решение
61

Проблема с вашим буферизующим решением заключается в том, что вы изначально объединяете любые "случайные" байты, которые ОС предоставляет вам, когда вы делаете 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).

ответил(а) 2015-08-08T23:59:00+03:00 5 лет, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема