2012-10-11 30 views
5

Mi objetivo final es transmitir video desde mi computadora portátil a un servidor. Estoy tratando de lograr esto mediante el uso de NodeJs en la computadora portátil & del servidor. Utilizo la biblioteca OpenCV para capturar el video en la computadora portátil y guardarlo en un archivo jpg. Luego leo el archivo y lo convierto en base64 para poder transportarlo usando el módulo Net.socket en Node. Este es un proceso continuo: captura, codifica y envía.NodeJS, OpenCV y transmisión de imágenes mediante el soquete de red

Aquí es el código de servidor para transmitir simplemente un archivo 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(); 
      }); 
     }); 
    }); 
}); 

En el bucle de cliente hasta que la aleta se recibe del servidor. Aquí está el código de cliente:

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); 
     } 
    }); 
}); 

El problema es que toda la imagen no se envía. Cuando abro el archivo recibido, copy.jpg, siempre hay un fragmento que falta en la parte inferior.

En la versión final, el objetivo es enviar un jpg tras otro y delimitar el final de cada 'jpg' a través de una palabra clave como 'EndOfFile'. Intenté hacer esto agregando la palabra clave 'EndOfFile' a mi imagen codificada en base64 antes de enviar pero en el extremo receptor que realmente se estropeó.

Muestra Advanced Server:

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

Uno del lado del cliente del bucle sería examinar cada fragmento de datos para la palabra clave y si se encuentra, entonces lo que está en la memoria intermedia se escribiría en un archivo y el restablecimiento búfer , listo para el próximo archivo.

Muestra cliente avanzado

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; 
    } 
}); 

He conseguido que esto funcione en Python así que creo que mi lógica es correcta, pero no estoy tan cómodo en NodeJS.

Si alguien pudiera decirme si esta es una manera sensata de hacer esto y dónde podría haberme equivocado.

¡Gracias de antemano!

+0

Me pregunto qué tan rápido es para su transmisión. En realidad, estaba tratando de hacer lo mismo enviando img base64 desde C/C++ opencv a través de socket. Pude hacer que funcionara, pero la velocidad de fotogramas es muy lenta y muy lenta. Creo que necesita algo de codificación para hacerlo más rápido. –

+0

Sí, este enfoque es muy lento porque no usa ninguna compresión. Terminé usando algo llamado GStreamer para encargarme de la transmisión. Sugiero que uses una herramienta similar que haga algún tipo de compresión sobre la marcha. En cualquier caso, este fue un buen ejercicio para las programaciones, pero nunca haría las cosas de esta manera para una producción o incluso un sistema de demostración. –

+0

En GStreamer, ¿cómo puede mostrar su transmisión de video en la página web? Ahora, estoy mirando el enfoque de webrtc que todavía es nuevo pero no está estandarizado. Puede enviar videos fácilmente por webcam, pero la transmisión de archivos de video sigue en progreso. –

Respuesta

0

Sospecho que está viendo el evento end mientras el último bit de datos aún está almacenado en el búfer.

Intente esperar el evento close en lugar del evento end. No estoy seguro acerca de los sockets, pero en otras API de nodo como spawn, el evento end se activa temprano, antes de que las secuencias relacionadas se vacíen, por lo que aún puede haber datos almacenados en búfer en espera.

Puede evitar manejar esto usted mismo mediante tuberías. Use fs.createWriteStream() y .pipe() la secuencia de socket en el archivo.

Cuestiones relacionadas