Добавить куски байтов в буфер и сохранить буфер в файл
У меня есть простое приложение С#, которое записывает экран с помощью 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;
});
Это правильный способ сделать это?
Проблема с вашим буферизующим решением заключается в том, что вы изначально объединяете любые "случайные" байты, которые ОС предоставляет вам, когда вы делаете 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)
.
Еще в рубрике
- Вопросы
- Corruption
- Добавить куски байтов в буфер и сохранить буфер в файл