2012-10-11 25 views
5

Il mio obiettivo finale è quello di riprodurre video dal mio portatile su un server. Sto provando a realizzare questo usando NodeJs sul computer portatile & il server. Uso la libreria OpenCV per acquisire il video sul laptop e salvarlo su un file jpg. Poi leggo il file e lo converto in base64 in modo che possa essere trasportato usando il modulo Net.socket nel nodo. Questo è un processo continuo: cattura, codifica e invia.NodeJS, OpenCV e streaming di immagini tramite socket di rete

Ecco il codice del server solo per la trasmissione di un unico file 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(); 
      }); 
     }); 
    }); 
}); 

Sul circuito cliente che fino a quando la FIN viene ricevuto dal server. Ecco il codice 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); 
     } 
    }); 
}); 

Il problema è che l'intera immagine non viene effettivamente inviata. Quando apro il file ricevuto, copy.jpg, c'è sempre un pezzo mancante in basso.

Nella versione finale l'obiettivo è di inviare un jpg dopo l'altro e delimitare la fine di ogni 'jpg' tramite una parola chiave come 'EndOfFile'. Ho cercato di farlo aggiungendo la parola chiave "EndOfFile" alla mia immagine codificata Base64 prima di inviarla, ma sul lato ricevente che si è veramente rovinato.

Esempio Advanced Server:

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

Un lato client il ciclo sarebbe esaminare ogni blocco di dati per la parola chiave e se si trovò allora tutto ciò che è nel buffer sarebbe scritto su file e il ripristino del buffer , pronto per il prossimo file.

Esempio client avanzato

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

ho ottenuto questo al lavoro in Python quindi penso che la mia logica è corretta ma non sono più confortevole in NodeJS.

Se qualcuno potrebbe dirmi se questo è un modo corretto per farlo e dove potrei aver sbagliato.

Grazie in anticipo!

+0

Mi chiedo quanto sia veloce per lo streaming. In realtà, stavo cercando di fare lo stesso inviando img base64 da C/C++ opencv via socket. Sono stato in grado di farlo funzionare, ma il frame rate è dannatamente lento e molto lento. Credo che sia necessario un po 'di codifica per renderlo più veloce. –

+0

Sì, questo approccio è molto lento perché non utilizza alcuna compressione. Ho finito per usare qualcosa chiamato GStreamer per occuparmi dello streaming per me. Ti suggerisco di utilizzare uno strumento simile che eseguirà una sorta di compressione al volo. Ad ogni modo, questo è stato un buon esercizio per il programmismo, ma non avrei mai fatto le cose in questo modo per una produzione o anche un sistema demo. –

+0

In GStreamer, come puoi mostrare il tuo video streaming sulla pagina web? Ora, sto guardando all'approccio webrtc che è ancora nuovo ma non ancora standardizzato. Può inviare facilmente lo streaming video tramite la webcam, ma lo streaming per i file video è ancora in corso. –

risposta

0

Sospetto che si stia verificando l'evento end mentre l'ultimo bit di dati è ancora memorizzato nel buffer.

Provare ad attendere l'evento close anziché l'evento end. Non sono sicuro dei socket, ma in altre API del nodo come spawn, l'evento end viene generato in anticipo, prima che i flussi correlati vengano scaricati, quindi potrebbero essere ancora presenti dati nel buffer in attesa.

Si potrebbe evitare di gestirlo da soli con le tubazioni. Utilizzare fs.createWriteStream() e .pipe() il flusso di socket nel file.

Problemi correlati