2012-10-11 22 views
5

का उपयोग कर नोडजेएस, ओपनसीवी और स्ट्रीमिंग छवियां मेरा अंतिम लक्ष्य मेरे लैपटॉप से ​​सर्वर पर वीडियो स्ट्रीम करना है। मैं लैपटॉप & सर्वर पर NodeJs का उपयोग करके इसे पूरा करने की कोशिश कर रहा हूं। मैं लैपटॉप पर वीडियो कैप्चर करने और इसे एक jpg फ़ाइल में सहेजने के लिए ओपनसीवी लाइब्रेरी का उपयोग करता हूं। मैं फिर फ़ाइल को पढ़ता हूं और इसे बेस 64 में परिवर्तित करता हूं ताकि मैं इसे नोड में Net.socket मॉड्यूल का उपयोग करके परिवहन कर सकूं। यह एक सतत प्रक्रिया है: कब्जा, एन्कोड, और भेजें।नेट सॉकेट

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

ग्राहक मैं पाश पर जब तक फिन सर्वर से प्राप्त किया जाता है:

यहाँ सिर्फ एक jpg फ़ाइल प्रसारण के लिए सर्वर कोड है। यहां ग्राहक कोड है:

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 भेजना है और 'endOfFile' जैसे किसी कीवर्ड के माध्यम से प्रत्येक 'jpg' के अंत को सीमित करना है। मैंने भेजने से पहले मेरी बेस 64 एन्कोडेड छवि में कीवर्ड 'एंडऑफफ़ाइल' को जोड़कर ऐसा करने की कोशिश की लेकिन प्राप्त होने वाले अंत में वास्तव में खराब हो गया।

नमूना उन्नत सर्वर:

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

एक ग्राहक के पक्ष पाश कीवर्ड के लिए डेटा के प्रत्येक टुकड़ा की जांच करेगा और यह तब जो कुछ भी लिखा जाएगा बफर में है दायर करने के लिए अगर यह पाया जाता है और बफर रीसेट , अगली फाइल के लिए तैयार है।

नमूना उन्नत क्लाइंट

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

मैं अजगर में काम करने के लिए इस मिल गया है तो मुझे लगता है मेरी तर्क सही है, लेकिन मैं NodeJS में के रूप में आरामदायक नहीं हूँ।

अगर कोई मुझे बता सकता है कि यह ऐसा करने का एक सौहार्दपूर्ण तरीका है और मैं गलत कहां से गलत हो सकता हूं।

अग्रिम धन्यवाद!

+0

मुझे आश्चर्य है कि यह आपकी स्ट्रीमिंग के लिए कितनी तेज़ है। असल में, मैं सॉकेट के माध्यम से सी/सी ++ ओपनसीवी से आईएमजी बेस 64 भेजकर ऐसा करने की कोशिश कर रहा था। मैं इसे काम करने में सक्षम था, लेकिन फ्रेम दर बहुत धीमी और बहुत अंतराल है। मुझे विश्वास है कि इसे तेज बनाने के लिए इसे कुछ एन्कोडिंग की आवश्यकता है। –

+0

हां यह दृष्टिकोण बहुत धीमा है क्योंकि यह किसी भी संपीड़न का उपयोग नहीं करता है। मैं स्ट्रीमिंग की देखभाल करने के लिए जीस्ट्रीमर नामक कुछ का उपयोग कर समाप्त हुआ। मेरा सुझाव है कि आप एक समान उपकरण का उपयोग करें जो फ्लाई पर कुछ प्रकार का संपीड़न करेगा। किसी भी दर पर, यह प्रोग्रामिंग के लिए एक अच्छा अभ्यास था, लेकिन मैं कभी भी उत्पादन या यहां तक ​​कि डेमो सिस्टम के लिए चीजें नहीं करता। –

+0

जीस्ट्रीमर में, आप अपने स्ट्रीमिंग वीडियो को वेबपृष्ठ पर कैसे दिखा सकते हैं? अब, मैं webrtc दृष्टिकोण देख रहा हूं जो अभी भी नया है लेकिन अभी तक मानकीकृत नहीं है। यह वेबकैम द्वारा आसानी से वीडियो स्ट्रीमिंग भेज सकता है लेकिन वीडियो फाइल के लिए स्ट्रीमिंग अभी भी प्रगति पर है। –

उत्तर

0

मुझे संदेह है कि आप end ईवेंट देख रहे हैं जबकि अंतिम डेटा अभी भी buffered है।

end ईवेंट की बजाय close ईवेंट की प्रतीक्षा करने का प्रयास करें। मुझे सॉकेट के बारे में निश्चित नहीं है, लेकिन spawn जैसे अन्य नोड एपीआई में, end ईवेंट संबंधित धाराओं को फ़्लश करने से पहले, जल्दी से निकाल दिया जाता है, इसलिए अभी भी डेटा प्रतीक्षा कर सकते हैं।

आप पाइपिंग द्वारा इसे स्वयं प्रबंधित करने से बच सकते हैं। फ़ाइल में सॉकेट स्ट्रीम fs.createWriteStream() और .pipe() का उपयोग करें।