2012-10-11 7 views
5

私の最終目標は、ラップトップからサーバーにビデオをストリームすることです。私はノートパソコンのNodeJsを使ってこれを達成しようとしています&サーバ。 OpenCVライブラリを使ってノートパソコンのビデオをキャプチャし、jpgファイルに保存します。次に、ファイルを読み込んでbase64に変換して、ノードのNet.socketモジュールを使用してファイルを転送できるようにします。これは連続的なプロセスです。キャプチャ、エンコード、および送信です。 FINは、サーバから受信されるまで、クライアントのIループでネットソケットを使用したNodeJS、OpenCVおよびストリーミングイメージ

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を開いたとき、常に下部に欠けているチャンクがあります。

最後のバージョンでは、1つのjpgを別のものに送り、 'EndOfFile'などのキーワードを使用して各 'jpg'の終わりを区切ります。私は送信する前にbase64でエンコードされたイメージにキーワード 'EndOfFile'を追加することでこれをやろうとしましたが、受信側では本当に台無しになってしまいました。

サンプルのAdvanced Server:

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

一つのクライアント側は、ループは、キーワードのデータの各チャンクを調べるでしょうし、それが見つかった場合には、バッファにあるものは何でもファイルに書き込まれ、バッファがリセットされます、次のファイルの準備が整いました。私はPythonで動作するようにこれを得ている

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

あなたのストリーミングがいかに速いのだろうか。実際には、私はC/C++ opencvからソケット経由でimg base64を送ることで同じことをしようとしていました。私はそれを動作させることができましたが、フレームレートは遅く、非常に遅れています。 私はそれがより速くするためにいくつかのエンコーディングが必要と信じています。 –

+0

はい、このアプローチは圧縮を使用しないため、非常に遅いです。私はストリーミングを世話するためにGStreamerというものを使用して終了しました。その場で何らかの圧縮を行う類似のツールを使用することをお勧めします。とにかく、これはプログラミングのための良い練習でしたが、私は生産やデモシステムでもこのようなことはしません。 –

+0

GStreamerでは、ストリーミングビデオをWebページにどのように表示できますか? 今、まだ新しくてまだ標準化されていないwebrtcアプローチを見ています。ウェブカメラでビデオストリーミングを簡単に送信できますが、進行中のビデオファイルをストリーミングすることができます。 –

答えて

0

データの最後のビットがまだバッファされている間にendイベントが発生していると思われます。

endイベントではなく、closeイベントを待ってください。私はソケットについてはわかりませんが、spawnのような他のNode APIでは、関連するストリームがフラッシュされる前に、endイベントが早く起動されるため、待機中のバッファされたデータが残っている可能性があります。

配管でこれを自分で管理することは避けることができます。ファイルへのソケットストリームはfs.createWriteStream().pipe()です。