Node.js - MJPEG TCP stream for base64 images

Based on paparazzo.js lib, I am trying to get base64 images from an MJPEG stream (streaming over TCP using GStreamer) in Node.js, and send them to clients via websockets.

I think I'm pretty close, but my images are corrupted. Here is the code I'm using:

var boundary = "----videoboundary";
var data = "";

var tcpServer = net.createServer(function (socket) {

    socket.on('data', function(chunk) {

        var boundaryIndex = chunk.toString().indexOf(boundary);

        if (boundaryIndex !== -1) {

            // Get the image last piece of data :
            data += chunk.toString().substring(0, boundaryIndex);

            // Convert the data to a base64 image and broadcast it :
            var image = new Buffer(data).toString('base64');
            io.sockets.emit('image', image);

            // Reset the data :
            data = '';

            // Get the remaining data (with new image headers) :
            var remaining = chunk.toString().substring(boundaryIndex);

            // Remove the new image headers and add the remaining data :
            var contentTypeMatches   = remaining.match(/Content-Type:\s+image\/jpeg\s+/);
            var contentLengthMatches = remaining.match(/Content-Length:\s+(\d+)\s+/);

            if(contentLengthMatches != null && contentLengthMatches.length > 1) {

                var newImageBeginning = remaining.indexOf(contentLengthMatches[0]) + contentLengthMatches[0].length;
                data += remaining.substring(newImageBeginning);
            }
            else if(contentTypeMatches != null) {

                var newImageBeginning = remaining.indexOf(contentTypeMatches[0]) + contentTypeMatches[0].length;
                data += remaining.substring(newImageBeginning);
            }
            else {

                var newImageBeginning = boundaryIndex + boundary.length;
                data += remaining.substring(newImageBeginning);

                io.sockets.emit('error', { message: 'Could not find beginning of next image' });
            }
        }
        else {
            data += chunk;
        }
    });
});

Any idea?

thank

+1
source share
1 answer

chunk.toString() converts the binary buffer to a string encoded in utf8 (default), therefore for binary image data that may cause some problems.

, , dicer. :

var Dicer = require('dicer');
var boundary = '----videoboundary';

var tcpServer = net.createServer(function(socket) {
    var dice = new Dicer({ boundary: boundary });

    dice.on('part', function(part) {
      var frameEncoded = '';
      part.setEncoding('base64');
      part.on('header', function(header) {
        // here you can verify content-type, content-length, or any other header
        // values if you need to
      }).on('data', function(data) {
        frameEncoded += data;
      }).on('end', function() {
        io.sockets.emit('image', frameEncoded);
      });
    }).on('finish', function() {
      console.log('End of parts');
    });
    socket.pipe(dice);
});
0

Source: https://habr.com/ru/post/1538548/


All Articles