NodeJS, OpenCV и потоковые изображения с использованием Net Socket

Моя конечная цель - потоковое видео с моего ноутбука на сервер. Я'я пытаюсь сделать это с помощью NodeJs на ноутбуке сервер. Я использую библиотеку OpenCV, чтобы захватить видео на ноутбуке и сохранить его в файл JPG. Затем я читаю файл и преобразую его в base64, чтобы можно было транспортировать его с помощью модуля Net.socket в Node. Это непрерывный процесс: захват, кодирование и отправка.

Вот код сервера для передачи только одного файла jpg:

var cv = require('opencv');
var fs = require('fs');
var net = require('net');
var camera = new cv.VideoCapture(0);
var server = net.createServer();
server.listen('50007', '127.0.0.1');

server.on('connection', function(socket){
    camera.read(function(image){
        image.save('original.jpg');

        fs.readFile('original.jpg', 'base64', function(err, image){
            socket.write(image, 'base64', function(){
                socket.end();
            });
        });
    });
});

На клиенте я зацикливаюсь, пока FIN не будет получен с сервера. Вот код клиента:

var net = require('net');
var fs = require('fs');
var client = new net.Socket();
var buffer ='';
client.setEncoding('base64');

client.connect('50007', '127.0.0.1', function(){
    console.log('Connecting to server...');
});

client.on('data', function(data){
    buffer += data;
});

client.on('end', function(){
    var dataBuffer = new Buffer(buffer, 'base64');
    fs.writeFile('copy.jpg', dataBuffer, function(err){
        if(err){
            console.log(err);
        }
    });
});

Проблема в том, что на самом деле все изображение не отправляется. Когда я открываю полученный файл, copy.jpg, в нижней части всегда отсутствует фрагмент.

В финальной версии цель состоит в том, чтобы отправлять один JPG за другим и разграничивать конец каждогоJPG» с помощью ключевого слова, такого какENDOFFILE», Я попытался сделать это, добавив ключевое словоENDOFFILE» на мое изображение в кодировке base64 перед отправкой, но на приемном конце, который действительно облажался.

Пример расширенного сервера:

fs.readFile('original.jpg', 'base64', function(err, image){
    image += 'EndOfFile';
    socket.write(image, 'base64');
}); 

На стороне клиента цикл будет проверять каждый кусок данных на наличие ключевого слова, и если он найдет его, то все, что находится в буфере, будет записано в файл, и сброс буфера будет готов к следующему файлу.

Образец Advanced ClientI '

client.on('data', function(data){
    if(data.indexOf('EndOfFile') > 0){
        buffer += data.substr(0, data.indexOf('EndOfLine'));
        var dataBuffer = new Buffer(buffer, 'base64');

        fs.writeFile('copy.jpg', dataBuffer, function(err){
            if(err){
                console.log(err);
            }
        });

        buffer = '';
    } else {
        buffer += data;
    }
});

Я получил это для работы в Python, поэтому я думаю, что моя логика верна, но яМне не так удобно в NodeJS.

Если бы кто-то мог сказать мне, если это нормальный способ сделать это и где я мог ошибиться.

Заранее спасибо!

 Przemek Lach16 июл. 2013 г., 20:14
Так что это была комбинация GStream и сервлетов. В конце конвейера GStreamer у нас был приемник TCP, и этот приемник отправлял данные сервлету, который затем перенаправлял их в тег HTML5 video. Вы можете заменить сервлет на что угодно. Основная идея заключается в том, что конвейер GStreamer завершился приемником TCP, а затем вам необходимо подключить видеоплеер к этому приемнику TCP.
 A-letubby16 июл. 2013 г., 06:36
В GStreamer, как вы можете показать свое потоковое видео на веб-странице? Теперь я смотрю на подход webrtc, который все еще новый, но еще не стандартизированный. Он может легко передавать потоковое видео с веб-камеры, но потоковое видео еще не завершено.
 Przemek Lach15 июл. 2013 г., 23:46
Да, этот подход очень медленный, потому что он не использует сжатие. В итоге я использовал что-то под названием GStreamer, чтобы позаботиться о потоковой передаче для меня. Я предлагаю вам использовать аналогичный инструмент, который будет выполнять какое-то сжатие на лету. Во всяком случае, это было хорошее упражнение для программирования, но я бы никогда не поступил таким образом для производства или даже для демонстрационной системы.
 Przemek Lach16 июл. 2013 г., 20:17
Более конкретно, этот элемент был назван tcpserversink. Был также элемент перед приемником, который делал кодирование видео. Я неЯ не помню название элемента, но я помню, что мы либо закодировали его в виде нескольких частей jpeg или vp8.
 A-letubby15 июл. 2013 г., 08:01
Интересно, как быстро это для вашей трансляции. На самом деле, я пытался сделать то же самое, отправив img base64 из C / C ++ opencv через сокет. Я смог заставить его работать, но частота кадров чертовски медленная и очень запаздывающая. Я считаю, что нужно немного кодирования, чтобы сделать это быстрее.
 Przemek Lach20 июл. 2013 г., 22:34
Какое разрешение ваши изображения?
 Samson20 июл. 2013 г., 19:28
Я реализую что-то похожее, испуская ~ 10 x закодированных изображений base64 (4 КБ) в секунду через веб-сокет для клиентов, которые я рисую, используя холст. Это работает довольно гладко.

Ответы на вопрос(1)

end событие, пока последний бит данных все еще находится в буфере.

Попробуйте дождатьсяclose событие, а неend событие. Я'я не уверен насчет сокетов, но в других Node API, таких какspawn,end Событие запускается раньше, до того как связанные потоки будут сброшены, так что буферизованные данные все еще могут ждать.

Вы могли бы избежать этого самостоятельно, обвязывая. использованиеfs.createWriteStream() а также.pipe() поток сокета к файлу.

Ваш ответ на вопрос